File: k_anonymity_trust_token_getter.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (148 lines) | stat: -rw-r--r-- 7,267 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_K_ANONYMITY_SERVICE_K_ANONYMITY_TRUST_TOKEN_GETTER_H_
#define CHROME_BROWSER_K_ANONYMITY_SERVICE_K_ANONYMITY_TRUST_TOKEN_GETTER_H_

#include <memory>
#include <string>

#include "base/containers/circular_deque.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "chrome/browser/k_anonymity_service/k_anonymity_service_storage.h"
#include "components/signin/public/identity_manager/access_token_info.h"
#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "net/base/isolation_info.h"
#include "net/http/http_response_headers.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/trust_tokens.mojom.h"

namespace network {
class SimpleURLLoader;
}  // namespace network

// This class performs the series of requests necessary to get a trust token
// from the Google K-anonymity server using hard-coded URLs. The trust token is
// stored by the network service, while the non-unique user ID and trust token
// key commitment are provided to the class's caller. The steps of this are:
// 1. Get an OAuth token with the K-anonymity service scope.
// 2. Request a non-unique user ID (short ID) from the k-anonymity auth server.
//    This requires the OAuth token for authentication.
// 3. Request the trust token key commitment corresponding to the short bucket
//    ID. Note that the receiver responds in a non-standard format that the
//    browser converts internally.
// 4. Request the trust token. This requires the OAuth token for authentication.
//
// The short ID and the trust token key commitment expire once every 24 hours.
// The trust token will be good until it is used or the key that created
// expires.
class KAnonymityTrustTokenGetter {
 public:
  // Callback where argument tells if the client has the trust token or not.
  using TryGetTrustTokenAndKeyCallback =
      base::OnceCallback<void(std::optional<KeyAndNonUniqueUserId>)>;

  // `identity_manager` and `answerer` must outlive the current instance
  KAnonymityTrustTokenGetter(
      signin::IdentityManager* identity_manager,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
      network::mojom::TrustTokenQueryAnswerer* answerer,
      KAnonymityServiceStorage* storage);

  ~KAnonymityTrustTokenGetter();

  // Check if we have a trust token and key commitment ready for use. If not,
  // tries to request the trust token and key commitment. The trust token will
  // be stored in the network service, while the key commitment and non-unique
  // user ID are cached. Calls the callback with the key commitment and
  // non-uniform user ID if successful and std::nullopt if not successful.
  // Calls to this function are serialized through the `pending_callbacks_`
  // queue to avoid making redundant requests -- since most of the request
  // results can be cached and reused. Since this function may need to get an
  // OAuth token, it needs to only be called from the browser UI thread. To
  // minimize the risk of a racing thread using the trust token the callback
  // should immediately initiate the request that uses the trust token.
  void TryGetTrustTokenAndKey(TryGetTrustTokenAndKeyCallback callback);

 private:
  struct PendingRequest {
    explicit PendingRequest(TryGetTrustTokenAndKeyCallback callback);
    ~PendingRequest();
    PendingRequest(PendingRequest&&) noexcept;
    PendingRequest& operator=(PendingRequest&&) noexcept;
    base::TimeTicks request_start;
    TryGetTrustTokenAndKeyCallback callback;
  };
  // Entry point for processing the request on the front of the queue.
  void TryGetTrustTokenAndKeyInternal();

  // Checks if `this` already has a cached non-expired token, if not try to get
  // the access token.
  void CheckAccessToken();
  // Calls the IdentityManager asynchronously to request the access token.
  void RequestAccessToken();
  // Gets the access token and caches the result.
  void OnAccessTokenRequestCompleted(GoogleServiceAuthError error,
                                     signin::AccessTokenInfo access_token_info);

  // Checks if `this` already has a cached non-expired key commitment, if not
  // triggers getting the non-unique user ID and key commitment.
  void CheckTrustTokenKeyCommitment();
  // Starts the HTTP request for the non-unique user ID.
  void FetchNonUniqueUserId();
  // Passes the non-unique user ID response body to the JSON parser.
  void OnFetchedNonUniqueUserId(std::unique_ptr<std::string> response);
  // Extracts the non-unique user ID from the decoded JSON and triggers fetching
  // the key commitment.
  void OnParsedNonUniqueUserId(data_decoder::DataDecoder::ValueOrError result);
  // Starts the HTTP request for the trust token key commitment.
  void FetchTrustTokenKeyCommitment(int non_unique_user_id);
  // Passes the trust token key commitment response body to the JSON parser.
  void OnFetchedTrustTokenKeyCommitment(int non_unique_user_id,
                                        std::unique_ptr<std::string> response);
  // Extracts the trust token key commitment from the custom response structure
  // provided by the Google k-anonymity server and reformats it into the V3
  // trust token key commitment format expected by the network service.
  void OnParsedTrustTokenKeyCommitment(
      int non_unique_user_id,
      data_decoder::DataDecoder::ValueOrError result);

  // Asynchronously queries the network service to see if there is at least one
  // trust token.
  void CheckTrustTokens();
  // Triggers fetching a trust token if we don't have one.
  void OnHasTrustTokensComplete(network::mojom::HasTrustTokensResultPtr result);
  // Starts the HTTP request to fetch the trust token.
  void FetchTrustToken();
  // Completes the request if the trust token was fetched successfully.
  void OnFetchedTrustToken(scoped_refptr<net::HttpResponseHeaders> headers);

  // Calls the callbacks for all queued requests indicating failure.
  void FailAllCallbacks();
  // Calls the callback for the front request in the queue indicating success.
  void CompleteOneRequest();
  // Calls the callback for the request indicating the provided status.
  void DoCallback(bool status);

  signin::AccessTokenInfo access_token_;
  base::circular_deque<PendingRequest> pending_callbacks_;

  raw_ptr<signin::IdentityManager> identity_manager_;
  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
  std::unique_ptr<network::SimpleURLLoader> url_loader_;
  raw_ptr<network::mojom::TrustTokenQueryAnswerer> trust_token_query_answerer_;
  raw_ptr<KAnonymityServiceStorage> storage_;
  net::IsolationInfo isolation_info_;
  std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher>
      access_token_fetcher_;
  url::Origin auth_origin_;

  base::WeakPtrFactory<KAnonymityTrustTokenGetter> weak_ptr_factory_{this};
};

#endif  // CHROME_BROWSER_K_ANONYMITY_SERVICE_K_ANONYMITY_TRUST_TOKEN_GETTER_H_