xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/crypto/tls_server_connection.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
6 #define QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
7 
8 #include <cstddef>
9 #include <cstdint>
10 #include <vector>
11 
12 #include "absl/status/status.h"
13 #include "absl/strings/string_view.h"
14 #include "openssl/base.h"
15 #include "openssl/ssl.h"
16 #include "quiche/quic/core/crypto/proof_source.h"
17 #include "quiche/quic/core/crypto/tls_connection.h"
18 #include "quiche/quic/core/quic_types.h"
19 #include "quiche/common/platform/api/quiche_export.h"
20 
21 namespace quic {
22 
23 // TlsServerConnection receives calls for client-specific BoringSSL callbacks
24 // and calls its Delegate for the implementation of those callbacks.
25 class QUICHE_EXPORT TlsServerConnection : public TlsConnection {
26  public:
27   // A TlsServerConnection::Delegate implement the server-specific methods that
28   // are set as callbacks for an SSL object.
29   class QUICHE_EXPORT Delegate {
30    public:
~Delegate()31     virtual ~Delegate() {}
32 
33    protected:
34     // Called from BoringSSL right after SNI is extracted, which is very early
35     // in the handshake process.
36     virtual ssl_select_cert_result_t EarlySelectCertCallback(
37         const SSL_CLIENT_HELLO* client_hello) = 0;
38 
39     // Called after the ClientHello extensions have been successfully parsed.
40     // Returns an SSL_TLSEXT_ERR_* value (see
41     // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_CTX_set_tlsext_servername_callback).
42     //
43     // On success, return SSL_TLSEXT_ERR_OK causes the server_name extension to
44     // be acknowledged in the ServerHello, or return SSL_TLSEXT_ERR_NOACK which
45     // causes it to be not acknowledged.
46     //
47     // If the function returns SSL_TLSEXT_ERR_ALERT_FATAL, then it puts in
48     // |*out_alert| the TLS alert value that the server will send.
49     //
50     virtual int TlsExtServernameCallback(int* out_alert) = 0;
51 
52     // Selects which ALPN to use based on the list sent by the client.
53     virtual int SelectAlpn(const uint8_t** out, uint8_t* out_len,
54                            const uint8_t* in, unsigned in_len) = 0;
55 
56     // Signs |in| using the signature algorithm specified by |sig_alg| (an
57     // SSL_SIGN_* value). If the signing operation cannot be completed
58     // synchronously, ssl_private_key_retry is returned. If there is an error
59     // signing, or if the signature is longer than |max_out|, then
60     // ssl_private_key_failure is returned. Otherwise, ssl_private_key_success
61     // is returned with the signature put in |*out| and the length in
62     // |*out_len|.
63     virtual ssl_private_key_result_t PrivateKeySign(uint8_t* out,
64                                                     size_t* out_len,
65                                                     size_t max_out,
66                                                     uint16_t sig_alg,
67                                                     absl::string_view in) = 0;
68 
69     // When PrivateKeySign returns ssl_private_key_retry, PrivateKeyComplete
70     // will be called after the async sign operation has completed.
71     // PrivateKeyComplete puts the resulting signature in |*out| and length in
72     // |*out_len|. If the length is greater than |max_out| or if there was an
73     // error in signing, then ssl_private_key_failure is returned. Otherwise,
74     // ssl_private_key_success is returned.
75     virtual ssl_private_key_result_t PrivateKeyComplete(uint8_t* out,
76                                                         size_t* out_len,
77                                                         size_t max_out) = 0;
78 
79     // The following functions are used to implement an SSL_TICKET_AEAD_METHOD.
80     // See
81     // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#ssl_ticket_aead_result_t
82     // for details on the BoringSSL API.
83 
84     // SessionTicketMaxOverhead returns the maximum number of bytes of overhead
85     // that SessionTicketSeal may add when encrypting a session ticket.
86     virtual size_t SessionTicketMaxOverhead() = 0;
87 
88     // SessionTicketSeal encrypts the session ticket in |in|, putting the
89     // resulting encrypted ticket in |out|, writing the length of the bytes
90     // written to |*out_len|, which is no larger than |max_out_len|. It returns
91     // 1 on success and 0 on error.
92     virtual int SessionTicketSeal(uint8_t* out, size_t* out_len,
93                                   size_t max_out_len, absl::string_view in) = 0;
94 
95     // SessionTicketOpen is called when BoringSSL has an encrypted session
96     // ticket |in| and wants the ticket decrypted. This decryption operation can
97     // happen synchronously or asynchronously.
98     //
99     // If the decrypted ticket is not available at the time of the function
100     // call, this function returns ssl_ticket_aead_retry. If this function
101     // returns ssl_ticket_aead_retry, then SSL_do_handshake will return
102     // SSL_ERROR_PENDING_TICKET. Once the pending ticket decryption has
103     // completed, SSL_do_handshake needs to be called again.
104     //
105     // When this function is called and the decrypted ticket is available
106     // (either the ticket was decrypted synchronously, or an asynchronous
107     // operation has completed and SSL_do_handshake has been called again), the
108     // decrypted ticket is put in |out|, and the length of that output is
109     // written to |*out_len|, not to exceed |max_out_len|, and
110     // ssl_ticket_aead_success is returned. If the ticket cannot be decrypted
111     // and should be ignored, this function returns
112     // ssl_ticket_aead_ignore_ticket and a full handshake will be performed
113     // instead. If a fatal error occurs, ssl_ticket_aead_error can be returned
114     // which will terminate the handshake.
115     virtual enum ssl_ticket_aead_result_t SessionTicketOpen(
116         uint8_t* out, size_t* out_len, size_t max_out_len,
117         absl::string_view in) = 0;
118 
119     // Provides the delegate for callbacks that are shared between client and
120     // server.
121     virtual TlsConnection::Delegate* ConnectionDelegate() = 0;
122 
123     friend class TlsServerConnection;
124   };
125 
126   TlsServerConnection(SSL_CTX* ssl_ctx, Delegate* delegate,
127                       QuicSSLConfig ssl_config);
128 
129   // Creates and configures an SSL_CTX that is appropriate for servers to use.
130   static bssl::UniquePtr<SSL_CTX> CreateSslCtx(ProofSource* proof_source);
131 
132   // Invoke |configure_ssl| to configure the SSL object.
133   absl::Status ConfigureSSL(
134       ProofSourceHandleCallback::ConfigureSSLFunc configure_ssl);
135 
136   void SetCertChain(const std::vector<CRYPTO_BUFFER*>& cert_chain);
137 
138   // Set the client cert mode to be used on this connection. This should be
139   // called right after cert selection at the latest, otherwise it is too late
140   // to has an effect.
141   void SetClientCertMode(ClientCertMode client_cert_mode);
142 
143  private:
144   // Specialization of TlsConnection::ConnectionFromSsl.
145   static TlsServerConnection* ConnectionFromSsl(SSL* ssl);
146 
147   static ssl_select_cert_result_t EarlySelectCertCallback(
148       const SSL_CLIENT_HELLO* client_hello);
149 
150   // These functions are registered as callbacks in BoringSSL and delegate their
151   // implementation to the matching methods in Delegate above.
152   static int TlsExtServernameCallback(SSL* ssl, int* out_alert, void* arg);
153   static int SelectAlpnCallback(SSL* ssl, const uint8_t** out, uint8_t* out_len,
154                                 const uint8_t* in, unsigned in_len, void* arg);
155 
156   // |kPrivateKeyMethod| is a vtable pointing to PrivateKeySign and
157   // PrivateKeyComplete used by the TLS stack to compute the signature for the
158   // CertificateVerify message (using the server's private key).
159   static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
160 
161   // The following functions make up the contents of |kPrivateKeyMethod|.
162   static ssl_private_key_result_t PrivateKeySign(
163       SSL* ssl, uint8_t* out, size_t* out_len, size_t max_out, uint16_t sig_alg,
164       const uint8_t* in, size_t in_len);
165   static ssl_private_key_result_t PrivateKeyComplete(SSL* ssl, uint8_t* out,
166                                                      size_t* out_len,
167                                                      size_t max_out);
168 
169   // Implementation of SSL_TICKET_AEAD_METHOD which delegates to corresponding
170   // methods in TlsServerConnection::Delegate (a.k.a. TlsServerHandshaker).
171   static const SSL_TICKET_AEAD_METHOD kSessionTicketMethod;
172 
173   // The following functions make up the contents of |kSessionTicketMethod|.
174   static size_t SessionTicketMaxOverhead(SSL* ssl);
175   static int SessionTicketSeal(SSL* ssl, uint8_t* out, size_t* out_len,
176                                size_t max_out_len, const uint8_t* in,
177                                size_t in_len);
178   static enum ssl_ticket_aead_result_t SessionTicketOpen(SSL* ssl, uint8_t* out,
179                                                          size_t* out_len,
180                                                          size_t max_out_len,
181                                                          const uint8_t* in,
182                                                          size_t in_len);
183 
184   // Install custom verify callback on ssl() if |ssl_config().client_cert_mode|
185   // is not ClientCertMode::kNone. Uninstall otherwise.
186   void UpdateCertVerifyCallback();
187 
188   Delegate* delegate_;
189 };
190 
191 }  // namespace quic
192 
193 #endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
194