diff --git a/components/web_discovery/browser/double_fetcher.cc b/components/web_discovery/browser/double_fetcher.cc index fbf8697b0010..907dbbae89e5 100644 --- a/components/web_discovery/browser/double_fetcher.cc +++ b/components/web_discovery/browser/double_fetcher.cc @@ -11,6 +11,8 @@ #include "brave/components/web_discovery/browser/request_queue.h" #include "brave/components/web_discovery/browser/util.h" #include "components/prefs/pref_service.h" +#include "net/http/http_status_code.h" +#include "services/network/public/cpp/header_util.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/mojom/url_response_head.mojom.h" @@ -99,7 +101,22 @@ void DoubleFetcher::OnFetchTimer(const base::Value& request_data) { void DoubleFetcher::OnRequestComplete( GURL url, std::optional response_body) { - auto result = ProcessCompletedRequest(&response_body); + bool result = false; + auto* response_info = url_loader_->ResponseInfo(); + if (response_info) { + auto response_code = response_info->headers->response_code(); + if (!network::IsSuccessfulStatus(response_code)) { + if (response_code >= net::HttpStatusCode::HTTP_BAD_REQUEST && + response_code < net::HttpStatusCode::HTTP_INTERNAL_SERVER_ERROR) { + // Only retry failures due to server error + // Mark as 'successful' if not a 5xx error, so we don't retry + result = true; + } + response_body = std::nullopt; + } else { + result = true; + } + } auto request_data = request_queue_.NotifyRequestComplete(result); @@ -112,21 +129,4 @@ void DoubleFetcher::OnRequestComplete( } } -bool DoubleFetcher::ProcessCompletedRequest( - std::optional* response_body) { - auto* response_info = url_loader_->ResponseInfo(); - if (!response_body || !response_info) { - return false; - } - auto response_code = response_info->headers->response_code(); - if (response_code < 200 || response_code >= 300) { - if (response_code >= 500) { - // Only retry failures due to server error - return false; - } - *response_body = std::nullopt; - } - return true; -} - } // namespace web_discovery diff --git a/components/web_discovery/browser/double_fetcher.h b/components/web_discovery/browser/double_fetcher.h index e2b8c979a78d..774c46d48dc9 100644 --- a/components/web_discovery/browser/double_fetcher.h +++ b/components/web_discovery/browser/double_fetcher.h @@ -51,7 +51,6 @@ class DoubleFetcher { private: void OnFetchTimer(const base::Value& request_data); void OnRequestComplete(GURL url, std::optional response_body); - bool ProcessCompletedRequest(std::optional* response_body); raw_ptr profile_prefs_; raw_ptr shared_url_loader_factory_; diff --git a/components/web_discovery/browser/ecdh_aes.cc b/components/web_discovery/browser/ecdh_aes.cc index 5049f97a9cc1..3ea7ca6c55af 100644 --- a/components/web_discovery/browser/ecdh_aes.cc +++ b/components/web_discovery/browser/ecdh_aes.cc @@ -3,15 +3,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at https://mozilla.org/MPL/2.0/. */ -#ifdef UNSAFE_BUFFERS_BUILD -#pragma allow_unsafe_buffers -#endif - #include "brave/components/web_discovery/browser/ecdh_aes.h" #include #include "base/base64.h" +#include "base/containers/span_writer.h" #include "base/logging.h" #include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" @@ -37,11 +34,6 @@ constexpr size_t kComponentOctSize = 32 * 2 + 1; constexpr size_t kEncodedPubKeyAndIv = 1 + kComponentOctSize + kIvSize; constexpr uint8_t kP256TypeByte = 0xea; -bssl::UniquePtr CreateECKey() { - return bssl::UniquePtr( - EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); -} - } // namespace AESEncryptResult::AESEncryptResult(std::vector data, @@ -53,9 +45,10 @@ AESEncryptResult::~AESEncryptResult() = default; AESEncryptResult::AESEncryptResult(const AESEncryptResult&) = default; std::optional DeriveAESKeyAndEncrypt( - const std::vector& server_pub_key, - const std::vector& data) { - auto client_private_key = CreateECKey(); + const base::span server_pub_key, + const base::span data) { + bssl::UniquePtr client_private_key( + EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); if (!client_private_key) { VLOG(1) << "Failed to init P-256 curve"; @@ -80,8 +73,8 @@ std::optional DeriveAESKeyAndEncrypt( return std::nullopt; } - uint8_t shared_key_material[kKeyMaterialSize]; - if (!ECDH_compute_key(shared_key_material, kKeyMaterialSize, + std::array shared_key_material; + if (!ECDH_compute_key(shared_key_material.data(), kKeyMaterialSize, server_public_point.get(), client_private_key.get(), nullptr)) { VLOG(1) << "Failed to set derive key via ECDH"; @@ -90,8 +83,7 @@ std::optional DeriveAESKeyAndEncrypt( auto key_material_hash = crypto::SHA256Hash(shared_key_material); - auto aes_key = std::vector(key_material_hash.begin(), - key_material_hash.begin() + kAesKeySize); + auto aes_key = base::span(key_material_hash).first(); auto* algo = EVP_aead_aes_128_gcm(); bssl::ScopedEVP_AEAD_CTX ctx; @@ -117,18 +109,22 @@ std::optional DeriveAESKeyAndEncrypt( output.resize(len); std::array public_component_and_iv; - public_component_and_iv[0] = kP256TypeByte; + auto public_component_and_iv_writer = + base::SpanWriter(base::span(public_component_and_iv)); + public_component_and_iv_writer.Write(kP256TypeByte); + + auto component = public_component_and_iv_writer.Skip(kComponentOctSize); - if (!EC_POINT_point2oct( - EC_group_p256(), EC_KEY_get0_public_key(client_private_key.get()), - POINT_CONVERSION_UNCOMPRESSED, public_component_and_iv.data() + 1, - kComponentOctSize, nullptr)) { + if (!EC_POINT_point2oct(EC_group_p256(), + EC_KEY_get0_public_key(client_private_key.get()), + POINT_CONVERSION_UNCOMPRESSED, component->data(), + kComponentOctSize, nullptr)) { VLOG(1) << "Failed to export EC public point/key"; return std::nullopt; } - base::ranges::copy(iv.begin(), iv.end(), - public_component_and_iv.begin() + kComponentOctSize + 1); + public_component_and_iv_writer.Write(iv); + CHECK_EQ(public_component_and_iv_writer.remaining(), 0u); return std::make_optional( output, base::Base64Encode(public_component_and_iv)); diff --git a/components/web_discovery/browser/ecdh_aes.h b/components/web_discovery/browser/ecdh_aes.h index d901d8f7be73..72612d9b9b13 100644 --- a/components/web_discovery/browser/ecdh_aes.h +++ b/components/web_discovery/browser/ecdh_aes.h @@ -10,6 +10,8 @@ #include #include +#include "base/containers/span.h" + namespace web_discovery { struct AESEncryptResult { @@ -24,8 +26,8 @@ struct AESEncryptResult { }; std::optional DeriveAESKeyAndEncrypt( - const std::vector& server_pub_key, - const std::vector& data); + const base::span server_pub_key, + const base::span data); } // namespace web_discovery diff --git a/components/web_discovery/browser/reporter.cc b/components/web_discovery/browser/reporter.cc index 815b052a452a..d2f10b191691 100644 --- a/components/web_discovery/browser/reporter.cc +++ b/components/web_discovery/browser/reporter.cc @@ -3,10 +3,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at https://mozilla.org/MPL/2.0/. */ -#ifdef UNSAFE_BUFFERS_BUILD -#pragma allow_unsafe_buffers -#endif - #include "brave/components/web_discovery/browser/reporter.h" #include @@ -21,6 +17,8 @@ #include "brave/components/web_discovery/browser/signature_basename.h" #include "brave/components/web_discovery/browser/util.h" #include "crypto/sha2.h" +#include "net/http/http_status_code.h" +#include "services/network/public/cpp/header_util.h" #include "services/network/public/cpp/resource_request_body.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" @@ -100,7 +98,8 @@ std::optional CompressAndEncrypt( uLongf compressed_data_size = compressBound(full_signed_message.size()); std::vector compressed_data(compressed_data_size + 2); if (zlib_internal::CompressHelper( - zlib_internal::ZLIB, compressed_data.data() + 2, + zlib_internal::ZLIB, + base::span(compressed_data).last(compressed_data_size).data(), &compressed_data_size, full_signed_message.data(), full_signed_message.size(), Z_DEFAULT_COMPRESSION, nullptr, nullptr) != Z_OK) { @@ -114,7 +113,7 @@ std::optional CompressAndEncrypt( return std::nullopt; } base::ranges::copy(base::U16ToBigEndian(compressed_data_size), - compressed_data.begin()); + compressed_data.data()); compressed_data[0] |= kCompressedMessageId; return DeriveAESKeyAndEncrypt(server_pub_key, compressed_data); } @@ -208,9 +207,8 @@ void Reporter::OnRequestSigned(std::string final_payload_json, final_payload_json.size()); base::SpanWriter message_writer(full_signed_message); if (!message_writer.WriteU8BigEndian(kSignedMessageId) || - !message_writer.Write(base::span( - reinterpret_cast(final_payload_json.data()), - final_payload_json.size())) || + !message_writer.Write(std::vector(final_payload_json.begin(), + final_payload_json.end())) || !message_writer.Write(base::DoubleToBigEndian(basename_count)) || !message_writer.Write(*signature)) { VLOG(1) << "Failed to pack signed message"; @@ -273,8 +271,8 @@ bool Reporter::ValidateResponse( return false; } auto response_code = headers->response_code(); - if (response_code < 200 || response_code >= 300) { - if (response_code >= 500) { + if (!network::IsSuccessfulStatus(response_code)) { + if (response_code >= net::HttpStatusCode::HTTP_INTERNAL_SERVER_ERROR) { // Only retry failures due to server error return false; }