• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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