diff --git a/components/oblivious_http/oblivious_http_chunk_processor.cc b/components/oblivious_http/oblivious_http_chunk_processor.cc index f9007230c0c..8bd81b17939 100644 --- a/components/oblivious_http/oblivious_http_chunk_processor.cc +++ b/components/oblivious_http/oblivious_http_chunk_processor.cc @@ -11,6 +11,10 @@ namespace oblivious_http { +namespace { +constexpr size_t kMaxEncryptChunkSize = 16384; +} // namespace + ObliviousHttpChunkProcessor::ObliviousHttpChunkProcessor( mojo::PendingRemote chunk_client_remote, @@ -55,12 +59,19 @@ ObliviousHttpChunkProcessor::Create( std::optional ObliviousHttpChunkProcessor::EncryptRequest( std::string_view plaintext) { CHECK(ohttp_client_); - auto result = - ohttp_client_->EncryptRequestChunk(plaintext, /*is_final_chunk=*/true); - if (!result.ok()) { - return std::nullopt; + + std::string result; + for (size_t offset = 0; offset < plaintext.size(); + offset += kMaxEncryptChunkSize) { + const bool is_final = offset + kMaxEncryptChunkSize >= plaintext.size(); + const auto chunk = plaintext.substr(offset, kMaxEncryptChunkSize); + auto encrypted = ohttp_client_->EncryptRequestChunk(chunk, is_final); + if (!encrypted.ok()) { + return std::nullopt; + } + result += std::move(*encrypted); } - return std::move(*result); + return result; } void ObliviousHttpChunkProcessor::OnDataReceived(std::string_view data, diff --git a/components/oblivious_http/oblivious_http_chunk_processor_unittest.cc b/components/oblivious_http/oblivious_http_chunk_processor_unittest.cc index 396700ec065..cf97f8f2e92 100644 --- a/components/oblivious_http/oblivious_http_chunk_processor_unittest.cc +++ b/components/oblivious_http/oblivious_http_chunk_processor_unittest.cc @@ -161,12 +161,13 @@ class ObliviousHttpChunkProcessorTest return result; } - void EncryptRequestAndGatewayDecrypt() { - auto encrypted_request = processor_->EncryptRequest(kTestRequestBody); + void EncryptRequestAndGatewayDecrypt( + std::string_view request_body = kTestRequestBody) { + auto encrypted_request = processor_->EncryptRequest(request_body); ASSERT_TRUE(encrypted_request.has_value()); ASSERT_TRUE( gateway_->DecryptRequest(*encrypted_request, /*end_stream=*/true).ok()); - EXPECT_EQ(kTestRequestBody, received_client_request_body_); + EXPECT_EQ(request_body, received_client_request_body_); } // Drives a full round-trip: encrypts kTestRequestBody, feeds the simulated @@ -233,6 +234,18 @@ TEST_F(ObliviousHttpChunkProcessorTest, EncryptRequestAndGatewayDecrypt(); } +TEST_F(ObliviousHttpChunkProcessorTest, + EncryptRequest_LargeRequest_GatewayDecryptsCorrectly) { + constexpr std::string_view kAlphabet = "abcdefghijklmnopqrstuvwxyz"; + constexpr size_t kLargeRequestSize = 50000; + std::string large_request; + large_request.reserve(kLargeRequestSize); + while (large_request.size() < kLargeRequestSize) { + large_request += kAlphabet; + } + EncryptRequestAndGatewayDecrypt(large_request); +} + TEST_F(ObliviousHttpChunkProcessorTest, RoundTrip_BodyChunksDeliveredToChunkClient) { auto future = RunRoundTrip("hello chunked", net::HTTP_OK,