xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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