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