xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2017 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/tls_handshaker.h"
6 
7 #include "absl/base/macros.h"
8 #include "absl/strings/str_cat.h"
9 #include "absl/strings/string_view.h"
10 #include "openssl/crypto.h"
11 #include "openssl/ssl.h"
12 #include "quiche/quic/core/quic_crypto_stream.h"
13 #include "quiche/quic/platform/api/quic_bug_tracker.h"
14 #include "quiche/quic/platform/api/quic_stack_trace.h"
15 
16 namespace quic {
17 
18 #define ENDPOINT (SSL_is_server(ssl()) ? "TlsServer: " : "TlsClient: ")
19 
ProofVerifierCallbackImpl(TlsHandshaker * parent)20 TlsHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
21     TlsHandshaker* parent)
22     : parent_(parent) {}
23 
~ProofVerifierCallbackImpl()24 TlsHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {}
25 
Run(bool ok,const std::string &,std::unique_ptr<ProofVerifyDetails> * details)26 void TlsHandshaker::ProofVerifierCallbackImpl::Run(
27     bool ok, const std::string& /*error_details*/,
28     std::unique_ptr<ProofVerifyDetails>* details) {
29   if (parent_ == nullptr) {
30     return;
31   }
32 
33   parent_->verify_details_ = std::move(*details);
34   parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid;
35   parent_->set_expected_ssl_error(SSL_ERROR_WANT_READ);
36   parent_->proof_verify_callback_ = nullptr;
37   if (parent_->verify_details_) {
38     parent_->OnProofVerifyDetailsAvailable(*parent_->verify_details_);
39   }
40   parent_->AdvanceHandshake();
41 }
42 
Cancel()43 void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() { parent_ = nullptr; }
44 
TlsHandshaker(QuicCryptoStream * stream,QuicSession * session)45 TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream, QuicSession* session)
46     : stream_(stream), handshaker_delegate_(session) {}
47 
~TlsHandshaker()48 TlsHandshaker::~TlsHandshaker() {
49   if (proof_verify_callback_) {
50     proof_verify_callback_->Cancel();
51   }
52 }
53 
ProcessInput(absl::string_view input,EncryptionLevel level)54 bool TlsHandshaker::ProcessInput(absl::string_view input,
55                                  EncryptionLevel level) {
56   if (parser_error_ != QUIC_NO_ERROR) {
57     return false;
58   }
59   // TODO(nharper): Call SSL_quic_read_level(ssl()) and check whether the
60   // encryption level BoringSSL expects matches the encryption level that we
61   // just received input at. If they mismatch, should ProcessInput return true
62   // or false? If data is for a future encryption level, it should be queued for
63   // later?
64   if (SSL_provide_quic_data(ssl(), TlsConnection::BoringEncryptionLevel(level),
65                             reinterpret_cast<const uint8_t*>(input.data()),
66                             input.size()) != 1) {
67     // SSL_provide_quic_data can fail for 3 reasons:
68     // - API misuse (calling it before SSL_set_custom_quic_method, which we
69     //   call in the TlsHandshaker c'tor)
70     // - Memory exhaustion when appending data to its buffer
71     // - Data provided at the wrong encryption level
72     //
73     // Of these, the only sensible error to handle is data provided at the wrong
74     // encryption level.
75     //
76     // Note: the error provided below has a good-sounding enum value, although
77     // it doesn't match the description as it's a QUIC Crypto specific error.
78     parser_error_ = QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
79     parser_error_detail_ = "TLS stack failed to receive data";
80     return false;
81   }
82   AdvanceHandshake();
83   return true;
84 }
85 
AdvanceHandshake()86 void TlsHandshaker::AdvanceHandshake() {
87   if (is_connection_closed()) {
88     return;
89   }
90   if (GetHandshakeState() >= HANDSHAKE_COMPLETE) {
91     ProcessPostHandshakeMessage();
92     return;
93   }
94 
95   QUICHE_BUG_IF(
96       quic_tls_server_async_done_no_flusher,
97       SSL_is_server(ssl()) && !handshaker_delegate_->PacketFlusherAttached())
98       << "is_server:" << SSL_is_server(ssl());
99 
100   QUIC_VLOG(1) << ENDPOINT << "Continuing handshake";
101   last_tls_alert_.reset();
102   int rv = SSL_do_handshake(ssl());
103 
104   if (is_connection_closed()) {
105     return;
106   }
107 
108   // If SSL_do_handshake return success(1) and we are in early data, it is
109   // possible that we have provided ServerHello to BoringSSL but it hasn't been
110   // processed. Retry SSL_do_handshake once will advance the handshake more in
111   // that case. If there are no unprocessed ServerHello, the retry will return a
112   // non-positive number.
113   if (rv == 1 && SSL_in_early_data(ssl())) {
114     OnEnterEarlyData();
115     rv = SSL_do_handshake(ssl());
116 
117     if (is_connection_closed()) {
118       return;
119     }
120 
121     QUIC_VLOG(1) << ENDPOINT
122                  << "SSL_do_handshake returned when entering early data. After "
123                  << "retry, rv=" << rv
124                  << ", SSL_in_early_data=" << SSL_in_early_data(ssl());
125     // The retry should either
126     // - Return <= 0 if the handshake is still pending, likely still in early
127     //   data.
128     // - Return 1 if the handshake has _actually_ finished. i.e.
129     //   SSL_in_early_data should be false.
130     //
131     // In either case, it should not both return 1 and stay in early data.
132     if (rv == 1 && SSL_in_early_data(ssl()) && !is_connection_closed()) {
133       QUIC_BUG(quic_handshaker_stay_in_early_data)
134           << "The original and the retry of SSL_do_handshake both returned "
135              "success and in early data";
136       CloseConnection(QUIC_HANDSHAKE_FAILED,
137                       "TLS handshake failed: Still in early data after retry");
138       return;
139     }
140   }
141 
142   if (rv == 1) {
143     FinishHandshake();
144     return;
145   }
146   int ssl_error = SSL_get_error(ssl(), rv);
147   if (ssl_error == expected_ssl_error_) {
148     return;
149   }
150   if (ShouldCloseConnectionOnUnexpectedError(ssl_error) &&
151       !is_connection_closed()) {
152     QUIC_VLOG(1) << "SSL_do_handshake failed; SSL_get_error returns "
153                  << ssl_error;
154     ERR_print_errors_fp(stderr);
155     if (last_tls_alert_.has_value()) {
156       std::string error_details =
157           absl::StrCat("TLS handshake failure (",
158                        EncryptionLevelToString(last_tls_alert_->level), ") ",
159                        static_cast<int>(last_tls_alert_->desc), ": ",
160                        SSL_alert_desc_string_long(last_tls_alert_->desc));
161       QUIC_DLOG(ERROR) << error_details;
162       CloseConnection(TlsAlertToQuicErrorCode(last_tls_alert_->desc),
163                       static_cast<QuicIetfTransportErrorCodes>(
164                           CRYPTO_ERROR_FIRST + last_tls_alert_->desc),
165                       error_details);
166     } else {
167       CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failed");
168     }
169   }
170 }
171 
CloseConnection(QuicErrorCode error,const std::string & reason_phrase)172 void TlsHandshaker::CloseConnection(QuicErrorCode error,
173                                     const std::string& reason_phrase) {
174   QUICHE_DCHECK(!reason_phrase.empty());
175   stream()->OnUnrecoverableError(error, reason_phrase);
176   is_connection_closed_ = true;
177 }
178 
CloseConnection(QuicErrorCode error,QuicIetfTransportErrorCodes ietf_error,const std::string & reason_phrase)179 void TlsHandshaker::CloseConnection(QuicErrorCode error,
180                                     QuicIetfTransportErrorCodes ietf_error,
181                                     const std::string& reason_phrase) {
182   QUICHE_DCHECK(!reason_phrase.empty());
183   stream()->OnUnrecoverableError(error, ietf_error, reason_phrase);
184   is_connection_closed_ = true;
185 }
186 
OnConnectionClosed(QuicErrorCode,ConnectionCloseSource)187 void TlsHandshaker::OnConnectionClosed(QuicErrorCode /*error*/,
188                                        ConnectionCloseSource /*source*/) {
189   is_connection_closed_ = true;
190 }
191 
ShouldCloseConnectionOnUnexpectedError(int)192 bool TlsHandshaker::ShouldCloseConnectionOnUnexpectedError(int /*ssl_error*/) {
193   return true;
194 }
195 
BufferSizeLimitForLevel(EncryptionLevel level) const196 size_t TlsHandshaker::BufferSizeLimitForLevel(EncryptionLevel level) const {
197   return SSL_quic_max_handshake_flight_len(
198       ssl(), TlsConnection::BoringEncryptionLevel(level));
199 }
200 
EarlyDataReason() const201 ssl_early_data_reason_t TlsHandshaker::EarlyDataReason() const {
202   return SSL_get_early_data_reason(ssl());
203 }
204 
Prf(const SSL_CIPHER * cipher)205 const EVP_MD* TlsHandshaker::Prf(const SSL_CIPHER* cipher) {
206 #if BORINGSSL_API_VERSION >= 23
207   return SSL_CIPHER_get_handshake_digest(cipher);
208 #else
209   return EVP_get_digestbynid(SSL_CIPHER_get_prf_nid(cipher));
210 #endif
211 }
212 
VerifyCert(uint8_t * out_alert)213 enum ssl_verify_result_t TlsHandshaker::VerifyCert(uint8_t* out_alert) {
214   if (verify_result_ != ssl_verify_retry ||
215       expected_ssl_error() == SSL_ERROR_WANT_CERTIFICATE_VERIFY) {
216     enum ssl_verify_result_t result = verify_result_;
217     verify_result_ = ssl_verify_retry;
218     *out_alert = cert_verify_tls_alert_;
219     return result;
220   }
221   const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl());
222   if (cert_chain == nullptr) {
223     *out_alert = SSL_AD_INTERNAL_ERROR;
224     return ssl_verify_invalid;
225   }
226   // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies.
227   std::vector<std::string> certs;
228   for (CRYPTO_BUFFER* cert : cert_chain) {
229     certs.push_back(
230         std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)),
231                     CRYPTO_BUFFER_len(cert)));
232   }
233   QUIC_DVLOG(1) << "VerifyCert: peer cert_chain length: " << certs.size();
234 
235   ProofVerifierCallbackImpl* proof_verify_callback =
236       new ProofVerifierCallbackImpl(this);
237 
238   cert_verify_tls_alert_ = *out_alert;
239   QuicAsyncStatus verify_result = VerifyCertChain(
240       certs, &cert_verify_error_details_, &verify_details_,
241       &cert_verify_tls_alert_,
242       std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
243   switch (verify_result) {
244     case QUIC_SUCCESS:
245       if (verify_details_) {
246         OnProofVerifyDetailsAvailable(*verify_details_);
247       }
248       return ssl_verify_ok;
249     case QUIC_PENDING:
250       proof_verify_callback_ = proof_verify_callback;
251       set_expected_ssl_error(SSL_ERROR_WANT_CERTIFICATE_VERIFY);
252       return ssl_verify_retry;
253     case QUIC_FAILURE:
254     default:
255       *out_alert = cert_verify_tls_alert_;
256       QUIC_LOG(INFO) << "Cert chain verification failed: "
257                      << cert_verify_error_details_;
258       return ssl_verify_invalid;
259   }
260 }
261 
SetWriteSecret(EncryptionLevel level,const SSL_CIPHER * cipher,absl::Span<const uint8_t> write_secret)262 void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
263                                    const SSL_CIPHER* cipher,
264                                    absl::Span<const uint8_t> write_secret) {
265   QUIC_DVLOG(1) << ENDPOINT << "SetWriteSecret level=" << level;
266   std::unique_ptr<QuicEncrypter> encrypter =
267       QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
268   const EVP_MD* prf = Prf(cipher);
269   CryptoUtils::SetKeyAndIV(prf, write_secret,
270                            handshaker_delegate_->parsed_version(),
271                            encrypter.get());
272   std::vector<uint8_t> header_protection_key =
273       CryptoUtils::GenerateHeaderProtectionKey(
274           prf, write_secret, handshaker_delegate_->parsed_version(),
275           encrypter->GetKeySize());
276   encrypter->SetHeaderProtectionKey(
277       absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
278                         header_protection_key.size()));
279   if (level == ENCRYPTION_FORWARD_SECURE) {
280     QUICHE_DCHECK(latest_write_secret_.empty());
281     latest_write_secret_.assign(write_secret.begin(), write_secret.end());
282     one_rtt_write_header_protection_key_ = header_protection_key;
283   }
284   handshaker_delegate_->OnNewEncryptionKeyAvailable(level,
285                                                     std::move(encrypter));
286 }
287 
SetReadSecret(EncryptionLevel level,const SSL_CIPHER * cipher,absl::Span<const uint8_t> read_secret)288 bool TlsHandshaker::SetReadSecret(EncryptionLevel level,
289                                   const SSL_CIPHER* cipher,
290                                   absl::Span<const uint8_t> read_secret) {
291   QUIC_DVLOG(1) << ENDPOINT << "SetReadSecret level=" << level
292                 << ", connection_closed=" << is_connection_closed();
293 
294   if (is_connection_closed()) {
295     return false;
296   }
297 
298   std::unique_ptr<QuicDecrypter> decrypter =
299       QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
300   const EVP_MD* prf = Prf(cipher);
301   CryptoUtils::SetKeyAndIV(prf, read_secret,
302                            handshaker_delegate_->parsed_version(),
303                            decrypter.get());
304   std::vector<uint8_t> header_protection_key =
305       CryptoUtils::GenerateHeaderProtectionKey(
306           prf, read_secret, handshaker_delegate_->parsed_version(),
307           decrypter->GetKeySize());
308   decrypter->SetHeaderProtectionKey(
309       absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
310                         header_protection_key.size()));
311   if (level == ENCRYPTION_FORWARD_SECURE) {
312     QUICHE_DCHECK(latest_read_secret_.empty());
313     latest_read_secret_.assign(read_secret.begin(), read_secret.end());
314     one_rtt_read_header_protection_key_ = header_protection_key;
315   }
316   return handshaker_delegate_->OnNewDecryptionKeyAvailable(
317       level, std::move(decrypter),
318       /*set_alternative_decrypter=*/false,
319       /*latch_once_used=*/false);
320 }
321 
322 std::unique_ptr<QuicDecrypter>
AdvanceKeysAndCreateCurrentOneRttDecrypter()323 TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
324   if (latest_read_secret_.empty() || latest_write_secret_.empty() ||
325       one_rtt_read_header_protection_key_.empty() ||
326       one_rtt_write_header_protection_key_.empty()) {
327     std::string error_details = "1-RTT secret(s) not set yet.";
328     QUIC_BUG(quic_bug_10312_1) << error_details;
329     CloseConnection(QUIC_INTERNAL_ERROR, error_details);
330     return nullptr;
331   }
332   const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
333   const EVP_MD* prf = Prf(cipher);
334   latest_read_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
335       prf, handshaker_delegate_->parsed_version(), latest_read_secret_);
336   latest_write_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
337       prf, handshaker_delegate_->parsed_version(), latest_write_secret_);
338 
339   std::unique_ptr<QuicDecrypter> decrypter =
340       QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
341   CryptoUtils::SetKeyAndIV(prf, latest_read_secret_,
342                            handshaker_delegate_->parsed_version(),
343                            decrypter.get());
344   decrypter->SetHeaderProtectionKey(absl::string_view(
345       reinterpret_cast<char*>(one_rtt_read_header_protection_key_.data()),
346       one_rtt_read_header_protection_key_.size()));
347 
348   return decrypter;
349 }
350 
CreateCurrentOneRttEncrypter()351 std::unique_ptr<QuicEncrypter> TlsHandshaker::CreateCurrentOneRttEncrypter() {
352   if (latest_write_secret_.empty() ||
353       one_rtt_write_header_protection_key_.empty()) {
354     std::string error_details = "1-RTT write secret not set yet.";
355     QUIC_BUG(quic_bug_10312_2) << error_details;
356     CloseConnection(QUIC_INTERNAL_ERROR, error_details);
357     return nullptr;
358   }
359   const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
360   std::unique_ptr<QuicEncrypter> encrypter =
361       QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
362   CryptoUtils::SetKeyAndIV(Prf(cipher), latest_write_secret_,
363                            handshaker_delegate_->parsed_version(),
364                            encrypter.get());
365   encrypter->SetHeaderProtectionKey(absl::string_view(
366       reinterpret_cast<char*>(one_rtt_write_header_protection_key_.data()),
367       one_rtt_write_header_protection_key_.size()));
368   return encrypter;
369 }
370 
ExportKeyingMaterialForLabel(absl::string_view label,absl::string_view context,size_t result_len,std::string * result)371 bool TlsHandshaker::ExportKeyingMaterialForLabel(absl::string_view label,
372                                                  absl::string_view context,
373                                                  size_t result_len,
374                                                  std::string* result) {
375   if (result == nullptr) {
376     return false;
377   }
378   result->resize(result_len);
379   return SSL_export_keying_material(
380              ssl(), reinterpret_cast<uint8_t*>(&*result->begin()), result_len,
381              label.data(), label.size(),
382              reinterpret_cast<const uint8_t*>(context.data()), context.size(),
383              !context.empty()) == 1;
384 }
385 
WriteMessage(EncryptionLevel level,absl::string_view data)386 void TlsHandshaker::WriteMessage(EncryptionLevel level,
387                                  absl::string_view data) {
388   stream_->WriteCryptoData(level, data);
389 }
390 
FlushFlight()391 void TlsHandshaker::FlushFlight() {}
392 
SendAlert(EncryptionLevel level,uint8_t desc)393 void TlsHandshaker::SendAlert(EncryptionLevel level, uint8_t desc) {
394   TlsAlert tls_alert;
395   tls_alert.level = level;
396   tls_alert.desc = desc;
397   last_tls_alert_ = tls_alert;
398 }
399 
MessageCallback(bool is_write,int,int content_type,absl::string_view data)400 void TlsHandshaker::MessageCallback(bool is_write, int /*version*/,
401                                     int content_type, absl::string_view data) {
402 #if BORINGSSL_API_VERSION >= 17
403   if (content_type == SSL3_RT_CLIENT_HELLO_INNER) {
404     // Notify QuicConnectionDebugVisitor. Most TLS messages can be seen in
405     // CRYPTO frames, but, with ECH enabled, the ClientHelloInner is encrypted
406     // separately.
407     if (is_write) {
408       handshaker_delegate_->OnEncryptedClientHelloSent(data);
409     } else {
410       handshaker_delegate_->OnEncryptedClientHelloReceived(data);
411     }
412   }
413 #else   // BORINGSSL_API_VERSION
414   (void)is_write;
415   (void)content_type;
416   (void)data;
417 #endif  // BORINGSSL_API_VERSION
418 }
419 
420 }  // namespace quic
421