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