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