Commit b1d4d3cc authored by David Van Cleve's avatar David Van Cleve Committed by Commit Bot

Refactor Trust Tokens helpers to use SuitableTrustTokenOrigin

Previously, the Trust Tokens request helpers enforced a collection of
uniform preconditions on their issuer and top frame origins via DCHECKs.
These were both conceptually enforced at the level "immediately above"
the factories (the request helper factory: crrev.com/c/2097057).

This CL makes a couple changes:
1. it removes the top frame origin DCHECKs and enforces the top frame
origins' constraints by requiring SuitableTrustTokenOrigin-typed top
frame origins; the type itself enforces the preconditions.
2. it moves the issuer origin checks conceptually into the request
helpers themselves, because the source of the issuer origin varies from
operation to operation (for issuance and redemption, it's the request's
destination URL; for signing, it's an additional parameter).

R=csharrison

Test: Expand unittests to cover unsuitable issuer origins.
Bug: 1042962
Change-Id: I8f0125eb796c3421bf082ea22fb1fe5f0f85007e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2134588
Commit-Queue: David Van Cleve <davidvc@chromium.org>
Reviewed-by: default avatarCharlie Harrison <csharrison@chromium.org>
Auto-Submit: David Van Cleve <davidvc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756367}
parent 640235d4
......@@ -37,6 +37,13 @@ class SuitableTrustTokenOrigin {
std::string Serialize() const;
const url::Origin& origin() const { return origin_; }
// This implicit "widening" conversion is allowed to ease drop-in use of
// SuitableTrustTokenOrigin in places currently requiring url::Origins with
// guaranteed preconditions. The intended use is creating a
// SuitableTrustTokenOrigin to confirm the preconditions, then directly
// passing the SuitableTrustTokenOrigin to url::Origin-accepting callsite.
operator const url::Origin&() const { return origin_; } // NOLINT
// Constructs a SuitableTrustTokenOrigin from the given origin. Public only as
// an implementation detail; clients should use |Create|.
SuitableTrustTokenOrigin(util::PassKey<SuitableTrustTokenOrigin>,
......
......@@ -14,6 +14,7 @@
#include "services/network/public/mojom/trust_tokens.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/network/trust_tokens/proto/public.pb.h"
#include "services/network/trust_tokens/suitable_trust_token_origin.h"
#include "services/network/trust_tokens/trust_token_http_headers.h"
#include "services/network/trust_tokens/trust_token_parameterization.h"
#include "services/network/trust_tokens/trust_token_store.h"
......@@ -23,19 +24,14 @@
namespace network {
TrustTokenRequestIssuanceHelper::TrustTokenRequestIssuanceHelper(
const url::Origin& top_level_origin,
SuitableTrustTokenOrigin top_level_origin,
TrustTokenStore* token_store,
std::unique_ptr<TrustTokenKeyCommitmentGetter> key_commitment_getter,
std::unique_ptr<Cryptographer> cryptographer)
: top_level_origin_(top_level_origin),
: top_level_origin_(std::move(top_level_origin)),
token_store_(token_store),
key_commitment_getter_(std::move(key_commitment_getter)),
cryptographer_(std::move(cryptographer)) {
DCHECK(top_level_origin.scheme() == url::kHttpsScheme ||
(top_level_origin.scheme() == url::kHttpScheme &&
IsOriginPotentiallyTrustworthy(top_level_origin)))
<< top_level_origin;
DCHECK(token_store_);
DCHECK(key_commitment_getter_);
DCHECK(cryptographer_);
......@@ -51,29 +47,30 @@ TrustTokenRequestIssuanceHelper::Cryptographer::UnblindedTokens::
void TrustTokenRequestIssuanceHelper::Begin(
net::URLRequest* request,
base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) {
DCHECK(request->url().SchemeIsHTTPOrHTTPS() &&
IsUrlPotentiallyTrustworthy(request->url()))
<< request->url();
DCHECK(request->initiator() &&
request->initiator()->scheme() == url::kHttpsScheme ||
(request->initiator()->scheme() == url::kHttpScheme &&
IsOriginPotentiallyTrustworthy(*request->initiator())))
<< (request->initiator() ? request->initiator()->Serialize()
: "(missing)");
issuer_ = url::Origin::Create(request->url());
if (!token_store_->SetAssociation(issuer_, top_level_origin_)) {
DCHECK(request);
DCHECK(!request->initiator() ||
IsOriginPotentiallyTrustworthy(*request->initiator()))
<< *request->initiator();
issuer_ = SuitableTrustTokenOrigin::Create(request->url());
if (!issuer_) {
std::move(done).Run(mojom::TrustTokenOperationStatus::kInvalidArgument);
return;
}
if (!token_store_->SetAssociation(*issuer_, top_level_origin_)) {
std::move(done).Run(mojom::TrustTokenOperationStatus::kResourceExhausted);
return;
}
if (token_store_->CountTokens(issuer_) == kTrustTokenPerIssuerTokenCapacity) {
if (token_store_->CountTokens(*issuer_) ==
kTrustTokenPerIssuerTokenCapacity) {
std::move(done).Run(mojom::TrustTokenOperationStatus::kResourceExhausted);
return;
}
key_commitment_getter_->Get(
issuer_,
*issuer_,
base::BindOnce(&TrustTokenRequestIssuanceHelper::OnGotKeyCommitment,
weak_ptr_factory_.GetWeakPtr(), request, std::move(done)));
}
......@@ -98,7 +95,7 @@ void TrustTokenRequestIssuanceHelper::OnGotKeyCommitment(
// Evict tokens signed with keys other than those from the issuer's most
// recent commitments.
token_store_->PruneStaleIssuerState(issuer_, commitment_result->keys);
token_store_->PruneStaleIssuerState(*issuer_, commitment_result->keys);
int batch_size = commitment_result->batch_size
? std::min(commitment_result->batch_size->value,
......@@ -154,7 +151,7 @@ mojom::TrustTokenOperationStatus TrustTokenRequestIssuanceHelper::Finalize(
return mojom::TrustTokenOperationStatus::kBadResponse;
}
token_store_->AddTokens(issuer_, base::make_span(maybe_tokens->tokens),
token_store_->AddTokens(*issuer_, base::make_span(maybe_tokens->tokens),
maybe_tokens->body_of_verifying_key);
return mojom::TrustTokenOperationStatus::kOk;
......
......@@ -14,6 +14,7 @@
#include "base/strings/string_piece_forward.h"
#include "services/network/public/mojom/trust_tokens.mojom-shared.h"
#include "services/network/trust_tokens/proto/public.pb.h"
#include "services/network/trust_tokens/suitable_trust_token_origin.h"
#include "services/network/trust_tokens/trust_token_key_commitment_getter.h"
#include "services/network/trust_tokens/trust_token_request_helper.h"
#include "url/origin.h"
......@@ -95,7 +96,7 @@ class TrustTokenRequestIssuanceHelper : public TrustTokenRequestHelper {
// REQUIRES: |token_store|, |key_commitment_getter|, and |cryptographer| must
// be non-null.
TrustTokenRequestIssuanceHelper(
const url::Origin& top_level_origin,
SuitableTrustTokenOrigin top_level_origin,
TrustTokenStore* token_store,
std::unique_ptr<TrustTokenKeyCommitmentGetter> key_commitment_getter,
std::unique_ptr<Cryptographer> cryptographer);
......@@ -155,8 +156,11 @@ class TrustTokenRequestIssuanceHelper : public TrustTokenRequestHelper {
base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done,
mojom::TrustTokenKeyCommitmentResultPtr commitment_result);
url::Origin issuer_;
const url::Origin top_level_origin_;
// |issuer_| needs to be a nullable type because it is initialized in |Begin|,
// but, once initialized, it will never be empty over the course of the
// operation's execution.
base::Optional<SuitableTrustTokenOrigin> issuer_;
const SuitableTrustTokenOrigin top_level_origin_;
TrustTokenStore* const token_store_;
const std::unique_ptr<TrustTokenKeyCommitmentGetter> key_commitment_getter_;
const std::unique_ptr<Cryptographer> cryptographer_;
......
......@@ -83,7 +83,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, RejectsIfTooManyIssuers) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
auto issuer = url::Origin::Create(GURL("https://issuer.com/"));
auto toplevel = url::Origin::Create(GURL("https://toplevel.com/"));
auto toplevel =
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/"));
// Associate the toplevel with the cap's worth of issuers different from
// |issuer|. (The cap is guaranteed to be quite small because of privacy
......@@ -119,8 +120,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, RejectsIfAtCapacity) {
/*issuing_key=*/"");
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::make_unique<FixedKeyCommitmentGetter>(),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::make_unique<FixedKeyCommitmentGetter>(),
std::make_unique<MockCryptographer>());
auto request = MakeURLRequest("https://issuer.com/");
......@@ -138,8 +139,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, RejectsIfKeyCommitmentFails) {
// Have the key commitment getter return nullptr, denoting that the key
// commitment fetch failed.
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::make_unique<FixedKeyCommitmentGetter>(issuer, nullptr),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::make_unique<FixedKeyCommitmentGetter>(issuer, nullptr),
std::make_unique<MockCryptographer>());
auto request = MakeURLRequest("https://issuer.com/");
......@@ -165,8 +166,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, RejectsIfAddingKeyFails) {
EXPECT_CALL(*cryptographer, AddKey(_)).WillOnce(Return(false));
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::move(getter), std::move(cryptographer));
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::move(getter), std::move(cryptographer));
auto request = MakeURLRequest("https://issuer.com/");
request->set_initiator(issuer);
......@@ -195,8 +196,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest,
EXPECT_CALL(*cryptographer, BeginIssuance(_)).WillOnce(Return(base::nullopt));
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::move(getter), std::move(cryptographer));
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::move(getter), std::move(cryptographer));
auto request = MakeURLRequest("https://issuer.com/");
request->set_initiator(issuer);
......@@ -230,8 +231,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, SetsRequestHeader) {
Return(std::string("this string contains some blinded tokens")));
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::move(getter), std::move(cryptographer));
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::move(getter), std::move(cryptographer));
auto request = MakeURLRequest("https://issuer.com/");
request->set_initiator(issuer);
......@@ -267,8 +268,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, SetsLoadFlag) {
Return(std::string("this string contains some blinded tokens")));
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::move(getter), std::move(cryptographer));
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::move(getter), std::move(cryptographer));
auto request = MakeURLRequest("https://issuer.com/");
request->set_initiator(issuer);
......@@ -298,8 +299,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, RejectsIfResponseOmitsHeader) {
Return(std::string("this string contains some blinded tokens")));
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::move(getter), std::move(cryptographer));
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::move(getter), std::move(cryptographer));
auto request = MakeURLRequest("https://issuer.com/");
request->set_initiator(issuer);
......@@ -337,8 +338,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, RejectsIfResponseIsUnusable) {
EXPECT_CALL(*cryptographer, ConfirmIssuance(_)).WillOnce(ReturnNull());
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::move(getter), std::move(cryptographer));
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::move(getter), std::move(cryptographer));
auto request = MakeURLRequest("https://issuer.com/");
request->set_initiator(issuer);
......@@ -383,8 +384,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, Success) {
.WillOnce(Return(ByMove(std::make_unique<UnblindedTokens>())));
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::move(getter), std::move(cryptographer));
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::move(getter), std::move(cryptographer));
auto request = MakeURLRequest("https://issuer.com/");
request->set_initiator(issuer);
......@@ -427,8 +428,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, AssociatesIssuerWithToplevel) {
Return(std::string("this string contains some blinded tokens")));
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::move(getter), std::move(cryptographer));
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::move(getter), std::move(cryptographer));
auto request = MakeURLRequest("https://issuer.com/");
request->set_initiator(issuer);
......@@ -438,8 +439,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, AssociatesIssuerWithToplevel) {
// After the operation has successfully begun, the issuer and the toplevel
// should be associated.
EXPECT_TRUE(store->IsAssociated(
issuer, url::Origin::Create(GURL("https://toplevel.com/"))));
EXPECT_TRUE(store->IsAssociated(issuer, *SuitableTrustTokenOrigin::Create(
GURL("https://toplevel.com/"))));
}
// Check that a successful end-to-end Begin/Finalize flow stores the obtained
......@@ -471,8 +472,8 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, StoresObtainedTokens) {
.WillOnce(Return(ByMove(std::move((unblinded_tokens)))));
TrustTokenRequestIssuanceHelper helper(
url::Origin::Create(GURL("https://toplevel.com/")), store.get(),
std::move(getter), std::move(cryptographer));
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::move(getter), std::move(cryptographer));
auto request = MakeURLRequest("https://issuer.com/");
request->set_initiator(issuer);
......@@ -498,4 +499,32 @@ TEST_F(TrustTokenRequestIssuanceHelperTest, StoresObtainedTokens) {
store->RetrieveMatchingTokens(issuer, std::move(match_all_keys)),
ElementsAre(Property(&TrustToken::body, "a signed, unblinded token")));
}
TEST_F(TrustTokenRequestIssuanceHelperTest, RejectsUnsuitableInsecureIssuer) {
auto store = TrustTokenStore::CreateInMemory();
TrustTokenRequestIssuanceHelper helper(
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::make_unique<FixedKeyCommitmentGetter>(),
std::make_unique<MockCryptographer>());
auto request = MakeURLRequest("http://insecure-issuer.com/");
EXPECT_EQ(ExecuteBeginOperationAndWaitForResult(&helper, request.get()),
mojom::TrustTokenOperationStatus::kInvalidArgument);
}
TEST_F(TrustTokenRequestIssuanceHelperTest,
RejectsUnsuitableNonHttpNonHttpsIssuer) {
auto store = TrustTokenStore::CreateInMemory();
TrustTokenRequestIssuanceHelper helper(
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com/")),
store.get(), std::make_unique<FixedKeyCommitmentGetter>(),
std::make_unique<MockCryptographer>());
auto request = MakeURLRequest("file:///non-https-issuer.txt");
EXPECT_EQ(ExecuteBeginOperationAndWaitForResult(&helper, request.get()),
mojom::TrustTokenOperationStatus::kInvalidArgument);
}
} // namespace network
......@@ -24,7 +24,7 @@
namespace network {
TrustTokenRequestRedemptionHelper::TrustTokenRequestRedemptionHelper(
const url::Origin& top_level_origin,
SuitableTrustTokenOrigin top_level_origin,
mojom::TrustTokenRefreshPolicy refresh_policy,
TrustTokenStore* token_store,
std::unique_ptr<TrustTokenKeyCommitmentGetter> key_commitment_getter,
......@@ -36,11 +36,6 @@ TrustTokenRequestRedemptionHelper::TrustTokenRequestRedemptionHelper(
key_commitment_getter_(std::move(key_commitment_getter)),
key_pair_generator_(std::move(key_pair_generator)),
cryptographer_(std::move(cryptographer)) {
DCHECK(top_level_origin.scheme() == url::kHttpsScheme ||
(top_level_origin.scheme() == url::kHttpScheme &&
IsOriginPotentiallyTrustworthy(top_level_origin)))
<< top_level_origin;
DCHECK(token_store_);
DCHECK(key_commitment_getter_);
DCHECK(key_pair_generator_);
......@@ -53,37 +48,38 @@ TrustTokenRequestRedemptionHelper::~TrustTokenRequestRedemptionHelper() =
void TrustTokenRequestRedemptionHelper::Begin(
net::URLRequest* request,
base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) {
DCHECK(request->url().SchemeIsHTTPOrHTTPS() &&
IsUrlPotentiallyTrustworthy(request->url()))
<< request->url();
DCHECK(request->initiator() &&
request->initiator()->scheme() == url::kHttpsScheme ||
(request->initiator()->scheme() == url::kHttpScheme &&
IsOriginPotentiallyTrustworthy(*request->initiator())))
<< (request->initiator() ? request->initiator()->Serialize() : "(none)");
issuer_ = url::Origin::Create(request->url());
DCHECK(request);
DCHECK(!request->initiator() ||
IsOriginPotentiallyTrustworthy(*request->initiator()))
<< *request->initiator();
issuer_ = SuitableTrustTokenOrigin::Create(request->url());
if (!issuer_) {
std::move(done).Run(mojom::TrustTokenOperationStatus::kInvalidArgument);
return;
}
if (refresh_policy_ == mojom::TrustTokenRefreshPolicy::kRefresh &&
!request->initiator()->IsSameOriginWith(issuer_)) {
(!request->initiator() ||
!request->initiator()->IsSameOriginWith(*issuer_))) {
std::move(done).Run(mojom::TrustTokenOperationStatus::kFailedPrecondition);
return;
}
if (!token_store_->SetAssociation(issuer_, top_level_origin_)) {
if (!token_store_->SetAssociation(*issuer_, top_level_origin_)) {
std::move(done).Run(mojom::TrustTokenOperationStatus::kResourceExhausted);
return;
}
if (refresh_policy_ == mojom::TrustTokenRefreshPolicy::kUseCached &&
token_store_->RetrieveNonstaleRedemptionRecord(issuer_,
token_store_->RetrieveNonstaleRedemptionRecord(*issuer_,
top_level_origin_)) {
std::move(done).Run(mojom::TrustTokenOperationStatus::kAlreadyExists);
return;
}
key_commitment_getter_->Get(
issuer_,
*issuer_,
base::BindOnce(&TrustTokenRequestRedemptionHelper::OnGotKeyCommitment,
weak_factory_.GetWeakPtr(), request, std::move(done)));
}
......@@ -99,7 +95,7 @@ void TrustTokenRequestRedemptionHelper::OnGotKeyCommitment(
// Evict tokens signed with keys other than those from the issuer's most
// recent commitments.
token_store_->PruneStaleIssuerState(issuer_, commitment_result->keys);
token_store_->PruneStaleIssuerState(*issuer_, commitment_result->keys);
base::Optional<TrustToken> maybe_token_to_redeem = RetrieveSingleToken();
if (!maybe_token_to_redeem) {
......@@ -132,7 +128,7 @@ void TrustTokenRequestRedemptionHelper::OnGotKeyCommitment(
// settings.
request->SetLoadFlags(request->load_flags() | net::LOAD_BYPASS_CACHE);
token_store_->DeleteToken(issuer_, *maybe_token_to_redeem);
token_store_->DeleteToken(*issuer_, *maybe_token_to_redeem);
std::move(done).Run(mojom::TrustTokenOperationStatus::kOk);
}
......@@ -181,7 +177,7 @@ mojom::TrustTokenOperationStatus TrustTokenRequestRedemptionHelper::Finalize(
record_to_store.set_body(std::move(*maybe_signed_redemption_record));
record_to_store.set_signing_key(std::move(signing_key_));
record_to_store.set_public_key(std::move(verification_key_));
token_store_->SetRedemptionRecord(issuer_, top_level_origin_,
token_store_->SetRedemptionRecord(*issuer_, top_level_origin_,
std::move(record_to_store));
return mojom::TrustTokenOperationStatus::kOk;
......@@ -197,7 +193,7 @@ TrustTokenRequestRedemptionHelper::RetrieveSingleToken() {
base::BindRepeating([](const std::string&) { return true; });
std::vector<TrustToken> matching_tokens =
token_store_->RetrieveMatchingTokens(issuer_, key_matcher);
token_store_->RetrieveMatchingTokens(*issuer_, key_matcher);
if (matching_tokens.empty())
return base::nullopt;
......
......@@ -14,6 +14,7 @@
#include "base/strings/string_piece_forward.h"
#include "services/network/public/mojom/trust_tokens.mojom.h"
#include "services/network/trust_tokens/proto/public.pb.h"
#include "services/network/trust_tokens/suitable_trust_token_origin.h"
#include "services/network/trust_tokens/trust_token_key_commitment_getter.h"
#include "services/network/trust_tokens/trust_token_request_helper.h"
#include "url/origin.h"
......@@ -98,7 +99,7 @@ class TrustTokenRequestRedemptionHelper : public TrustTokenRequestHelper {
// |cryptographer| are delegates that help execute the protocol; see
// their class comments.
TrustTokenRequestRedemptionHelper(
const url::Origin& top_level_origin,
SuitableTrustTokenOrigin top_level_origin,
mojom::TrustTokenRefreshPolicy refresh_policy,
TrustTokenStore* token_store,
std::unique_ptr<TrustTokenKeyCommitmentGetter> key_commitment_getter,
......@@ -161,7 +162,11 @@ class TrustTokenRequestRedemptionHelper : public TrustTokenRequestHelper {
// |issuer_|, |top_level_origin_|, and |refresh_policy_| are parameters
// determining the scope and control flow of the redemption operation.
url::Origin issuer_;
//
// |issuer_| needs to be a nullable type because it is initialized in |Begin|,
// but, once initialized, it will never be empty over the course of the
// operation's execution.
base::Optional<SuitableTrustTokenOrigin> issuer_;
const url::Origin top_level_origin_;
const mojom::TrustTokenRefreshPolicy refresh_policy_;
......
......@@ -180,36 +180,31 @@ TrustTokenRequestSigningHelper::TrustTokenRequestSigningHelper(
std::unique_ptr<Signer> signer,
std::unique_ptr<TrustTokenRequestCanonicalizer> canonicalizer)
: token_store_(token_store),
params_(params),
params_(std::move(params)),
signer_(std::move(signer)),
canonicalizer_(std::move(canonicalizer)) {
DCHECK(params_.issuer.scheme() == url::kHttpsScheme ||
(params_.issuer.scheme() == url::kHttpScheme &&
IsOriginPotentiallyTrustworthy(params_.issuer)));
DCHECK(params_.toplevel.scheme() == url::kHttpsScheme ||
(params_.toplevel.scheme() == url::kHttpScheme &&
IsOriginPotentiallyTrustworthy(params_.toplevel)));
}
canonicalizer_(std::move(canonicalizer)) {}
TrustTokenRequestSigningHelper::~TrustTokenRequestSigningHelper() = default;
Params::Params() = default;
Params::Params(SuitableTrustTokenOrigin issuer,
SuitableTrustTokenOrigin toplevel)
: issuer(std::move(issuer)), toplevel(std::move(toplevel)) {}
Params::~Params() = default;
Params::Params(const Params&) = default;
// The type alias causes a linter false positive.
// NOLINTNEXTLINE(misc-unconventional-assign-operator)
Params& Params::operator=(const Params&) = default;
Params::Params(Params&&) = default;
// NOLINTNEXTLINE(misc-unconventional-assign-operator)
Params& Params::operator=(Params&&) = default;
void TrustTokenRequestSigningHelper::Begin(
net::URLRequest* request,
base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) {
DCHECK(request);
DCHECK(request->url().SchemeIsHTTPOrHTTPS() &&
IsUrlPotentiallyTrustworthy(request->url()));
DCHECK(request->initiator() &&
request->initiator()->scheme() == url::kHttpsScheme ||
(request->initiator()->scheme() == url::kHttpScheme &&
IsOriginPotentiallyTrustworthy(*request->initiator())));
DCHECK(!request->initiator() ||
IsOriginPotentiallyTrustworthy(*request->initiator()))
<< *request->initiator();
// This class is responsible for adding these headers; callers should not add
// them.
......
......@@ -15,6 +15,7 @@
#include "net/http/http_request_headers.h"
#include "services/network/public/mojom/trust_tokens.mojom-shared.h"
#include "services/network/public/mojom/url_response_head.mojom-forward.h"
#include "services/network/trust_tokens/suitable_trust_token_origin.h"
#include "services/network/trust_tokens/trust_token_request_helper.h"
#include "url/origin.h"
......@@ -69,11 +70,13 @@ class TrustTokenRequestSigningHelper : public TrustTokenRequestHelper {
'T', 'r', 'u', 's', 't', ' ', 'T', 'o', 'k', 'e', 'n', ' ', 'v', '0'};
struct Params {
Params();
Params(SuitableTrustTokenOrigin issuer, SuitableTrustTokenOrigin toplevel);
~Params();
Params(const Params&);
Params& operator=(const Params&);
Params(Params&&);
Params& operator=(Params&&);
// |issuer| is the Trust Tokens issuer origin for which to retrieve a Signed
// Redemption Record and matching signing key. This must be both (1) HTTP or
......@@ -82,11 +85,11 @@ class TrustTokenRequestSigningHelper : public TrustTokenRequestHelper {
// 1. HTTP or HTTPS so that the scheme serializes in a sensible manner in
// order to serve as a key for persisting state.
// 2. potentially trustworthy origin to satisfy Web security requirements.
url::Origin issuer;
SuitableTrustTokenOrigin issuer;
// |toplevel| is the top-level origin of the initiating request. This must
// satisfy the same preconditions as |issuer|.
url::Origin toplevel;
SuitableTrustTokenOrigin toplevel;
// |additional_headers_to_sign| is a list of headers to sign, in addition to
// those specified by the request's Signed-Headers header. If these are not
......
......@@ -233,10 +233,10 @@ MATCHER_P2(Header,
TEST_F(TrustTokenRequestSigningHelperTest, WontSignIfNoRedemptionRecord) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.sign_request_data = mojom::TrustTokenSignRequestData::kHeadersOnly;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
TrustTokenRequestSigningHelper helper(
store.get(), std::move(params), std::make_unique<FakeSigner>(),
......@@ -261,10 +261,10 @@ TEST_F(TrustTokenRequestSigningHelperTest, MergesHeaders) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.sign_request_data = mojom::TrustTokenSignRequestData::kHeadersOnly;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
params.additional_headers_to_sign = std::vector<std::string>{"Sec-Time"};
SignedTrustTokenRedemptionRecord my_record;
......@@ -306,10 +306,10 @@ TEST_F(TrustTokenRequestSigningHelperTest,
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.sign_request_data = mojom::TrustTokenSignRequestData::kHeadersOnly;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
SignedTrustTokenRedemptionRecord my_record;
my_record.set_public_key("key");
......@@ -345,10 +345,10 @@ TEST_F(TrustTokenRequestSigningHelperTest,
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.sign_request_data = mojom::TrustTokenSignRequestData::kHeadersOnly;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
params.additional_headers_to_sign = std::vector<std::string>{
"this header name is definitely not in "
"TrustTokenRequestSigningHelper::kSignableRequestHeaders"};
......@@ -383,11 +383,11 @@ class TrustTokenRequestSigningHelperTestWithMockTime
TEST_F(TrustTokenRequestSigningHelperTestWithMockTime, ProvidesTimeHeader) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.sign_request_data = mojom::TrustTokenSignRequestData::kHeadersOnly;
params.should_add_timestamp = true;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
SignedTrustTokenRedemptionRecord my_record;
my_record.set_public_key("key");
......@@ -413,10 +413,9 @@ TEST_F(TrustTokenRequestSigningHelperTest,
RedemptionRecordAttachmentWithoutSigning) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
params.sign_request_data = mojom::TrustTokenSignRequestData::kHeadersOnly;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.should_add_timestamp = true;
params.sign_request_data = mojom::TrustTokenSignRequestData::kOmit;
......@@ -446,10 +445,10 @@ TEST_F(TrustTokenRequestSigningHelperTest,
TEST_F(TrustTokenRequestSigningHelperTest, SignAndVerifyMinimal) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.sign_request_data = mojom::TrustTokenSignRequestData::kHeadersOnly;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
SignedTrustTokenRedemptionRecord my_record;
my_record.set_public_key("key");
......@@ -482,10 +481,10 @@ TEST_F(TrustTokenRequestSigningHelperTest, SignAndVerifyMinimal) {
TEST_F(TrustTokenRequestSigningHelperTest, SignAndVerifyWithHeaders) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.sign_request_data = mojom::TrustTokenSignRequestData::kHeadersOnly;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
SignedTrustTokenRedemptionRecord record;
record.set_body("I am a signed token redemption record");
record.set_public_key("key");
......@@ -515,10 +514,10 @@ TEST_F(TrustTokenRequestSigningHelperTest, SignAndVerifyWithHeaders) {
TEST_F(TrustTokenRequestSigningHelperTest, SignAndVerifyTimestampHeader) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.sign_request_data = mojom::TrustTokenSignRequestData::kHeadersOnly;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
params.additional_headers_to_sign = std::vector<std::string>{"sec-time"};
params.should_add_timestamp = true;
......@@ -558,9 +557,9 @@ TEST_F(TrustTokenRequestSigningHelperTest,
SignAndVerifyWithHeadersAndDestinationUrl) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.sign_request_data = mojom::TrustTokenSignRequestData::kInclude;
SignedTrustTokenRedemptionRecord record;
......@@ -608,10 +607,10 @@ TEST_F(TrustTokenRequestSigningHelperTest,
TEST_F(TrustTokenRequestSigningHelperTest, CatchesSignatureFailure) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateInMemory();
TrustTokenRequestSigningHelper::Params params;
TrustTokenRequestSigningHelper::Params params(
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com")),
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")));
params.sign_request_data = mojom::TrustTokenSignRequestData::kHeadersOnly;
params.issuer = url::Origin::Create(GURL("https://issuer.com"));
params.toplevel = url::Origin::Create(GURL("https://toplevel.com"));
SignedTrustTokenRedemptionRecord my_record;
my_record.set_public_key("key");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment