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