File: blind_sign_message_android_impl.h

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (142 lines) | stat: -rw-r--r-- 5,946 bytes parent folder | download | duplicates (7)
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
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_IP_PROTECTION_ANDROID_BLIND_SIGN_MESSAGE_ANDROID_IMPL_H_
#define COMPONENTS_IP_PROTECTION_ANDROID_BLIND_SIGN_MESSAGE_ANDROID_IMPL_H_

#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>

#include "base/containers/queue.h"
#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "components/ip_protection/android/android_auth_client_lib/cpp/ip_protection_auth_client_interface.h"
#include "net/third_party/quiche/src/quiche/blind_sign_auth/blind_sign_message_interface.h"
#include "net/third_party/quiche/src/quiche/blind_sign_auth/proto/auth_and_sign.pb.h"
#include "net/third_party/quiche/src/quiche/blind_sign_auth/proto/get_initial_data.pb.h"

namespace ip_protection {

// Uses the IpProtectionAuthClient to make IPC calls to service implementing IP
// Protection for async requests in BlindSignAuth. DoRequest makes an IPC
// request for either GetInitialData or AuthAndSign and if successful, receives
// a response body which is returned in a BlindSignMessageResponse along with a
// status_code of `absl::StatusCode::kOk`. An AuthRequestError is returned if
// otherwise and is mapped to an `absl::Status`.
//
// AuthRequestError will either be transient, persistent, or other (some failure
// not explicitly communicated by the service). AuthRequestError::kTransient
// maps to absl::Unavailable given that the client can retry the failing call.
// AuthRequestError::kPersistent maps to absl::FailedPreconditionError
// indicating that the request cannot be retried. AuthRequestError::kOther
// is for all other errors that are unexpected and therefore maps to
// absl::Unavailable so the request can be retried with backoff.
//
// See go/canonical-codes for more information on error codes.
class BlindSignMessageAndroidImpl : public quiche::BlindSignMessageInterface {
 public:
  // A request that has been queued, waiting for an internal
  // IpProtectionAuthClient to become ready.
  //
  // Public for testing.
  using PendingRequest = std::tuple<quiche::BlindSignMessageRequestType,
                                    std::string,
                                    quiche::BlindSignMessageCallback>;
  // Factory signature for creating IpProtectionAuthClient(Interface)s.
  //
  // Public for testing.
  using ClientFactory = void(
      base::OnceCallback<ip_protection::android::
                             IpProtectionAuthClientInterface::ClientCreated>);

  BlindSignMessageAndroidImpl();

  ~BlindSignMessageAndroidImpl() override;

  // quiche::BlindSignMessageInterface implementation:
  void DoRequest(quiche::BlindSignMessageRequestType request_type,
                 std::optional<std::string_view> authorization_header,
                 const std::string& body,
                 quiche::BlindSignMessageCallback callback) override;

  // Set the auth client factory to be used when an auth client needs to be
  // created.
  void SetIpProtectionAuthClientFactoryForTesting(
      base::RepeatingCallback<ClientFactory> factory) {
    CHECK(factory);
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    client_factory_ = std::move(factory);
  }

  ip_protection::android::IpProtectionAuthClientInterface*
  GetIpProtectionAuthClientForTesting() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return ip_protection_auth_client_.get();
  }

  const base::queue<PendingRequest>& GetPendingRequestsForTesting() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return pending_requests_;
  }

 private:
  using IpProtectionAuthClientInterface =
      ip_protection::android::IpProtectionAuthClientInterface;

  // Request to bind to the Android IP Protection service by creating a
  // connected instance of `ip_protection_auth_client_`.
  void CreateIpProtectionAuthClient();

  // Makes either a GetInitialDataRequest or AuthAndSignRequest to the signing
  // server using `ip_protection_auth_client_`.
  void SendRequest(quiche::BlindSignMessageRequestType request_type,
                   const std::string& body,
                   quiche::BlindSignMessageCallback callback);

  // Processes queued requests once `ip_protection_auth_client_` becomes
  // available.
  void ProcessPendingRequests();

  void OnCreateIpProtectionAuthClientComplete(
      base::TimeTicks start_time,
      base::expected<std::unique_ptr<IpProtectionAuthClientInterface>,
                     std::string> ip_protection_auth_client);

  template <typename ResponseType>
  void OnSendRequestComplete(
      base::WeakPtr<IpProtectionAuthClientInterface>
          requesting_ip_protection_auth_client,
      quiche::BlindSignMessageCallback callback,
      base::TimeTicks start_time,
      base::expected<ResponseType, ip_protection::android::AuthRequestError>
          response);

  SEQUENCE_CHECKER(sequence_checker_);

  // The factory method for creating an IpProtectionAuthClient(Interface). Can
  // be reconfigured by tests (See SetIpProtectionAuthClientFactoryForTesting).
  // Must not be null.
  base::RepeatingCallback<ClientFactory> client_factory_;

  std::unique_ptr<IpProtectionAuthClientInterface> ip_protection_auth_client_
      GUARDED_BY_CONTEXT(sequence_checker_) = nullptr;

  // Queue of incoming requests waiting for `ip_protection_auth_client_` to
  // connect to the Android IP Protection service. Once an instance is
  // connected, the queue should be empty.
  base::queue<PendingRequest> pending_requests_;

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

}  // namespace ip_protection

#endif  // COMPONENTS_IP_PROTECTION_ANDROID_BLIND_SIGN_MESSAGE_ANDROID_IMPL_H_