xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/crypto/tls_server_connection.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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