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