Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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_ |
| OLD | NEW |