1 // Copyright (c) 2012 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/quic_crypto_client_handshaker.h"
6
7 #include <memory>
8 #include <string>
9
10 #include "absl/strings/str_cat.h"
11 #include "quiche/quic/core/crypto/crypto_protocol.h"
12 #include "quiche/quic/core/crypto/crypto_utils.h"
13 #include "quiche/quic/core/quic_session.h"
14 #include "quiche/quic/core/quic_types.h"
15 #include "quiche/quic/platform/api/quic_client_stats.h"
16 #include "quiche/quic/platform/api/quic_flags.h"
17 #include "quiche/quic/platform/api/quic_logging.h"
18 #include "quiche/common/platform/api/quiche_logging.h"
19
20 namespace quic {
21
22 QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
ProofVerifierCallbackImpl(QuicCryptoClientHandshaker * parent)23 ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent)
24 : parent_(parent) {}
25
26 QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
~ProofVerifierCallbackImpl()27 ~ProofVerifierCallbackImpl() {}
28
Run(bool ok,const std::string & error_details,std::unique_ptr<ProofVerifyDetails> * details)29 void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Run(
30 bool ok, const std::string& error_details,
31 std::unique_ptr<ProofVerifyDetails>* details) {
32 if (parent_ == nullptr) {
33 return;
34 }
35
36 parent_->verify_ok_ = ok;
37 parent_->verify_error_details_ = error_details;
38 parent_->verify_details_ = std::move(*details);
39 parent_->proof_verify_callback_ = nullptr;
40 parent_->DoHandshakeLoop(nullptr);
41
42 // The ProofVerifier owns this object and will delete it when this method
43 // returns.
44 }
45
Cancel()46 void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Cancel() {
47 parent_ = nullptr;
48 }
49
QuicCryptoClientHandshaker(const QuicServerId & server_id,QuicCryptoClientStream * stream,QuicSession * session,std::unique_ptr<ProofVerifyContext> verify_context,QuicCryptoClientConfig * crypto_config,QuicCryptoClientStream::ProofHandler * proof_handler)50 QuicCryptoClientHandshaker::QuicCryptoClientHandshaker(
51 const QuicServerId& server_id, QuicCryptoClientStream* stream,
52 QuicSession* session, std::unique_ptr<ProofVerifyContext> verify_context,
53 QuicCryptoClientConfig* crypto_config,
54 QuicCryptoClientStream::ProofHandler* proof_handler)
55 : QuicCryptoHandshaker(stream, session),
56 stream_(stream),
57 session_(session),
58 delegate_(session),
59 next_state_(STATE_IDLE),
60 num_client_hellos_(0),
61 crypto_config_(crypto_config),
62 server_id_(server_id),
63 generation_counter_(0),
64 verify_context_(std::move(verify_context)),
65 proof_verify_callback_(nullptr),
66 proof_handler_(proof_handler),
67 verify_ok_(false),
68 proof_verify_start_time_(QuicTime::Zero()),
69 num_scup_messages_received_(0),
70 encryption_established_(false),
71 one_rtt_keys_available_(false),
72 crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
73
~QuicCryptoClientHandshaker()74 QuicCryptoClientHandshaker::~QuicCryptoClientHandshaker() {
75 if (proof_verify_callback_) {
76 proof_verify_callback_->Cancel();
77 }
78 }
79
OnHandshakeMessage(const CryptoHandshakeMessage & message)80 void QuicCryptoClientHandshaker::OnHandshakeMessage(
81 const CryptoHandshakeMessage& message) {
82 QuicCryptoHandshaker::OnHandshakeMessage(message);
83 if (message.tag() == kSCUP) {
84 if (!one_rtt_keys_available()) {
85 stream_->OnUnrecoverableError(
86 QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE,
87 "Early SCUP disallowed");
88 return;
89 }
90
91 // |message| is an update from the server, so we treat it differently from a
92 // handshake message.
93 HandleServerConfigUpdateMessage(message);
94 num_scup_messages_received_++;
95 return;
96 }
97
98 // Do not process handshake messages after the handshake is confirmed.
99 if (one_rtt_keys_available()) {
100 stream_->OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
101 "Unexpected handshake message");
102 return;
103 }
104
105 DoHandshakeLoop(&message);
106 }
107
CryptoConnect()108 bool QuicCryptoClientHandshaker::CryptoConnect() {
109 next_state_ = STATE_INITIALIZE;
110 DoHandshakeLoop(nullptr);
111 return session()->connection()->connected();
112 }
113
num_sent_client_hellos() const114 int QuicCryptoClientHandshaker::num_sent_client_hellos() const {
115 return num_client_hellos_;
116 }
117
IsResumption() const118 bool QuicCryptoClientHandshaker::IsResumption() const {
119 QUIC_BUG_IF(quic_bug_12522_1, !one_rtt_keys_available_);
120 // While 0-RTT handshakes could be considered to be like resumption, QUIC
121 // Crypto doesn't have the same notion of a resumption like TLS does.
122 return false;
123 }
124
EarlyDataAccepted() const125 bool QuicCryptoClientHandshaker::EarlyDataAccepted() const {
126 QUIC_BUG_IF(quic_bug_12522_2, !one_rtt_keys_available_);
127 return num_client_hellos_ == 1;
128 }
129
EarlyDataReason() const130 ssl_early_data_reason_t QuicCryptoClientHandshaker::EarlyDataReason() const {
131 return early_data_reason_;
132 }
133
ReceivedInchoateReject() const134 bool QuicCryptoClientHandshaker::ReceivedInchoateReject() const {
135 QUIC_BUG_IF(quic_bug_12522_3, !one_rtt_keys_available_);
136 return num_client_hellos_ >= 3;
137 }
138
num_scup_messages_received() const139 int QuicCryptoClientHandshaker::num_scup_messages_received() const {
140 return num_scup_messages_received_;
141 }
142
chlo_hash() const143 std::string QuicCryptoClientHandshaker::chlo_hash() const { return chlo_hash_; }
144
encryption_established() const145 bool QuicCryptoClientHandshaker::encryption_established() const {
146 return encryption_established_;
147 }
148
IsCryptoFrameExpectedForEncryptionLevel(EncryptionLevel) const149 bool QuicCryptoClientHandshaker::IsCryptoFrameExpectedForEncryptionLevel(
150 EncryptionLevel /*level*/) const {
151 return true;
152 }
153
154 EncryptionLevel
GetEncryptionLevelToSendCryptoDataOfSpace(PacketNumberSpace space) const155 QuicCryptoClientHandshaker::GetEncryptionLevelToSendCryptoDataOfSpace(
156 PacketNumberSpace space) const {
157 if (space == INITIAL_DATA) {
158 return ENCRYPTION_INITIAL;
159 }
160 QUICHE_DCHECK(false);
161 return NUM_ENCRYPTION_LEVELS;
162 }
163
one_rtt_keys_available() const164 bool QuicCryptoClientHandshaker::one_rtt_keys_available() const {
165 return one_rtt_keys_available_;
166 }
167
168 const QuicCryptoNegotiatedParameters&
crypto_negotiated_params() const169 QuicCryptoClientHandshaker::crypto_negotiated_params() const {
170 return *crypto_negotiated_params_;
171 }
172
crypto_message_parser()173 CryptoMessageParser* QuicCryptoClientHandshaker::crypto_message_parser() {
174 return QuicCryptoHandshaker::crypto_message_parser();
175 }
176
GetHandshakeState() const177 HandshakeState QuicCryptoClientHandshaker::GetHandshakeState() const {
178 return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
179 }
180
OnHandshakeDoneReceived()181 void QuicCryptoClientHandshaker::OnHandshakeDoneReceived() {
182 QUICHE_DCHECK(false);
183 }
184
OnNewTokenReceived(absl::string_view)185 void QuicCryptoClientHandshaker::OnNewTokenReceived(
186 absl::string_view /*token*/) {
187 QUICHE_DCHECK(false);
188 }
189
BufferSizeLimitForLevel(EncryptionLevel level) const190 size_t QuicCryptoClientHandshaker::BufferSizeLimitForLevel(
191 EncryptionLevel level) const {
192 return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
193 }
194
195 std::unique_ptr<QuicDecrypter>
AdvanceKeysAndCreateCurrentOneRttDecrypter()196 QuicCryptoClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
197 // Key update is only defined in QUIC+TLS.
198 QUICHE_DCHECK(false);
199 return nullptr;
200 }
201
202 std::unique_ptr<QuicEncrypter>
CreateCurrentOneRttEncrypter()203 QuicCryptoClientHandshaker::CreateCurrentOneRttEncrypter() {
204 // Key update is only defined in QUIC+TLS.
205 QUICHE_DCHECK(false);
206 return nullptr;
207 }
208
OnConnectionClosed(QuicErrorCode,ConnectionCloseSource)209 void QuicCryptoClientHandshaker::OnConnectionClosed(
210 QuicErrorCode /*error*/, ConnectionCloseSource /*source*/) {
211 next_state_ = STATE_CONNECTION_CLOSED;
212 }
213
HandleServerConfigUpdateMessage(const CryptoHandshakeMessage & server_config_update)214 void QuicCryptoClientHandshaker::HandleServerConfigUpdateMessage(
215 const CryptoHandshakeMessage& server_config_update) {
216 QUICHE_DCHECK(server_config_update.tag() == kSCUP);
217 std::string error_details;
218 QuicCryptoClientConfig::CachedState* cached =
219 crypto_config_->LookupOrCreate(server_id_);
220 QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate(
221 server_config_update, session()->connection()->clock()->WallNow(),
222 session()->transport_version(), chlo_hash_, cached,
223 crypto_negotiated_params_, &error_details);
224
225 if (error != QUIC_NO_ERROR) {
226 stream_->OnUnrecoverableError(
227 error, "Server config update invalid: " + error_details);
228 return;
229 }
230
231 QUICHE_DCHECK(one_rtt_keys_available());
232 if (proof_verify_callback_) {
233 proof_verify_callback_->Cancel();
234 }
235 next_state_ = STATE_INITIALIZE_SCUP;
236 DoHandshakeLoop(nullptr);
237 }
238
DoHandshakeLoop(const CryptoHandshakeMessage * in)239 void QuicCryptoClientHandshaker::DoHandshakeLoop(
240 const CryptoHandshakeMessage* in) {
241 QuicCryptoClientConfig::CachedState* cached =
242 crypto_config_->LookupOrCreate(server_id_);
243
244 QuicAsyncStatus rv = QUIC_SUCCESS;
245 do {
246 QUICHE_CHECK_NE(STATE_NONE, next_state_);
247 const State state = next_state_;
248 next_state_ = STATE_IDLE;
249 rv = QUIC_SUCCESS;
250 switch (state) {
251 case STATE_INITIALIZE:
252 DoInitialize(cached);
253 break;
254 case STATE_SEND_CHLO:
255 DoSendCHLO(cached);
256 return; // return waiting to hear from server.
257 case STATE_RECV_REJ:
258 DoReceiveREJ(in, cached);
259 break;
260 case STATE_VERIFY_PROOF:
261 rv = DoVerifyProof(cached);
262 break;
263 case STATE_VERIFY_PROOF_COMPLETE:
264 DoVerifyProofComplete(cached);
265 break;
266 case STATE_RECV_SHLO:
267 DoReceiveSHLO(in, cached);
268 break;
269 case STATE_IDLE:
270 // This means that the peer sent us a message that we weren't expecting.
271 stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
272 "Handshake in idle state");
273 return;
274 case STATE_INITIALIZE_SCUP:
275 DoInitializeServerConfigUpdate(cached);
276 break;
277 case STATE_NONE:
278 QUICHE_NOTREACHED();
279 return;
280 case STATE_CONNECTION_CLOSED:
281 rv = QUIC_FAILURE;
282 return; // We are done.
283 }
284 } while (rv != QUIC_PENDING && next_state_ != STATE_NONE);
285 }
286
DoInitialize(QuicCryptoClientConfig::CachedState * cached)287 void QuicCryptoClientHandshaker::DoInitialize(
288 QuicCryptoClientConfig::CachedState* cached) {
289 if (!cached->IsEmpty() && !cached->signature().empty()) {
290 // Note that we verify the proof even if the cached proof is valid.
291 // This allows us to respond to CA trust changes or certificate
292 // expiration because it may have been a while since we last verified
293 // the proof.
294 QUICHE_DCHECK(crypto_config_->proof_verifier());
295 // Track proof verification time when cached server config is used.
296 proof_verify_start_time_ = session()->connection()->clock()->Now();
297 chlo_hash_ = cached->chlo_hash();
298 // If the cached state needs to be verified, do it now.
299 next_state_ = STATE_VERIFY_PROOF;
300 } else {
301 next_state_ = STATE_SEND_CHLO;
302 }
303 }
304
DoSendCHLO(QuicCryptoClientConfig::CachedState * cached)305 void QuicCryptoClientHandshaker::DoSendCHLO(
306 QuicCryptoClientConfig::CachedState* cached) {
307 // Send the client hello in plaintext.
308 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
309 encryption_established_ = false;
310 if (num_client_hellos_ >= QuicCryptoClientStream::kMaxClientHellos) {
311 stream_->OnUnrecoverableError(
312 QUIC_CRYPTO_TOO_MANY_REJECTS,
313 absl::StrCat("More than ", QuicCryptoClientStream::kMaxClientHellos,
314 " rejects"));
315 return;
316 }
317 num_client_hellos_++;
318
319 CryptoHandshakeMessage out;
320 QUICHE_DCHECK(session() != nullptr);
321 QUICHE_DCHECK(session()->config() != nullptr);
322 // Send all the options, regardless of whether we're sending an
323 // inchoate or subsequent hello.
324 session()->config()->ToHandshakeMessage(&out, session()->transport_version());
325
326 bool fill_inchoate_client_hello = false;
327 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
328 early_data_reason_ = ssl_early_data_no_session_offered;
329 fill_inchoate_client_hello = true;
330 } else if (session()->config()->HasClientRequestedIndependentOption(
331 kQNZ2, session()->perspective()) &&
332 num_client_hellos_ == 1) {
333 early_data_reason_ = ssl_early_data_disabled;
334 fill_inchoate_client_hello = true;
335 }
336 if (fill_inchoate_client_hello) {
337 crypto_config_->FillInchoateClientHello(
338 server_id_, session()->supported_versions().front(), cached,
339 session()->connection()->random_generator(),
340 /* demand_x509_proof= */ true, crypto_negotiated_params_, &out);
341 // Pad the inchoate client hello to fill up a packet.
342 const QuicByteCount kFramingOverhead = 50; // A rough estimate.
343 const QuicByteCount max_packet_size =
344 session()->connection()->max_packet_length();
345 if (max_packet_size <= kFramingOverhead) {
346 QUIC_DLOG(DFATAL) << "max_packet_length (" << max_packet_size
347 << ") has no room for framing overhead.";
348 stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR,
349 "max_packet_size too smalll");
350 return;
351 }
352 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
353 QUIC_DLOG(DFATAL) << "Client hello won't fit in a single packet.";
354 stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR, "CHLO too large");
355 return;
356 }
357 next_state_ = STATE_RECV_REJ;
358 chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
359 session()->connection()->set_fully_pad_crypto_handshake_packets(
360 crypto_config_->pad_inchoate_hello());
361 SendHandshakeMessage(out, ENCRYPTION_INITIAL);
362 return;
363 }
364
365 std::string error_details;
366 QuicErrorCode error = crypto_config_->FillClientHello(
367 server_id_, session()->connection()->connection_id(),
368 session()->supported_versions().front(),
369 session()->connection()->version(), cached,
370 session()->connection()->clock()->WallNow(),
371 session()->connection()->random_generator(), crypto_negotiated_params_,
372 &out, &error_details);
373 if (error != QUIC_NO_ERROR) {
374 // Flush the cached config so that, if it's bad, the server has a
375 // chance to send us another in the future.
376 cached->InvalidateServerConfig();
377 stream_->OnUnrecoverableError(error, error_details);
378 return;
379 }
380 chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
381 if (cached->proof_verify_details()) {
382 proof_handler_->OnProofVerifyDetailsAvailable(
383 *cached->proof_verify_details());
384 }
385 next_state_ = STATE_RECV_SHLO;
386 session()->connection()->set_fully_pad_crypto_handshake_packets(
387 crypto_config_->pad_full_hello());
388 SendHandshakeMessage(out, ENCRYPTION_INITIAL);
389 // Be prepared to decrypt with the new server write key.
390 delegate_->OnNewEncryptionKeyAvailable(
391 ENCRYPTION_ZERO_RTT,
392 std::move(crypto_negotiated_params_->initial_crypters.encrypter));
393 delegate_->OnNewDecryptionKeyAvailable(
394 ENCRYPTION_ZERO_RTT,
395 std::move(crypto_negotiated_params_->initial_crypters.decrypter),
396 /*set_alternative_decrypter=*/true,
397 /*latch_once_used=*/true);
398 encryption_established_ = true;
399 delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
400 if (early_data_reason_ == ssl_early_data_unknown && num_client_hellos_ > 1) {
401 early_data_reason_ = ssl_early_data_peer_declined;
402 }
403 }
404
DoReceiveREJ(const CryptoHandshakeMessage * in,QuicCryptoClientConfig::CachedState * cached)405 void QuicCryptoClientHandshaker::DoReceiveREJ(
406 const CryptoHandshakeMessage* in,
407 QuicCryptoClientConfig::CachedState* cached) {
408 // We sent a dummy CHLO because we didn't have enough information to
409 // perform a handshake, or we sent a full hello that the server
410 // rejected. Here we hope to have a REJ that contains the information
411 // that we need.
412 if (in->tag() != kREJ) {
413 next_state_ = STATE_NONE;
414 stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
415 "Expected REJ");
416 return;
417 }
418
419 QuicTagVector reject_reasons;
420 static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
421 if (in->GetTaglist(kRREJ, &reject_reasons) == QUIC_NO_ERROR) {
422 uint32_t packed_error = 0;
423 for (size_t i = 0; i < reject_reasons.size(); ++i) {
424 // HANDSHAKE_OK is 0 and don't report that as error.
425 if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) {
426 continue;
427 }
428 HandshakeFailureReason reason =
429 static_cast<HandshakeFailureReason>(reject_reasons[i]);
430 packed_error |= 1 << (reason - 1);
431 }
432 QUIC_DVLOG(1) << "Reasons for rejection: " << packed_error;
433 }
434
435 // Receipt of a REJ message means that the server received the CHLO
436 // so we can cancel and retransmissions.
437 delegate_->NeuterUnencryptedData();
438
439 std::string error_details;
440 QuicErrorCode error = crypto_config_->ProcessRejection(
441 *in, session()->connection()->clock()->WallNow(),
442 session()->transport_version(), chlo_hash_, cached,
443 crypto_negotiated_params_, &error_details);
444
445 if (error != QUIC_NO_ERROR) {
446 next_state_ = STATE_NONE;
447 stream_->OnUnrecoverableError(error, error_details);
448 return;
449 }
450 if (!cached->proof_valid()) {
451 if (!cached->signature().empty()) {
452 // Note that we only verify the proof if the cached proof is not
453 // valid. If the cached proof is valid here, someone else must have
454 // just added the server config to the cache and verified the proof,
455 // so we can assume no CA trust changes or certificate expiration
456 // has happened since then.
457 next_state_ = STATE_VERIFY_PROOF;
458 return;
459 }
460 }
461 next_state_ = STATE_SEND_CHLO;
462 }
463
DoVerifyProof(QuicCryptoClientConfig::CachedState * cached)464 QuicAsyncStatus QuicCryptoClientHandshaker::DoVerifyProof(
465 QuicCryptoClientConfig::CachedState* cached) {
466 ProofVerifier* verifier = crypto_config_->proof_verifier();
467 QUICHE_DCHECK(verifier);
468 next_state_ = STATE_VERIFY_PROOF_COMPLETE;
469 generation_counter_ = cached->generation_counter();
470
471 ProofVerifierCallbackImpl* proof_verify_callback =
472 new ProofVerifierCallbackImpl(this);
473
474 verify_ok_ = false;
475
476 QuicAsyncStatus status = verifier->VerifyProof(
477 server_id_.host(), server_id_.port(), cached->server_config(),
478 session()->transport_version(), chlo_hash_, cached->certs(),
479 cached->cert_sct(), cached->signature(), verify_context_.get(),
480 &verify_error_details_, &verify_details_,
481 std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
482
483 switch (status) {
484 case QUIC_PENDING:
485 proof_verify_callback_ = proof_verify_callback;
486 QUIC_DVLOG(1) << "Doing VerifyProof";
487 break;
488 case QUIC_FAILURE:
489 break;
490 case QUIC_SUCCESS:
491 verify_ok_ = true;
492 break;
493 }
494 return status;
495 }
496
DoVerifyProofComplete(QuicCryptoClientConfig::CachedState * cached)497 void QuicCryptoClientHandshaker::DoVerifyProofComplete(
498 QuicCryptoClientConfig::CachedState* cached) {
499 if (proof_verify_start_time_.IsInitialized()) {
500 QUIC_CLIENT_HISTOGRAM_TIMES(
501 "QuicSession.VerifyProofTime.CachedServerConfig",
502 (session()->connection()->clock()->Now() - proof_verify_start_time_),
503 QuicTime::Delta::FromMilliseconds(1), QuicTime::Delta::FromSeconds(10),
504 50, "");
505 }
506 if (!verify_ok_) {
507 if (verify_details_) {
508 proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_);
509 }
510 if (num_client_hellos_ == 0) {
511 cached->Clear();
512 next_state_ = STATE_INITIALIZE;
513 return;
514 }
515 next_state_ = STATE_NONE;
516 QUIC_CLIENT_HISTOGRAM_BOOL("QuicVerifyProofFailed.HandshakeConfirmed",
517 one_rtt_keys_available(), "");
518 stream_->OnUnrecoverableError(QUIC_PROOF_INVALID,
519 "Proof invalid: " + verify_error_details_);
520 return;
521 }
522
523 // Check if generation_counter has changed between STATE_VERIFY_PROOF and
524 // STATE_VERIFY_PROOF_COMPLETE state changes.
525 if (generation_counter_ != cached->generation_counter()) {
526 next_state_ = STATE_VERIFY_PROOF;
527 } else {
528 SetCachedProofValid(cached);
529 cached->SetProofVerifyDetails(verify_details_.release());
530 if (!one_rtt_keys_available()) {
531 next_state_ = STATE_SEND_CHLO;
532 } else {
533 next_state_ = STATE_NONE;
534 }
535 }
536 }
537
DoReceiveSHLO(const CryptoHandshakeMessage * in,QuicCryptoClientConfig::CachedState * cached)538 void QuicCryptoClientHandshaker::DoReceiveSHLO(
539 const CryptoHandshakeMessage* in,
540 QuicCryptoClientConfig::CachedState* cached) {
541 next_state_ = STATE_NONE;
542 // We sent a CHLO that we expected to be accepted and now we're
543 // hoping for a SHLO from the server to confirm that. First check
544 // to see whether the response was a reject, and if so, move on to
545 // the reject-processing state.
546 if (in->tag() == kREJ) {
547 // A reject message must be sent in ENCRYPTION_INITIAL.
548 if (session()->connection()->last_decrypted_level() != ENCRYPTION_INITIAL) {
549 // The rejection was sent encrypted!
550 stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
551 "encrypted REJ message");
552 return;
553 }
554 next_state_ = STATE_RECV_REJ;
555 return;
556 }
557
558 if (in->tag() != kSHLO) {
559 stream_->OnUnrecoverableError(
560 QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
561 absl::StrCat("Expected SHLO or REJ. Received: ",
562 QuicTagToString(in->tag())));
563 return;
564 }
565
566 if (session()->connection()->last_decrypted_level() == ENCRYPTION_INITIAL) {
567 // The server hello was sent without encryption.
568 stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
569 "unencrypted SHLO message");
570 return;
571 }
572 if (num_client_hellos_ == 1) {
573 early_data_reason_ = ssl_early_data_accepted;
574 }
575
576 std::string error_details;
577 QuicErrorCode error = crypto_config_->ProcessServerHello(
578 *in, session()->connection()->connection_id(),
579 session()->connection()->version(),
580 session()->connection()->server_supported_versions(), cached,
581 crypto_negotiated_params_, &error_details);
582
583 if (error != QUIC_NO_ERROR) {
584 stream_->OnUnrecoverableError(error,
585 "Server hello invalid: " + error_details);
586 return;
587 }
588 error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details);
589 if (error != QUIC_NO_ERROR) {
590 stream_->OnUnrecoverableError(error,
591 "Server hello invalid: " + error_details);
592 return;
593 }
594 session()->OnConfigNegotiated();
595
596 CrypterPair* crypters = &crypto_negotiated_params_->forward_secure_crypters;
597 // TODO(agl): we don't currently latch this decrypter because the idea
598 // has been floated that the server shouldn't send packets encrypted
599 // with the FORWARD_SECURE key until it receives a FORWARD_SECURE
600 // packet from the client.
601 delegate_->OnNewEncryptionKeyAvailable(ENCRYPTION_FORWARD_SECURE,
602 std::move(crypters->encrypter));
603 delegate_->OnNewDecryptionKeyAvailable(ENCRYPTION_FORWARD_SECURE,
604 std::move(crypters->decrypter),
605 /*set_alternative_decrypter=*/true,
606 /*latch_once_used=*/false);
607 one_rtt_keys_available_ = true;
608 delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
609 delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
610 delegate_->NeuterHandshakeData();
611 }
612
DoInitializeServerConfigUpdate(QuicCryptoClientConfig::CachedState * cached)613 void QuicCryptoClientHandshaker::DoInitializeServerConfigUpdate(
614 QuicCryptoClientConfig::CachedState* cached) {
615 bool update_ignored = false;
616 if (!cached->IsEmpty() && !cached->signature().empty()) {
617 // Note that we verify the proof even if the cached proof is valid.
618 QUICHE_DCHECK(crypto_config_->proof_verifier());
619 next_state_ = STATE_VERIFY_PROOF;
620 } else {
621 update_ignored = true;
622 next_state_ = STATE_NONE;
623 }
624 QUIC_CLIENT_HISTOGRAM_COUNTS("QuicNumServerConfig.UpdateMessagesIgnored",
625 update_ignored, 1, 1000000, 50, "");
626 }
627
SetCachedProofValid(QuicCryptoClientConfig::CachedState * cached)628 void QuicCryptoClientHandshaker::SetCachedProofValid(
629 QuicCryptoClientConfig::CachedState* cached) {
630 cached->SetProofValid();
631 proof_handler_->OnProofValid(*cached);
632 }
633
634 } // namespace quic
635