|  | #ifndef QUICHE_OBLIVIOUS_HTTP_BUFFERS_OBLIVIOUS_HTTP_REQUEST_H_ | 
|  | #define QUICHE_OBLIVIOUS_HTTP_BUFFERS_OBLIVIOUS_HTTP_REQUEST_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <optional> | 
|  | #include <string> | 
|  |  | 
|  | #include "absl/status/statusor.h" | 
|  | #include "absl/strings/string_view.h" | 
|  | #include "openssl/hpke.h" | 
|  | #include "quiche/oblivious_http/common/oblivious_http_header_key_config.h" | 
|  |  | 
|  | namespace quiche { | 
|  | // 1. Handles client side encryption of the payload that will subsequently be | 
|  | // added to HTTP POST body and passed on to Relay. | 
|  | // 2. Handles server side decryption of the payload received in HTTP POST body | 
|  | // from Relay. | 
|  | // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.3 | 
|  | class QUICHE_EXPORT ObliviousHttpRequest { | 
|  | public: | 
|  | // Holds the HPKE related data received from request. This context is created | 
|  | // during request processing, and subsequently passed into response handling | 
|  | // in `ObliviousHttpResponse`. | 
|  | class QUICHE_EXPORT Context { | 
|  | public: | 
|  | ~Context() = default; | 
|  |  | 
|  | // Movable | 
|  | Context(Context&& other) = default; | 
|  | Context& operator=(Context&& other) = default; | 
|  |  | 
|  | private: | 
|  | explicit Context(bssl::UniquePtr<EVP_HPKE_CTX> hpke_context, | 
|  | std::string encapsulated_key); | 
|  |  | 
|  | // All accessors must be friends to read `Context`. | 
|  | friend class ObliviousHttpRequest; | 
|  | friend class ObliviousHttpResponse; | 
|  | // Tests which need access. | 
|  | friend class | 
|  | ObliviousHttpRequest_TestDecapsulateWithSpecAppendixAExample_Test; | 
|  | friend class ObliviousHttpRequest_TestEncapsulatedRequestStructure_Test; | 
|  | friend class | 
|  | ObliviousHttpRequest_TestEncapsulatedOhttpEncryptedPayload_Test; | 
|  | friend class ObliviousHttpRequest_TestDeterministicSeededOhttpRequest_Test; | 
|  | friend class ObliviousHttpResponse_EndToEndTestForResponse_Test; | 
|  | friend class ObliviousHttpResponse_TestEncapsulateWithQuicheRandom_Test; | 
|  |  | 
|  | bssl::UniquePtr<EVP_HPKE_CTX> hpke_context_; | 
|  | std::string encapsulated_key_; | 
|  | }; | 
|  | // Parse the OHTTP request from the given `encrypted_data`. | 
|  | // On success, returns obj that callers will use to `GetPlaintextData`. | 
|  | // Generic Usecase : server-side calls this method in the context of Request. | 
|  | static absl::StatusOr<ObliviousHttpRequest> CreateServerObliviousRequest( | 
|  | absl::string_view encrypted_data, const EVP_HPKE_KEY& gateway_key, | 
|  | const ObliviousHttpHeaderKeyConfig& ohttp_key_config, | 
|  | absl::string_view request_label = | 
|  | ObliviousHttpHeaderKeyConfig::kOhttpRequestLabel); | 
|  |  | 
|  | // Constructs an OHTTP request for the given `plaintext_payload`. | 
|  | // On success, returns obj that callers will use to `EncapsulateAndSerialize` | 
|  | // OHttp request. | 
|  | static absl::StatusOr<ObliviousHttpRequest> CreateClientObliviousRequest( | 
|  | std::string plaintext_payload, absl::string_view hpke_public_key, | 
|  | const ObliviousHttpHeaderKeyConfig& ohttp_key_config, | 
|  | absl::string_view request_label = | 
|  | ObliviousHttpHeaderKeyConfig::kOhttpRequestLabel); | 
|  |  | 
|  | // Same as above but accepts a random number seed for testing. | 
|  | static absl::StatusOr<ObliviousHttpRequest> CreateClientWithSeedForTesting( | 
|  | std::string plaintext_payload, absl::string_view hpke_public_key, | 
|  | const ObliviousHttpHeaderKeyConfig& ohttp_key_config, | 
|  | absl::string_view seed, | 
|  | absl::string_view request_label = | 
|  | ObliviousHttpHeaderKeyConfig::kOhttpRequestLabel); | 
|  |  | 
|  | // Movable. | 
|  | ObliviousHttpRequest(ObliviousHttpRequest&& other) = default; | 
|  | ObliviousHttpRequest& operator=(ObliviousHttpRequest&& other) = default; | 
|  |  | 
|  | ~ObliviousHttpRequest() = default; | 
|  |  | 
|  | // Returns serialized OHTTP request bytestring. | 
|  | // @note: This method MUST NOT be called after `ReleaseContext()` has been | 
|  | // called. | 
|  | std::string EncapsulateAndSerialize() const; | 
|  |  | 
|  | // Generic Usecase : server-side calls this method after Decapsulation using | 
|  | // `CreateServerObliviousRequest`. | 
|  | absl::string_view GetPlaintextData() const; | 
|  |  | 
|  | // Oblivious HTTP request context is created after successful creation of | 
|  | // `this` object, and subsequently passed into the `ObliviousHttpResponse` for | 
|  | // followup response handling. | 
|  | // @returns: This rvalue reference qualified member function transfers the | 
|  | // ownership of `Context` to the caller, and further invokes | 
|  | // ClangTidy:misc-use-after-move warning if callers try to extract `Context` | 
|  | // twice after the fact that the ownership has already been transferred. | 
|  | // @note: Callers shouldn't extract the `Context` until you're done with this | 
|  | // Request and its data. | 
|  | Context ReleaseContext() && { | 
|  | return std::move(oblivious_http_request_context_.value()); | 
|  | } | 
|  |  | 
|  | private: | 
|  | explicit ObliviousHttpRequest( | 
|  | bssl::UniquePtr<EVP_HPKE_CTX> hpke_context, std::string encapsulated_key, | 
|  | const ObliviousHttpHeaderKeyConfig& ohttp_key_config, | 
|  | std::string req_ciphertext, std::string req_plaintext); | 
|  |  | 
|  | static absl::StatusOr<ObliviousHttpRequest> EncapsulateWithSeed( | 
|  | std::string plaintext_payload, absl::string_view hpke_public_key, | 
|  | const ObliviousHttpHeaderKeyConfig& ohttp_key_config, | 
|  | absl::string_view seed, absl::string_view request_label); | 
|  |  | 
|  | // This field will be empty after calling `ReleaseContext()`. | 
|  | std::optional<Context> oblivious_http_request_context_; | 
|  | ObliviousHttpHeaderKeyConfig key_config_; | 
|  | std::string request_ciphertext_; | 
|  | std::string request_plaintext_; | 
|  | }; | 
|  |  | 
|  | }  // namespace quiche | 
|  |  | 
|  | #endif  // QUICHE_OBLIVIOUS_HTTP_BUFFERS_OBLIVIOUS_HTTP_REQUEST_H_ |