blob: eccf275b24318237facdd04734a62cc2c3bc792a [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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 "net/third_party/quiche/src/quic/core/tls_handshaker.h"
6
7#include "third_party/boringssl/src/include/openssl/crypto.h"
8#include "third_party/boringssl/src/include/openssl/ssl.h"
9#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
10#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
bnc4e9283d2019-12-17 07:08:57 -080012#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080013#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014
15namespace quic {
16
QUICHE teama6ef0a62019-03-07 20:34:33 -050017TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream,
18 QuicSession* session,
dschinazi17d42422019-06-18 16:35:07 -070019 SSL_CTX* /*ssl_ctx*/)
fayangd58736d2019-11-27 13:35:31 -080020 : stream_(stream), session_(session), delegate_(session) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050021}
22
23TlsHandshaker::~TlsHandshaker() {}
24
dmcardlecf0bfcf2019-12-13 08:08:21 -080025bool TlsHandshaker::ProcessInput(quiche::QuicheStringPiece input,
26 EncryptionLevel level) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050027 if (parser_error_ != QUIC_NO_ERROR) {
28 return false;
29 }
30 // TODO(nharper): Call SSL_quic_read_level(ssl()) and check whether the
31 // encryption level BoringSSL expects matches the encryption level that we
32 // just received input at. If they mismatch, should ProcessInput return true
33 // or false? If data is for a future encryption level, it should be queued for
34 // later?
nharper6ebe83b2019-06-13 17:43:52 -070035 if (SSL_provide_quic_data(ssl(), TlsConnection::BoringEncryptionLevel(level),
QUICHE teama6ef0a62019-03-07 20:34:33 -050036 reinterpret_cast<const uint8_t*>(input.data()),
37 input.size()) != 1) {
38 // SSL_provide_quic_data can fail for 3 reasons:
39 // - API misuse (calling it before SSL_set_custom_quic_method, which we
40 // call in the TlsHandshaker c'tor)
41 // - Memory exhaustion when appending data to its buffer
42 // - Data provided at the wrong encryption level
43 //
44 // Of these, the only sensible error to handle is data provided at the wrong
45 // encryption level.
46 //
47 // Note: the error provided below has a good-sounding enum value, although
48 // it doesn't match the description as it's a QUIC Crypto specific error.
49 parser_error_ = QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
50 parser_error_detail_ = "TLS stack failed to receive data";
51 return false;
52 }
53 AdvanceHandshake();
54 return true;
55}
56
nharper486a8a92019-08-28 16:25:10 -070057size_t TlsHandshaker::BufferSizeLimitForLevel(EncryptionLevel level) const {
58 return SSL_quic_max_handshake_flight_len(
59 ssl(), TlsConnection::BoringEncryptionLevel(level));
60}
61
QUICHE teama6ef0a62019-03-07 20:34:33 -050062const EVP_MD* TlsHandshaker::Prf() {
63 return EVP_get_digestbynid(
64 SSL_CIPHER_get_prf_nid(SSL_get_pending_cipher(ssl())));
65}
66
QUICHE teama6ef0a62019-03-07 20:34:33 -050067void TlsHandshaker::SetEncryptionSecret(
68 EncryptionLevel level,
69 const std::vector<uint8_t>& read_secret,
70 const std::vector<uint8_t>& write_secret) {
fayangd58736d2019-11-27 13:35:31 -080071 std::unique_ptr<QuicEncrypter> encrypter =
72 QuicEncrypter::CreateFromCipherSuite(
73 SSL_CIPHER_get_id(SSL_get_pending_cipher(ssl())));
74 CryptoUtils::SetKeyAndIV(Prf(), write_secret, encrypter.get());
75 std::unique_ptr<QuicDecrypter> decrypter =
76 QuicDecrypter::CreateFromCipherSuite(
77 SSL_CIPHER_get_id(SSL_get_pending_cipher(ssl())));
78 CryptoUtils::SetKeyAndIV(Prf(), read_secret, decrypter.get());
79 delegate_->OnNewKeysAvailable(level, std::move(decrypter),
80 /*set_alternative_decrypter=*/false,
81 /*latch_once_used=*/false,
82 std::move(encrypter));
QUICHE teama6ef0a62019-03-07 20:34:33 -050083}
84
dmcardlecf0bfcf2019-12-13 08:08:21 -080085void TlsHandshaker::WriteMessage(EncryptionLevel level,
86 quiche::QuicheStringPiece data) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050087 stream_->WriteCryptoData(level, data);
88}
89
90void TlsHandshaker::FlushFlight() {}
91
dschinazi17d42422019-06-18 16:35:07 -070092void TlsHandshaker::SendAlert(EncryptionLevel /*level*/, uint8_t desc) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050093 // TODO(nharper): Alerts should be sent on the wire as a 16-bit QUIC error
94 // code computed to be 0x100 | desc (draft-ietf-quic-tls-14, section 4.8).
95 // This puts it in the range reserved for CRYPTO_ERROR
96 // (draft-ietf-quic-transport-14, section 11.3). However, according to
97 // quic_error_codes.h, this QUIC implementation only sends 1-byte error codes
98 // right now.
dschinazi35e749e2019-04-09 09:36:04 -070099 QUIC_DLOG(INFO) << "TLS failing handshake due to alert "
100 << static_cast<int>(desc);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500101 CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failure");
102}
103
104} // namespace quic