Add ability to specify preferred groups for TLS handshake.
PiperOrigin-RevId: 538556697
diff --git a/quiche/quic/core/crypto/quic_crypto_client_config.h b/quiche/quic/core/crypto/quic_crypto_client_config.h
index 546f4d1..693d0d4 100644
--- a/quiche/quic/core/crypto/quic_crypto_client_config.h
+++ b/quiche/quic/core/crypto/quic_crypto_client_config.h
@@ -354,6 +354,18 @@
// suffix will be used to initialize the cached state for this server.
void AddCanonicalSuffix(const std::string& suffix);
+ // The groups to use for key exchange in the TLS handshake.
+ const std::vector<uint16_t>& preferred_groups() const {
+ return preferred_groups_;
+ }
+
+ // Sets the preferred groups that will be used in the TLS handshake. Values
+ // in the |preferred_groups| vector are NamedGroup enum codepoints from
+ // https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.7.
+ void set_preferred_groups(const std::vector<uint16_t>& preferred_groups) {
+ preferred_groups_ = preferred_groups;
+ }
+
// Saves the |user_agent_id| that will be passed in QUIC's CHLO message.
void set_user_agent_id(const std::string& user_agent_id) {
user_agent_id_ = user_agent_id;
@@ -433,6 +445,9 @@
bssl::UniquePtr<SSL_CTX> ssl_ctx_;
+ // The groups to use for key exchange in the TLS handshake.
+ std::vector<uint16_t> preferred_groups_;
+
// The |user_agent_id_| passed in QUIC's CHLO message.
std::string user_agent_id_;
diff --git a/quiche/quic/core/crypto/quic_crypto_server_config.h b/quiche/quic/core/crypto/quic_crypto_server_config.h
index 77be1f4..5805c88 100644
--- a/quiche/quic/core/crypto/quic_crypto_server_config.h
+++ b/quiche/quic/core/crypto/quic_crypto_server_config.h
@@ -439,6 +439,18 @@
SSL_CTX* ssl_ctx() const;
+ // The groups to use for key exchange in the TLS handshake;
+ const std::vector<uint16_t>& preferred_groups() const {
+ return preferred_groups_;
+ }
+
+ // Sets the preferred groups that will be used in the TLS handshake. Values
+ // in the |preferred_groups| vector are NamedGroup enum codepoints from
+ // https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.7.
+ void set_preferred_groups(const std::vector<uint16_t>& preferred_groups) {
+ preferred_groups_ = preferred_groups;
+ }
+
// Pre-shared key used during the handshake.
const std::string& pre_shared_key() const { return pre_shared_key_; }
void set_pre_shared_key(absl::string_view psk) {
@@ -895,6 +907,9 @@
// ssl_ctx_ contains the server configuration for doing TLS handshakes.
bssl::UniquePtr<SSL_CTX> ssl_ctx_;
+ // The groups to use for key exchange in the TLS handshake;
+ std::vector<uint16_t> preferred_groups_;
+
// These fields store configuration values. See the comments for their
// respective setter functions.
uint32_t source_address_token_future_secs_;
diff --git a/quiche/quic/core/tls_client_handshaker.cc b/quiche/quic/core/tls_client_handshaker.cc
index 74537f7..8ae63cc 100644
--- a/quiche/quic/core/tls_client_handshaker.cc
+++ b/quiche/quic/core/tls_client_handshaker.cc
@@ -52,6 +52,12 @@
cert_and_key->private_key.private_key());
}
}
+#if BORINGSSL_API_VERSION >= 22
+ if (!crypto_config->preferred_groups().empty()) {
+ SSL_set1_group_ids(ssl(), crypto_config->preferred_groups().data(),
+ crypto_config->preferred_groups().size());
+ }
+#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 0459de3..b11dd0c 100644
--- a/quiche/quic/core/tls_client_handshaker_test.cc
+++ b/quiche/quic/core/tls_client_handshaker_test.cc
@@ -858,6 +858,22 @@
EXPECT_FALSE(stream()->crypto_negotiated_params().encrypted_client_hello);
}
+#if BORINGSSL_API_VERSION >= 22
+TEST_P(TlsClientHandshakerTest, EnableKyber) {
+ crypto_config_->set_preferred_groups({SSL_GROUP_X25519_KYBER768_DRAFT00});
+ server_crypto_config_->set_preferred_groups(
+ {SSL_GROUP_X25519_KYBER768_DRAFT00, SSL_GROUP_X25519, SSL_GROUP_SECP256R1,
+ SSL_GROUP_SECP384R1});
+ CreateConnection();
+
+ CompleteCryptoHandshake();
+ EXPECT_TRUE(stream()->encryption_established());
+ EXPECT_TRUE(stream()->one_rtt_keys_available());
+ EXPECT_EQ(SSL_GROUP_X25519_KYBER768_DRAFT00,
+ SSL_get_group_id(stream()->GetSsl()));
+}
+#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 f4bbd3d..8407bc6 100644
--- a/quiche/quic/core/tls_server_handshaker.cc
+++ b/quiche/quic/core/tls_server_handshaker.cc
@@ -205,6 +205,12 @@
if (session->connection()->context()->tracer) {
tls_connection_.EnableInfoCallback();
}
+#if BORINGSSL_API_VERSION >= 22
+ if (!crypto_config->preferred_groups().empty()) {
+ SSL_set1_group_ids(ssl(), crypto_config->preferred_groups().data(),
+ crypto_config->preferred_groups().size());
+ }
+#endif // BORINGSSL_API_VERSION
}
TlsServerHandshaker::~TlsServerHandshaker() { CancelOutstandingCallbacks(); }
diff --git a/quiche/quic/core/tls_server_handshaker_test.cc b/quiche/quic/core/tls_server_handshaker_test.cc
index e68ea65..39a34a5 100644
--- a/quiche/quic/core/tls_server_handshaker_test.cc
+++ b/quiche/quic/core/tls_server_handshaker_test.cc
@@ -1163,6 +1163,24 @@
.empty());
}
+#if BORINGSSL_API_VERSION >= 22
+TEST_P(TlsServerHandshakerTest, EnableKyber) {
+ server_crypto_config_->set_preferred_groups(
+ {SSL_GROUP_X25519_KYBER768_DRAFT00});
+ client_crypto_config_->set_preferred_groups(
+ {SSL_GROUP_X25519_KYBER768_DRAFT00, SSL_GROUP_X25519, SSL_GROUP_SECP256R1,
+ SSL_GROUP_SECP384R1});
+
+ InitializeServer();
+ InitializeFakeClient();
+ CompleteCryptoHandshake();
+ ExpectHandshakeSuccessful();
+ EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol());
+ EXPECT_EQ(SSL_GROUP_X25519_KYBER768_DRAFT00,
+ SSL_get_group_id(server_stream()->GetSsl()));
+}
+#endif // BORINGSSL_API_VERSION
+
} // namespace
} // namespace test
} // namespace quic