blob: 6f0bc4dcdfb3dccd2cd7a0a3e2c6b2c92cc60e9b [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"
11#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
12#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
13#include "net/third_party/quiche/src/quic/core/quic_session.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080014#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
15#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050016
17namespace quic {
18
19TlsClientHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
20 TlsClientHandshaker* parent)
21 : parent_(parent) {}
22
23TlsClientHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {}
24
25void TlsClientHandshaker::ProofVerifierCallbackImpl::Run(
26 bool ok,
dschinazi17d42422019-06-18 16:35:07 -070027 const std::string& /*error_details*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -050028 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_->state_ = STATE_HANDSHAKE_RUNNING;
36 parent_->proof_verify_callback_ = nullptr;
nharper40bdf532019-10-03 11:16:22 -070037 parent_->proof_handler_->OnProofVerifyDetailsAvailable(
38 *parent_->verify_details_);
QUICHE teama6ef0a62019-03-07 20:34:33 -050039 parent_->AdvanceHandshake();
40}
41
42void TlsClientHandshaker::ProofVerifierCallbackImpl::Cancel() {
43 parent_ = nullptr;
44}
45
46TlsClientHandshaker::TlsClientHandshaker(
nharperdf7a77b2019-11-11 13:12:45 -080047 const QuicServerId& server_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050048 QuicCryptoStream* stream,
49 QuicSession* session,
QUICHE teama6ef0a62019-03-07 20:34:33 -050050 std::unique_ptr<ProofVerifyContext> verify_context,
nharperdf7a77b2019-11-11 13:12:45 -080051 QuicCryptoClientConfig* crypto_config,
52 QuicCryptoClientStream::ProofHandler* proof_handler)
nharper80d3b172020-01-17 11:43:39 -080053 : TlsHandshaker(stream, session),
nharperf579b5e2020-01-21 14:11:18 -080054 session_(session),
QUICHE teama6ef0a62019-03-07 20:34:33 -050055 server_id_(server_id),
nharperdf7a77b2019-11-11 13:12:45 -080056 proof_verifier_(crypto_config->proof_verifier()),
QUICHE teama6ef0a62019-03-07 20:34:33 -050057 verify_context_(std::move(verify_context)),
nharper40bdf532019-10-03 11:16:22 -070058 proof_handler_(proof_handler),
nharperdf7a77b2019-11-11 13:12:45 -080059 session_cache_(crypto_config->session_cache()),
60 user_agent_id_(crypto_config->user_agent_id()),
nharper6ebe83b2019-06-13 17:43:52 -070061 crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
nharperdf7a77b2019-11-11 13:12:45 -080062 tls_connection_(crypto_config->ssl_ctx(), this) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050063
64TlsClientHandshaker::~TlsClientHandshaker() {
65 if (proof_verify_callback_) {
66 proof_verify_callback_->Cancel();
67 }
68}
69
QUICHE teama6ef0a62019-03-07 20:34:33 -050070bool TlsClientHandshaker::CryptoConnect() {
QUICHE teama6ef0a62019-03-07 20:34:33 -050071 state_ = STATE_HANDSHAKE_RUNNING;
QUICHE teama6ef0a62019-03-07 20:34:33 -050072
nharper0f51d2e2019-12-11 17:52:05 -080073 // Set the SNI to send, if any.
QUICHE teama6ef0a62019-03-07 20:34:33 -050074 SSL_set_connect_state(ssl());
nharper0f51d2e2019-12-11 17:52:05 -080075 if (!server_id_.host().empty() &&
76 SSL_set_tlsext_host_name(ssl(), server_id_.host().c_str()) != 1) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050077 return false;
78 }
79
vasilvv4724c9c2019-08-29 11:52:11 -070080 if (!SetAlpn()) {
81 CloseConnection(QUIC_HANDSHAKE_FAILED, "Client failed to set ALPN");
dschinazi35e749e2019-04-09 09:36:04 -070082 return false;
83 }
dschinazi35e749e2019-04-09 09:36:04 -070084
QUICHE teama6ef0a62019-03-07 20:34:33 -050085 // Set the Transport Parameters to send in the ClientHello
86 if (!SetTransportParameters()) {
87 CloseConnection(QUIC_HANDSHAKE_FAILED,
dschinazi91453642019-08-01 11:12:15 -070088 "Client failed to set Transport Parameters");
QUICHE teama6ef0a62019-03-07 20:34:33 -050089 return false;
90 }
91
nharperdf7a77b2019-11-11 13:12:45 -080092 // Set a session to resume, if there is one.
93 if (session_cache_) {
94 std::unique_ptr<QuicResumptionState> cached_state =
95 session_cache_->Lookup(server_id_, SSL_get_SSL_CTX(ssl()));
96 if (cached_state) {
97 SSL_set_session(ssl(), cached_state->tls_session.get());
98 }
99 }
100
QUICHE teama6ef0a62019-03-07 20:34:33 -0500101 // Start the handshake.
102 AdvanceHandshake();
103 return session()->connection()->connected();
104}
105
vasilvv4724c9c2019-08-29 11:52:11 -0700106static bool IsValidAlpn(const std::string& alpn_string) {
107 return alpn_string.length() <= std::numeric_limits<uint8_t>::max();
108}
109
110bool TlsClientHandshaker::SetAlpn() {
111 std::vector<std::string> alpns = session()->GetAlpnsToOffer();
112 if (alpns.empty()) {
113 if (allow_empty_alpn_for_tests_) {
114 return true;
115 }
116
117 QUIC_BUG << "ALPN missing";
118 return false;
119 }
120 if (!std::all_of(alpns.begin(), alpns.end(), IsValidAlpn)) {
121 QUIC_BUG << "ALPN too long";
122 return false;
123 }
124
125 // SSL_set_alpn_protos expects a sequence of one-byte-length-prefixed
126 // strings.
127 uint8_t alpn[1024];
128 QuicDataWriter alpn_writer(sizeof(alpn), reinterpret_cast<char*>(alpn));
129 bool success = true;
130 for (const std::string& alpn_string : alpns) {
131 success = success && alpn_writer.WriteUInt8(alpn_string.size()) &&
132 alpn_writer.WriteStringPiece(alpn_string);
133 }
134 success =
135 success && (SSL_set_alpn_protos(ssl(), alpn, alpn_writer.length()) == 0);
136 if (!success) {
137 QUIC_BUG << "Failed to set ALPN: "
dmcardlecf0bfcf2019-12-13 08:08:21 -0800138 << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece(
139 alpn_writer.data(), alpn_writer.length()));
vasilvv4724c9c2019-08-29 11:52:11 -0700140 return false;
141 }
142 QUIC_DLOG(INFO) << "Client using ALPN: '" << alpns[0] << "'";
143 return true;
144}
145
QUICHE teama6ef0a62019-03-07 20:34:33 -0500146bool TlsClientHandshaker::SetTransportParameters() {
147 TransportParameters params;
148 params.perspective = Perspective::IS_CLIENT;
149 params.version =
150 CreateQuicVersionLabel(session()->supported_versions().front());
151
152 if (!session()->config()->FillTransportParameters(&params)) {
153 return false;
154 }
155 params.google_quic_params->SetStringPiece(kUAID, user_agent_id_);
156
157 std::vector<uint8_t> param_bytes;
dschinazi6c84c142019-07-31 09:11:49 -0700158 return SerializeTransportParameters(session()->connection()->version(),
159 params, &param_bytes) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500160 SSL_set_quic_transport_params(ssl(), param_bytes.data(),
161 param_bytes.size()) == 1;
162}
163
164bool TlsClientHandshaker::ProcessTransportParameters(
vasilvvc48c8712019-03-11 13:38:16 -0700165 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500166 TransportParameters params;
167 const uint8_t* param_bytes;
168 size_t param_bytes_len;
169 SSL_get_peer_quic_transport_params(ssl(), &param_bytes, &param_bytes_len);
170 if (param_bytes_len == 0 ||
dschinazi6c84c142019-07-31 09:11:49 -0700171 !ParseTransportParameters(session()->connection()->version(),
172 Perspective::IS_SERVER, param_bytes,
173 param_bytes_len, &params)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500174 *error_details = "Unable to parse Transport Parameters";
175 return false;
176 }
177
dschinazi6cf4d2a2019-04-30 16:20:23 -0700178 // When interoperating with non-Google implementations that do not send
179 // the version extension, set it to what we expect.
180 if (params.version == 0) {
181 params.version = CreateQuicVersionLabel(session()->connection()->version());
182 }
183 if (params.supported_versions.empty()) {
184 params.supported_versions.push_back(params.version);
185 }
186
QUICHE teama6ef0a62019-03-07 20:34:33 -0500187 if (params.version !=
188 CreateQuicVersionLabel(session()->connection()->version())) {
189 *error_details = "Version mismatch detected";
190 return false;
191 }
192 if (CryptoUtils::ValidateServerHelloVersions(
193 params.supported_versions,
194 session()->connection()->server_supported_versions(),
195 error_details) != QUIC_NO_ERROR ||
196 session()->config()->ProcessTransportParameters(
197 params, SERVER, error_details) != QUIC_NO_ERROR) {
dschinazid1967a22019-04-03 16:11:32 -0700198 DCHECK(!error_details->empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500199 return false;
200 }
201
202 session()->OnConfigNegotiated();
203 return true;
204}
205
206int TlsClientHandshaker::num_sent_client_hellos() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207 return 0;
208}
209
nharper02703962019-11-07 12:23:13 -0800210bool TlsClientHandshaker::IsResumption() const {
fayang685367a2020-01-14 10:40:15 -0800211 QUIC_BUG_IF(!one_rtt_keys_available_);
nharperdf7a77b2019-11-11 13:12:45 -0800212 return SSL_session_reused(ssl()) == 1;
nharper02703962019-11-07 12:23:13 -0800213}
214
nharper4084fc92020-02-10 14:43:35 -0800215bool TlsClientHandshaker::EarlyDataAccepted() const {
216 QUIC_BUG_IF(!one_rtt_keys_available_);
217 return SSL_early_data_accepted(ssl()) == 1;
218}
219
220bool TlsClientHandshaker::ReceivedInchoateReject() const {
221 QUIC_BUG_IF(!one_rtt_keys_available_);
222 // REJ messages are a QUIC crypto feature, so TLS always returns false.
223 return false;
224}
225
QUICHE teama6ef0a62019-03-07 20:34:33 -0500226int TlsClientHandshaker::num_scup_messages_received() const {
227 // SCUP messages aren't sent or received when using the TLS handshake.
228 return 0;
229}
230
vasilvvc48c8712019-03-11 13:38:16 -0700231std::string TlsClientHandshaker::chlo_hash() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500232 return "";
233}
234
235bool TlsClientHandshaker::encryption_established() const {
236 return encryption_established_;
237}
238
fayang685367a2020-01-14 10:40:15 -0800239bool TlsClientHandshaker::one_rtt_keys_available() const {
240 return one_rtt_keys_available_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500241}
242
243const QuicCryptoNegotiatedParameters&
244TlsClientHandshaker::crypto_negotiated_params() const {
245 return *crypto_negotiated_params_;
246}
247
248CryptoMessageParser* TlsClientHandshaker::crypto_message_parser() {
249 return TlsHandshaker::crypto_message_parser();
250}
251
fayang9a863cf2020-01-16 14:12:11 -0800252HandshakeState TlsClientHandshaker::GetHandshakeState() const {
fayang01062942020-01-22 07:23:23 -0800253 if (handshake_confirmed_) {
254 return HANDSHAKE_CONFIRMED;
255 }
fayang9a863cf2020-01-16 14:12:11 -0800256 if (one_rtt_keys_available_) {
257 return HANDSHAKE_COMPLETE;
258 }
259 if (state_ >= STATE_ENCRYPTION_HANDSHAKE_DATA_SENT) {
260 return HANDSHAKE_PROCESSED;
261 }
262 return HANDSHAKE_START;
263}
264
nharper486a8a92019-08-28 16:25:10 -0700265size_t TlsClientHandshaker::BufferSizeLimitForLevel(
266 EncryptionLevel level) const {
267 return TlsHandshaker::BufferSizeLimitForLevel(level);
268}
269
fayang2f2915d2020-01-24 06:47:15 -0800270void TlsClientHandshaker::OnOneRttPacketAcknowledged() {
271 OnHandshakeConfirmed();
272}
273
fayang01062942020-01-22 07:23:23 -0800274void TlsClientHandshaker::OnHandshakeDoneReceived() {
275 if (!one_rtt_keys_available_) {
276 CloseConnection(QUIC_HANDSHAKE_FAILED,
277 "Unexpected handshake done received");
278 return;
279 }
fayang2f2915d2020-01-24 06:47:15 -0800280 OnHandshakeConfirmed();
281}
282
283void TlsClientHandshaker::OnHandshakeConfirmed() {
284 DCHECK(one_rtt_keys_available_);
fayang01062942020-01-22 07:23:23 -0800285 if (handshake_confirmed_) {
286 return;
287 }
288 handshake_confirmed_ = true;
renjietangbd33b622020-02-12 16:52:30 -0800289 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
290 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
fayang01062942020-01-22 07:23:23 -0800291}
292
QUICHE teama6ef0a62019-03-07 20:34:33 -0500293void TlsClientHandshaker::AdvanceHandshake() {
294 if (state_ == STATE_CONNECTION_CLOSED) {
295 QUIC_LOG(INFO)
296 << "TlsClientHandshaker received message after connection closed";
297 return;
298 }
299 if (state_ == STATE_IDLE) {
dschinazi91453642019-08-01 11:12:15 -0700300 CloseConnection(QUIC_HANDSHAKE_FAILED,
301 "Client observed TLS handshake idle failure");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500302 return;
303 }
304 if (state_ == STATE_HANDSHAKE_COMPLETE) {
nharperdf7a77b2019-11-11 13:12:45 -0800305 int rv = SSL_process_quic_post_handshake(ssl());
306 if (rv != 1) {
307 CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected post-handshake data");
308 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500309 return;
310 }
311
312 QUIC_LOG(INFO) << "TlsClientHandshaker: continuing handshake";
313 int rv = SSL_do_handshake(ssl());
314 if (rv == 1) {
315 FinishHandshake();
316 return;
317 }
318 int ssl_error = SSL_get_error(ssl(), rv);
319 bool should_close = true;
320 switch (state_) {
321 case STATE_HANDSHAKE_RUNNING:
322 should_close = ssl_error != SSL_ERROR_WANT_READ;
323 break;
324 case STATE_CERT_VERIFY_PENDING:
325 should_close = ssl_error != SSL_ERROR_WANT_CERTIFICATE_VERIFY;
326 break;
327 default:
328 should_close = true;
329 }
330 if (should_close && state_ != STATE_CONNECTION_CLOSED) {
331 // TODO(nharper): Surface error details from the error queue when ssl_error
332 // is SSL_ERROR_SSL.
333 QUIC_LOG(WARNING) << "SSL_do_handshake failed; closing connection";
dschinazi91453642019-08-01 11:12:15 -0700334 CloseConnection(QUIC_HANDSHAKE_FAILED,
335 "Client observed TLS handshake failure");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500336 }
337}
338
339void TlsClientHandshaker::CloseConnection(QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -0700340 const std::string& reason_phrase) {
dschinazid1967a22019-04-03 16:11:32 -0700341 DCHECK(!reason_phrase.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500342 state_ = STATE_CONNECTION_CLOSED;
renjietang87df0d02020-02-13 11:53:52 -0800343 stream()->OnUnrecoverableError(error, reason_phrase);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500344}
345
346void TlsClientHandshaker::FinishHandshake() {
347 QUIC_LOG(INFO) << "Client: handshake finished";
348 state_ = STATE_HANDSHAKE_COMPLETE;
349
vasilvvc48c8712019-03-11 13:38:16 -0700350 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500351 if (!ProcessTransportParameters(&error_details)) {
dschinazid1967a22019-04-03 16:11:32 -0700352 DCHECK(!error_details.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500353 CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
354 return;
355 }
356
dschinazi35e749e2019-04-09 09:36:04 -0700357 const uint8_t* alpn_data = nullptr;
358 unsigned alpn_length = 0;
359 SSL_get0_alpn_selected(ssl(), &alpn_data, &alpn_length);
dschinazi91453642019-08-01 11:12:15 -0700360
361 if (alpn_length == 0) {
362 QUIC_DLOG(ERROR) << "Client: server did not select ALPN";
363 // TODO(b/130164908) this should send no_application_protocol
364 // instead of QUIC_HANDSHAKE_FAILED.
365 CloseConnection(QUIC_HANDSHAKE_FAILED, "Server did not select ALPN");
366 return;
dschinazi35e749e2019-04-09 09:36:04 -0700367 }
368
dschinazi91453642019-08-01 11:12:15 -0700369 std::string received_alpn_string(reinterpret_cast<const char*>(alpn_data),
370 alpn_length);
vasilvvad7424f2019-08-30 00:27:14 -0700371 std::vector<std::string> offered_alpns = session()->GetAlpnsToOffer();
372 if (std::find(offered_alpns.begin(), offered_alpns.end(),
373 received_alpn_string) == offered_alpns.end()) {
dschinazi91453642019-08-01 11:12:15 -0700374 QUIC_LOG(ERROR) << "Client: received mismatched ALPN '"
vasilvvad7424f2019-08-30 00:27:14 -0700375 << received_alpn_string;
dschinazi91453642019-08-01 11:12:15 -0700376 // TODO(b/130164908) this should send no_application_protocol
377 // instead of QUIC_HANDSHAKE_FAILED.
378 CloseConnection(QUIC_HANDSHAKE_FAILED, "Client received mismatched ALPN");
379 return;
380 }
vasilvvad7424f2019-08-30 00:27:14 -0700381 session()->OnAlpnSelected(received_alpn_string);
dschinazi91453642019-08-01 11:12:15 -0700382 QUIC_DLOG(INFO) << "Client: server selected ALPN: '" << received_alpn_string
383 << "'";
384
QUICHE teama6ef0a62019-03-07 20:34:33 -0500385 encryption_established_ = true;
fayang685367a2020-01-14 10:40:15 -0800386 one_rtt_keys_available_ = true;
nharper8f759922019-10-09 11:08:36 -0700387
388 // Fill crypto_negotiated_params_:
389 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
390 if (cipher) {
391 crypto_negotiated_params_->cipher_suite = SSL_CIPHER_get_value(cipher);
392 }
393 crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
394 crypto_negotiated_params_->peer_signature_algorithm =
395 SSL_get_peer_signature_algorithm(ssl());
rch9001a962019-12-17 10:44:04 -0800396
renjietangbd33b622020-02-12 16:52:30 -0800397 handshaker_delegate()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500398}
399
QUICHE teama6ef0a62019-03-07 20:34:33 -0500400enum ssl_verify_result_t TlsClientHandshaker::VerifyCert(uint8_t* out_alert) {
401 if (verify_result_ != ssl_verify_retry ||
402 state_ == STATE_CERT_VERIFY_PENDING) {
403 enum ssl_verify_result_t result = verify_result_;
404 verify_result_ = ssl_verify_retry;
405 return result;
406 }
407 const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl());
408 if (cert_chain == nullptr) {
409 *out_alert = SSL_AD_INTERNAL_ERROR;
410 return ssl_verify_invalid;
411 }
412 // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies.
vasilvvc48c8712019-03-11 13:38:16 -0700413 std::vector<std::string> certs;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500414 for (CRYPTO_BUFFER* cert : cert_chain) {
415 certs.push_back(
vasilvvc48c8712019-03-11 13:38:16 -0700416 std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)),
417 CRYPTO_BUFFER_len(cert)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500418 }
QUICHE team38c190b2019-05-08 09:12:01 -0700419 const uint8_t* ocsp_response_raw;
420 size_t ocsp_response_len;
421 SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len);
422 std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw),
423 ocsp_response_len);
424 const uint8_t* sct_list_raw;
425 size_t sct_list_len;
426 SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len);
427 std::string sct_list(reinterpret_cast<const char*>(sct_list_raw),
428 sct_list_len);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500429
430 ProofVerifierCallbackImpl* proof_verify_callback =
431 new ProofVerifierCallbackImpl(this);
432
433 QuicAsyncStatus verify_result = proof_verifier_->VerifyCertChain(
QUICHE team38c190b2019-05-08 09:12:01 -0700434 server_id_.host(), certs, ocsp_response, sct_list, verify_context_.get(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500435 &cert_verify_error_details_, &verify_details_,
436 std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
437 switch (verify_result) {
438 case QUIC_SUCCESS:
nharper40bdf532019-10-03 11:16:22 -0700439 proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500440 return ssl_verify_ok;
441 case QUIC_PENDING:
442 proof_verify_callback_ = proof_verify_callback;
443 state_ = STATE_CERT_VERIFY_PENDING;
444 return ssl_verify_retry;
445 case QUIC_FAILURE:
446 default:
447 QUIC_LOG(INFO) << "Cert chain verification failed: "
448 << cert_verify_error_details_;
449 return ssl_verify_invalid;
450 }
451}
452
nharperdf7a77b2019-11-11 13:12:45 -0800453void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) {
454 if (session_cache_ == nullptr) {
455 QUIC_DVLOG(1) << "No session cache, not inserting a session";
456 return;
457 }
458 auto cache_state = std::make_unique<QuicResumptionState>();
459 cache_state->tls_session = std::move(session);
460 session_cache_->Insert(server_id_, std::move(cache_state));
461}
462
fayangd58736d2019-11-27 13:35:31 -0800463void TlsClientHandshaker::WriteMessage(EncryptionLevel level,
dmcardlecf0bfcf2019-12-13 08:08:21 -0800464 quiche::QuicheStringPiece data) {
fayangd58736d2019-11-27 13:35:31 -0800465 if (level == ENCRYPTION_HANDSHAKE &&
466 state_ < STATE_ENCRYPTION_HANDSHAKE_DATA_SENT) {
467 state_ = STATE_ENCRYPTION_HANDSHAKE_DATA_SENT;
renjietangbd33b622020-02-12 16:52:30 -0800468 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
469 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
fayangd58736d2019-11-27 13:35:31 -0800470 }
471 TlsHandshaker::WriteMessage(level, data);
472}
473
QUICHE teama6ef0a62019-03-07 20:34:33 -0500474} // namespace quic