Internal change PiperOrigin-RevId: 429370483
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h index 3deafcc..0702707 100644 --- a/quic/core/crypto/crypto_protocol.h +++ b/quic/core/crypto/crypto_protocol.h
@@ -429,6 +429,7 @@ const QuicTag kSRWP = TAG('S', 'R', 'W', 'P'); // Enable retransmittable on // wire PING (ROWP) on the // server side. +const QuicTag kGSR0 = TAG('G', 'S', 'R', '0'); // Selective Resumption // Client Hints triggers. const QuicTag kGWCH = TAG('G', 'W', 'C', 'H');
diff --git a/quic/core/crypto/tls_connection.cc b/quic/core/crypto/tls_connection.cc index 901ae66..e534f7d 100644 --- a/quic/core/crypto/tls_connection.cc +++ b/quic/core/crypto/tls_connection.cc
@@ -120,6 +120,11 @@ }); } +void TlsConnection::DisableTicketSupport() { + ssl_config_.disable_ticket_support = true; + SSL_set_options(ssl(), SSL_OP_NO_TICKET); +} + // static bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx() { CRYPTO_library_init();
diff --git a/quic/core/crypto/tls_connection.h b/quic/core/crypto/tls_connection.h index a7a869a..5e80185 100644 --- a/quic/core/crypto/tls_connection.h +++ b/quic/core/crypto/tls_connection.h
@@ -90,6 +90,11 @@ // Configure the SSL such that delegate_->InfoCallback will be called. void EnableInfoCallback(); + // Configure the SSL to disable session ticket support. Note that, this + // function simply sets the |SSL_OP_NO_TICKET| option on the SSL object, it + // does not check whether it is too late to do so. + void DisableTicketSupport(); + // Functions to convert between BoringSSL's enum ssl_encryption_level_t and // QUIC's EncryptionLevel. static EncryptionLevel QuicEncryptionLevel(enum ssl_encryption_level_t level);
diff --git a/quic/core/http/quic_server_session_base.h b/quic/core/http/quic_server_session_base.h index 5903de6..e6afc19 100644 --- a/quic/core/http/quic_server_session_base.h +++ b/quic/core/http/quic_server_session_base.h
@@ -68,6 +68,8 @@ serving_region_ = serving_region; } + const std::string& serving_region() const { return serving_region_; } + QuicSSLConfig GetSSLConfig() const override; protected:
diff --git a/quic/core/quic_crypto_server_stream.cc b/quic/core/quic_crypto_server_stream.cc index 55b7bf1..1f8b026 100644 --- a/quic/core/quic_crypto_server_stream.cc +++ b/quic/core/quic_crypto_server_stream.cc
@@ -309,6 +309,11 @@ ++num_server_config_update_messages_sent_; } +bool QuicCryptoServerStream::DisableResumption() { + QUICHE_DCHECK(false) << "Not supported for QUIC crypto."; + return false; +} + bool QuicCryptoServerStream::IsZeroRtt() const { return num_handshake_messages_ == 1 && num_handshake_messages_with_server_nonces_ == 0; @@ -332,6 +337,11 @@ return zero_rtt_attempted_; } +bool QuicCryptoServerStream::EarlyDataAttempted() const { + QUICHE_DCHECK(false) << "Not supported for QUIC crypto."; + return zero_rtt_attempted_; +} + void QuicCryptoServerStream::SetPreviousCachedNetworkParams( CachedNetworkParameters cached_network_params) { previous_cached_network_params_.reset(
diff --git a/quic/core/quic_crypto_server_stream.h b/quic/core/quic_crypto_server_stream.h index aca9e9a..05f68e6 100644 --- a/quic/core/quic_crypto_server_stream.h +++ b/quic/core/quic_crypto_server_stream.h
@@ -34,9 +34,11 @@ bool GetBase64SHA256ClientChannelID(std::string* output) const override; void SendServerConfigUpdate( const CachedNetworkParameters* cached_network_params) override; + bool DisableResumption() override; bool IsZeroRtt() const override; bool IsResumption() const override; bool ResumptionAttempted() const override; + bool EarlyDataAttempted() const override; int NumServerConfigUpdateMessagesSent() const override; const CachedNetworkParameters* PreviousCachedNetworkParams() const override; void SetPreviousCachedNetworkParams(
diff --git a/quic/core/quic_crypto_server_stream_base.h b/quic/core/quic_crypto_server_stream_base.h index 0a2a63e..dcefdfb 100644 --- a/quic/core/quic_crypto_server_stream_base.h +++ b/quic/core/quic_crypto_server_stream_base.h
@@ -62,6 +62,11 @@ virtual void SendServerConfigUpdate( const CachedNetworkParameters* cached_network_params) = 0; + // Disables TLS resumption, should be called as early as possible. + // Return true if resumption is disabled. + // Return false if nothing happened, typically it means it is called too late. + virtual bool DisableResumption() = 0; + // Returns true if the connection was a successful 0-RTT resumption. virtual bool IsZeroRtt() const = 0; @@ -73,6 +78,10 @@ // the resumption actually occurred. virtual bool ResumptionAttempted() const = 0; + // Returns true if the client attempted to use early data, as indicated by the + // "early_data" TLS extension. TLS only. + virtual bool EarlyDataAttempted() const = 0; + // NOTE: Indicating that the Expect-CT header should be sent here presents // a layering violation to some extent. The Expect-CT header only applies to // HTTP connections, while this class can be used for non-HTTP applications.
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc index a16e729..dc4b39a 100644 --- a/quic/core/tls_server_handshaker.cc +++ b/quic/core/tls_server_handshaker.cc
@@ -278,6 +278,14 @@ // SCUP messages aren't supported when using the TLS handshake. } +bool TlsServerHandshaker::DisableResumption() { + if (!can_disable_resumption_ || !session()->connection()->connected()) { + return false; + } + tls_connection_.DisableTicketSupport(); + return true; +} + bool TlsServerHandshaker::IsZeroRtt() const { return SSL_early_data_accepted(ssl()); } @@ -290,6 +298,14 @@ return ticket_received_; } +bool TlsServerHandshaker::EarlyDataAttempted() const { + QUIC_BUG_IF(quic_tls_early_data_attempted_too_early, + !select_cert_status_.has_value()) + << "EarlyDataAttempted must be called after EarlySelectCertCallback is " + "started"; + return early_data_attempted_; +} + int TlsServerHandshaker::NumServerConfigUpdateMessagesSent() const { // SCUP messages aren't supported when using the TLS handshake. return 0; @@ -881,6 +897,10 @@ ticket_received_ = SSL_early_callback_ctx_extension_get( client_hello, TLSEXT_TYPE_pre_shared_key, &unused_extension_bytes, &unused_extension_len); + + early_data_attempted_ = SSL_early_callback_ctx_extension_get( + client_hello, TLSEXT_TYPE_early_data, &unused_extension_bytes, + &unused_extension_len); } // This callback is called very early by Boring SSL, most of the SSL_get_foo @@ -950,6 +970,7 @@ return ssl_select_cert_error; } + can_disable_resumption_ = false; const QuicAsyncStatus status = proof_source_handle_->SelectCertificate( session()->connection()->self_address().Normalized(), session()->connection()->peer_address().Normalized(),
diff --git a/quic/core/tls_server_handshaker.h b/quic/core/tls_server_handshaker.h index d2f37b0..c2ea44b 100644 --- a/quic/core/tls_server_handshaker.h +++ b/quic/core/tls_server_handshaker.h
@@ -45,9 +45,12 @@ bool GetBase64SHA256ClientChannelID(std::string* output) const override; void SendServerConfigUpdate( const CachedNetworkParameters* cached_network_params) override; + bool DisableResumption() override; bool IsZeroRtt() const override; bool IsResumption() const override; bool ResumptionAttempted() const override; + // Must be called after EarlySelectCertCallback is started. + bool EarlyDataAttempted() const override; int NumServerConfigUpdateMessagesSent() const override; const CachedNetworkParameters* PreviousCachedNetworkParams() const override; void SetPreviousCachedNetworkParams( @@ -344,6 +347,9 @@ // indicates that the client attempted a resumption. bool ticket_received_ = false; + // True if the "early_data" extension is in the client hello. + bool early_data_attempted_ = false; + // Force SessionTicketOpen to return ssl_ticket_aead_ignore_ticket if called. bool ignore_ticket_open_ = false; @@ -367,6 +373,7 @@ HandshakeState state_ = HANDSHAKE_START; bool encryption_established_ = false; bool valid_alpn_received_ = false; + bool can_disable_resumption_ = true; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> crypto_negotiated_params_; TlsServerConnection tls_connection_;