No public description PiperOrigin-RevId: 587835279
diff --git a/quiche/quic/core/crypto/quic_crypto_client_config.h b/quiche/quic/core/crypto/quic_crypto_client_config.h index 35433f3..e0cc26c 100644 --- a/quiche/quic/core/crypto/quic_crypto_client_config.h +++ b/quiche/quic/core/crypto/quic_crypto_client_config.h
@@ -403,6 +403,13 @@ bool pad_full_hello() const { return pad_full_hello_; } void set_pad_full_hello(bool new_value) { pad_full_hello_ = new_value; } +#if BORINGSSL_API_VERSION >= 27 + bool alps_use_new_codepoint() const { return alps_use_new_codepoint_; } + void set_alps_use_new_codepoint(bool new_value) { + alps_use_new_codepoint_ = new_value; + } +#endif // BORINGSSL_API_VERSION + private: // Sets the members to reasonable, default values. void SetDefaults(); @@ -474,6 +481,11 @@ // other means of verifying the client. bool pad_inchoate_hello_ = true; bool pad_full_hello_ = true; + +#if BORINGSSL_API_VERSION >= 27 + // Set whether ALPS uses the new codepoint or not. + bool alps_use_new_codepoint_ = false; +#endif // BORINGSSL_API_VERSION }; } // namespace quic
diff --git a/quiche/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h index b5537c3..dc53509 100644 --- a/quiche/quic/core/quic_flags_list.h +++ b/quiche/quic/core/quic_flags_list.h
@@ -45,6 +45,8 @@ QUIC_FLAG(quic_reloadable_flag_quic_can_send_ack_frequency, true) // If true, allow client to enable BBRv2 on server via connection option \'B2ON\'. QUIC_FLAG(quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, true) +// If true, allow quic to use new ALPS codepoint to negotiate during handshake for H3 if client sends new ALPS codepoint. +QUIC_FLAG(quic_reloadable_flag_quic_gfe_allow_alps_new_codepoint, false) // If true, always bundle qpack decoder data with other frames opportunistically. QUIC_FLAG(quic_restart_flag_quic_opport_bundle_qpack_decoder_data2, false) // If true, an endpoint does not detect path degrading or blackholing until handshake gets confirmed.
diff --git a/quiche/quic/core/tls_client_handshaker.cc b/quiche/quic/core/tls_client_handshaker.cc index 244fbbb..30831e7 100644 --- a/quiche/quic/core/tls_client_handshaker.cc +++ b/quiche/quic/core/tls_client_handshaker.cc
@@ -58,6 +58,12 @@ crypto_config->preferred_groups().size()); } #endif // BORINGSSL_API_VERSION + +#if BORINGSSL_API_VERSION >= 27 + // Make sure we use the right ALPS codepoint. + SSL_set_alps_use_new_codepoint(ssl(), + crypto_config->alps_use_new_codepoint()); +#endif // BORINGSSL_API_VERSION } TlsClientHandshaker::~TlsClientHandshaker() {}
diff --git a/quiche/quic/core/tls_client_handshaker_test.cc b/quiche/quic/core/tls_client_handshaker_test.cc index 8b2ea68..35c0328 100644 --- a/quiche/quic/core/tls_client_handshaker_test.cc +++ b/quiche/quic/core/tls_client_handshaker_test.cc
@@ -878,6 +878,41 @@ } #endif // BORINGSSL_API_VERSION +#if BORINGSSL_API_VERSION >= 27 +TEST_P(TlsClientHandshakerTest, EnableClientAlpsUseNewCodepoint) { + // The intent of this test is to demonstrate no matter whether server + // allows the new ALPS codepoint or not, the handshake should complete + // successfully. + for (bool server_allow_alps_new_codepoint : {true, false}) { + SCOPED_TRACE(absl::StrCat("Test allows alps new codepoint:", + server_allow_alps_new_codepoint)); + crypto_config_->set_alps_use_new_codepoint(true); + absl::SetFlag(&FLAGS_gfe2_reloadable_flag_quic_gfe_allow_alps_new_codepoint, + server_allow_alps_new_codepoint); + CreateConnection(); + + // Add a DoS callback on the server, to test that the client sent the new + // ALPS codepoint. + static bool callback_ran; + callback_ran = false; + SSL_CTX_set_dos_protection_cb( + server_crypto_config_->ssl_ctx(), + [](const SSL_CLIENT_HELLO* client_hello) -> int { + const uint8_t* data; + size_t len; + EXPECT_TRUE(SSL_early_callback_ctx_extension_get( + client_hello, TLSEXT_TYPE_application_settings, &data, &len)); + callback_ran = true; + return 1; + }); + + CompleteCryptoHandshake(); + EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol()); + EXPECT_TRUE(callback_ran); + } +} +#endif // BORINGSSL_API_VERSION + } // namespace } // namespace test } // namespace quic
diff --git a/quiche/quic/core/tls_server_handshaker.cc b/quiche/quic/core/tls_server_handshaker.cc index 8173a5a..d141f1a 100644 --- a/quiche/quic/core/tls_server_handshaker.cc +++ b/quiche/quic/core/tls_server_handshaker.cc
@@ -603,6 +603,17 @@ return {}; } +bool TlsServerHandshaker::UseAlpsNewCodepoint() const { + if (!select_cert_status_.has_value()) { + QUIC_BUG(quic_tls_check_alps_new_codepoint_too_early) + << "UseAlpsNewCodepoint must be called after " + "EarlySelectCertCallback is started"; + return false; + } + + return alps_new_codepoint_received_; +} + void TlsServerHandshaker::FinishHandshake() { QUICHE_DCHECK(!SSL_in_early_data(ssl())); @@ -883,6 +894,24 @@ early_data_attempted_ = SSL_early_callback_ctx_extension_get( client_hello, TLSEXT_TYPE_early_data, &unused_extension_bytes, &unused_extension_len); + +#if BORINGSSL_API_VERSION >= 27 + if (GetQuicReloadableFlag(quic_gfe_allow_alps_new_codepoint)) { + QUIC_RELOADABLE_FLAG_COUNT(quic_gfe_allow_alps_new_codepoint); + + alps_new_codepoint_received_ = SSL_early_callback_ctx_extension_get( + client_hello, TLSEXT_TYPE_application_settings, + &unused_extension_bytes, &unused_extension_len); + // Make sure we use the right ALPS codepoint. + int use_alps_new_codepoint = 0; + if (alps_new_codepoint_received_) { + QUIC_CODE_COUNT(quic_gfe_alps_use_new_codepoint); + use_alps_new_codepoint = 1; + } + QUIC_DLOG(INFO) << "ALPS use new codepoint: " << use_alps_new_codepoint; + SSL_set_alps_use_new_codepoint(ssl(), use_alps_new_codepoint); + } +#endif // BORINGSSL_API_VERSION } // This callback is called very early by Boring SSL, most of the SSL_get_foo
diff --git a/quiche/quic/core/tls_server_handshaker.h b/quiche/quic/core/tls_server_handshaker.h index 682c9f8..5f571ed 100644 --- a/quiche/quic/core/tls_server_handshaker.h +++ b/quiche/quic/core/tls_server_handshaker.h
@@ -98,6 +98,10 @@ virtual std::string GetAcceptChValueForHostname( const std::string& hostname) const; + // Returns whether server uses new ALPS codepoint to negotiate application + // settings. If client sends new ALPS codepoint in ClientHello, return true. + bool UseAlpsNewCodepoint() const; + // Get the ClientCertMode that is currently in effect on this handshaker. ClientCertMode client_cert_mode() const { return tls_connection_.ssl_config().client_cert_mode; @@ -345,6 +349,9 @@ // Force SessionTicketOpen to return ssl_ticket_aead_ignore_ticket if called. bool ignore_ticket_open_ = false; + // True if new ALPS codepoint in the ClientHello. + bool alps_new_codepoint_received_ = false; + // nullopt means select cert hasn't started. std::optional<QuicAsyncStatus> select_cert_status_;
diff --git a/quiche/quic/core/tls_server_handshaker_test.cc b/quiche/quic/core/tls_server_handshaker_test.cc index 39a34a5..9e4eb9d 100644 --- a/quiche/quic/core/tls_server_handshaker_test.cc +++ b/quiche/quic/core/tls_server_handshaker_test.cc
@@ -1181,6 +1181,48 @@ } #endif // BORINGSSL_API_VERSION +#if BORINGSSL_API_VERSION >= 27 +TEST_P(TlsServerHandshakerTest, AlpsUseNewCodepoint) { + const struct { + bool client_use_alps_new_codepoint; + bool server_allow_alps_new_codepoint; + } tests[] = { + // The intent of this test is to demonstrate different combinations of + // ALPS codepoint settings works well for both client and server. + {true, true}, + {false, true}, + {false, false}, + {true, true}, + }; + for (size_t i = 0; i < arraysize(tests); i++) { + SCOPED_TRACE(absl::StrCat("Test #", i)); + const auto& test = tests[i]; + client_crypto_config_->set_alps_use_new_codepoint( + test.client_use_alps_new_codepoint); + absl::SetFlag(&FLAGS_gfe2_reloadable_flag_quic_gfe_allow_alps_new_codepoint, + test.server_allow_alps_new_codepoint); + + ASSERT_TRUE(SetupClientCert()); + InitializeFakeClient(); + + InitializeServerWithFakeProofSourceHandle(); + server_handshaker_->SetupProofSourceHandle( + /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC, + /*compute_signature_action=*/FakeProofSourceHandle::Action:: + DELEGATE_SYNC); + + // Start handshake. + AdvanceHandshakeWithFakeClient(); + EXPECT_EQ(test.client_use_alps_new_codepoint, + server_handshaker_->UseAlpsNewCodepoint()); + + CompleteCryptoHandshake(); + ExpectHandshakeSuccessful(); + EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol()); + } +} +#endif // BORINGSSL_API_VERSION + } // namespace } // namespace test } // namespace quic