1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROMEOS_DBUS_ATTESTATION_ATTESTATION_CLIENT_H_
6 #define CHROMEOS_DBUS_ATTESTATION_ATTESTATION_CLIENT_H_
7 
8 #include <deque>
9 #include <vector>
10 
11 #include "base/callback.h"
12 #include "base/component_export.h"
13 #include "base/time/time.h"
14 #include "chromeos/dbus/attestation/interface.pb.h"
15 
16 namespace dbus {
17 class Bus;
18 }
19 
20 namespace chromeos {
21 
22 // AttestationClient is used to communicate with the org.chromium.Attestation
23 // service. All method should be called from the origin thread (UI thread) which
24 // initializes the DBusThreadManager instance.
COMPONENT_EXPORT(CHROMEOS_DBUS_ATTESTATION)25 class COMPONENT_EXPORT(CHROMEOS_DBUS_ATTESTATION) AttestationClient {
26  public:
27   using GetKeyInfoCallback =
28       base::OnceCallback<void(const ::attestation::GetKeyInfoReply&)>;
29   using GetEndorsementInfoCallback =
30       base::OnceCallback<void(const ::attestation::GetEndorsementInfoReply&)>;
31   using GetAttestationKeyInfoCallback = base::OnceCallback<void(
32       const ::attestation::GetAttestationKeyInfoReply&)>;
33   using ActivateAttestationKeyCallback = base::OnceCallback<void(
34       const ::attestation::ActivateAttestationKeyReply&)>;
35   using CreateCertifiableKeyCallback =
36       base::OnceCallback<void(const ::attestation::CreateCertifiableKeyReply&)>;
37   using DecryptCallback =
38       base::OnceCallback<void(const ::attestation::DecryptReply&)>;
39   using SignCallback =
40       base::OnceCallback<void(const ::attestation::SignReply&)>;
41   using RegisterKeyWithChapsTokenCallback = base::OnceCallback<void(
42       const ::attestation::RegisterKeyWithChapsTokenReply&)>;
43   using GetEnrollmentPreparationsCallback = base::OnceCallback<void(
44       const ::attestation::GetEnrollmentPreparationsReply&)>;
45   using GetStatusCallback =
46       base::OnceCallback<void(const ::attestation::GetStatusReply&)>;
47   using VerifyCallback =
48       base::OnceCallback<void(const ::attestation::VerifyReply&)>;
49   using CreateEnrollRequestCallback =
50       base::OnceCallback<void(const ::attestation::CreateEnrollRequestReply&)>;
51   using FinishEnrollCallback =
52       base::OnceCallback<void(const ::attestation::FinishEnrollReply&)>;
53   using CreateCertificateRequestCallback = base::OnceCallback<void(
54       const ::attestation::CreateCertificateRequestReply&)>;
55   using FinishCertificateRequestCallback = base::OnceCallback<void(
56       const ::attestation::FinishCertificateRequestReply&)>;
57   using EnrollCallback =
58       base::OnceCallback<void(const ::attestation::EnrollReply&)>;
59   using GetCertificateCallback =
60       base::OnceCallback<void(const ::attestation::GetCertificateReply&)>;
61   using SignEnterpriseChallengeCallback = base::OnceCallback<void(
62       const ::attestation::SignEnterpriseChallengeReply&)>;
63   using SignSimpleChallengeCallback =
64       base::OnceCallback<void(const ::attestation::SignSimpleChallengeReply&)>;
65   using SetKeyPayloadCallback =
66       base::OnceCallback<void(const ::attestation::SetKeyPayloadReply&)>;
67   using DeleteKeysCallback =
68       base::OnceCallback<void(const ::attestation::DeleteKeysReply&)>;
69   using ResetIdentityCallback =
70       base::OnceCallback<void(const ::attestation::ResetIdentityReply&)>;
71   using GetEnrollmentIdCallback =
72       base::OnceCallback<void(const ::attestation::GetEnrollmentIdReply&)>;
73   using GetCertifiedNvIndexCallback =
74       base::OnceCallback<void(const ::attestation::GetCertifiedNvIndexReply&)>;
75 
76   // Interface with testing functionality. Accessed through GetTestInterface(),
77   // only implemented in the fake implementation.
78   class TestInterface {
79    public:
80     // Sets the preparation status to |is_prepared|. If no injected sequence by
81     // |ConfigureEnrollmentPreparationsSequence| the enrollment preparations
82     // always returns |is_prepared|.
83     virtual void ConfigureEnrollmentPreparations(bool is_prepared) = 0;
84     // Injects |sequence| of enrollment preparations. Once injected, the
85     // returned enrollment preparations status will be the element popped from
86     // the |sequence| one-by-one until all the elements are consumed.
87     virtual void ConfigureEnrollmentPreparationsSequence(
88         std::deque<bool> sequence) = 0;
89     // Injects a bad status to `GetEnrollmentPreparations()` calls. By design,
90     // this only accepts bad status so |STATUS_SUCCESS| is seen as an illegal
91     // input and abort the program. To recover the fake behavior to successful
92     // calls, call ConfigureEnrollmentPreparations(Sequence)?.
93     virtual void ConfigureEnrollmentPreparationsStatus(
94         ::attestation::AttestationStatus status) = 0;
95 
96     // Gets the mutable |GetStatusReply| that is returned when queried.
97     virtual ::attestation::GetStatusReply* mutable_status_reply() = 0;
98 
99     // Allowlists |request| so the certificate requests that comes in afterwards
100     // will get a fake certificate. If any alias of |request| has been
101     // allowlisted this functions performs no-ops.
102     virtual void AllowlistCertificateRequest(
103         const ::attestation::GetCertificateRequest& request) = 0;
104 
105     // Gets the history of `DeleteKeys()` requests.
106     virtual const std::vector<::attestation::DeleteKeysRequest>&
107     delete_keys_history() const = 0;
108 
109     // Clears the request history of `DeleteKeys()`.
110     virtual void ClearDeleteKeysHistory() = 0;
111 
112     // Sets returned enrollment ids, when ignoring/not ignoring cache,
113     // respectively.
114     virtual void set_enrollment_id_ignore_cache(const std::string& id) = 0;
115     virtual void set_cached_enrollment_id(const std::string& id) = 0;
116     // Sets the returned status of `GetEnrollmentId()` to be D-Bus error for
117     // `count` times to emulate D-Bus late availability.
118     virtual void set_enrollment_id_dbus_error_count(int count) = 0;
119 
120     // Gets the reply to the key info query as a fake database.
121     virtual ::attestation::GetKeyInfoReply* GetMutableKeyInfoReply(
122         const std::string& username,
123         const std::string& label) = 0;
124     // Sets the returned status of `GetKeyInfo()` to be D-Bus error for
125     // `count` times to emulate D-Bus late availability.
126     virtual void set_key_info_dbus_error_count(int count) = 0;
127     // Gets the remaining count of `GetKeyInfo()` replying D-Bus error.
128     virtual int key_info_dbus_error_count() const = 0;
129 
130     // Verifies if `signed_data` is signed against `challenge`.
131     virtual bool VerifySimpleChallengeResponse(
132         const std::string& challenge,
133         const ::attestation::SignedData& signed_data) = 0;
134 
135     // Sets the status code returned by `SignSimpleChallenge()`.
136     virtual void set_sign_simple_challenge_status(
137         ::attestation::AttestationStatus status) = 0;
138     // Allowlists the key used to sign simple challenge.
139     virtual void AllowlistSignSimpleChallengeKey(const std::string& username,
140                                                  const std::string& label) = 0;
141 
142     // Sets the status code returned by `RegisterKeyWithChapsToken()`.
143     virtual void set_register_key_status(
144         ::attestation::AttestationStatus status) = 0;
145     // Allowlists the key allowed to be registered to the key store.
146     virtual void AllowlistRegisterKey(const std::string& username,
147                                       const std::string& label) = 0;
148 
149     // Sets the status code returned by `SignEnterpriseChallenge()`.
150     virtual void set_sign_enterprise_challenge_status(
151         ::attestation::AttestationStatus status) = 0;
152     // Allowlists the key used to sign enterprise challenge. Note that
153     // `include_signed_public_key` and `challenge` are ignored for key
154     // comparison because they are are part of the key but the inputs for
155     // signature generation.
156     virtual void AllowlistSignEnterpriseChallengeKey(
157         const ::attestation::SignEnterpriseChallengeRequest& request) = 0;
158     // Signs the enterprise `challenge` with this class the same way the
159     // enterprise challenge is signed.
160     virtual std::string GetEnterpriseChallengeFakeSignature(
161         const std::string& challenge,
162         bool include_spkac) const = 0;
163     // Sets the delay to the time we reply to `SignEnterpriseChallenge()`.
164     virtual void set_sign_enterprise_challenge_delay(
165         const base::TimeDelta& delay) = 0;
166 
167     // Sets the status code returned by `CreateEnrollRequestRequest()`.
168     virtual void set_enroll_request_status(
169         ::attestation::AttestationStatus status) = 0;
170     // Gets the fake enroll request when the status is configured to be good.
171     virtual std::string GetFakePcaEnrollRequest() const = 0;
172     // Gets the fake enroll response that is accepted by `FinishEnroll()`.
173     virtual std::string GetFakePcaEnrollResponse() const = 0;
174 
175     // Allowlists the request that has `username`, `request_origin`, `profile`,
176     // and `key_type`, so the certificate requests that comes in afterwards will
177     // be successfully created.
178     virtual void AllowlistLegacyCreateCertificateRequest(
179         const std::string& username,
180         const std::string& request_origin,
181         ::attestation::CertificateProfile profile,
182         ::attestation::KeyType key_type) = 0;
183     // Sets the status code returned by `CreateCertificateRequest()`.
184     virtual void set_cert_request_status(
185         ::attestation::AttestationStatus status) = 0;
186     // Gets the fake certificate request when the status is configured to be
187     // good.
188     virtual std::string GetFakePcaCertRequest() const = 0;
189     // Gets the fake enroll response that is accepted by
190     // `FinishCertificateRequest()`.
191     virtual std::string GetFakePcaCertResponse() const = 0;
192     // Gets the fake certificate that is returned by
193     // successful `FinishCertificateRequest()`.
194     virtual std::string GetFakeCertificate() const = 0;
195   };
196 
197   // Not copyable or movable.
198   AttestationClient(const AttestationClient&) = delete;
199   AttestationClient& operator=(const AttestationClient&) = delete;
200   AttestationClient(AttestationClient&&) = delete;
201   AttestationClient& operator=(AttestationClient&&) = delete;
202 
203   // Creates and initializes the global instance. |bus| must not be null.
204   static void Initialize(dbus::Bus* bus);
205 
206   // Creates and initializes a fake global instance if not already created.
207   static void InitializeFake();
208 
209   // Destroys the global instance.
210   static void Shutdown();
211 
212   // Returns the global instance which may be null if not initialized.
213   static AttestationClient* Get();
214 
215   // Checks if |reply| indicates the attestation service is prepared with any
216   // ACA.
217   static bool IsAttestationPrepared(
218       const ::attestation::GetEnrollmentPreparationsReply& reply);
219 
220   // Gets the verified access server type from command-line arguments.
221   static ::attestation::VAType GetVerifiedAccessServerType();
222 
223   // Attestation daemon D-Bus method calls. See org.chromium.Attestation.xml and
224   // the corresponding protobuf definitions in Chromium OS code for the
225   // documentation of the methods and request/ messages.
226 
227   virtual void GetKeyInfo(const ::attestation::GetKeyInfoRequest& request,
228                           GetKeyInfoCallback callback) = 0;
229 
230   virtual void GetEndorsementInfo(
231       const ::attestation::GetEndorsementInfoRequest& request,
232       GetEndorsementInfoCallback callback) = 0;
233 
234   virtual void GetAttestationKeyInfo(
235       const ::attestation::GetAttestationKeyInfoRequest& request,
236       GetAttestationKeyInfoCallback callback) = 0;
237 
238   virtual void ActivateAttestationKey(
239       const ::attestation::ActivateAttestationKeyRequest& request,
240       ActivateAttestationKeyCallback callback) = 0;
241 
242   virtual void CreateCertifiableKey(
243       const ::attestation::CreateCertifiableKeyRequest& request,
244       CreateCertifiableKeyCallback callback) = 0;
245 
246   virtual void Decrypt(const ::attestation::DecryptRequest& request,
247                        DecryptCallback callback) = 0;
248 
249   virtual void Sign(const ::attestation::SignRequest& request,
250                     SignCallback callback) = 0;
251 
252   virtual void RegisterKeyWithChapsToken(
253       const ::attestation::RegisterKeyWithChapsTokenRequest& request,
254       RegisterKeyWithChapsTokenCallback callback) = 0;
255 
256   virtual void GetEnrollmentPreparations(
257       const ::attestation::GetEnrollmentPreparationsRequest& request,
258       GetEnrollmentPreparationsCallback callback) = 0;
259 
260   virtual void GetStatus(const ::attestation::GetStatusRequest& request,
261                          GetStatusCallback callback) = 0;
262 
263   virtual void Verify(const ::attestation::VerifyRequest& request,
264                       VerifyCallback callback) = 0;
265 
266   virtual void CreateEnrollRequest(
267       const ::attestation::CreateEnrollRequestRequest& request,
268       CreateEnrollRequestCallback callback) = 0;
269 
270   virtual void FinishEnroll(const ::attestation::FinishEnrollRequest& request,
271                             FinishEnrollCallback callback) = 0;
272 
273   virtual void CreateCertificateRequest(
274       const ::attestation::CreateCertificateRequestRequest& request,
275       CreateCertificateRequestCallback callback) = 0;
276 
277   virtual void FinishCertificateRequest(
278       const ::attestation::FinishCertificateRequestRequest& request,
279       FinishCertificateRequestCallback callback) = 0;
280 
281   virtual void Enroll(const ::attestation::EnrollRequest& request,
282                       EnrollCallback callback) = 0;
283 
284   virtual void GetCertificate(
285       const ::attestation::GetCertificateRequest& request,
286       GetCertificateCallback callback) = 0;
287 
288   virtual void SignEnterpriseChallenge(
289       const ::attestation::SignEnterpriseChallengeRequest& request,
290       SignEnterpriseChallengeCallback callback) = 0;
291 
292   virtual void SignSimpleChallenge(
293       const ::attestation::SignSimpleChallengeRequest& request,
294       SignSimpleChallengeCallback callback) = 0;
295 
296   virtual void SetKeyPayload(const ::attestation::SetKeyPayloadRequest& request,
297                              SetKeyPayloadCallback callback) = 0;
298 
299   virtual void DeleteKeys(const ::attestation::DeleteKeysRequest& request,
300                           DeleteKeysCallback callback) = 0;
301 
302   virtual void ResetIdentity(const ::attestation::ResetIdentityRequest& request,
303                              ResetIdentityCallback callback) = 0;
304 
305   virtual void GetEnrollmentId(
306       const ::attestation::GetEnrollmentIdRequest& request,
307       GetEnrollmentIdCallback callback) = 0;
308 
309   virtual void GetCertifiedNvIndex(
310       const ::attestation::GetCertifiedNvIndexRequest& request,
311       GetCertifiedNvIndexCallback callback) = 0;
312 
313   // Returns an interface for testing (fake only), or returns nullptr.
314   virtual TestInterface* GetTestInterface() = 0;
315 
316  protected:
317   // Initialize/Shutdown should be used instead.
318   AttestationClient();
319   virtual ~AttestationClient();
320 };
321 
322 }  // namespace chromeos
323 
324 #endif  // CHROMEOS_DBUS_ATTESTATION_ATTESTATION_CLIENT_H_
325