blob: 374db08265a02c7207c61842229cdc0df1e3d0c8 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_TRUST_TOKENS_TRUST_TOKEN_STORE_H_
#define NET_TRUST_TOKENS_TRUST_TOKEN_STORE_H_
#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "net/trust_tokens/proto/public.pb.h"
#include "net/trust_tokens/trust_token_persister.h"
#include "net/trust_tokens/types.h"
#include "url/origin.h"
namespace net {
// A TrustTokenStore provides operations on persistent state necessary for
// the various steps of the Trust TrustTokens protocol.
//
// For more information about the protocol, see the explainer at
// https://github.com/WICG/trust-token-api.
//
// TrustTokenStore translates operations germane to different steps
// of token issuance, token redemption, and request signing into
// operations in the key-value representation used by the persistence
// layer.
//
// For example, it provides operations:
// - checking preconditions for the different protocol steps;
// - storing unblinded, signed tokens; and
// - managing Signed Redemption Records (SRRs) and corresponding key pairs.
//
// TrustTokenStore's methods do minimal precondition checking and, in
// particular, only selectively verify protocol-level invariants and
// input integrity.
class TrustTokenStore {
public:
class RecordExpiryDelegate {
public:
virtual ~RecordExpiryDelegate() = default;
// Returns whether the given Signed Redemption Record has expired.
// This is implemented with a delegate to abstract away reading
// the values of SRRs (they're opaque to this store).
virtual bool IsRecordExpired(
const SignedTrustTokenRedemptionRecord& record) = 0;
};
// Creates a new TrustTokenStore passing read and write operations through
// to the given persister.
//
// Until the underlying BoringSSL functionality is implemented to extract
// expiry timestamps from Signed Redemption Record bodies, defaults to
// never expiring stored SRRs.
//
// |persister| must not be null.
explicit TrustTokenStore(std::unique_ptr<TrustTokenPersister> persister);
// Creates a TrustTokenStore relying on the given delegate for judging whether
// signed redemption records have expired.
//
// |persister| must not be null.
TrustTokenStore(
std::unique_ptr<TrustTokenPersister> persister,
std::unique_ptr<RecordExpiryDelegate> expiry_delegate_for_testing);
virtual ~TrustTokenStore();
//// Methods related to ratelimits:
// Updates the given issuer's last issuance time to now.
//
// |issuer| must not be opaque.
virtual void RecordIssuance(const url::Origin& issuer);
// Returns the time since the last call to RecordIssuance for
// issuer |issuer|, or nullopt in the following two cases:
// 1. there is no currently-recorded prior issuance for the
// issuer, or
// 2. the time since the last issuance is negative (because
// of, for instance, corruption or clock skew).
//
// |issuer| must not be opaque.
WARN_UNUSED_RESULT virtual base::Optional<base::TimeDelta>
TimeSinceLastIssuance(const url::Origin& issuer);
// Updates the given (issuer, top-level) origin pair's last redemption time
// to now.
//
// |issuer| and |top_level| must not be opaque.
virtual void RecordRedemption(const url::Origin& issuer,
const url::Origin& top_level);
// Returns the time elapsed since the last redemption recorded by
// RecordRedemption for issuer |issuer| and top level |top_level|,
// or nullopt in the following two cases:
// 1. there was no prior redemption for the (issuer,
// top-level origin) pair.
// 2. the time since the last redepmption is negative (because
// of, for instance, corruption or clock skew).
//
// |issuer| and |top_level| must not be opaque.
WARN_UNUSED_RESULT virtual base::Optional<base::TimeDelta>
TimeSinceLastRedemption(const url::Origin& issuer,
const url::Origin& top_level);
// Returns whether |issuer| is associated with |top_level|.
//
// |issuer| and |top_level| must not be opaque.
WARN_UNUSED_RESULT virtual bool IsAssociated(const url::Origin& issuer,
const url::Origin& top_level);
// Associates |issuer| with |top_level|. (It's the caller's responsibility to
// enforce any cap on the number of top levels per issuer.)
//
// |issuer| and |top_level| must not be opaque.
virtual void SetAssociation(const url::Origin& issuer,
const url::Origin& top_level);
//// Methods related to reading and writing issuer values configured via key
//// commitment queries, such as key commitments and batch sizes:
// Returns all stored key commitments (including related metadata:
// see the definition of TrustTokenKeyCommitment) for the given issuer.
//
// |issuer| must not be opaque.
WARN_UNUSED_RESULT virtual std::vector<TrustTokenKeyCommitment>
KeyCommitments(const url::Origin& issuer);
// Sets the key commitments for |issuer| to exactly the keys in |keys|.
// If there is a key in |keys| with the same key() as a key already stored:
// - maintains the "first seen at" time for the key
// - updates the expiry date to the new expiry date, even if it is sooner
// than the previous expiry date
//
// Also prunes all state corresponding to keys *not* in |keys|:
// - removes all stored signed tokens for |issuer| that were signed with
// keys not in |keys|
// - removes all key commitments for |issuer| with keys not in |keys|
//
// It is the client's responsibility to validate the
// reasonableness of the given keys' expiry times. (For instance, one might
// wish to avoid providing keys with expiry times in the past.)
//
// |issuer| must not be opaque, and the commitments in |keys| must have
// distinct keys.
virtual void SetKeyCommitmentsAndPruneStaleState(
const url::Origin& issuer,
base::span<const TrustTokenKeyCommitment> keys);
// Returns the "batch size" (number of blinded tokens to provide per issuance
// request) for the given issuer, if present and greater than 0. Otherwise,
// returns nullopt.
//
// |issuer| must not be opaque.
WARN_UNUSED_RESULT virtual base::Optional<int> BatchSize(
const url::Origin& issuer);
// Sets the given issuer's batch size (see above).
//
// |issuer| must not be opaque; |batch_size| must be at least 1.
virtual void SetBatchSize(const url::Origin& issuer, int batch_size);
//// Methods related to reading and writing signed tokens:
// Associates to the given issuer additional signed
// trust tokens with:
// - token bodies given by |token_bodies|
// - signing keys given by |issuing_key|.
//
// |issuer| must not be opaque and must have a stored
// key commitment corresponding to |issuing_key|.
virtual void AddTokens(const url::Origin& issuer,
base::span<const std::string> token_bodies,
base::StringPiece issuing_key);
// Returns all signed tokens from |issuer| signed by keys matching
// the given predicate.
//
// |issuer| must not be opaque.
WARN_UNUSED_RESULT virtual std::vector<TrustToken> RetrieveMatchingTokens(
const url::Origin& issuer,
base::RepeatingCallback<bool(const std::string&)> key_matcher);
// If |to_delete| is a token issued by |issuer|, deletes the token.
//
// |issuer| must not be opaque.
void DeleteToken(const url::Origin& issuer, const TrustToken& to_delete);
//// Methods concerning Signed Redemption Records (SRRs)
// Sets the cached SRR corresponding to the pair (issuer, top_level)
// to |record|. Overwrites any existing record.
//
// |issuer| and |top_level| must not be opaque.
virtual void SetRedemptionRecord(
const url::Origin& issuer,
const url::Origin& top_level,
const SignedTrustTokenRedemptionRecord& record);
// Attempts to retrieve the stored SRR for the given pair of (issuer,
// top-level) origins.
// - If the pair has a current (i.e., non-expired) SRR, returns that SRR.
// - Otherwise, returns nullopt.
//
// |issuer| and |top_level| must not be opaque.
WARN_UNUSED_RESULT virtual base::Optional<SignedTrustTokenRedemptionRecord>
RetrieveNonstaleRedemptionRecord(const url::Origin& issuer,
const url::Origin& top_level);
private:
std::unique_ptr<TrustTokenPersister> persister_;
std::unique_ptr<RecordExpiryDelegate> record_expiry_delegate_;
};
} // namespace net
#endif // NET_TRUST_TOKENS_TRUST_TOKEN_STORE_H_