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