masque_tcp_server: create one gateway per request

This allows us to handle multiple requests concurrently, and will be required to supported multiple keys.

PiperOrigin-RevId: 947498026
diff --git a/quiche/quic/masque/masque_tcp_server_bin.cc b/quiche/quic/masque/masque_tcp_server_bin.cc
index bfc15db..e741222 100644
--- a/quiche/quic/masque/masque_tcp_server_bin.cc
+++ b/quiche/quic/masque/masque_tcp_server_bin.cc
@@ -151,7 +151,8 @@
     virtual void SavePendingGatewayRequest(
         MasqueH2Connection* connection, int32_t stream_id,
         MasqueConnectionPool::RequestId request_id,
-        ObliviousHttpRequest::Context&& ohttp_context) = 0;
+        ObliviousHttpRequest::Context&& ohttp_context,
+        ObliviousHttpGateway&& ohttp_gateway) = 0;
   };
 
   static absl::StatusOr<std::unique_ptr<MasqueOhttpGateway>> Create() {
@@ -162,16 +163,32 @@
     return ohttp_gateway;
   }
 
+  absl::StatusOr<std::string> GetPrivateKey(uint8_t key_id) {
+    auto it = hpke_private_keys_.find(key_id);
+    if (it == hpke_private_keys_.end()) {
+      return absl::NotFoundError("OHTTP key not found");
+    }
+    return it->second;
+  }
+
   absl::Status HandleRequest(MasqueConnectionPool* pool,
                              MasqueH2Connection* connection, int32_t stream_id,
                              const std::string& encapsulated_request) {
-    if (!ohttp_gateway_.has_value()) {
-      QUICHE_LOG(ERROR) << "Not ready to handle OHTTP request";
+    if (!ohttp_key_configs_) {
       return absl::InternalError("Not ready to handle OHTTP request");
     }
     QUICHE_ASSIGN_OR_RETURN(
+        ObliviousHttpHeaderKeyConfig ohttp_header_key_config,
+        ohttp_key_configs_->GetConfigForPayload(encapsulated_request));
+    QUICHE_ASSIGN_OR_RETURN(std::string private_key,
+                            GetPrivateKey(ohttp_header_key_config.GetKeyId()));
+    QUICHE_ASSIGN_OR_RETURN(
+        ObliviousHttpGateway ohttp_gateway,
+        ObliviousHttpGateway::Create(std::move(private_key),
+                                     ohttp_header_key_config));
+    QUICHE_ASSIGN_OR_RETURN(
         ObliviousHttpRequest decrypted_request,
-        ohttp_gateway_->DecryptObliviousHttpRequest(encapsulated_request));
+        ohttp_gateway.DecryptObliviousHttpRequest(encapsulated_request));
     QUICHE_ASSIGN_OR_RETURN(
         BinaryHttpRequest binary_request,
         BinaryHttpRequest::Create(decrypted_request.GetPlaintextData()));
@@ -189,16 +206,15 @@
     QUICHE_LOG(INFO) << "Sent decapsulated request";
     visitor_->SavePendingGatewayRequest(
         connection, stream_id, request_id,
-        std::move(decrypted_request).ReleaseContext());
+        std::move(decrypted_request).ReleaseContext(),
+        std::move(ohttp_gateway));
     return absl::OkStatus();
   }
 
   absl::StatusOr<MasqueConnectionPool::Message> HandleResponse(
       MasqueConnectionPool::Message&& response,
-      ObliviousHttpRequest::Context&& ohttp_context) {
-    if (!ohttp_gateway_.has_value()) {
-      return absl::InternalError("Not ready to handle OHTTP response");
-    }
+      ObliviousHttpRequest::Context&& ohttp_context,
+      ObliviousHttpGateway&& ohttp_gateway) {
     auto status_pair = response.headers.find(":status");
     if (status_pair == response.headers.end()) {
       return absl::InternalError("Response is missing status code");
@@ -218,7 +234,7 @@
     QUICHE_ASSIGN_OR_RETURN(std::string encoded_response,
                             binary_response.Serialize());
     QUICHE_ASSIGN_OR_RETURN(ObliviousHttpResponse ohttp_response,
-                            ohttp_gateway_->CreateObliviousHttpResponse(
+                            ohttp_gateway.CreateObliviousHttpResponse(
                                 std::move(encoded_response), ohttp_context));
     MasqueConnectionPool::Message outer_response;
     outer_response.headers[":status"] = "200";
@@ -291,18 +307,6 @@
                      << ohttp_key_configs_->DebugString();
     QUICHE_ASSIGN_OR_RETURN(concatenated_keys_,
                             ohttp_key_configs_->GenerateConcatenatedKeys());
-
-    QUICHE_ASSIGN_OR_RETURN(
-        ObliviousHttpHeaderKeyConfig ohttp_header_key_config,
-        ObliviousHttpHeaderKeyConfig::Create(
-            config.key_id, config.kem_id,
-            config.symmetric_algorithms.begin()->kdf_id,
-            config.symmetric_algorithms.begin()->aead_id));
-    QUICHE_ASSIGN_OR_RETURN(
-        ObliviousHttpGateway ohttp_gateway,
-        ObliviousHttpGateway::Create(hpke_private_keys_[key_id],
-                                     ohttp_header_key_config));
-    ohttp_gateway_.emplace(std::move(ohttp_gateway));
     return absl::OkStatus();
   }
 
@@ -311,7 +315,6 @@
   absl::flat_hash_map<uint8_t, std::string> hpke_private_keys_;
   std::optional<ObliviousHttpKeyConfigs> ohttp_key_configs_;
   std::string concatenated_keys_;
-  std::optional<ObliviousHttpGateway> ohttp_gateway_;
 };
 
 static int SelectAlpnCallback(SSL* /*ssl*/, const uint8_t** out,
@@ -722,11 +725,11 @@
     quiche::HttpHeaderBlock response_headers;
     std::string response_body;
     if (response.ok()) {
-      if (pending_request.ohttp_context.has_value()) {
+      if (pending_request.ohttp_context && pending_request.ohttp_gateway) {
         absl::StatusOr<MasqueConnectionPool::Message> gateway_response =
             masque_ohttp_gateway_->HandleResponse(
-                std::move(*response),
-                std::move(*pending_request.ohttp_context));
+                std::move(*response), std::move(*pending_request.ohttp_context),
+                std::move(*pending_request.ohttp_gateway));
         if (!gateway_response.ok()) {
           response_headers[":status"] = "500";
           response_body = absl::StrCat("Failed to handle gateway response: ",
@@ -831,11 +834,13 @@
   void SavePendingGatewayRequest(
       MasqueH2Connection* connection, int32_t stream_id,
       MasqueConnectionPool::RequestId request_id,
-      ObliviousHttpRequest::Context&& ohttp_context) override {
+      ObliviousHttpRequest::Context&& ohttp_context,
+      ObliviousHttpGateway&& ohttp_gateway) override {
     PendingRequest pending_request;
     pending_request.connection = connection;
     pending_request.stream_id = stream_id;
     pending_request.ohttp_context = std::move(ohttp_context);
+    pending_request.ohttp_gateway = std::move(ohttp_gateway);
     pending_requests_.insert({request_id, std::move(pending_request)});
   }
 
@@ -844,6 +849,7 @@
     MasqueH2Connection* connection = nullptr;  // Not owned.
     int32_t stream_id = -1;
     std::optional<ObliviousHttpRequest::Context> ohttp_context;
+    std::optional<ObliviousHttpGateway> ohttp_gateway;
   };
 
   void AcceptConnection() {