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