Return INVALID_ARGUMENT instead of INTERNAL if a request can't be decrypted

This can cause a 500 if the client encrypts a request using the incorrect public
key or otherwise sends well-formed gibberish.

PiperOrigin-RevId: 502954059
diff --git a/quiche/common/quiche_crypto_logging.cc b/quiche/common/quiche_crypto_logging.cc
index 7f3eb2a..17d5407 100644
--- a/quiche/common/quiche_crypto_logging.cc
+++ b/quiche/common/quiche_crypto_logging.cc
@@ -28,7 +28,7 @@
   }
 }
 
-absl::Status SslErrorAsStatus(absl::string_view msg) {
+absl::Status SslErrorAsStatus(absl::string_view msg, absl::StatusCode code) {
   std::string message;
   absl::StrAppend(&message, msg, "OpenSSL error: ");
   while (uint32_t error = ERR_get_error()) {
@@ -36,7 +36,7 @@
     ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf));
     absl::StrAppend(&message, buf);
   }
-  return absl::InternalError(message);
+  return absl::Status(code, message);
 }
 
 }  // namespace quiche
diff --git a/quiche/common/quiche_crypto_logging.h b/quiche/common/quiche_crypto_logging.h
index 709694d..8806672 100644
--- a/quiche/common/quiche_crypto_logging.h
+++ b/quiche/common/quiche_crypto_logging.h
@@ -18,7 +18,8 @@
 
 // Include OpenSSL error stack in Status msg so that callers could choose to
 // only log it in debug builds if required.
-absl::Status SslErrorAsStatus(absl::string_view msg);
+absl::Status SslErrorAsStatus(
+    absl::string_view msg, absl::StatusCode code = absl::StatusCode::kInternal);
 
 }  // namespace quiche
 
diff --git a/quiche/oblivious_http/buffers/oblivious_http_request.cc b/quiche/oblivious_http/buffers/oblivious_http_request.cc
index 5a43eb2..7c0b2ea 100644
--- a/quiche/oblivious_http/buffers/oblivious_http_request.cc
+++ b/quiche/oblivious_http/buffers/oblivious_http_request.cc
@@ -84,7 +84,8 @@
           &decrypted_len, decrypted.size(),
           reinterpret_cast<const uint8_t*>(ciphertext_received.data()),
           ciphertext_received.size(), nullptr, 0)) {
-    return SslErrorAsStatus("Failed to decrypt.");
+    return SslErrorAsStatus("Failed to decrypt.",
+                            absl::StatusCode::kInvalidArgument);
   }
   decrypted.resize(decrypted_len);
   return ObliviousHttpRequest(
diff --git a/quiche/oblivious_http/buffers/oblivious_http_request_test.cc b/quiche/oblivious_http/buffers/oblivious_http_request_test.cc
index 546de96..b788e5c 100644
--- a/quiche/oblivious_http/buffers/oblivious_http_request_test.cc
+++ b/quiche/oblivious_http/buffers/oblivious_http_request_test.cc
@@ -34,6 +34,12 @@
   return absl::HexStringToBytes(public_key);
 }
 
+std::string GetAlternativeHpkePublicKey() {
+  absl::string_view public_key =
+      "6d21cfe09fbea5122f9ebc2eb2a69fcc4f06408cd54aac934f012e76fcdcef63";
+  return absl::HexStringToBytes(public_key);
+}
+
 std::string GetSeed() {
   absl::string_view seed =
       "52c4a758a802cd8b936eceea314432798d5baf2d7e9235dc084ab1b9cfa2f736";
@@ -264,4 +270,18 @@
   EXPECT_EQ(decrypted, "test");
 }
 
+TEST(ObliviousHttpRequest, EndToEndTestForRequestWithWrongKey) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(5, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  auto encapsulate = ObliviousHttpRequest::CreateClientObliviousRequest(
+      "test", GetAlternativeHpkePublicKey(), ohttp_key_config);
+  ASSERT_TRUE(encapsulate.ok());
+  auto oblivious_request = encapsulate->EncapsulateAndSerialize();
+  auto decapsulate = ObliviousHttpRequest::CreateServerObliviousRequest(
+      oblivious_request,
+      *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config)),
+      ohttp_key_config);
+  EXPECT_EQ(decapsulate.status().code(), absl::StatusCode::kInvalidArgument);
+}
 }  // namespace quiche