OHTTP: allow unsupported symmetric HPKE algorithms in key config This is required by RFC 9458. PiperOrigin-RevId: 944608033
diff --git a/quiche/oblivious_http/common/oblivious_http_header_key_config.cc b/quiche/oblivious_http/common/oblivious_http_header_key_config.cc index 3fd170f..f046ea1 100644 --- a/quiche/oblivious_http/common/oblivious_http_header_key_config.cc +++ b/quiche/oblivious_http/common/oblivious_http_header_key_config.cc
@@ -388,6 +388,7 @@ return absl::InvalidArgumentError("Failed to read symmetric algorithms"); } QuicheDataReader sub_reader(alg_bytes); + bool found_supported_symmetric_algs = false; while (!sub_reader.IsDoneReading()) { uint16_t kdf_id; if (!sub_reader.ReadUInt16(&kdf_id)) { @@ -398,12 +399,20 @@ return absl::InvalidArgumentError("Failed to read aead_id"); } - // TODO(kmg): Add support to ignore key types in the server response that - // aren't supported by the client. + if (!CheckKdfId(kdf_id).ok() || !CheckAeadId(aead_id).ok()) { + // Skip unsupported symmetric algorithms pairs. + continue; + } + QUICHE_ASSIGN_OR_RETURN( ObliviousHttpHeaderKeyConfig cfg, ObliviousHttpHeaderKeyConfig::Create(key_id, kem_id, kdf_id, aead_id)); configs[key_id].emplace_back(std::move(cfg)); + found_supported_symmetric_algs = true; + } + if (!found_supported_symmetric_algs) { + return absl::InvalidArgumentError(absl::StrCat( + "No supported symmetric algorithms found for key_id ", key_id)); } // Intentionally allow extra data at the end of the key config. This will // allow us to use it for extensions. See
diff --git a/quiche/oblivious_http/common/oblivious_http_header_key_config_test.cc b/quiche/oblivious_http/common/oblivious_http_header_key_config_test.cc index 6e831fc..1f2cc64 100644 --- a/quiche/oblivious_http/common/oblivious_http_header_key_config_test.cc +++ b/quiche/oblivious_http/common/oblivious_http_header_key_config_test.cc
@@ -210,6 +210,47 @@ IsOkAndHolds(expected_public_key)); } +TEST(ObliviousHttpKeyConfigs, SomeUnsupportedSymmetricAlgorithms) { + std::string key; + ASSERT_TRUE( + absl::HexStringToBytes("4b" // key_id + "0020" // kem_id + "606162636465666768696a6b6c6d6e6f" // public_key + "707172737475767778797a7b7c7d7e7f" // public_key + "0008" // len(symmetric_algorithms) + "0001BEEF" // HKDF_SHA256, Unsupported + "00010002", // HKDF_SHA256, AES_256_GCM + &key)); + auto configs = ObliviousHttpKeyConfigs::ParseConcatenatedKeys(key); + QUICHE_ASSERT_OK(configs); + EXPECT_THAT(*configs, Property(&ObliviousHttpKeyConfigs::NumKeys, 1)); + EXPECT_THAT( + configs->PreferredConfig(), + AllOf(HasKeyId(0x4b), HasKemId(EVP_HPKE_DHKEM_X25519_HKDF_SHA256), + HasKdfId(EVP_HPKE_HKDF_SHA256), HasAeadId(EVP_HPKE_AES_256_GCM))); + std::string expected_public_key; + ASSERT_TRUE(absl::HexStringToBytes( + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f", + &expected_public_key)); + EXPECT_THAT(configs->GetPublicKeyForId(configs->PreferredConfig().GetKeyId()), + IsOkAndHolds(expected_public_key)); +} + +TEST(ObliviousHttpKeyConfigs, NoSupportedSymmetricAlgorithms) { + std::string key; + ASSERT_TRUE(absl::HexStringToBytes( + // First key config. + "4b" // key_id + "0020" // kem_id + "606162636465666768696a6b6c6d6e6f" // public_key + "707172737475767778797a7b7c7d7e7f" // public_key + "0008" // len(symmetric_algorithms) + "0001DEAD" // HKDF_SHA256, Unsupported + "0001BEEF", // HKDF_SHA256, Unsupported + &key)); + EXPECT_FALSE(ObliviousHttpKeyConfigs::ParseConcatenatedKeys(key).ok()); +} + TEST(ObliviousHttpKeyConfigs, TwoSimilarKeyConfigs) { std::string key; ASSERT_TRUE(absl::HexStringToBytes(