• 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 #include "quiche/quic/core/crypto/tls_server_connection.h"
6 
7 #include "absl/strings/string_view.h"
8 #include "openssl/ssl.h"
9 #include "quiche/quic/core/crypto/proof_source.h"
10 #include "quiche/quic/core/quic_types.h"
11 #include "quiche/quic/platform/api/quic_flag_utils.h"
12 #include "quiche/quic/platform/api/quic_flags.h"
13 
14 namespace quic {
15 
TlsServerConnection(SSL_CTX * ssl_ctx,Delegate * delegate,QuicSSLConfig ssl_config)16 TlsServerConnection::TlsServerConnection(SSL_CTX* ssl_ctx, Delegate* delegate,
17                                          QuicSSLConfig ssl_config)
18     : TlsConnection(ssl_ctx, delegate->ConnectionDelegate(),
19                     std::move(ssl_config)),
20       delegate_(delegate) {
21   // By default, cert verify callback is not installed on ssl(), so only need to
22   // UpdateCertVerifyCallback() if client_cert_mode is not kNone.
23   if (TlsConnection::ssl_config().client_cert_mode != ClientCertMode::kNone) {
24     UpdateCertVerifyCallback();
25   }
26 }
27 
28 // static
CreateSslCtx(ProofSource * proof_source)29 bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx(
30     ProofSource* proof_source) {
31   bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
32 
33   // Server does not request/verify client certs by default. Individual server
34   // connections may call SSL_set_custom_verify on their SSL object to request
35   // client certs.
36 
37   SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(),
38                                          &TlsExtServernameCallback);
39   SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr);
40   // We don't actually need the TicketCrypter here, but we need to know
41   // whether it's set.
42   if (proof_source->GetTicketCrypter()) {
43     QUIC_CODE_COUNT(quic_session_tickets_enabled);
44     SSL_CTX_set_ticket_aead_method(ssl_ctx.get(),
45                                    &TlsServerConnection::kSessionTicketMethod);
46   } else {
47     QUIC_CODE_COUNT(quic_session_tickets_disabled);
48   }
49 
50   SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
51 
52   SSL_CTX_set_select_certificate_cb(
53       ssl_ctx.get(), &TlsServerConnection::EarlySelectCertCallback);
54   SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
55 
56   // Allow ProofSource to change SSL_CTX settings.
57   proof_source->OnNewSslCtx(ssl_ctx.get());
58 
59   return ssl_ctx;
60 }
61 
SetCertChain(const std::vector<CRYPTO_BUFFER * > & cert_chain)62 void TlsServerConnection::SetCertChain(
63     const std::vector<CRYPTO_BUFFER*>& cert_chain) {
64   SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), nullptr,
65                         &TlsServerConnection::kPrivateKeyMethod);
66 }
67 
SetClientCertMode(ClientCertMode client_cert_mode)68 void TlsServerConnection::SetClientCertMode(ClientCertMode client_cert_mode) {
69   if (ssl_config().client_cert_mode == client_cert_mode) {
70     return;
71   }
72 
73   mutable_ssl_config().client_cert_mode = client_cert_mode;
74   UpdateCertVerifyCallback();
75 }
76 
UpdateCertVerifyCallback()77 void TlsServerConnection::UpdateCertVerifyCallback() {
78   const ClientCertMode client_cert_mode = ssl_config().client_cert_mode;
79   if (client_cert_mode == ClientCertMode::kNone) {
80     SSL_set_custom_verify(ssl(), SSL_VERIFY_NONE, nullptr);
81     return;
82   }
83 
84   int mode = SSL_VERIFY_PEER;
85   if (client_cert_mode == ClientCertMode::kRequire) {
86     mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
87   } else {
88     QUICHE_DCHECK_EQ(client_cert_mode, ClientCertMode::kRequest);
89   }
90   SSL_set_custom_verify(ssl(), mode, &VerifyCallback);
91 }
92 
93 const SSL_PRIVATE_KEY_METHOD TlsServerConnection::kPrivateKeyMethod{
94     &TlsServerConnection::PrivateKeySign,
95     nullptr,  // decrypt
96     &TlsServerConnection::PrivateKeyComplete,
97 };
98 
99 // static
ConnectionFromSsl(SSL * ssl)100 TlsServerConnection* TlsServerConnection::ConnectionFromSsl(SSL* ssl) {
101   return static_cast<TlsServerConnection*>(
102       TlsConnection::ConnectionFromSsl(ssl));
103 }
104 
105 // static
EarlySelectCertCallback(const SSL_CLIENT_HELLO * client_hello)106 ssl_select_cert_result_t TlsServerConnection::EarlySelectCertCallback(
107     const SSL_CLIENT_HELLO* client_hello) {
108   return ConnectionFromSsl(client_hello->ssl)
109       ->delegate_->EarlySelectCertCallback(client_hello);
110 }
111 
112 // static
TlsExtServernameCallback(SSL * ssl,int * out_alert,void *)113 int TlsServerConnection::TlsExtServernameCallback(SSL* ssl, int* out_alert,
114                                                   void* /*arg*/) {
115   return ConnectionFromSsl(ssl)->delegate_->TlsExtServernameCallback(out_alert);
116 }
117 
118 // static
SelectAlpnCallback(SSL * ssl,const uint8_t ** out,uint8_t * out_len,const uint8_t * in,unsigned in_len,void *)119 int TlsServerConnection::SelectAlpnCallback(SSL* ssl, const uint8_t** out,
120                                             uint8_t* out_len, const uint8_t* in,
121                                             unsigned in_len, void* /*arg*/) {
122   return ConnectionFromSsl(ssl)->delegate_->SelectAlpn(out, out_len, in,
123                                                        in_len);
124 }
125 
126 // static
PrivateKeySign(SSL * ssl,uint8_t * out,size_t * out_len,size_t max_out,uint16_t sig_alg,const uint8_t * in,size_t in_len)127 ssl_private_key_result_t TlsServerConnection::PrivateKeySign(
128     SSL* ssl, uint8_t* out, size_t* out_len, size_t max_out, uint16_t sig_alg,
129     const uint8_t* in, size_t in_len) {
130   return ConnectionFromSsl(ssl)->delegate_->PrivateKeySign(
131       out, out_len, max_out, sig_alg,
132       absl::string_view(reinterpret_cast<const char*>(in), in_len));
133 }
134 
135 // static
PrivateKeyComplete(SSL * ssl,uint8_t * out,size_t * out_len,size_t max_out)136 ssl_private_key_result_t TlsServerConnection::PrivateKeyComplete(
137     SSL* ssl, uint8_t* out, size_t* out_len, size_t max_out) {
138   return ConnectionFromSsl(ssl)->delegate_->PrivateKeyComplete(out, out_len,
139                                                                max_out);
140 }
141 
142 // static
143 const SSL_TICKET_AEAD_METHOD TlsServerConnection::kSessionTicketMethod{
144     TlsServerConnection::SessionTicketMaxOverhead,
145     TlsServerConnection::SessionTicketSeal,
146     TlsServerConnection::SessionTicketOpen,
147 };
148 
149 // static
SessionTicketMaxOverhead(SSL * ssl)150 size_t TlsServerConnection::SessionTicketMaxOverhead(SSL* ssl) {
151   return ConnectionFromSsl(ssl)->delegate_->SessionTicketMaxOverhead();
152 }
153 
154 // static
SessionTicketSeal(SSL * ssl,uint8_t * out,size_t * out_len,size_t max_out_len,const uint8_t * in,size_t in_len)155 int TlsServerConnection::SessionTicketSeal(SSL* ssl, uint8_t* out,
156                                            size_t* out_len, size_t max_out_len,
157                                            const uint8_t* in, size_t in_len) {
158   return ConnectionFromSsl(ssl)->delegate_->SessionTicketSeal(
159       out, out_len, max_out_len,
160       absl::string_view(reinterpret_cast<const char*>(in), in_len));
161 }
162 
163 // static
SessionTicketOpen(SSL * ssl,uint8_t * out,size_t * out_len,size_t max_out_len,const uint8_t * in,size_t in_len)164 enum ssl_ticket_aead_result_t TlsServerConnection::SessionTicketOpen(
165     SSL* ssl, uint8_t* out, size_t* out_len, size_t max_out_len,
166     const uint8_t* in, size_t in_len) {
167   return ConnectionFromSsl(ssl)->delegate_->SessionTicketOpen(
168       out, out_len, max_out_len,
169       absl::string_view(reinterpret_cast<const char*>(in), in_len));
170 }
171 
172 }  // namespace quic
173