xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/crypto/tls_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_connection.h"
6 
7 #include "absl/strings/string_view.h"
8 #include "openssl/ssl.h"
9 #include "quiche/quic/platform/api/quic_bug_tracker.h"
10 
11 namespace quic {
12 
13 namespace {
14 
15 // BoringSSL allows storing extra data off of some of its data structures,
16 // including the SSL struct. To allow for multiple callers to store data, each
17 // caller can use a different index for setting and getting data. These indices
18 // are globals handed out by calling SSL_get_ex_new_index.
19 //
20 // SslIndexSingleton calls SSL_get_ex_new_index on its construction, and then
21 // provides this index to be used in calls to SSL_get_ex_data/SSL_set_ex_data.
22 // This is used to store in the SSL struct a pointer to the TlsConnection which
23 // owns it.
24 class SslIndexSingleton {
25  public:
GetInstance()26   static SslIndexSingleton* GetInstance() {
27     static SslIndexSingleton* instance = new SslIndexSingleton();
28     return instance;
29   }
30 
ssl_ex_data_index_connection() const31   int ssl_ex_data_index_connection() const {
32     return ssl_ex_data_index_connection_;
33   }
34 
35  private:
SslIndexSingleton()36   SslIndexSingleton() {
37     CRYPTO_library_init();
38     ssl_ex_data_index_connection_ =
39         SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
40     QUICHE_CHECK_LE(0, ssl_ex_data_index_connection_);
41   }
42 
43   SslIndexSingleton(const SslIndexSingleton&) = delete;
44   SslIndexSingleton& operator=(const SslIndexSingleton&) = delete;
45 
46   // The index to supply to SSL_get_ex_data/SSL_set_ex_data for getting/setting
47   // the TlsConnection pointer.
48   int ssl_ex_data_index_connection_;
49 };
50 
51 }  // namespace
52 
53 // static
QuicEncryptionLevel(enum ssl_encryption_level_t level)54 EncryptionLevel TlsConnection::QuicEncryptionLevel(
55     enum ssl_encryption_level_t level) {
56   switch (level) {
57     case ssl_encryption_initial:
58       return ENCRYPTION_INITIAL;
59     case ssl_encryption_early_data:
60       return ENCRYPTION_ZERO_RTT;
61     case ssl_encryption_handshake:
62       return ENCRYPTION_HANDSHAKE;
63     case ssl_encryption_application:
64       return ENCRYPTION_FORWARD_SECURE;
65     default:
66       QUIC_BUG(quic_bug_10698_1)
67           << "Invalid ssl_encryption_level_t " << static_cast<int>(level);
68       return ENCRYPTION_INITIAL;
69   }
70 }
71 
72 // static
BoringEncryptionLevel(EncryptionLevel level)73 enum ssl_encryption_level_t TlsConnection::BoringEncryptionLevel(
74     EncryptionLevel level) {
75   switch (level) {
76     case ENCRYPTION_INITIAL:
77       return ssl_encryption_initial;
78     case ENCRYPTION_HANDSHAKE:
79       return ssl_encryption_handshake;
80     case ENCRYPTION_ZERO_RTT:
81       return ssl_encryption_early_data;
82     case ENCRYPTION_FORWARD_SECURE:
83       return ssl_encryption_application;
84     default:
85       QUIC_BUG(quic_bug_10698_2)
86           << "Invalid encryption level " << static_cast<int>(level);
87       return ssl_encryption_initial;
88   }
89 }
90 
TlsConnection(SSL_CTX * ssl_ctx,TlsConnection::Delegate * delegate,QuicSSLConfig ssl_config)91 TlsConnection::TlsConnection(SSL_CTX* ssl_ctx,
92                              TlsConnection::Delegate* delegate,
93                              QuicSSLConfig ssl_config)
94     : delegate_(delegate),
95       ssl_(SSL_new(ssl_ctx)),
96       ssl_config_(std::move(ssl_config)) {
97   SSL_set_ex_data(
98       ssl(), SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection(),
99       this);
100   if (ssl_config_.early_data_enabled.has_value()) {
101     const int early_data_enabled = *ssl_config_.early_data_enabled ? 1 : 0;
102     SSL_set_early_data_enabled(ssl(), early_data_enabled);
103   }
104   if (ssl_config_.signing_algorithm_prefs.has_value()) {
105     SSL_set_signing_algorithm_prefs(
106         ssl(), ssl_config_.signing_algorithm_prefs->data(),
107         ssl_config_.signing_algorithm_prefs->size());
108   }
109   if (ssl_config_.disable_ticket_support.has_value()) {
110     if (*ssl_config_.disable_ticket_support) {
111       SSL_set_options(ssl(), SSL_OP_NO_TICKET);
112     }
113   }
114 }
115 
EnableInfoCallback()116 void TlsConnection::EnableInfoCallback() {
117   SSL_set_info_callback(
118       ssl(), +[](const SSL* ssl, int type, int value) {
119         ConnectionFromSsl(ssl)->delegate_->InfoCallback(type, value);
120       });
121 }
122 
DisableTicketSupport()123 void TlsConnection::DisableTicketSupport() {
124   ssl_config_.disable_ticket_support = true;
125   SSL_set_options(ssl(), SSL_OP_NO_TICKET);
126 }
127 
128 // static
CreateSslCtx()129 bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx() {
130   CRYPTO_library_init();
131   bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_with_buffers_method()));
132   SSL_CTX_set_min_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
133   SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
134   SSL_CTX_set_quic_method(ssl_ctx.get(), &kSslQuicMethod);
135   SSL_CTX_set_msg_callback(ssl_ctx.get(), &MessageCallback);
136   return ssl_ctx;
137 }
138 
139 // static
ConnectionFromSsl(const SSL * ssl)140 TlsConnection* TlsConnection::ConnectionFromSsl(const SSL* ssl) {
141   return reinterpret_cast<TlsConnection*>(SSL_get_ex_data(
142       ssl, SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection()));
143 }
144 
145 // static
VerifyCallback(SSL * ssl,uint8_t * out_alert)146 enum ssl_verify_result_t TlsConnection::VerifyCallback(SSL* ssl,
147                                                        uint8_t* out_alert) {
148   return ConnectionFromSsl(ssl)->delegate_->VerifyCert(out_alert);
149 }
150 
151 const SSL_QUIC_METHOD TlsConnection::kSslQuicMethod{
152     TlsConnection::SetReadSecretCallback, TlsConnection::SetWriteSecretCallback,
153     TlsConnection::WriteMessageCallback, TlsConnection::FlushFlightCallback,
154     TlsConnection::SendAlertCallback};
155 
156 // static
SetReadSecretCallback(SSL * ssl,enum ssl_encryption_level_t level,const SSL_CIPHER * cipher,const uint8_t * secret,size_t secret_length)157 int TlsConnection::SetReadSecretCallback(SSL* ssl,
158                                          enum ssl_encryption_level_t level,
159                                          const SSL_CIPHER* cipher,
160                                          const uint8_t* secret,
161                                          size_t secret_length) {
162   TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
163   if (!delegate->SetReadSecret(QuicEncryptionLevel(level), cipher,
164                                absl::MakeSpan(secret, secret_length))) {
165     return 0;
166   }
167   return 1;
168 }
169 
170 // static
SetWriteSecretCallback(SSL * ssl,enum ssl_encryption_level_t level,const SSL_CIPHER * cipher,const uint8_t * secret,size_t secret_length)171 int TlsConnection::SetWriteSecretCallback(SSL* ssl,
172                                           enum ssl_encryption_level_t level,
173                                           const SSL_CIPHER* cipher,
174                                           const uint8_t* secret,
175                                           size_t secret_length) {
176   TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
177   delegate->SetWriteSecret(QuicEncryptionLevel(level), cipher,
178                            absl::MakeSpan(secret, secret_length));
179   return 1;
180 }
181 
182 // static
WriteMessageCallback(SSL * ssl,enum ssl_encryption_level_t level,const uint8_t * data,size_t len)183 int TlsConnection::WriteMessageCallback(SSL* ssl,
184                                         enum ssl_encryption_level_t level,
185                                         const uint8_t* data, size_t len) {
186   ConnectionFromSsl(ssl)->delegate_->WriteMessage(
187       QuicEncryptionLevel(level),
188       absl::string_view(reinterpret_cast<const char*>(data), len));
189   return 1;
190 }
191 
192 // static
FlushFlightCallback(SSL * ssl)193 int TlsConnection::FlushFlightCallback(SSL* ssl) {
194   ConnectionFromSsl(ssl)->delegate_->FlushFlight();
195   return 1;
196 }
197 
198 // static
SendAlertCallback(SSL * ssl,enum ssl_encryption_level_t level,uint8_t desc)199 int TlsConnection::SendAlertCallback(SSL* ssl,
200                                      enum ssl_encryption_level_t level,
201                                      uint8_t desc) {
202   ConnectionFromSsl(ssl)->delegate_->SendAlert(QuicEncryptionLevel(level),
203                                                desc);
204   return 1;
205 }
206 
207 // static
MessageCallback(int is_write,int version,int content_type,const void * buf,size_t len,SSL * ssl,void *)208 void TlsConnection::MessageCallback(int is_write, int version, int content_type,
209                                     const void* buf, size_t len, SSL* ssl,
210                                     void*) {
211   ConnectionFromSsl(ssl)->delegate_->MessageCallback(
212       is_write != 0, version, content_type,
213       absl::string_view(static_cast<const char*>(buf), len));
214 }
215 
216 }  // namespace quic
217