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