blob: baac324a3b7b6c316d91da2a23b3a86f830a3093 [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_client_handshaker.h"
6
dschinazi35e749e2019-04-09 09:36:04 -07007#include <cstring>
vasilvv872e7a32019-03-12 16:42:44 -07008#include <string>
9
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "third_party/boringssl/src/include/openssl/ssl.h"
renjietangf21e3852020-04-13 15:45:39 -070011#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
13#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
14#include "net/third_party/quiche/src/quic/core/quic_session.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080015#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
16#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050017
18namespace quic {
19
20TlsClientHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
21 TlsClientHandshaker* parent)
22 : parent_(parent) {}
23
24TlsClientHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {}
25
26void TlsClientHandshaker::ProofVerifierCallbackImpl::Run(
27 bool ok,
dschinazi17d42422019-06-18 16:35:07 -070028 const std::string& /*error_details*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -050029 std::unique_ptr<ProofVerifyDetails>* details) {
30 if (parent_ == nullptr) {
31 return;
32 }
33
34 parent_->verify_details_ = std::move(*details);
35 parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid;
36 parent_->state_ = STATE_HANDSHAKE_RUNNING;
37 parent_->proof_verify_callback_ = nullptr;
nharper40bdf532019-10-03 11:16:22 -070038 parent_->proof_handler_->OnProofVerifyDetailsAvailable(
39 *parent_->verify_details_);
QUICHE teama6ef0a62019-03-07 20:34:33 -050040 parent_->AdvanceHandshake();
41}
42
43void TlsClientHandshaker::ProofVerifierCallbackImpl::Cancel() {
44 parent_ = nullptr;
45}
46
47TlsClientHandshaker::TlsClientHandshaker(
nharperdf7a77b2019-11-11 13:12:45 -080048 const QuicServerId& server_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050049 QuicCryptoStream* stream,
50 QuicSession* session,
QUICHE teama6ef0a62019-03-07 20:34:33 -050051 std::unique_ptr<ProofVerifyContext> verify_context,
nharperdf7a77b2019-11-11 13:12:45 -080052 QuicCryptoClientConfig* crypto_config,
53 QuicCryptoClientStream::ProofHandler* proof_handler)
nharper80d3b172020-01-17 11:43:39 -080054 : TlsHandshaker(stream, session),
nharperf579b5e2020-01-21 14:11:18 -080055 session_(session),
QUICHE teama6ef0a62019-03-07 20:34:33 -050056 server_id_(server_id),
nharperdf7a77b2019-11-11 13:12:45 -080057 proof_verifier_(crypto_config->proof_verifier()),
QUICHE teama6ef0a62019-03-07 20:34:33 -050058 verify_context_(std::move(verify_context)),
nharper40bdf532019-10-03 11:16:22 -070059 proof_handler_(proof_handler),
nharperdf7a77b2019-11-11 13:12:45 -080060 session_cache_(crypto_config->session_cache()),
61 user_agent_id_(crypto_config->user_agent_id()),
dschinaziaaaf1a42020-04-16 11:44:31 -070062 pre_shared_key_(crypto_config->pre_shared_key()),
nharper6ebe83b2019-06-13 17:43:52 -070063 crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
nharperdf7a77b2019-11-11 13:12:45 -080064 tls_connection_(crypto_config->ssl_ctx(), this) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050065
66TlsClientHandshaker::~TlsClientHandshaker() {
67 if (proof_verify_callback_) {
68 proof_verify_callback_->Cancel();
69 }
70}
71
QUICHE teama6ef0a62019-03-07 20:34:33 -050072bool TlsClientHandshaker::CryptoConnect() {
QUICHE teama6ef0a62019-03-07 20:34:33 -050073 state_ = STATE_HANDSHAKE_RUNNING;
QUICHE teama6ef0a62019-03-07 20:34:33 -050074
dschinaziaaaf1a42020-04-16 11:44:31 -070075 if (!pre_shared_key_.empty()) {
76 // TODO(b/154162689) add PSK support to QUIC+TLS.
77 std::string error_details =
78 "QUIC client pre-shared keys not yet supported with TLS";
79 QUIC_BUG << error_details;
80 CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
81 return false;
82 }
83
nharper0f51d2e2019-12-11 17:52:05 -080084 // Set the SNI to send, if any.
QUICHE teama6ef0a62019-03-07 20:34:33 -050085 SSL_set_connect_state(ssl());
nharper0f51d2e2019-12-11 17:52:05 -080086 if (!server_id_.host().empty() &&
87 SSL_set_tlsext_host_name(ssl(), server_id_.host().c_str()) != 1) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050088 return false;
89 }
90
vasilvv4724c9c2019-08-29 11:52:11 -070091 if (!SetAlpn()) {
92 CloseConnection(QUIC_HANDSHAKE_FAILED, "Client failed to set ALPN");
dschinazi35e749e2019-04-09 09:36:04 -070093 return false;
94 }
dschinazi35e749e2019-04-09 09:36:04 -070095
QUICHE teama6ef0a62019-03-07 20:34:33 -050096 // Set the Transport Parameters to send in the ClientHello
97 if (!SetTransportParameters()) {
98 CloseConnection(QUIC_HANDSHAKE_FAILED,
dschinazi91453642019-08-01 11:12:15 -070099 "Client failed to set Transport Parameters");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500100 return false;
101 }
102
nharperdf7a77b2019-11-11 13:12:45 -0800103 // Set a session to resume, if there is one.
104 if (session_cache_) {
105 std::unique_ptr<QuicResumptionState> cached_state =
106 session_cache_->Lookup(server_id_, SSL_get_SSL_CTX(ssl()));
107 if (cached_state) {
108 SSL_set_session(ssl(), cached_state->tls_session.get());
109 }
110 }
111
QUICHE teama6ef0a62019-03-07 20:34:33 -0500112 // Start the handshake.
113 AdvanceHandshake();
114 return session()->connection()->connected();
115}
116
vasilvv4724c9c2019-08-29 11:52:11 -0700117static bool IsValidAlpn(const std::string& alpn_string) {
118 return alpn_string.length() <= std::numeric_limits<uint8_t>::max();
119}
120
121bool TlsClientHandshaker::SetAlpn() {
122 std::vector<std::string> alpns = session()->GetAlpnsToOffer();
123 if (alpns.empty()) {
124 if (allow_empty_alpn_for_tests_) {
125 return true;
126 }
127
128 QUIC_BUG << "ALPN missing";
129 return false;
130 }
131 if (!std::all_of(alpns.begin(), alpns.end(), IsValidAlpn)) {
132 QUIC_BUG << "ALPN too long";
133 return false;
134 }
135
136 // SSL_set_alpn_protos expects a sequence of one-byte-length-prefixed
137 // strings.
138 uint8_t alpn[1024];
139 QuicDataWriter alpn_writer(sizeof(alpn), reinterpret_cast<char*>(alpn));
140 bool success = true;
141 for (const std::string& alpn_string : alpns) {
142 success = success && alpn_writer.WriteUInt8(alpn_string.size()) &&
143 alpn_writer.WriteStringPiece(alpn_string);
144 }
145 success =
146 success && (SSL_set_alpn_protos(ssl(), alpn, alpn_writer.length()) == 0);
147 if (!success) {
148 QUIC_BUG << "Failed to set ALPN: "
dmcardlecf0bfcf2019-12-13 08:08:21 -0800149 << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece(
150 alpn_writer.data(), alpn_writer.length()));
vasilvv4724c9c2019-08-29 11:52:11 -0700151 return false;
152 }
153 QUIC_DLOG(INFO) << "Client using ALPN: '" << alpns[0] << "'";
154 return true;
155}
156
QUICHE teama6ef0a62019-03-07 20:34:33 -0500157bool TlsClientHandshaker::SetTransportParameters() {
158 TransportParameters params;
159 params.perspective = Perspective::IS_CLIENT;
160 params.version =
161 CreateQuicVersionLabel(session()->supported_versions().front());
162
163 if (!session()->config()->FillTransportParameters(&params)) {
164 return false;
165 }
166 params.google_quic_params->SetStringPiece(kUAID, user_agent_id_);
167
168 std::vector<uint8_t> param_bytes;
dschinazi6c84c142019-07-31 09:11:49 -0700169 return SerializeTransportParameters(session()->connection()->version(),
170 params, &param_bytes) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171 SSL_set_quic_transport_params(ssl(), param_bytes.data(),
172 param_bytes.size()) == 1;
173}
174
175bool TlsClientHandshaker::ProcessTransportParameters(
vasilvvc48c8712019-03-11 13:38:16 -0700176 std::string* error_details) {
renjietangcc12f432020-04-09 16:44:22 -0700177 received_transport_params_ = std::make_unique<TransportParameters>();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500178 const uint8_t* param_bytes;
179 size_t param_bytes_len;
180 SSL_get_peer_quic_transport_params(ssl(), &param_bytes, &param_bytes_len);
dschinazi7b8f0c72020-03-02 13:17:57 -0800181 if (param_bytes_len == 0) {
182 *error_details = "Server's transport parameters are missing";
183 return false;
184 }
185 std::string parse_error_details;
186 if (!ParseTransportParameters(
187 session()->connection()->version(), Perspective::IS_SERVER,
renjietangcc12f432020-04-09 16:44:22 -0700188 param_bytes, param_bytes_len, received_transport_params_.get(),
189 &parse_error_details)) {
dschinazi7b8f0c72020-03-02 13:17:57 -0800190 DCHECK(!parse_error_details.empty());
191 *error_details =
192 "Unable to parse server's transport parameters: " + parse_error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500193 return false;
194 }
195
dschinazi6cf4d2a2019-04-30 16:20:23 -0700196 // When interoperating with non-Google implementations that do not send
197 // the version extension, set it to what we expect.
renjietangcc12f432020-04-09 16:44:22 -0700198 if (received_transport_params_->version == 0) {
199 received_transport_params_->version =
200 CreateQuicVersionLabel(session()->connection()->version());
dschinazi6cf4d2a2019-04-30 16:20:23 -0700201 }
renjietangcc12f432020-04-09 16:44:22 -0700202 if (received_transport_params_->supported_versions.empty()) {
203 received_transport_params_->supported_versions.push_back(
204 received_transport_params_->version);
dschinazi6cf4d2a2019-04-30 16:20:23 -0700205 }
206
renjietangcc12f432020-04-09 16:44:22 -0700207 if (received_transport_params_->version !=
QUICHE teama6ef0a62019-03-07 20:34:33 -0500208 CreateQuicVersionLabel(session()->connection()->version())) {
209 *error_details = "Version mismatch detected";
210 return false;
211 }
212 if (CryptoUtils::ValidateServerHelloVersions(
renjietangcc12f432020-04-09 16:44:22 -0700213 received_transport_params_->supported_versions,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500214 session()->connection()->server_supported_versions(),
215 error_details) != QUIC_NO_ERROR ||
216 session()->config()->ProcessTransportParameters(
renjietangcc12f432020-04-09 16:44:22 -0700217 *received_transport_params_, SERVER, error_details) !=
218 QUIC_NO_ERROR) {
dschinazid1967a22019-04-03 16:11:32 -0700219 DCHECK(!error_details->empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220 return false;
221 }
222
223 session()->OnConfigNegotiated();
224 return true;
225}
226
227int TlsClientHandshaker::num_sent_client_hellos() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500228 return 0;
229}
230
nharper02703962019-11-07 12:23:13 -0800231bool TlsClientHandshaker::IsResumption() const {
fayang685367a2020-01-14 10:40:15 -0800232 QUIC_BUG_IF(!one_rtt_keys_available_);
nharperdf7a77b2019-11-11 13:12:45 -0800233 return SSL_session_reused(ssl()) == 1;
nharper02703962019-11-07 12:23:13 -0800234}
235
nharper4084fc92020-02-10 14:43:35 -0800236bool TlsClientHandshaker::EarlyDataAccepted() const {
237 QUIC_BUG_IF(!one_rtt_keys_available_);
238 return SSL_early_data_accepted(ssl()) == 1;
239}
240
241bool TlsClientHandshaker::ReceivedInchoateReject() const {
242 QUIC_BUG_IF(!one_rtt_keys_available_);
243 // REJ messages are a QUIC crypto feature, so TLS always returns false.
244 return false;
245}
246
QUICHE teama6ef0a62019-03-07 20:34:33 -0500247int TlsClientHandshaker::num_scup_messages_received() const {
248 // SCUP messages aren't sent or received when using the TLS handshake.
249 return 0;
250}
251
vasilvvc48c8712019-03-11 13:38:16 -0700252std::string TlsClientHandshaker::chlo_hash() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500253 return "";
254}
255
256bool TlsClientHandshaker::encryption_established() const {
257 return encryption_established_;
258}
259
fayang685367a2020-01-14 10:40:15 -0800260bool TlsClientHandshaker::one_rtt_keys_available() const {
261 return one_rtt_keys_available_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500262}
263
264const QuicCryptoNegotiatedParameters&
265TlsClientHandshaker::crypto_negotiated_params() const {
266 return *crypto_negotiated_params_;
267}
268
269CryptoMessageParser* TlsClientHandshaker::crypto_message_parser() {
270 return TlsHandshaker::crypto_message_parser();
271}
272
fayang9a863cf2020-01-16 14:12:11 -0800273HandshakeState TlsClientHandshaker::GetHandshakeState() const {
fayang01062942020-01-22 07:23:23 -0800274 if (handshake_confirmed_) {
275 return HANDSHAKE_CONFIRMED;
276 }
fayang9a863cf2020-01-16 14:12:11 -0800277 if (one_rtt_keys_available_) {
278 return HANDSHAKE_COMPLETE;
279 }
280 if (state_ >= STATE_ENCRYPTION_HANDSHAKE_DATA_SENT) {
281 return HANDSHAKE_PROCESSED;
282 }
283 return HANDSHAKE_START;
284}
285
nharper486a8a92019-08-28 16:25:10 -0700286size_t TlsClientHandshaker::BufferSizeLimitForLevel(
287 EncryptionLevel level) const {
288 return TlsHandshaker::BufferSizeLimitForLevel(level);
289}
290
fayang2f2915d2020-01-24 06:47:15 -0800291void TlsClientHandshaker::OnOneRttPacketAcknowledged() {
292 OnHandshakeConfirmed();
293}
294
fayang01062942020-01-22 07:23:23 -0800295void TlsClientHandshaker::OnHandshakeDoneReceived() {
296 if (!one_rtt_keys_available_) {
297 CloseConnection(QUIC_HANDSHAKE_FAILED,
298 "Unexpected handshake done received");
299 return;
300 }
fayang2f2915d2020-01-24 06:47:15 -0800301 OnHandshakeConfirmed();
302}
303
fayanga45ee8a2020-03-20 08:56:11 -0700304void TlsClientHandshaker::SetWriteSecret(
305 EncryptionLevel level,
306 const SSL_CIPHER* cipher,
307 const std::vector<uint8_t>& write_secret) {
308 if (GetQuicRestartFlag(quic_send_settings_on_write_key_available) &&
309 level == ENCRYPTION_FORWARD_SECURE) {
310 encryption_established_ = true;
311 }
312 TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
313}
314
fayang2f2915d2020-01-24 06:47:15 -0800315void TlsClientHandshaker::OnHandshakeConfirmed() {
316 DCHECK(one_rtt_keys_available_);
fayang01062942020-01-22 07:23:23 -0800317 if (handshake_confirmed_) {
318 return;
319 }
320 handshake_confirmed_ = true;
renjietangbd33b622020-02-12 16:52:30 -0800321 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
322 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
fayang01062942020-01-22 07:23:23 -0800323}
324
QUICHE teama6ef0a62019-03-07 20:34:33 -0500325void TlsClientHandshaker::AdvanceHandshake() {
326 if (state_ == STATE_CONNECTION_CLOSED) {
327 QUIC_LOG(INFO)
328 << "TlsClientHandshaker received message after connection closed";
329 return;
330 }
331 if (state_ == STATE_IDLE) {
dschinazi91453642019-08-01 11:12:15 -0700332 CloseConnection(QUIC_HANDSHAKE_FAILED,
333 "Client observed TLS handshake idle failure");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500334 return;
335 }
336 if (state_ == STATE_HANDSHAKE_COMPLETE) {
nharperdf7a77b2019-11-11 13:12:45 -0800337 int rv = SSL_process_quic_post_handshake(ssl());
338 if (rv != 1) {
339 CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected post-handshake data");
340 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500341 return;
342 }
343
344 QUIC_LOG(INFO) << "TlsClientHandshaker: continuing handshake";
345 int rv = SSL_do_handshake(ssl());
346 if (rv == 1) {
347 FinishHandshake();
348 return;
349 }
350 int ssl_error = SSL_get_error(ssl(), rv);
351 bool should_close = true;
352 switch (state_) {
353 case STATE_HANDSHAKE_RUNNING:
354 should_close = ssl_error != SSL_ERROR_WANT_READ;
355 break;
356 case STATE_CERT_VERIFY_PENDING:
357 should_close = ssl_error != SSL_ERROR_WANT_CERTIFICATE_VERIFY;
358 break;
359 default:
360 should_close = true;
361 }
362 if (should_close && state_ != STATE_CONNECTION_CLOSED) {
363 // TODO(nharper): Surface error details from the error queue when ssl_error
364 // is SSL_ERROR_SSL.
365 QUIC_LOG(WARNING) << "SSL_do_handshake failed; closing connection";
dschinazi91453642019-08-01 11:12:15 -0700366 CloseConnection(QUIC_HANDSHAKE_FAILED,
367 "Client observed TLS handshake failure");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500368 }
369}
370
371void TlsClientHandshaker::CloseConnection(QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -0700372 const std::string& reason_phrase) {
dschinazid1967a22019-04-03 16:11:32 -0700373 DCHECK(!reason_phrase.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500374 state_ = STATE_CONNECTION_CLOSED;
renjietang87df0d02020-02-13 11:53:52 -0800375 stream()->OnUnrecoverableError(error, reason_phrase);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500376}
377
378void TlsClientHandshaker::FinishHandshake() {
379 QUIC_LOG(INFO) << "Client: handshake finished";
380 state_ = STATE_HANDSHAKE_COMPLETE;
fayanga45ee8a2020-03-20 08:56:11 -0700381 if (GetQuicRestartFlag(quic_send_settings_on_write_key_available)) {
382 // Fill crypto_negotiated_params_:
383 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
384 if (cipher) {
385 crypto_negotiated_params_->cipher_suite = SSL_CIPHER_get_value(cipher);
386 }
387 crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
388 crypto_negotiated_params_->peer_signature_algorithm =
389 SSL_get_peer_signature_algorithm(ssl());
390 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500391
vasilvvc48c8712019-03-11 13:38:16 -0700392 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500393 if (!ProcessTransportParameters(&error_details)) {
dschinazid1967a22019-04-03 16:11:32 -0700394 DCHECK(!error_details.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500395 CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
396 return;
397 }
398
dschinazi35e749e2019-04-09 09:36:04 -0700399 const uint8_t* alpn_data = nullptr;
400 unsigned alpn_length = 0;
401 SSL_get0_alpn_selected(ssl(), &alpn_data, &alpn_length);
dschinazi91453642019-08-01 11:12:15 -0700402
403 if (alpn_length == 0) {
404 QUIC_DLOG(ERROR) << "Client: server did not select ALPN";
405 // TODO(b/130164908) this should send no_application_protocol
406 // instead of QUIC_HANDSHAKE_FAILED.
407 CloseConnection(QUIC_HANDSHAKE_FAILED, "Server did not select ALPN");
408 return;
dschinazi35e749e2019-04-09 09:36:04 -0700409 }
410
dschinazi91453642019-08-01 11:12:15 -0700411 std::string received_alpn_string(reinterpret_cast<const char*>(alpn_data),
412 alpn_length);
vasilvvad7424f2019-08-30 00:27:14 -0700413 std::vector<std::string> offered_alpns = session()->GetAlpnsToOffer();
414 if (std::find(offered_alpns.begin(), offered_alpns.end(),
415 received_alpn_string) == offered_alpns.end()) {
dschinazi91453642019-08-01 11:12:15 -0700416 QUIC_LOG(ERROR) << "Client: received mismatched ALPN '"
vasilvvad7424f2019-08-30 00:27:14 -0700417 << received_alpn_string;
dschinazi91453642019-08-01 11:12:15 -0700418 // TODO(b/130164908) this should send no_application_protocol
419 // instead of QUIC_HANDSHAKE_FAILED.
420 CloseConnection(QUIC_HANDSHAKE_FAILED, "Client received mismatched ALPN");
421 return;
422 }
vasilvvad7424f2019-08-30 00:27:14 -0700423 session()->OnAlpnSelected(received_alpn_string);
dschinazi91453642019-08-01 11:12:15 -0700424 QUIC_DLOG(INFO) << "Client: server selected ALPN: '" << received_alpn_string
425 << "'";
426
fayanga45ee8a2020-03-20 08:56:11 -0700427 if (!GetQuicRestartFlag(quic_send_settings_on_write_key_available)) {
428 encryption_established_ = true;
429 }
fayang685367a2020-01-14 10:40:15 -0800430 one_rtt_keys_available_ = true;
nharper8f759922019-10-09 11:08:36 -0700431
fayanga45ee8a2020-03-20 08:56:11 -0700432 if (!GetQuicRestartFlag(quic_send_settings_on_write_key_available)) {
433 // Fill crypto_negotiated_params_:
434 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
435 if (cipher) {
436 crypto_negotiated_params_->cipher_suite = SSL_CIPHER_get_value(cipher);
437 }
438 crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
439 crypto_negotiated_params_->peer_signature_algorithm =
440 SSL_get_peer_signature_algorithm(ssl());
nharper8f759922019-10-09 11:08:36 -0700441 }
rch9001a962019-12-17 10:44:04 -0800442
fayangd18bfb92020-03-19 17:24:21 -0700443 handshaker_delegate()->OnOneRttKeysAvailable();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500444}
445
QUICHE teama6ef0a62019-03-07 20:34:33 -0500446enum ssl_verify_result_t TlsClientHandshaker::VerifyCert(uint8_t* out_alert) {
447 if (verify_result_ != ssl_verify_retry ||
448 state_ == STATE_CERT_VERIFY_PENDING) {
449 enum ssl_verify_result_t result = verify_result_;
450 verify_result_ = ssl_verify_retry;
451 return result;
452 }
453 const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl());
454 if (cert_chain == nullptr) {
455 *out_alert = SSL_AD_INTERNAL_ERROR;
456 return ssl_verify_invalid;
457 }
458 // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies.
vasilvvc48c8712019-03-11 13:38:16 -0700459 std::vector<std::string> certs;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500460 for (CRYPTO_BUFFER* cert : cert_chain) {
461 certs.push_back(
vasilvvc48c8712019-03-11 13:38:16 -0700462 std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)),
463 CRYPTO_BUFFER_len(cert)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500464 }
QUICHE team38c190b2019-05-08 09:12:01 -0700465 const uint8_t* ocsp_response_raw;
466 size_t ocsp_response_len;
467 SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len);
468 std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw),
469 ocsp_response_len);
470 const uint8_t* sct_list_raw;
471 size_t sct_list_len;
472 SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len);
473 std::string sct_list(reinterpret_cast<const char*>(sct_list_raw),
474 sct_list_len);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500475
476 ProofVerifierCallbackImpl* proof_verify_callback =
477 new ProofVerifierCallbackImpl(this);
478
479 QuicAsyncStatus verify_result = proof_verifier_->VerifyCertChain(
QUICHE team38c190b2019-05-08 09:12:01 -0700480 server_id_.host(), certs, ocsp_response, sct_list, verify_context_.get(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500481 &cert_verify_error_details_, &verify_details_,
482 std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
483 switch (verify_result) {
484 case QUIC_SUCCESS:
nharper9b3cba42020-04-16 08:17:20 -0700485 if (verify_details_) {
486 proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_);
487 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500488 return ssl_verify_ok;
489 case QUIC_PENDING:
490 proof_verify_callback_ = proof_verify_callback;
491 state_ = STATE_CERT_VERIFY_PENDING;
492 return ssl_verify_retry;
493 case QUIC_FAILURE:
494 default:
495 QUIC_LOG(INFO) << "Cert chain verification failed: "
496 << cert_verify_error_details_;
497 return ssl_verify_invalid;
498 }
499}
500
nharperdf7a77b2019-11-11 13:12:45 -0800501void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) {
502 if (session_cache_ == nullptr) {
503 QUIC_DVLOG(1) << "No session cache, not inserting a session";
504 return;
505 }
renjietang0cc1b102020-04-08 12:48:34 -0700506 session_cache_->Insert(server_id_, std::move(session), nullptr, nullptr);
nharperdf7a77b2019-11-11 13:12:45 -0800507}
508
fayangd58736d2019-11-27 13:35:31 -0800509void TlsClientHandshaker::WriteMessage(EncryptionLevel level,
dmcardlecf0bfcf2019-12-13 08:08:21 -0800510 quiche::QuicheStringPiece data) {
fayangd58736d2019-11-27 13:35:31 -0800511 if (level == ENCRYPTION_HANDSHAKE &&
512 state_ < STATE_ENCRYPTION_HANDSHAKE_DATA_SENT) {
513 state_ = STATE_ENCRYPTION_HANDSHAKE_DATA_SENT;
renjietangbd33b622020-02-12 16:52:30 -0800514 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
515 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
fayangd58736d2019-11-27 13:35:31 -0800516 }
517 TlsHandshaker::WriteMessage(level, data);
518}
519
renjietangf21e3852020-04-13 15:45:39 -0700520void TlsClientHandshaker::OnApplicationState(
521 std::unique_ptr<ApplicationState> application_state) {
522 received_application_state_ = std::move(application_state);
523}
524
QUICHE teama6ef0a62019-03-07 20:34:33 -0500525} // namespace quic