• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 (dont_close_connection_in_tls_alert_callback_ &&
156         last_tls_alert_.has_value()) {
157       QUIC_RELOADABLE_FLAG_COUNT_N(
158           quic_dont_close_connection_in_tls_alert_callback, 2, 2);
159       std::string error_details =
160           absl::StrCat("TLS handshake failure (",
161                        EncryptionLevelToString(last_tls_alert_->level), ") ",
162                        static_cast<int>(last_tls_alert_->desc), ": ",
163                        SSL_alert_desc_string_long(last_tls_alert_->desc));
164       QUIC_DLOG(ERROR) << error_details;
165       CloseConnection(TlsAlertToQuicErrorCode(last_tls_alert_->desc),
166                       static_cast<QuicIetfTransportErrorCodes>(
167                           CRYPTO_ERROR_FIRST + last_tls_alert_->desc),
168                       error_details);
169     } else {
170       CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failed");
171     }
172   }
173 }
174 
CloseConnection(QuicErrorCode error,const std::string & reason_phrase)175 void TlsHandshaker::CloseConnection(QuicErrorCode error,
176                                     const std::string& reason_phrase) {
177   QUICHE_DCHECK(!reason_phrase.empty());
178   stream()->OnUnrecoverableError(error, reason_phrase);
179   is_connection_closed_ = true;
180 }
181 
CloseConnection(QuicErrorCode error,QuicIetfTransportErrorCodes ietf_error,const std::string & reason_phrase)182 void TlsHandshaker::CloseConnection(QuicErrorCode error,
183                                     QuicIetfTransportErrorCodes ietf_error,
184                                     const std::string& reason_phrase) {
185   QUICHE_DCHECK(!reason_phrase.empty());
186   stream()->OnUnrecoverableError(error, ietf_error, reason_phrase);
187   is_connection_closed_ = true;
188 }
189 
OnConnectionClosed(QuicErrorCode,ConnectionCloseSource)190 void TlsHandshaker::OnConnectionClosed(QuicErrorCode /*error*/,
191                                        ConnectionCloseSource /*source*/) {
192   is_connection_closed_ = true;
193 }
194 
ShouldCloseConnectionOnUnexpectedError(int)195 bool TlsHandshaker::ShouldCloseConnectionOnUnexpectedError(int /*ssl_error*/) {
196   return true;
197 }
198 
BufferSizeLimitForLevel(EncryptionLevel level) const199 size_t TlsHandshaker::BufferSizeLimitForLevel(EncryptionLevel level) const {
200   return SSL_quic_max_handshake_flight_len(
201       ssl(), TlsConnection::BoringEncryptionLevel(level));
202 }
203 
EarlyDataReason() const204 ssl_early_data_reason_t TlsHandshaker::EarlyDataReason() const {
205   return SSL_get_early_data_reason(ssl());
206 }
207 
Prf(const SSL_CIPHER * cipher)208 const EVP_MD* TlsHandshaker::Prf(const SSL_CIPHER* cipher) {
209   return EVP_get_digestbynid(SSL_CIPHER_get_prf_nid(cipher));
210 }
211 
VerifyCert(uint8_t * out_alert)212 enum ssl_verify_result_t TlsHandshaker::VerifyCert(uint8_t* out_alert) {
213   if (verify_result_ != ssl_verify_retry ||
214       expected_ssl_error() == SSL_ERROR_WANT_CERTIFICATE_VERIFY) {
215     enum ssl_verify_result_t result = verify_result_;
216     verify_result_ = ssl_verify_retry;
217     *out_alert = cert_verify_tls_alert_;
218     return result;
219   }
220   const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl());
221   if (cert_chain == nullptr) {
222     *out_alert = SSL_AD_INTERNAL_ERROR;
223     return ssl_verify_invalid;
224   }
225   // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies.
226   std::vector<std::string> certs;
227   for (CRYPTO_BUFFER* cert : cert_chain) {
228     certs.push_back(
229         std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)),
230                     CRYPTO_BUFFER_len(cert)));
231   }
232   QUIC_DVLOG(1) << "VerifyCert: peer cert_chain length: " << certs.size();
233 
234   ProofVerifierCallbackImpl* proof_verify_callback =
235       new ProofVerifierCallbackImpl(this);
236 
237   cert_verify_tls_alert_ = *out_alert;
238   QuicAsyncStatus verify_result = VerifyCertChain(
239       certs, &cert_verify_error_details_, &verify_details_,
240       &cert_verify_tls_alert_,
241       std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
242   switch (verify_result) {
243     case QUIC_SUCCESS:
244       if (verify_details_) {
245         OnProofVerifyDetailsAvailable(*verify_details_);
246       }
247       return ssl_verify_ok;
248     case QUIC_PENDING:
249       proof_verify_callback_ = proof_verify_callback;
250       set_expected_ssl_error(SSL_ERROR_WANT_CERTIFICATE_VERIFY);
251       return ssl_verify_retry;
252     case QUIC_FAILURE:
253     default:
254       *out_alert = cert_verify_tls_alert_;
255       QUIC_LOG(INFO) << "Cert chain verification failed: "
256                      << cert_verify_error_details_;
257       return ssl_verify_invalid;
258   }
259 }
260 
SetWriteSecret(EncryptionLevel level,const SSL_CIPHER * cipher,absl::Span<const uint8_t> write_secret)261 void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
262                                    const SSL_CIPHER* cipher,
263                                    absl::Span<const uint8_t> write_secret) {
264   QUIC_DVLOG(1) << ENDPOINT << "SetWriteSecret level=" << level;
265   std::unique_ptr<QuicEncrypter> encrypter =
266       QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
267   const EVP_MD* prf = Prf(cipher);
268   CryptoUtils::SetKeyAndIV(prf, write_secret,
269                            handshaker_delegate_->parsed_version(),
270                            encrypter.get());
271   std::vector<uint8_t> header_protection_key =
272       CryptoUtils::GenerateHeaderProtectionKey(
273           prf, write_secret, handshaker_delegate_->parsed_version(),
274           encrypter->GetKeySize());
275   encrypter->SetHeaderProtectionKey(
276       absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
277                         header_protection_key.size()));
278   if (level == ENCRYPTION_FORWARD_SECURE) {
279     QUICHE_DCHECK(latest_write_secret_.empty());
280     latest_write_secret_.assign(write_secret.begin(), write_secret.end());
281     one_rtt_write_header_protection_key_ = header_protection_key;
282   }
283   handshaker_delegate_->OnNewEncryptionKeyAvailable(level,
284                                                     std::move(encrypter));
285 }
286 
SetReadSecret(EncryptionLevel level,const SSL_CIPHER * cipher,absl::Span<const uint8_t> read_secret)287 bool TlsHandshaker::SetReadSecret(EncryptionLevel level,
288                                   const SSL_CIPHER* cipher,
289                                   absl::Span<const uint8_t> read_secret) {
290   QUIC_DVLOG(1) << ENDPOINT << "SetReadSecret level=" << level;
291   std::unique_ptr<QuicDecrypter> decrypter =
292       QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
293   const EVP_MD* prf = Prf(cipher);
294   CryptoUtils::SetKeyAndIV(prf, read_secret,
295                            handshaker_delegate_->parsed_version(),
296                            decrypter.get());
297   std::vector<uint8_t> header_protection_key =
298       CryptoUtils::GenerateHeaderProtectionKey(
299           prf, read_secret, handshaker_delegate_->parsed_version(),
300           decrypter->GetKeySize());
301   decrypter->SetHeaderProtectionKey(
302       absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
303                         header_protection_key.size()));
304   if (level == ENCRYPTION_FORWARD_SECURE) {
305     QUICHE_DCHECK(latest_read_secret_.empty());
306     latest_read_secret_.assign(read_secret.begin(), read_secret.end());
307     one_rtt_read_header_protection_key_ = header_protection_key;
308   }
309   return handshaker_delegate_->OnNewDecryptionKeyAvailable(
310       level, std::move(decrypter),
311       /*set_alternative_decrypter=*/false,
312       /*latch_once_used=*/false);
313 }
314 
315 std::unique_ptr<QuicDecrypter>
AdvanceKeysAndCreateCurrentOneRttDecrypter()316 TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
317   if (latest_read_secret_.empty() || latest_write_secret_.empty() ||
318       one_rtt_read_header_protection_key_.empty() ||
319       one_rtt_write_header_protection_key_.empty()) {
320     std::string error_details = "1-RTT secret(s) not set yet.";
321     QUIC_BUG(quic_bug_10312_1) << error_details;
322     CloseConnection(QUIC_INTERNAL_ERROR, error_details);
323     return nullptr;
324   }
325   const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
326   const EVP_MD* prf = Prf(cipher);
327   latest_read_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
328       prf, handshaker_delegate_->parsed_version(), latest_read_secret_);
329   latest_write_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
330       prf, handshaker_delegate_->parsed_version(), latest_write_secret_);
331 
332   std::unique_ptr<QuicDecrypter> decrypter =
333       QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
334   CryptoUtils::SetKeyAndIV(prf, latest_read_secret_,
335                            handshaker_delegate_->parsed_version(),
336                            decrypter.get());
337   decrypter->SetHeaderProtectionKey(absl::string_view(
338       reinterpret_cast<char*>(one_rtt_read_header_protection_key_.data()),
339       one_rtt_read_header_protection_key_.size()));
340 
341   return decrypter;
342 }
343 
CreateCurrentOneRttEncrypter()344 std::unique_ptr<QuicEncrypter> TlsHandshaker::CreateCurrentOneRttEncrypter() {
345   if (latest_write_secret_.empty() ||
346       one_rtt_write_header_protection_key_.empty()) {
347     std::string error_details = "1-RTT write secret not set yet.";
348     QUIC_BUG(quic_bug_10312_2) << error_details;
349     CloseConnection(QUIC_INTERNAL_ERROR, error_details);
350     return nullptr;
351   }
352   const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
353   std::unique_ptr<QuicEncrypter> encrypter =
354       QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
355   CryptoUtils::SetKeyAndIV(Prf(cipher), latest_write_secret_,
356                            handshaker_delegate_->parsed_version(),
357                            encrypter.get());
358   encrypter->SetHeaderProtectionKey(absl::string_view(
359       reinterpret_cast<char*>(one_rtt_write_header_protection_key_.data()),
360       one_rtt_write_header_protection_key_.size()));
361   return encrypter;
362 }
363 
ExportKeyingMaterialForLabel(absl::string_view label,absl::string_view context,size_t result_len,std::string * result)364 bool TlsHandshaker::ExportKeyingMaterialForLabel(absl::string_view label,
365                                                  absl::string_view context,
366                                                  size_t result_len,
367                                                  std::string* result) {
368   if (result == nullptr) {
369     return false;
370   }
371   result->resize(result_len);
372   return SSL_export_keying_material(
373              ssl(), reinterpret_cast<uint8_t*>(&*result->begin()), result_len,
374              label.data(), label.size(),
375              reinterpret_cast<const uint8_t*>(context.data()), context.size(),
376              !context.empty()) == 1;
377 }
378 
WriteMessage(EncryptionLevel level,absl::string_view data)379 void TlsHandshaker::WriteMessage(EncryptionLevel level,
380                                  absl::string_view data) {
381   stream_->WriteCryptoData(level, data);
382 }
383 
FlushFlight()384 void TlsHandshaker::FlushFlight() {}
385 
SendAlert(EncryptionLevel level,uint8_t desc)386 void TlsHandshaker::SendAlert(EncryptionLevel level, uint8_t desc) {
387   if (dont_close_connection_in_tls_alert_callback_) {
388     QUIC_RELOADABLE_FLAG_COUNT_N(
389         quic_dont_close_connection_in_tls_alert_callback, 1, 2);
390     TlsAlert tls_alert;
391     tls_alert.level = level;
392     tls_alert.desc = desc;
393     last_tls_alert_ = tls_alert;
394   } else {
395     std::string error_details = absl::StrCat(
396         "TLS handshake failure (", EncryptionLevelToString(level), ") ",
397         static_cast<int>(desc), ": ", SSL_alert_desc_string_long(desc));
398     QUIC_DLOG(ERROR) << error_details;
399     CloseConnection(
400         TlsAlertToQuicErrorCode(desc),
401         static_cast<QuicIetfTransportErrorCodes>(CRYPTO_ERROR_FIRST + desc),
402         error_details);
403   }
404 }
405 
406 }  // namespace quic
407