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