blob: 17e2674f1c29c963371f5910710b8acd446879ca [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"
11#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
12#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
13
14namespace quic {
15
16namespace {
17
18class SslIndexSingleton {
19 public:
20 static SslIndexSingleton* GetInstance() {
21 static SslIndexSingleton* instance = new SslIndexSingleton();
22 return instance;
23 }
24
25 int HandshakerIndex() const { return ssl_ex_data_index_handshaker_; }
26
27 private:
28 SslIndexSingleton() {
29 CRYPTO_library_init();
30 ssl_ex_data_index_handshaker_ =
31 SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
32 CHECK_LE(0, ssl_ex_data_index_handshaker_);
33 }
34
35 SslIndexSingleton(const SslIndexSingleton&) = delete;
36 SslIndexSingleton& operator=(const SslIndexSingleton&) = delete;
37
38 int ssl_ex_data_index_handshaker_;
39};
40
41} // namespace
42
43TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream,
44 QuicSession* session,
45 SSL_CTX* ssl_ctx)
46 : stream_(stream), session_(session) {
47 ssl_.reset(SSL_new(ssl_ctx));
48 SSL_set_ex_data(ssl(), SslIndexSingleton::GetInstance()->HandshakerIndex(),
49 this);
50}
51
52TlsHandshaker::~TlsHandshaker() {}
53
54bool TlsHandshaker::ProcessInput(QuicStringPiece input, EncryptionLevel level) {
55 if (parser_error_ != QUIC_NO_ERROR) {
56 return false;
57 }
58 // TODO(nharper): Call SSL_quic_read_level(ssl()) and check whether the
59 // encryption level BoringSSL expects matches the encryption level that we
60 // just received input at. If they mismatch, should ProcessInput return true
61 // or false? If data is for a future encryption level, it should be queued for
62 // later?
63 if (SSL_provide_quic_data(ssl(), BoringEncryptionLevel(level),
64 reinterpret_cast<const uint8_t*>(input.data()),
65 input.size()) != 1) {
66 // SSL_provide_quic_data can fail for 3 reasons:
67 // - API misuse (calling it before SSL_set_custom_quic_method, which we
68 // call in the TlsHandshaker c'tor)
69 // - Memory exhaustion when appending data to its buffer
70 // - Data provided at the wrong encryption level
71 //
72 // Of these, the only sensible error to handle is data provided at the wrong
73 // encryption level.
74 //
75 // Note: the error provided below has a good-sounding enum value, although
76 // it doesn't match the description as it's a QUIC Crypto specific error.
77 parser_error_ = QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
78 parser_error_detail_ = "TLS stack failed to receive data";
79 return false;
80 }
81 AdvanceHandshake();
82 return true;
83}
84
85// static
86bssl::UniquePtr<SSL_CTX> TlsHandshaker::CreateSslCtx() {
87 CRYPTO_library_init();
88 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_with_buffers_method()));
89 SSL_CTX_set_min_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
90 SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
91 SSL_CTX_set_quic_method(ssl_ctx.get(), &kSslQuicMethod);
92 return ssl_ctx;
93}
94
95// static
96TlsHandshaker* TlsHandshaker::HandshakerFromSsl(const SSL* ssl) {
97 return reinterpret_cast<TlsHandshaker*>(SSL_get_ex_data(
98 ssl, SslIndexSingleton::GetInstance()->HandshakerIndex()));
99}
100
101// static
102EncryptionLevel TlsHandshaker::QuicEncryptionLevel(
103 enum ssl_encryption_level_t level) {
104 switch (level) {
105 case ssl_encryption_initial:
QUICHE team6987b4a2019-03-15 16:23:04 -0700106 return ENCRYPTION_INITIAL;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500107 case ssl_encryption_early_data:
108 case ssl_encryption_handshake:
109 return ENCRYPTION_ZERO_RTT;
110 case ssl_encryption_application:
111 return ENCRYPTION_FORWARD_SECURE;
112 }
113}
114
115// static
116enum ssl_encryption_level_t TlsHandshaker::BoringEncryptionLevel(
117 EncryptionLevel level) {
118 switch (level) {
QUICHE team6987b4a2019-03-15 16:23:04 -0700119 case ENCRYPTION_INITIAL:
QUICHE teama6ef0a62019-03-07 20:34:33 -0500120 return ssl_encryption_initial;
QUICHE team88ea0082019-03-15 10:05:26 -0700121 case ENCRYPTION_HANDSHAKE:
QUICHE teama6ef0a62019-03-07 20:34:33 -0500122 case ENCRYPTION_ZERO_RTT:
123 return ssl_encryption_handshake;
124 case ENCRYPTION_FORWARD_SECURE:
125 return ssl_encryption_application;
126 default:
127 QUIC_BUG << "Invalid encryption level " << level;
128 return ssl_encryption_initial;
129 }
130}
131
132const EVP_MD* TlsHandshaker::Prf() {
133 return EVP_get_digestbynid(
134 SSL_CIPHER_get_prf_nid(SSL_get_pending_cipher(ssl())));
135}
136
137std::unique_ptr<QuicEncrypter> TlsHandshaker::CreateEncrypter(
138 const std::vector<uint8_t>& pp_secret) {
139 std::unique_ptr<QuicEncrypter> encrypter =
140 QuicEncrypter::CreateFromCipherSuite(
141 SSL_CIPHER_get_id(SSL_get_pending_cipher(ssl())));
142 CryptoUtils::SetKeyAndIV(Prf(), pp_secret, encrypter.get());
143 return encrypter;
144}
145
146std::unique_ptr<QuicDecrypter> TlsHandshaker::CreateDecrypter(
147 const std::vector<uint8_t>& pp_secret) {
148 std::unique_ptr<QuicDecrypter> decrypter =
149 QuicDecrypter::CreateFromCipherSuite(
150 SSL_CIPHER_get_id(SSL_get_pending_cipher(ssl())));
151 CryptoUtils::SetKeyAndIV(Prf(), pp_secret, decrypter.get());
152 return decrypter;
153}
154
155const SSL_QUIC_METHOD TlsHandshaker::kSslQuicMethod{
156 TlsHandshaker::SetEncryptionSecretCallback,
157 TlsHandshaker::WriteMessageCallback, TlsHandshaker::FlushFlightCallback,
158 TlsHandshaker::SendAlertCallback};
159
160// static
161int TlsHandshaker::SetEncryptionSecretCallback(
162 SSL* ssl,
163 enum ssl_encryption_level_t level,
164 const uint8_t* read_key,
165 const uint8_t* write_key,
166 size_t secret_len) {
167 // TODO(nharper): replace these vectors and memcpys with spans (which
168 // unfortunately doesn't yet exist in quic/platform/api).
169 std::vector<uint8_t> read_secret(secret_len), write_secret(secret_len);
170 memcpy(read_secret.data(), read_key, secret_len);
171 memcpy(write_secret.data(), write_key, secret_len);
172 HandshakerFromSsl(ssl)->SetEncryptionSecret(QuicEncryptionLevel(level),
173 read_secret, write_secret);
174 return 1;
175}
176
177// static
178int TlsHandshaker::WriteMessageCallback(SSL* ssl,
179 enum ssl_encryption_level_t level,
180 const uint8_t* data,
181 size_t len) {
182 HandshakerFromSsl(ssl)->WriteMessage(
183 QuicEncryptionLevel(level),
184 QuicStringPiece(reinterpret_cast<const char*>(data), len));
185 return 1;
186}
187
188// static
189int TlsHandshaker::FlushFlightCallback(SSL* ssl) {
190 HandshakerFromSsl(ssl)->FlushFlight();
191 return 1;
192}
193
194// static
195int TlsHandshaker::SendAlertCallback(SSL* ssl,
196 enum ssl_encryption_level_t level,
197 uint8_t desc) {
198 HandshakerFromSsl(ssl)->SendAlert(QuicEncryptionLevel(level), desc);
199 return 1;
200}
201
202void TlsHandshaker::SetEncryptionSecret(
203 EncryptionLevel level,
204 const std::vector<uint8_t>& read_secret,
205 const std::vector<uint8_t>& write_secret) {
206 std::unique_ptr<QuicEncrypter> encrypter = CreateEncrypter(write_secret);
207 session()->connection()->SetEncrypter(level, std::move(encrypter));
208 if (level != ENCRYPTION_FORWARD_SECURE) {
209 std::unique_ptr<QuicDecrypter> decrypter = CreateDecrypter(read_secret);
210 session()->connection()->SetDecrypter(level, std::move(decrypter));
211 } else {
212 // When forward-secure read keys are available, they get set as the
213 // alternative decrypter instead of the primary decrypter. One reason for
214 // this is that after the forward secure keys become available, the server
215 // still has crypto handshake messages to read at the handshake encryption
216 // level, meaning that both the ENCRYPTION_ZERO_RTT and
217 // ENCRYPTION_FORWARD_SECURE decrypters need to be available. (Tests also
218 // assume that an alternative decrypter gets set, so at some point we need
219 // to call SetAlternativeDecrypter.)
220 std::unique_ptr<QuicDecrypter> decrypter = CreateDecrypter(read_secret);
221 session()->connection()->SetAlternativeDecrypter(
222 level, std::move(decrypter), /*latch_once_used*/ true);
223 }
224}
225
226void TlsHandshaker::WriteMessage(EncryptionLevel level, QuicStringPiece data) {
227 stream_->WriteCryptoData(level, data);
228}
229
230void TlsHandshaker::FlushFlight() {}
231
232void TlsHandshaker::SendAlert(EncryptionLevel level, uint8_t desc) {
233 // TODO(nharper): Alerts should be sent on the wire as a 16-bit QUIC error
234 // code computed to be 0x100 | desc (draft-ietf-quic-tls-14, section 4.8).
235 // This puts it in the range reserved for CRYPTO_ERROR
236 // (draft-ietf-quic-transport-14, section 11.3). However, according to
237 // quic_error_codes.h, this QUIC implementation only sends 1-byte error codes
238 // right now.
239 CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failure");
240}
241
242} // namespace quic