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(