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