Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(446)

Side by Side Diff: chrome/browser/chromeos/attestation/platform_verification_flow.h

Issue 50093002: Added a timeout for platform verification key generation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_ 5 #ifndef CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_
6 #define CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_ 6 #define CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_
7 7
8 #include <string> 8 #include <string>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "url/gurl.h" 14 #include "url/gurl.h"
15 15
16 class PrefService; 16 class PrefService;
17 17
18 namespace content { 18 namespace content {
19 class WebContents; 19 class WebContents;
20 } 20 }
21 21
22 namespace cryptohome { 22 namespace cryptohome {
23 class AsyncMethodCaller; 23 class AsyncMethodCaller;
24 } 24 }
25 25
26 namespace user_prefs { 26 namespace user_prefs {
27 class PrefRegistrySyncable; 27 class PrefRegistrySyncable;
28 } 28 }
29 29
30 namespace chromeos { 30 namespace chromeos {
31 31
32 class CryptohomeClient; 32 class CryptohomeClient;
33 class UserManager; 33 class UserManager;
34 class User; 34 class User;
35 35
36 namespace attestation { 36 namespace attestation {
37 37
38 class AttestationFlow; 38 class AttestationFlow;
39 39
40 // This class allows platform verification for the content protection use case. 40 // This class allows platform verification for the content protection use case.
41 // All methods must only be called on the UI thread. Example: 41 // All methods must only be called on the UI thread. Example:
42 // PlatformVerificationFlow verifier; 42 // scoped_refptr<PlatformVerificationFlow> verifier =
43 // new PlatformVerificationFlow();
43 // PlatformVerificationFlow::Callback callback = base::Bind(&MyCallback); 44 // PlatformVerificationFlow::Callback callback = base::Bind(&MyCallback);
44 // verifier.ChallengePlatformKey(my_web_contents, "my_id", "some_challenge", 45 // verifier->ChallengePlatformKey(my_web_contents, "my_id", "some_challenge",
45 // callback); 46 // callback);
46 class PlatformVerificationFlow { 47 //
48 // This class is RefCountedThreadSafe because it may need to outlive its caller.
49 // The attestation flow that needs to happen to establish a certified platform
50 // key may take minutes on some hardware. This class will timeout after a much
51 // shorter time so the caller can proceed without platform verification but it
52 // is important that the pending operation be allowed to finish. If the
53 // attestation flow is aborted at any stage, it will need to start over. If we
54 // use weak pointers, the attestation flow will stop when the next callback is
55 // run. So we need the instance to stay alive until the platform key is fully
56 // certified so the next time ChallegePlatformKey() is invoked it will be quick.
57 class PlatformVerificationFlow
58 : public base::RefCountedThreadSafe<PlatformVerificationFlow> {
47 public: 59 public:
48 enum Result { 60 enum Result {
49 SUCCESS, // The operation succeeded. 61 SUCCESS, // The operation succeeded.
50 INTERNAL_ERROR, // The operation failed unexpectedly. 62 INTERNAL_ERROR, // The operation failed unexpectedly.
51 PLATFORM_NOT_VERIFIED, // The platform cannot be verified. For example: 63 PLATFORM_NOT_VERIFIED, // The platform cannot be verified. For example:
52 // - It is not a Chrome device. 64 // - It is not a Chrome device.
53 // - It is not running a verified OS image. 65 // - It is not running a verified OS image.
54 USER_REJECTED, // The user explicitly rejected the operation. 66 USER_REJECTED, // The user explicitly rejected the operation.
55 POLICY_REJECTED, // The operation is not allowed by policy/settings. 67 POLICY_REJECTED, // The operation is not allowed by policy/settings.
68 TIMEOUT, // The operation timed out.
56 }; 69 };
57 70
58 enum ConsentType { 71 enum ConsentType {
59 CONSENT_TYPE_NONE, // No consent necessary. 72 CONSENT_TYPE_NONE, // No consent necessary.
60 CONSENT_TYPE_ATTESTATION, // Consent to use attestation. 73 CONSENT_TYPE_ATTESTATION, // Consent to use attestation.
61 CONSENT_TYPE_ALWAYS, // Consent because 'Always Ask' was requested. 74 CONSENT_TYPE_ALWAYS, // Consent because 'Always Ask' was requested.
62 }; 75 };
63 76
64 enum ConsentResponse { 77 enum ConsentResponse {
65 CONSENT_RESPONSE_NONE, 78 CONSENT_RESPONSE_NONE,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 PlatformVerificationFlow(); 117 PlatformVerificationFlow();
105 118
106 // An alternate constructor which specifies dependent objects explicitly. 119 // An alternate constructor which specifies dependent objects explicitly.
107 // This is useful in testing. The caller retains ownership of all pointers. 120 // This is useful in testing. The caller retains ownership of all pointers.
108 PlatformVerificationFlow(AttestationFlow* attestation_flow, 121 PlatformVerificationFlow(AttestationFlow* attestation_flow,
109 cryptohome::AsyncMethodCaller* async_caller, 122 cryptohome::AsyncMethodCaller* async_caller,
110 CryptohomeClient* cryptohome_client, 123 CryptohomeClient* cryptohome_client,
111 UserManager* user_manager, 124 UserManager* user_manager,
112 Delegate* delegate); 125 Delegate* delegate);
113 126
114 virtual ~PlatformVerificationFlow();
115
116 // Invokes an asynchronous operation to challenge a platform key. Any user 127 // Invokes an asynchronous operation to challenge a platform key. Any user
117 // interaction will be associated with |web_contents|. The |service_id| is an 128 // interaction will be associated with |web_contents|. The |service_id| is an
118 // arbitrary value but it should uniquely identify the origin of the request 129 // arbitrary value but it should uniquely identify the origin of the request
119 // and should not be determined by that origin; its purpose is to prevent 130 // and should not be determined by that origin; its purpose is to prevent
120 // collusion between multiple services. The |challenge| is also an arbitrary 131 // collusion between multiple services. The |challenge| is also an arbitrary
121 // value but it should be time sensitive or associated to some kind of session 132 // value but it should be time sensitive or associated to some kind of session
122 // because its purpose is to prevent certificate replay. The |callback| will 133 // because its purpose is to prevent certificate replay. The |callback| will
123 // be called when the operation completes. The duration of the operation can 134 // be called when the operation completes. The duration of the operation can
124 // vary depending on system state, hardware capabilities, and interaction with 135 // vary depending on system state, hardware capabilities, and interaction with
125 // the user. 136 // the user.
126 void ChallengePlatformKey(content::WebContents* web_contents, 137 void ChallengePlatformKey(content::WebContents* web_contents,
127 const std::string& service_id, 138 const std::string& service_id,
128 const std::string& challenge, 139 const std::string& challenge,
129 const ChallengeCallback& callback); 140 const ChallengeCallback& callback);
130 141
131 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs); 142 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs);
132 143
133 void set_testing_prefs(PrefService* testing_prefs) { 144 void set_testing_prefs(PrefService* testing_prefs) {
134 testing_prefs_ = testing_prefs; 145 testing_prefs_ = testing_prefs;
135 } 146 }
136 147
137 void set_testing_url(const GURL& testing_url) { 148 void set_testing_url(const GURL& testing_url) {
138 testing_url_ = testing_url; 149 testing_url_ = testing_url;
139 } 150 }
140 151
152 void set_timeout_delay(int timeout_delay) {
153 timeout_delay_ = timeout_delay;
154 }
155
141 private: 156 private:
157 // Tracks timeout status for an asynchronous operation.
158 struct TimeoutStatus : public base::RefCountedThreadSafe<TimeoutStatus> {
DaleCurtis 2013/10/30 18:06:00 Why all this instead of base::DelayTimer from base
Darren Krahn 2013/10/30 19:14:30 AFAICT, DelayTimer offers no real benefit over Pos
DaleCurtis 2013/10/30 20:11:52 Ah I forgot there can be multiple calls outstandin
Darren Krahn 2013/10/30 22:24:53 Good suggestion -- updated to use base::Timer and
159 bool finished;
160 bool timed_out;
161
162 TimeoutStatus() : finished(false), timed_out(false) {}
163
164 private:
165 friend class base::RefCountedThreadSafe<TimeoutStatus>;
166 ~TimeoutStatus() {}
167 };
168
169 // Holds the arguments of a ChallengePlatformKey call. This is convenient for
170 // use with base::Bind so we don't get too many arguments.
171 struct ChallengeContext {
172 content::WebContents* web_contents;
173 std::string service_id;
174 std::string challenge;
175 ChallengeCallback callback;
176 };
177
178 friend class base::RefCountedThreadSafe<PlatformVerificationFlow>;
179 ~PlatformVerificationFlow();
180
142 // Checks whether we need to prompt the user for consent before proceeding and 181 // Checks whether we need to prompt the user for consent before proceeding and
143 // invokes the consent UI if so. All parameters are the same as in 182 // invokes the consent UI if so. The arguments to ChallengePlatformKey are
144 // ChallengePlatformKey except for the additional |attestation_enrolled| which 183 // in |context| and |attestation_enrolled| specifies whether attestation has
145 // specifies whether attestation has been enrolled for this device. 184 // been enrolled for this device.
146 void CheckConsent(content::WebContents* web_contents, 185 void CheckConsent(const ChallengeContext& context,
147 const std::string& service_id,
148 const std::string& challenge,
149 const ChallengeCallback& callback,
150 bool attestation_enrolled); 186 bool attestation_enrolled);
151 187
152 // A callback called when the user has given their consent response. All 188 // A callback called when the user has given their consent response. The
153 // parameters are the same as in ChallengePlatformKey except for the 189 // arguments to ChallengePlatformKey are in |context|. |consent_type| and
154 // additional |consent_type| and |consent_response| which indicate the consent 190 // |consent_response| indicate the consent type and user response,
155 // type and user response, respectively. If the response indicates that the 191 // respectively. If the response indicates that the operation should proceed,
156 // operation should proceed, this method invokes a certificate request. 192 // this method invokes a certificate request.
157 void OnConsentResponse(content::WebContents* web_contents, 193 void OnConsentResponse(const ChallengeContext& context,
158 const std::string& service_id,
159 const std::string& challenge,
160 const ChallengeCallback& callback,
161 ConsentType consent_type, 194 ConsentType consent_type,
162 ConsentResponse consent_response); 195 ConsentResponse consent_response);
163 196
164 // A callback called when an attestation certificate request operation 197 // A callback called when an attestation certificate request operation
165 // completes. |service_id|, |challenge|, and |callback| are the same as in 198 // completes. The arguments to ChallengePlatformKey are in |context|.
166 // ChallengePlatformKey. |user_id| identifies the user for which the 199 // |user_id| identifies the user for which the certificate was requested.
167 // certificate was requested. |operation_success| is true iff the certificate 200 // |operation_success| is true iff the certificate request operation
168 // request operation succeeded. |certificate| holds the certificate for the 201 // succeeded. |certificate| holds the certificate for the platform key on
169 // platform key on success. If the certificate request was successful, this 202 // success. If the certificate request was successful, this method invokes a
170 // method invokes a request to sign the challenge. 203 // request to sign the challenge. If the operation timed out prior to this
171 void OnCertificateReady(const std::string& user_id, 204 // method being called, this method does nothing - notably, the callback is
172 const std::string& service_id, 205 // not invoked.
173 const std::string& challenge, 206 void OnCertificateReady(const ChallengeContext& context,
174 const ChallengeCallback& callback, 207 const std::string& user_id,
208 TimeoutStatus* timeout_status,
175 bool operation_success, 209 bool operation_success,
176 const std::string& certificate); 210 const std::string& certificate);
177 211
212 // A callback run after a constant delay to handle timeouts for lengthy
213 // certificate requests. |context.callback| will be invoked with a TIMEOUT
214 // result if the certificate request has not already finished.
215 void OnCertificateTimeout(const ChallengeContext& context,
216 TimeoutStatus* timeout_status);
217
178 // A callback called when a challenge signing request has completed. The 218 // A callback called when a challenge signing request has completed. The
179 // |certificate| is the platform certificate for the key which signed the 219 // |certificate| is the platform certificate for the key which signed the
180 // |challenge|. |callback| is the same as in ChallengePlatformKey. 220 // |challenge|. The arguments to ChallengePlatformKey are in |context|.
181 // |operation_success| is true iff the challenge signing operation was 221 // |operation_success| is true iff the challenge signing operation was
182 // successful. If it was successful, |response_data| holds the challenge 222 // successful. If it was successful, |response_data| holds the challenge
183 // response and the method will invoke |callback|. 223 // response and the method will invoke |context.callback|.
184 void OnChallengeReady(const std::string& certificate, 224 void OnChallengeReady(const ChallengeContext& context,
185 const std::string& challenge, 225 const std::string& certificate,
186 const ChallengeCallback& callback,
187 bool operation_success, 226 bool operation_success,
188 const std::string& response_data); 227 const std::string& response_data);
189 228
190 // Gets prefs associated with the given |web_contents|. If prefs have been 229 // Gets prefs associated with the given |web_contents|. If prefs have been
191 // set explicitly using set_testing_prefs(), then these are always returned. 230 // set explicitly using set_testing_prefs(), then these are always returned.
192 // If no prefs are associated with |web_contents| then NULL is returned. 231 // If no prefs are associated with |web_contents| then NULL is returned.
193 PrefService* GetPrefs(content::WebContents* web_contents); 232 PrefService* GetPrefs(content::WebContents* web_contents);
194 233
195 // Gets the URL associated with the given |web_contents|. If a URL as been 234 // Gets the URL associated with the given |web_contents|. If a URL as been
196 // set explicitly using set_testing_url(), then this value is always returned. 235 // set explicitly using set_testing_url(), then this value is always returned.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 274
236 AttestationFlow* attestation_flow_; 275 AttestationFlow* attestation_flow_;
237 scoped_ptr<AttestationFlow> default_attestation_flow_; 276 scoped_ptr<AttestationFlow> default_attestation_flow_;
238 cryptohome::AsyncMethodCaller* async_caller_; 277 cryptohome::AsyncMethodCaller* async_caller_;
239 CryptohomeClient* cryptohome_client_; 278 CryptohomeClient* cryptohome_client_;
240 UserManager* user_manager_; 279 UserManager* user_manager_;
241 Delegate* delegate_; 280 Delegate* delegate_;
242 scoped_ptr<Delegate> default_delegate_; 281 scoped_ptr<Delegate> default_delegate_;
243 PrefService* testing_prefs_; 282 PrefService* testing_prefs_;
244 GURL testing_url_; 283 GURL testing_url_;
245 284 int timeout_delay_;
DaleCurtis 2013/10/30 20:11:52 base::TimeDelta
Darren Krahn 2013/10/30 22:24:53 Done.
246 // Note: This should remain the last member so it'll be destroyed and
247 // invalidate the weak pointers before any other members are destroyed.
248 base::WeakPtrFactory<PlatformVerificationFlow> weak_factory_;
249 285
250 DISALLOW_COPY_AND_ASSIGN(PlatformVerificationFlow); 286 DISALLOW_COPY_AND_ASSIGN(PlatformVerificationFlow);
251 }; 287 };
252 288
253 } // namespace attestation 289 } // namespace attestation
254 } // namespace chromeos 290 } // namespace chromeos
255 291
256 #endif // CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_ 292 #endif // CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698