1 // Copyright (c) 2012 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_ATTESTATION_ATTESTATION_FLOW_H_
6 #define CHROMEOS_ATTESTATION_ATTESTATION_FLOW_H_
7
8 #include <memory>
9 #include <string>
10
11 #include "base/callback_forward.h"
12 #include "base/component_export.h"
13 #include "base/macros.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/time/time.h"
16 #include "base/timer/timer.h"
17 #include "chromeos/dbus/attestation/interface.pb.h"
18 #include "chromeos/dbus/constants/attestation_constants.h"
19 #include "chromeos/dbus/dbus_method_call_status.h"
20 #include "third_party/cros_system_api/dbus/service_constants.h"
21
22 class AccountId;
23
24 namespace chromeos {
25
26 class AttestationClient;
27
28 namespace attestation {
29
30 // Interface for access to the Privacy CA server.
COMPONENT_EXPORT(CHROMEOS_ATTESTATION)31 class COMPONENT_EXPORT(CHROMEOS_ATTESTATION) ServerProxy {
32 public:
33 using DataCallback =
34 base::OnceCallback<void(bool success, const std::string& data)>;
35 virtual ~ServerProxy();
36 virtual void SendEnrollRequest(const std::string& request,
37 DataCallback on_response) = 0;
38 virtual void SendCertificateRequest(const std::string& request,
39 DataCallback on_response) = 0;
40 virtual PrivacyCAType GetType();
41 };
42
43 // Implements the message flow for Chrome OS attestation tasks. Generally this
44 // consists of coordinating messages between the Chrome OS attestation service
45 // and the Chrome OS Privacy CA server. Sample usage:
46 //
47 // AttestationFlow flow(std::move(my_server_proxy));
48 // AttestationFlow::CertificateCallback callback = base::Bind(&MyCallback);
49 // flow.GetCertificate(ENTERPRISE_USER_CERTIFICATE, false, callback);
50 //
51 // This class is not thread safe.
COMPONENT_EXPORT(CHROMEOS_ATTESTATION)52 class COMPONENT_EXPORT(CHROMEOS_ATTESTATION) AttestationFlow {
53 public:
54 using CertificateCallback =
55 base::OnceCallback<void(AttestationStatus status,
56 const std::string& pem_certificate_chain)>;
57
58 // Returns the attestation key type for a given |certificate_profile|.
59 //
60 // Parameters
61 // certificate_profile - Specifies what kind of certificate the key is for.
62 static AttestationKeyType GetKeyTypeForProfile(
63 AttestationCertificateProfile certificate_profile);
64
65 explicit AttestationFlow(std::unique_ptr<ServerProxy> server_proxy);
66 AttestationFlow(std::unique_ptr<ServerProxy> server_proxy,
67 ::attestation::KeyType crypto_key_type);
68
69 virtual ~AttestationFlow();
70
71 // Sets the timeout for attestation to be ready.
72 void set_ready_timeout(base::TimeDelta ready_timeout) {
73 ready_timeout_ = ready_timeout;
74 }
75 // Gets the timeout for attestation to be ready.
76 base::TimeDelta ready_timeout() const { return ready_timeout_; }
77
78 // Sets the retry delay.
79 void set_retry_delay(base::TimeDelta retry_delay) {
80 retry_delay_ = retry_delay;
81 }
82
83 // Returns the retry delay.
84 base::TimeDelta retry_delay() { return retry_delay_; }
85
86 // Gets an attestation certificate for a hardware-protected key. If a key for
87 // the given profile does not exist, it will be generated and a certificate
88 // request will be made to the Chrome OS Privacy CA to issue a certificate for
89 // the key. If the key already exists and |force_new_key| is false, the
90 // existing certificate is returned.
91 //
92 // Parameters
93 // certificate_profile - Specifies what kind of certificate should be
94 // requested from the CA.
95 // account_id - Identifies the currently active user. This is ignored when
96 // using the enterprise machine cert profile.
97 // request_origin - For content protection profiles, certificate requests
98 // are origin-specific. This string must uniquely identify
99 // the origin of the request.
100 // force_new_key - If set to true, a new key will be generated even if a key
101 // already exists for the profile. The new key will replace
102 // the existing key on success.
103 // key_name - The name of the key. If left empty, a default name derived
104 // from the |certificate_profile| and |account_id| will be used.
105 // callback - A callback which will be called when the operation completes.
106 // On success |result| will be true and |data| will contain the
107 // PCA-issued certificate chain in PEM format.
108 virtual void GetCertificate(AttestationCertificateProfile certificate_profile,
109 const AccountId& account_id,
110 const std::string& request_origin,
111 bool force_new_key,
112 const std::string& key_name,
113 CertificateCallback callback);
114
115 private:
116 // Handles the result of a call to `GetStatus()` for enrollment status.
117 // Reports success if enrollment is complete and otherwise starts the process.
118 //
119 // Parameters
120 // callback - Called with the success or failure of the enrollment.
121 // result - Result of `GetStatus()`, which contains `enrolled` field.
122 void OnEnrollmentCheckComplete(base::OnceCallback<void(bool)> callback,
123 const ::attestation::GetStatusReply& reply);
124
125 // Asynchronously waits for attestation to be ready and start enrollment once
126 // it is. If attestation is not ready by the time the flow's timeout is
127 // reached, fail.
128 //
129 // Parameters
130 // end_time - Time after which preparation should time out.
131 // callback - Called with the success or failure of the enrollment.
132 void WaitForAttestationPrepared(base::TimeTicks end_time,
133 base::OnceCallback<void(bool)> callback);
134
135 // Handles the result of a call to GetEnrollmentPreparations. Starts
136 // enrollment on success and retries after |retry_delay_| if not.
137 //
138 // Parameters
139 // end_time - Time after which preparation should time out.
140 // callback - Called with the success or failure of the enrollment.
141 // reply - Reply from the attestation service.
142 void OnPreparedCheckComplete(
143 base::TimeTicks end_time,
144 base::OnceCallback<void(bool)> callback,
145 const ::attestation::GetEnrollmentPreparationsReply& reply);
146
147 // Called when the attestation daemon has finished creating an enrollment
148 // request for the Privacy CA. The request is asynchronously forwarded as-is
149 // to the PCA.
150 //
151 // Parameters
152 // callback - Called with the success or failure of the enrollment.
153 // reply - The reply of `CreateEnrollRequest()`.
154 void SendEnrollRequestToPCA(
155 base::OnceCallback<void(bool)> callback,
156 const ::attestation::CreateEnrollRequestReply& reply);
157
158 // Called when the Privacy CA responds to an enrollment request. The response
159 // is asynchronously forwarded as-is to the attestation daemon in order to
160 // complete the enrollment operation.
161 //
162 // Parameters
163 // callback - Called with the success or failure of the enrollment.
164 // success - The status of the Privacy CA operation.
165 // data - The response data from the Privacy CA.
166 void SendEnrollResponseToDaemon(base::OnceCallback<void(bool)> callback,
167 bool success,
168 const std::string& data);
169
170 // Called when the attestation daemon completes an enrollment operation. If
171 // the operation was successful, the next_task callback is called.
172 //
173 // Parameters
174 // callback - Called with the success or failure of the enrollment.
175 // reply - The reply of `FinishEnroll()`.
176 void OnEnrollComplete(base::OnceCallback<void(bool)> callback,
177 const ::attestation::FinishEnrollReply& reply);
178
179 // Asynchronously initiates the certificate request flow. Attestation
180 // enrollment must complete successfully before this operation can succeed.
181 //
182 // Parameters
183 // certificate_profile - Specifies what kind of certificate should be
184 // requested from the CA.
185 // account_id - Identifies the active user.
186 // request_origin - An identifier for the origin of this request.
187 // generate_new_key - If set to true a new key is generated.
188 // key_name - The name of the key. If left empty, a default name derived
189 // from the |certificate_profile| and |account_id| will be used.
190 // callback - Called when the operation completes.
191 // enrolled - Success or failure of the enrollment phase.
192 void StartCertificateRequest(
193 const AttestationCertificateProfile certificate_profile,
194 const AccountId& account_id,
195 const std::string& request_origin,
196 bool generate_new_key,
197 const std::string& key_name,
198 CertificateCallback callback,
199 bool enrolled);
200
201 // Called with the reply to `GetKeyInfo()`. Will query the existing
202 // certificate if it exists and otherwise start a new certificate request.
203 //
204 // Parameters
205 // certificate_profile - Specifies what kind of certificate should be
206 // requested from the CA.
207 // account_id - Identifies the active user.
208 // request_origin - An identifier for the origin of this request.
209 // generate_new_key - If set to true a new key is generated.
210 // key_name - The name of the key. If left empty, a default name derived
211 // from the |certificate_profile| and |account_id| will be used.
212 // callback - Called when the operation completes.
213 // reply - The reply of `GetKeyInfo()`.
214 void OnGetKeyInfoComplete(AttestationCertificateProfile certificate_profile,
215 const AccountId& account_id,
216 const std::string& request_origin,
217 const std::string& key_name,
218 AttestationKeyType key_type,
219 CertificateCallback callback,
220 const ::attestation::GetKeyInfoReply& reply);
221
222 // Called when the attestation daemon has finished creating a certificate
223 // request for the Privacy CA. The request is asynchronously forwarded as-is
224 // to the PCA.
225 //
226 // Parameters
227 // key_type - The type of the key for which a certificate is requested.
228 // account_id - Identifies the active user.
229 // key_name - The name of the key for which a certificate is requested.
230 // callback - Called when the operation completes.
231 // reply - the result returned by |AttestationClient|.
232 void SendCertificateRequestToPCA(
233 AttestationKeyType key_type,
234 const AccountId& account_id,
235 const std::string& key_name,
236 CertificateCallback callback,
237 const ::attestation::CreateCertificateRequestReply& reply);
238
239 // Called when the Privacy CA responds to a certificate request. The response
240 // is asynchronously forwarded as-is to the attestation daemon in order to
241 // complete the operation.
242 //
243 // Parameters
244 // key_type - The type of the key for which a certificate is requested.
245 // account_id - Identifies the active user.
246 // key_name - The name of the key for which a certificate is requested.
247 // callback - Called when the operation completes.
248 // success - The status of the Privacy CA operation.
249 // data - The response data from the Privacy CA.
250 void SendCertificateResponseToDaemon(AttestationKeyType key_type,
251 const AccountId& account_id,
252 const std::string& key_name,
253 CertificateCallback callback,
254 bool success,
255 const std::string& data);
256
257 // Called after attestation service finishes processing of a certificate
258 // request.
259 //
260 // Parameters
261 // callback - Called when the operation completes.
262 // reply - The reply of `FinishCertificateRequest()`.
263 void OnCertRequestFinished(
264 CertificateCallback callback,
265 const ::attestation::FinishCertificateRequestReply& reply);
266
267 AttestationClient* attestation_client_;
268 std::unique_ptr<ServerProxy> server_proxy_;
269
270 // The key type that asks attestation service to create with.
271 const ::attestation::KeyType crypto_key_type_;
272
273 base::TimeDelta ready_timeout_;
274 base::TimeDelta retry_delay_;
275
276 base::WeakPtrFactory<AttestationFlow> weak_factory_{this};
277
278 DISALLOW_COPY_AND_ASSIGN(AttestationFlow);
279 };
280
281 } // namespace attestation
282 } // namespace chromeos
283
284 #endif // CHROMEOS_ATTESTATION_ATTESTATION_FLOW_H_
285