Skip to content

Commit

Permalink
[IP Protection] Make token server parameters Finch-configurable
Browse files Browse the repository at this point in the history
Bug: 1444621
Change-Id: I1277ff080e9faa3cd2eca421a2cecd055142b174
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4793026
Commit-Queue: Andrew Williams <awillia@chromium.org>
Reviewed-by: David Schinazi <dschinazi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1186977}
  • Loading branch information
recvfrom authored and Chromium LUCI CQ committed Aug 23, 2023
1 parent c14c610 commit 3b434e9
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 26 deletions.
21 changes: 16 additions & 5 deletions chrome/browser/ip_protection/blind_sign_http_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "base/strings/strcat.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "net/base/features.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
Expand Down Expand Up @@ -57,7 +58,11 @@ const char kIpProtectionContentType[] = "application/x-protobuf";
BlindSignHttpImpl::BlindSignHttpImpl(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
: url_loader_factory_(std::move(url_loader_factory)),
ip_protection_server_url_(BlindSignHttpImpl::kIpProtectionServerUrl) {
ip_protection_server_url_(net::features::kIpPrivacyTokenServer.Get()),
ip_protection_server_get_initial_data_path_(
net::features::kIpPrivacyTokenServerGetInitialDataPath.Get()),
ip_protection_server_get_tokens_path_(
net::features::kIpPrivacyTokenServerGetTokensPath.Get()) {
CHECK(url_loader_factory_);
}

Expand All @@ -72,18 +77,24 @@ void BlindSignHttpImpl::DoRequest(quiche::BlindSignHttpRequestType request_type,
GURL::Replacements replacements;
switch (request_type) {
case quiche::BlindSignHttpRequestType::kGetInitialData:
replacements.SetPathStr(kIpProtectionServerGetInitialDataPath);
replacements.SetPathStr(ip_protection_server_get_initial_data_path_);
break;
case quiche::BlindSignHttpRequestType::kAuthAndSign:
replacements.SetPathStr(kIpProtectionServerAuthAndSignPath);
replacements.SetPathStr(ip_protection_server_get_tokens_path_);
break;
case quiche::BlindSignHttpRequestType::kUnknown:
NOTREACHED_NORETURN();
}

GURL request_url = ip_protection_server_url_.ReplaceComponents(replacements);
if (!request_url.is_valid()) {
std::move(callback_)(
absl::InternalError("Invalid IP Protection Token URL"));
return;
}

auto resource_request = std::make_unique<network::ResourceRequest>();
resource_request->url =
ip_protection_server_url_.ReplaceComponents(replacements);
resource_request->url = std::move(request_url);
resource_request->method = net::HttpRequestHeaders::kPostMethod;
resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
resource_request->headers.SetHeader(
Expand Down
10 changes: 2 additions & 8 deletions chrome/browser/ip_protection/blind_sign_http_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,6 @@ class SimpleURLLoader;
} // namespace network
class BlindSignHttpImpl : public quiche::BlindSignHttpInterface {
public:
// TODO(https://crbug.com/1444621): Make these configurable via Finch.
static constexpr char kIpProtectionServerUrl[] =
"https://autopush-phosphor-pa.sandbox.googleapis.com";
static constexpr char kIpProtectionServerGetInitialDataPath[] =
"/v1/getInitialData";
static constexpr char kIpProtectionServerAuthAndSignPath[] =
"/v1/authWithHeaderCreds";

explicit BlindSignHttpImpl(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
~BlindSignHttpImpl() override;
Expand All @@ -42,6 +34,8 @@ class BlindSignHttpImpl : public quiche::BlindSignHttpInterface {
quiche::BlindSignHttpCallback callback_;

const GURL ip_protection_server_url_;
const std::string ip_protection_server_get_initial_data_path_;
const std::string ip_protection_server_get_tokens_path_;

base::WeakPtrFactory<BlindSignHttpImpl> weak_ptr_factory_{this};
};
Expand Down
64 changes: 51 additions & 13 deletions chrome/browser/ip_protection/blind_sign_http_impl_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@

#include "base/strings/strcat.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "net/base/features.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
Expand All @@ -23,13 +25,23 @@ class BlindSignHttpImplTest : public testing::Test {
http_fetcher_ = std::make_unique<BlindSignHttpImpl>(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_));
token_server_get_initial_data_url_ = GURL(base::StrCat(
{net::features::kIpPrivacyTokenServer.Get(),
net::features::kIpPrivacyTokenServerGetInitialDataPath.Get()}));
ASSERT_TRUE(token_server_get_initial_data_url_.is_valid());
token_server_get_tokens_url_ = GURL(base::StrCat(
{net::features::kIpPrivacyTokenServer.Get(),
net::features::kIpPrivacyTokenServerGetTokensPath.Get()}));
ASSERT_TRUE(token_server_get_tokens_url_.is_valid());
}

base::test::TaskEnvironment task_environment_;
network::TestURLLoaderFactory test_url_loader_factory_;
std::unique_ptr<BlindSignHttpImpl> http_fetcher_;
std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
identity_test_env_adaptor_;
GURL token_server_get_initial_data_url_;
GURL token_server_get_tokens_url_;
};

TEST_F(BlindSignHttpImplTest, DoRequestSendsCorrectRequest) {
Expand All @@ -40,11 +52,8 @@ TEST_F(BlindSignHttpImplTest, DoRequestSendsCorrectRequest) {
// Set up the response to return from the mock.
auto head = network::mojom::URLResponseHead::New();
std::string response_body = "Response body";
GURL test_url = GURL(
base::StrCat({BlindSignHttpImpl::kIpProtectionServerUrl,
BlindSignHttpImpl::kIpProtectionServerGetInitialDataPath}));
test_url_loader_factory_.AddResponse(
test_url, std::move(head), response_body,
token_server_get_initial_data_url_, std::move(head), response_body,
network::URLLoaderCompletionStatus(net::OK));

base::test::TestFuture<absl::StatusOr<quiche::BlindSignHttpResponse>>
Expand Down Expand Up @@ -75,11 +84,8 @@ TEST_F(BlindSignHttpImplTest, DoRequestFailsToConnectReturnsFailureStatus) {
// Mock no response from Authentication Server (such as a network error).
std::string response_body;
auto head = network::mojom::URLResponseHead::New();
GURL test_url = GURL(
base::StrCat({BlindSignHttpImpl::kIpProtectionServerUrl,
BlindSignHttpImpl::kIpProtectionServerAuthAndSignPath}));
test_url_loader_factory_.AddResponse(
test_url, std::move(head), response_body,
token_server_get_tokens_url_, std::move(head), response_body,
network::URLLoaderCompletionStatus(net::ERR_FAILED));

base::test::TestFuture<absl::StatusOr<quiche::BlindSignHttpResponse>>
Expand All @@ -99,6 +105,41 @@ TEST_F(BlindSignHttpImplTest, DoRequestFailsToConnectReturnsFailureStatus) {
EXPECT_EQ(absl::StatusCode::kInternal, result.status().code());
}

TEST_F(BlindSignHttpImplTest, DoRequestInvalidFinchParametersFailsGracefully) {
std::map<std::string, std::string> parameters;
parameters["IpPrivacyTokenServer"] = "<(^_^)>";
parameters["IpPrivacyTokenServerGetInitialDataPath"] = "(>_<)";
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeatureWithParameters(
net::features::kEnableIpProtectionProxy, std::move(parameters));

// Create a new BlindSignHttpImpl for this test so that the new FeatureParams
// get used.
std::unique_ptr<BlindSignHttpImpl> http_fetcher =
std::make_unique<BlindSignHttpImpl>(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_));

auto request_type = quiche::BlindSignHttpRequestType::kGetInitialData;
std::string authorization_header = "token";
std::string body = "body";

base::test::TestFuture<absl::StatusOr<quiche::BlindSignHttpResponse>>
result_future;
auto callback =
[&result_future](absl::StatusOr<quiche::BlindSignHttpResponse> response) {
result_future.SetValue(std::move(response));
};

http_fetcher->DoRequest(request_type, authorization_header, body,
std::move(callback));

absl::StatusOr<quiche::BlindSignHttpResponse> result = result_future.Get();

EXPECT_EQ("Invalid IP Protection Token URL", result.status().message());
EXPECT_EQ(absl::StatusCode::kInternal, result.status().code());
}

TEST_F(BlindSignHttpImplTest, DoRequestHttpFailureStatus) {
auto request_type = quiche::BlindSignHttpRequestType::kAuthAndSign;
std::string authorization_header = "token";
Expand All @@ -107,11 +148,8 @@ TEST_F(BlindSignHttpImplTest, DoRequestHttpFailureStatus) {
// Mock a non-200 HTTP response from Authentication Server.
std::string response_body;
auto head = network::mojom::URLResponseHead::New();
GURL test_url = GURL(
base::StrCat({BlindSignHttpImpl::kIpProtectionServerUrl,
BlindSignHttpImpl::kIpProtectionServerAuthAndSignPath}));
test_url_loader_factory_.AddResponse(test_url.spec(), response_body,
net::HTTP_BAD_REQUEST);
test_url_loader_factory_.AddResponse(token_server_get_tokens_url_.spec(),
response_body, net::HTTP_BAD_REQUEST);

base::test::TestFuture<absl::StatusOr<quiche::BlindSignHttpResponse>>
result_future;
Expand Down
13 changes: 13 additions & 0 deletions net/base/features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,19 @@ const base::FeatureParam<std::string> kIpPrivacyProxyAllowlist{
&kEnableIpProtectionProxy, /*name=*/"IpPrivacyProxyAllowlist",
/*default_value=*/""};

const base::FeatureParam<std::string> kIpPrivacyTokenServer{
&kEnableIpProtectionProxy, /*name=*/"IpPrivacyTokenServer",
/*default_value=*/"https://autopush-phosphor-pa.sandbox.googleapis.com"};

const base::FeatureParam<std::string> kIpPrivacyTokenServerGetInitialDataPath{
&kEnableIpProtectionProxy,
/*name=*/"IpPrivacyTokenServerGetInitialDataPath",
/*default_value=*/"/v1/getInitialData"};

const base::FeatureParam<std::string> kIpPrivacyTokenServerGetTokensPath{
&kEnableIpProtectionProxy, /*name=*/"IpPrivacyTokenServerGetTokensPath",
/*default_value=*/"/v1/authWithHeaderCreds"};

const base::FeatureParam<int> kIpPrivacyAuthTokenCacheBatchSize{
&kEnableIpProtectionProxy, /*name=*/"IpPrivacyAuthTokenCacheBatchSize",
/*default_value=*/64};
Expand Down
13 changes: 13 additions & 0 deletions net/base/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,19 @@ NET_EXPORT extern const base::FeatureParam<std::string> kIpPrivacyProxyServer;
NET_EXPORT extern const base::FeatureParam<std::string>
kIpPrivacyProxyAllowlist;

// Sets the name of the IP protection auth token server.
NET_EXPORT extern const base::FeatureParam<std::string> kIpPrivacyTokenServer;

// Sets the path component of the IP protection auth token server URL used for
// getting initial token signing data.
NET_EXPORT extern const base::FeatureParam<std::string>
kIpPrivacyTokenServerGetInitialDataPath;

// Sets the path component of the IP protection auth token server URL used for
// getting blind-signed tokens.
NET_EXPORT extern const base::FeatureParam<std::string>
kIpPrivacyTokenServerGetTokensPath;

// Sets the batch size to fetch new auth tokens for IP protection.
NET_EXPORT extern const base::FeatureParam<int>
kIpPrivacyAuthTokenCacheBatchSize;
Expand Down

0 comments on commit 3b434e9

Please sign in to comment.