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