xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.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_server_stream.h"
6 
7 #include <memory>
8 #include <string>
9 
10 #include "absl/base/macros.h"
11 #include "absl/strings/string_view.h"
12 #include "openssl/sha.h"
13 #include "quiche/quic/core/quic_types.h"
14 #include "quiche/quic/platform/api/quic_flag_utils.h"
15 #include "quiche/quic/platform/api/quic_testvalue.h"
16 #include "quiche/common/platform/api/quiche_logging.h"
17 #include "quiche/common/quiche_text_utils.h"
18 
19 namespace quic {
20 
21 class QuicCryptoServerStream::ProcessClientHelloCallback
22     : public ProcessClientHelloResultCallback {
23  public:
ProcessClientHelloCallback(QuicCryptoServerStream * parent,const quiche::QuicheReferenceCountedPointer<ValidateClientHelloResultCallback::Result> & result)24   ProcessClientHelloCallback(
25       QuicCryptoServerStream* parent,
26       const quiche::QuicheReferenceCountedPointer<
27           ValidateClientHelloResultCallback::Result>& result)
28       : parent_(parent), result_(result) {}
29 
Run(QuicErrorCode error,const std::string & error_details,std::unique_ptr<CryptoHandshakeMessage> message,std::unique_ptr<DiversificationNonce> diversification_nonce,std::unique_ptr<ProofSource::Details> proof_source_details)30   void Run(
31       QuicErrorCode error, const std::string& error_details,
32       std::unique_ptr<CryptoHandshakeMessage> message,
33       std::unique_ptr<DiversificationNonce> diversification_nonce,
34       std::unique_ptr<ProofSource::Details> proof_source_details) override {
35     if (parent_ == nullptr) {
36       return;
37     }
38 
39     parent_->FinishProcessingHandshakeMessageAfterProcessClientHello(
40         *result_, error, error_details, std::move(message),
41         std::move(diversification_nonce), std::move(proof_source_details));
42   }
43 
Cancel()44   void Cancel() { parent_ = nullptr; }
45 
46  private:
47   QuicCryptoServerStream* parent_;
48   quiche::QuicheReferenceCountedPointer<
49       ValidateClientHelloResultCallback::Result>
50       result_;
51 };
52 
QuicCryptoServerStream(const QuicCryptoServerConfig * crypto_config,QuicCompressedCertsCache * compressed_certs_cache,QuicSession * session,QuicCryptoServerStreamBase::Helper * helper)53 QuicCryptoServerStream::QuicCryptoServerStream(
54     const QuicCryptoServerConfig* crypto_config,
55     QuicCompressedCertsCache* compressed_certs_cache, QuicSession* session,
56     QuicCryptoServerStreamBase::Helper* helper)
57     : QuicCryptoServerStreamBase(session),
58       QuicCryptoHandshaker(this, session),
59       session_(session),
60       delegate_(session),
61       crypto_config_(crypto_config),
62       compressed_certs_cache_(compressed_certs_cache),
63       signed_config_(new QuicSignedServerConfig),
64       helper_(helper),
65       num_handshake_messages_(0),
66       num_handshake_messages_with_server_nonces_(0),
67       send_server_config_update_cb_(nullptr),
68       num_server_config_update_messages_sent_(0),
69       zero_rtt_attempted_(false),
70       chlo_packet_size_(0),
71       validate_client_hello_cb_(nullptr),
72       encryption_established_(false),
73       one_rtt_keys_available_(false),
74       one_rtt_packet_decrypted_(false),
75       crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
76 
~QuicCryptoServerStream()77 QuicCryptoServerStream::~QuicCryptoServerStream() {
78   CancelOutstandingCallbacks();
79 }
80 
CancelOutstandingCallbacks()81 void QuicCryptoServerStream::CancelOutstandingCallbacks() {
82   // Detach from the validation callback.  Calling this multiple times is safe.
83   if (validate_client_hello_cb_ != nullptr) {
84     validate_client_hello_cb_->Cancel();
85     validate_client_hello_cb_ = nullptr;
86   }
87   if (send_server_config_update_cb_ != nullptr) {
88     send_server_config_update_cb_->Cancel();
89     send_server_config_update_cb_ = nullptr;
90   }
91   if (std::shared_ptr<ProcessClientHelloCallback> cb =
92           process_client_hello_cb_.lock()) {
93     cb->Cancel();
94     process_client_hello_cb_.reset();
95   }
96 }
97 
OnHandshakeMessage(const CryptoHandshakeMessage & message)98 void QuicCryptoServerStream::OnHandshakeMessage(
99     const CryptoHandshakeMessage& message) {
100   QuicCryptoHandshaker::OnHandshakeMessage(message);
101   ++num_handshake_messages_;
102   chlo_packet_size_ = session()->connection()->GetCurrentPacket().length();
103 
104   // Do not process handshake messages after the handshake is confirmed.
105   if (one_rtt_keys_available_) {
106     OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
107                          "Unexpected handshake message from client");
108     return;
109   }
110 
111   if (message.tag() != kCHLO) {
112     OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
113                          "Handshake packet not CHLO");
114     return;
115   }
116 
117   if (validate_client_hello_cb_ != nullptr ||
118       !process_client_hello_cb_.expired()) {
119     // Already processing some other handshake message.  The protocol
120     // does not allow for clients to send multiple handshake messages
121     // before the server has a chance to respond.
122     OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
123                          "Unexpected handshake message while processing CHLO");
124     return;
125   }
126 
127   chlo_hash_ =
128       CryptoUtils::HashHandshakeMessage(message, Perspective::IS_SERVER);
129 
130   std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this));
131   QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
132   QUICHE_DCHECK(process_client_hello_cb_.expired());
133   validate_client_hello_cb_ = cb.get();
134   crypto_config_->ValidateClientHello(
135       message, GetClientAddress(), session()->connection()->self_address(),
136       transport_version(), session()->connection()->clock(), signed_config_,
137       std::move(cb));
138 }
139 
FinishProcessingHandshakeMessage(quiche::QuicheReferenceCountedPointer<ValidateClientHelloResultCallback::Result> result,std::unique_ptr<ProofSource::Details> details)140 void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
141     quiche::QuicheReferenceCountedPointer<
142         ValidateClientHelloResultCallback::Result>
143         result,
144     std::unique_ptr<ProofSource::Details> details) {
145   // Clear the callback that got us here.
146   QUICHE_DCHECK(validate_client_hello_cb_ != nullptr);
147   QUICHE_DCHECK(process_client_hello_cb_.expired());
148   validate_client_hello_cb_ = nullptr;
149 
150   auto cb = std::make_shared<ProcessClientHelloCallback>(this, result);
151   process_client_hello_cb_ = cb;
152   ProcessClientHello(result, std::move(details), std::move(cb));
153 }
154 
155 void QuicCryptoServerStream::
FinishProcessingHandshakeMessageAfterProcessClientHello(const ValidateClientHelloResultCallback::Result & result,QuicErrorCode error,const std::string & error_details,std::unique_ptr<CryptoHandshakeMessage> reply,std::unique_ptr<DiversificationNonce> diversification_nonce,std::unique_ptr<ProofSource::Details> proof_source_details)156     FinishProcessingHandshakeMessageAfterProcessClientHello(
157         const ValidateClientHelloResultCallback::Result& result,
158         QuicErrorCode error, const std::string& error_details,
159         std::unique_ptr<CryptoHandshakeMessage> reply,
160         std::unique_ptr<DiversificationNonce> diversification_nonce,
161         std::unique_ptr<ProofSource::Details> proof_source_details) {
162   // Clear the callback that got us here.
163   QUICHE_DCHECK(!process_client_hello_cb_.expired());
164   QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
165   process_client_hello_cb_.reset();
166   proof_source_details_ = std::move(proof_source_details);
167 
168   AdjustTestValue("quic::QuicCryptoServerStream::after_process_client_hello",
169                   session());
170 
171   if (!session()->connection()->connected()) {
172     QUIC_CODE_COUNT(quic_crypto_disconnected_after_process_client_hello);
173     QUIC_LOG_FIRST_N(INFO, 10)
174         << "After processing CHLO, QUIC connection has been closed with code "
175         << session()->error() << ", details: " << session()->error_details();
176     return;
177   }
178 
179   const CryptoHandshakeMessage& message = result.client_hello;
180   if (error != QUIC_NO_ERROR) {
181     OnUnrecoverableError(error, error_details);
182     return;
183   }
184 
185   if (reply->tag() != kSHLO) {
186     session()->connection()->set_fully_pad_crypto_handshake_packets(
187         crypto_config_->pad_rej());
188     // Send REJ in plaintext.
189     SendHandshakeMessage(*reply, ENCRYPTION_INITIAL);
190     return;
191   }
192 
193   // If we are returning a SHLO then we accepted the handshake.  Now
194   // process the negotiated configuration options as part of the
195   // session config.
196   QuicConfig* config = session()->config();
197   OverrideQuicConfigDefaults(config);
198   std::string process_error_details;
199   const QuicErrorCode process_error =
200       config->ProcessPeerHello(message, CLIENT, &process_error_details);
201   if (process_error != QUIC_NO_ERROR) {
202     OnUnrecoverableError(process_error, process_error_details);
203     return;
204   }
205 
206   session()->OnConfigNegotiated();
207 
208   config->ToHandshakeMessage(reply.get(), session()->transport_version());
209 
210   // Receiving a full CHLO implies the client is prepared to decrypt with
211   // the new server write key.  We can start to encrypt with the new server
212   // write key.
213   //
214   // NOTE: the SHLO will be encrypted with the new server write key.
215   delegate_->OnNewEncryptionKeyAvailable(
216       ENCRYPTION_ZERO_RTT,
217       std::move(crypto_negotiated_params_->initial_crypters.encrypter));
218   delegate_->OnNewDecryptionKeyAvailable(
219       ENCRYPTION_ZERO_RTT,
220       std::move(crypto_negotiated_params_->initial_crypters.decrypter),
221       /*set_alternative_decrypter=*/false,
222       /*latch_once_used=*/false);
223   delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
224   delegate_->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
225   session()->connection()->SetDiversificationNonce(*diversification_nonce);
226 
227   session()->connection()->set_fully_pad_crypto_handshake_packets(
228       crypto_config_->pad_shlo());
229   // Send SHLO in ENCRYPTION_ZERO_RTT.
230   SendHandshakeMessage(*reply, ENCRYPTION_ZERO_RTT);
231   delegate_->OnNewEncryptionKeyAvailable(
232       ENCRYPTION_FORWARD_SECURE,
233       std::move(crypto_negotiated_params_->forward_secure_crypters.encrypter));
234   delegate_->OnNewDecryptionKeyAvailable(
235       ENCRYPTION_FORWARD_SECURE,
236       std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
237       /*set_alternative_decrypter=*/true,
238       /*latch_once_used=*/false);
239   encryption_established_ = true;
240   one_rtt_keys_available_ = true;
241   delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
242   delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
243 }
244 
SendServerConfigUpdate(const CachedNetworkParameters * cached_network_params)245 void QuicCryptoServerStream::SendServerConfigUpdate(
246     const CachedNetworkParameters* cached_network_params) {
247   if (!one_rtt_keys_available_) {
248     return;
249   }
250 
251   if (send_server_config_update_cb_ != nullptr) {
252     QUIC_DVLOG(1)
253         << "Skipped server config update since one is already in progress";
254     return;
255   }
256 
257   std::unique_ptr<SendServerConfigUpdateCallback> cb(
258       new SendServerConfigUpdateCallback(this));
259   send_server_config_update_cb_ = cb.get();
260 
261   crypto_config_->BuildServerConfigUpdateMessage(
262       session()->transport_version(), chlo_hash_,
263       previous_source_address_tokens_, session()->connection()->self_address(),
264       GetClientAddress(), session()->connection()->clock(),
265       session()->connection()->random_generator(), compressed_certs_cache_,
266       *crypto_negotiated_params_, cached_network_params, std::move(cb));
267 }
268 
269 QuicCryptoServerStream::SendServerConfigUpdateCallback::
SendServerConfigUpdateCallback(QuicCryptoServerStream * parent)270     SendServerConfigUpdateCallback(QuicCryptoServerStream* parent)
271     : parent_(parent) {}
272 
Cancel()273 void QuicCryptoServerStream::SendServerConfigUpdateCallback::Cancel() {
274   parent_ = nullptr;
275 }
276 
277 // From BuildServerConfigUpdateMessageResultCallback
Run(bool ok,const CryptoHandshakeMessage & message)278 void QuicCryptoServerStream::SendServerConfigUpdateCallback::Run(
279     bool ok, const CryptoHandshakeMessage& message) {
280   if (parent_ == nullptr) {
281     return;
282   }
283   parent_->FinishSendServerConfigUpdate(ok, message);
284 }
285 
FinishSendServerConfigUpdate(bool ok,const CryptoHandshakeMessage & message)286 void QuicCryptoServerStream::FinishSendServerConfigUpdate(
287     bool ok, const CryptoHandshakeMessage& message) {
288   // Clear the callback that got us here.
289   QUICHE_DCHECK(send_server_config_update_cb_ != nullptr);
290   send_server_config_update_cb_ = nullptr;
291 
292   if (!ok) {
293     QUIC_DVLOG(1) << "Server: Failed to build server config update (SCUP)!";
294     return;
295   }
296 
297   QUIC_DVLOG(1) << "Server: Sending server config update: "
298                 << message.DebugString();
299 
300   // Send server config update in ENCRYPTION_FORWARD_SECURE.
301   SendHandshakeMessage(message, ENCRYPTION_FORWARD_SECURE);
302 
303   ++num_server_config_update_messages_sent_;
304 }
305 
DisableResumption()306 bool QuicCryptoServerStream::DisableResumption() {
307   QUICHE_DCHECK(false) << "Not supported for QUIC crypto.";
308   return false;
309 }
310 
IsZeroRtt() const311 bool QuicCryptoServerStream::IsZeroRtt() const {
312   return num_handshake_messages_ == 1 &&
313          num_handshake_messages_with_server_nonces_ == 0;
314 }
315 
IsResumption() const316 bool QuicCryptoServerStream::IsResumption() const {
317   // QUIC Crypto doesn't have a non-0-RTT resumption mode.
318   return IsZeroRtt();
319 }
320 
NumServerConfigUpdateMessagesSent() const321 int QuicCryptoServerStream::NumServerConfigUpdateMessagesSent() const {
322   return num_server_config_update_messages_sent_;
323 }
324 
325 const CachedNetworkParameters*
PreviousCachedNetworkParams() const326 QuicCryptoServerStream::PreviousCachedNetworkParams() const {
327   return previous_cached_network_params_.get();
328 }
329 
ResumptionAttempted() const330 bool QuicCryptoServerStream::ResumptionAttempted() const {
331   return zero_rtt_attempted_;
332 }
333 
EarlyDataAttempted() const334 bool QuicCryptoServerStream::EarlyDataAttempted() const {
335   QUICHE_DCHECK(false) << "Not supported for QUIC crypto.";
336   return zero_rtt_attempted_;
337 }
338 
SetPreviousCachedNetworkParams(CachedNetworkParameters cached_network_params)339 void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
340     CachedNetworkParameters cached_network_params) {
341   previous_cached_network_params_.reset(
342       new CachedNetworkParameters(cached_network_params));
343 }
344 
OnPacketDecrypted(EncryptionLevel level)345 void QuicCryptoServerStream::OnPacketDecrypted(EncryptionLevel level) {
346   if (level == ENCRYPTION_FORWARD_SECURE) {
347     one_rtt_packet_decrypted_ = true;
348     delegate_->NeuterHandshakeData();
349   }
350 }
351 
OnHandshakeDoneReceived()352 void QuicCryptoServerStream::OnHandshakeDoneReceived() { QUICHE_DCHECK(false); }
353 
OnNewTokenReceived(absl::string_view)354 void QuicCryptoServerStream::OnNewTokenReceived(absl::string_view /*token*/) {
355   QUICHE_DCHECK(false);
356 }
357 
GetAddressToken(const CachedNetworkParameters *) const358 std::string QuicCryptoServerStream::GetAddressToken(
359     const CachedNetworkParameters* /*cached_network_parameters*/) const {
360   QUICHE_DCHECK(false);
361   return "";
362 }
363 
ValidateAddressToken(absl::string_view) const364 bool QuicCryptoServerStream::ValidateAddressToken(
365     absl::string_view /*token*/) const {
366   QUICHE_DCHECK(false);
367   return false;
368 }
369 
ShouldSendExpectCTHeader() const370 bool QuicCryptoServerStream::ShouldSendExpectCTHeader() const {
371   return signed_config_->proof.send_expect_ct_header;
372 }
373 
DidCertMatchSni() const374 bool QuicCryptoServerStream::DidCertMatchSni() const {
375   return signed_config_->proof.cert_matched_sni;
376 }
377 
ProofSourceDetails() const378 const ProofSource::Details* QuicCryptoServerStream::ProofSourceDetails() const {
379   return proof_source_details_.get();
380 }
381 
GetBase64SHA256ClientChannelID(std::string * output) const382 bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID(
383     std::string* output) const {
384   if (!encryption_established() ||
385       crypto_negotiated_params_->channel_id.empty()) {
386     return false;
387   }
388 
389   const std::string& channel_id(crypto_negotiated_params_->channel_id);
390   uint8_t digest[SHA256_DIGEST_LENGTH];
391   SHA256(reinterpret_cast<const uint8_t*>(channel_id.data()), channel_id.size(),
392          digest);
393 
394   quiche::QuicheTextUtils::Base64Encode(digest, ABSL_ARRAYSIZE(digest), output);
395   return true;
396 }
397 
EarlyDataReason() const398 ssl_early_data_reason_t QuicCryptoServerStream::EarlyDataReason() const {
399   if (IsZeroRtt()) {
400     return ssl_early_data_accepted;
401   }
402   if (zero_rtt_attempted_) {
403     return ssl_early_data_session_not_resumed;
404   }
405   return ssl_early_data_no_session_offered;
406 }
407 
encryption_established() const408 bool QuicCryptoServerStream::encryption_established() const {
409   return encryption_established_;
410 }
411 
one_rtt_keys_available() const412 bool QuicCryptoServerStream::one_rtt_keys_available() const {
413   return one_rtt_keys_available_;
414 }
415 
416 const QuicCryptoNegotiatedParameters&
crypto_negotiated_params() const417 QuicCryptoServerStream::crypto_negotiated_params() const {
418   return *crypto_negotiated_params_;
419 }
420 
crypto_message_parser()421 CryptoMessageParser* QuicCryptoServerStream::crypto_message_parser() {
422   return QuicCryptoHandshaker::crypto_message_parser();
423 }
424 
GetHandshakeState() const425 HandshakeState QuicCryptoServerStream::GetHandshakeState() const {
426   return one_rtt_packet_decrypted_ ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
427 }
428 
SetServerApplicationStateForResumption(std::unique_ptr<ApplicationState>)429 void QuicCryptoServerStream::SetServerApplicationStateForResumption(
430     std::unique_ptr<ApplicationState> /*state*/) {
431   // QUIC Crypto doesn't need to remember any application state as part of doing
432   // 0-RTT resumption, so this function is a no-op.
433 }
434 
BufferSizeLimitForLevel(EncryptionLevel level) const435 size_t QuicCryptoServerStream::BufferSizeLimitForLevel(
436     EncryptionLevel level) const {
437   return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
438 }
439 
440 std::unique_ptr<QuicDecrypter>
AdvanceKeysAndCreateCurrentOneRttDecrypter()441 QuicCryptoServerStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
442   // Key update is only defined in QUIC+TLS.
443   QUICHE_DCHECK(false);
444   return nullptr;
445 }
446 
447 std::unique_ptr<QuicEncrypter>
CreateCurrentOneRttEncrypter()448 QuicCryptoServerStream::CreateCurrentOneRttEncrypter() {
449   // Key update is only defined in QUIC+TLS.
450   QUICHE_DCHECK(false);
451   return nullptr;
452 }
453 
ProcessClientHello(quiche::QuicheReferenceCountedPointer<ValidateClientHelloResultCallback::Result> result,std::unique_ptr<ProofSource::Details> proof_source_details,std::shared_ptr<ProcessClientHelloResultCallback> done_cb)454 void QuicCryptoServerStream::ProcessClientHello(
455     quiche::QuicheReferenceCountedPointer<
456         ValidateClientHelloResultCallback::Result>
457         result,
458     std::unique_ptr<ProofSource::Details> proof_source_details,
459     std::shared_ptr<ProcessClientHelloResultCallback> done_cb) {
460   proof_source_details_ = std::move(proof_source_details);
461   const CryptoHandshakeMessage& message = result->client_hello;
462   std::string error_details;
463   if (!helper_->CanAcceptClientHello(
464           message, GetClientAddress(), session()->connection()->peer_address(),
465           session()->connection()->self_address(), &error_details)) {
466     done_cb->Run(QUIC_HANDSHAKE_FAILED, error_details, nullptr, nullptr,
467                  nullptr);
468     return;
469   }
470 
471   absl::string_view user_agent_id;
472   message.GetStringPiece(quic::kUAID, &user_agent_id);
473   if (!session()->user_agent_id().has_value() && !user_agent_id.empty()) {
474     session()->SetUserAgentId(std::string(user_agent_id));
475   }
476 
477   if (!result->info.server_nonce.empty()) {
478     ++num_handshake_messages_with_server_nonces_;
479   }
480 
481   if (num_handshake_messages_ == 1) {
482     // Client attempts zero RTT handshake by sending a non-inchoate CHLO.
483     absl::string_view public_value;
484     zero_rtt_attempted_ = message.GetStringPiece(kPUBS, &public_value);
485   }
486 
487   // Store the bandwidth estimate from the client.
488   if (result->cached_network_params.bandwidth_estimate_bytes_per_second() > 0) {
489     previous_cached_network_params_.reset(
490         new CachedNetworkParameters(result->cached_network_params));
491   }
492   previous_source_address_tokens_ = result->info.source_address_tokens;
493 
494   QuicConnection* connection = session()->connection();
495   crypto_config_->ProcessClientHello(
496       result, /*reject_only=*/false, connection->connection_id(),
497       connection->self_address(), GetClientAddress(), connection->version(),
498       session()->supported_versions(), connection->clock(),
499       connection->random_generator(), compressed_certs_cache_,
500       crypto_negotiated_params_, signed_config_,
501       QuicCryptoStream::CryptoMessageFramingOverhead(
502           transport_version(), connection->connection_id()),
503       chlo_packet_size_, std::move(done_cb));
504 }
505 
OverrideQuicConfigDefaults(QuicConfig *)506 void QuicCryptoServerStream::OverrideQuicConfigDefaults(
507     QuicConfig* /*config*/) {}
508 
ValidateCallback(QuicCryptoServerStream * parent)509 QuicCryptoServerStream::ValidateCallback::ValidateCallback(
510     QuicCryptoServerStream* parent)
511     : parent_(parent) {}
512 
Cancel()513 void QuicCryptoServerStream::ValidateCallback::Cancel() { parent_ = nullptr; }
514 
Run(quiche::QuicheReferenceCountedPointer<Result> result,std::unique_ptr<ProofSource::Details> details)515 void QuicCryptoServerStream::ValidateCallback::Run(
516     quiche::QuicheReferenceCountedPointer<Result> result,
517     std::unique_ptr<ProofSource::Details> details) {
518   if (parent_ != nullptr) {
519     parent_->FinishProcessingHandshakeMessage(std::move(result),
520                                               std::move(details));
521   }
522 }
523 
GetClientAddress()524 const QuicSocketAddress QuicCryptoServerStream::GetClientAddress() {
525   return session()->connection()->peer_address();
526 }
527 
GetSsl() const528 SSL* QuicCryptoServerStream::GetSsl() const { return nullptr; }
529 
IsCryptoFrameExpectedForEncryptionLevel(EncryptionLevel) const530 bool QuicCryptoServerStream::IsCryptoFrameExpectedForEncryptionLevel(
531     EncryptionLevel /*level*/) const {
532   return true;
533 }
534 
535 EncryptionLevel
GetEncryptionLevelToSendCryptoDataOfSpace(PacketNumberSpace space) const536 QuicCryptoServerStream::GetEncryptionLevelToSendCryptoDataOfSpace(
537     PacketNumberSpace space) const {
538   if (space == INITIAL_DATA) {
539     return ENCRYPTION_INITIAL;
540   }
541   if (space == APPLICATION_DATA) {
542     return ENCRYPTION_ZERO_RTT;
543   }
544   QUICHE_DCHECK(false);
545   return NUM_ENCRYPTION_LEVELS;
546 }
547 
548 }  // namespace quic
549