| 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 "base/time/time.h" |
| 15 #include "base/timer/timer.h" |
| 14 #include "url/gurl.h" | 16 #include "url/gurl.h" |
| 15 | 17 |
| 16 class HostContentSettingsMap; | 18 class HostContentSettingsMap; |
| 17 class PrefService; | 19 class PrefService; |
| 18 | 20 |
| 19 namespace content { | 21 namespace content { |
| 20 class WebContents; | 22 class WebContents; |
| 21 } | 23 } |
| 22 | 24 |
| 23 namespace cryptohome { | 25 namespace cryptohome { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 34 class UserManager; | 36 class UserManager; |
| 35 class User; | 37 class User; |
| 36 | 38 |
| 37 namespace attestation { | 39 namespace attestation { |
| 38 | 40 |
| 39 class AttestationFlow; | 41 class AttestationFlow; |
| 40 class PlatformVerificationFlowTest; | 42 class PlatformVerificationFlowTest; |
| 41 | 43 |
| 42 // This class allows platform verification for the content protection use case. | 44 // This class allows platform verification for the content protection use case. |
| 43 // All methods must only be called on the UI thread. Example: | 45 // All methods must only be called on the UI thread. Example: |
| 44 // PlatformVerificationFlow verifier; | 46 // scoped_refptr<PlatformVerificationFlow> verifier = |
| 47 // new PlatformVerificationFlow(); |
| 45 // PlatformVerificationFlow::Callback callback = base::Bind(&MyCallback); | 48 // PlatformVerificationFlow::Callback callback = base::Bind(&MyCallback); |
| 46 // verifier.ChallengePlatformKey(my_web_contents, "my_id", "some_challenge", | 49 // verifier->ChallengePlatformKey(my_web_contents, "my_id", "some_challenge", |
| 47 // callback); | 50 // callback); |
| 48 class PlatformVerificationFlow { | 51 // |
| 52 // This class is RefCountedThreadSafe because it may need to outlive its caller. |
| 53 // The attestation flow that needs to happen to establish a certified platform |
| 54 // key may take minutes on some hardware. This class will timeout after a much |
| 55 // shorter time so the caller can proceed without platform verification but it |
| 56 // is important that the pending operation be allowed to finish. If the |
| 57 // attestation flow is aborted at any stage, it will need to start over. If we |
| 58 // use weak pointers, the attestation flow will stop when the next callback is |
| 59 // run. So we need the instance to stay alive until the platform key is fully |
| 60 // certified so the next time ChallegePlatformKey() is invoked it will be quick. |
| 61 class PlatformVerificationFlow |
| 62 : public base::RefCountedThreadSafe<PlatformVerificationFlow> { |
| 49 public: | 63 public: |
| 50 enum Result { | 64 enum Result { |
| 51 SUCCESS, // The operation succeeded. | 65 SUCCESS, // The operation succeeded. |
| 52 INTERNAL_ERROR, // The operation failed unexpectedly. | 66 INTERNAL_ERROR, // The operation failed unexpectedly. |
| 53 PLATFORM_NOT_VERIFIED, // The platform cannot be verified. For example: | 67 PLATFORM_NOT_VERIFIED, // The platform cannot be verified. For example: |
| 54 // - It is not a Chrome device. | 68 // - It is not a Chrome device. |
| 55 // - It is not running a verified OS image. | 69 // - It is not running a verified OS image. |
| 56 USER_REJECTED, // The user explicitly rejected the operation. | 70 USER_REJECTED, // The user explicitly rejected the operation. |
| 57 POLICY_REJECTED, // The operation is not allowed by policy/settings. | 71 POLICY_REJECTED, // The operation is not allowed by policy/settings. |
| 72 TIMEOUT, // The operation timed out. |
| 58 }; | 73 }; |
| 59 | 74 |
| 60 enum ConsentResponse { | 75 enum ConsentResponse { |
| 61 CONSENT_RESPONSE_NONE, | 76 CONSENT_RESPONSE_NONE, |
| 62 CONSENT_RESPONSE_ALLOW, | 77 CONSENT_RESPONSE_ALLOW, |
| 63 CONSENT_RESPONSE_DENY, | 78 CONSENT_RESPONSE_DENY, |
| 64 }; | 79 }; |
| 65 | 80 |
| 66 // An interface which allows settings and UI to be abstracted for testing | 81 // An interface which allows settings and UI to be abstracted for testing |
| 67 // purposes. For normal operation the default implementation should be used. | 82 // purposes. For normal operation the default implementation should be used. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 PlatformVerificationFlow(); | 115 PlatformVerificationFlow(); |
| 101 | 116 |
| 102 // An alternate constructor which specifies dependent objects explicitly. | 117 // An alternate constructor which specifies dependent objects explicitly. |
| 103 // This is useful in testing. The caller retains ownership of all pointers. | 118 // This is useful in testing. The caller retains ownership of all pointers. |
| 104 PlatformVerificationFlow(AttestationFlow* attestation_flow, | 119 PlatformVerificationFlow(AttestationFlow* attestation_flow, |
| 105 cryptohome::AsyncMethodCaller* async_caller, | 120 cryptohome::AsyncMethodCaller* async_caller, |
| 106 CryptohomeClient* cryptohome_client, | 121 CryptohomeClient* cryptohome_client, |
| 107 UserManager* user_manager, | 122 UserManager* user_manager, |
| 108 Delegate* delegate); | 123 Delegate* delegate); |
| 109 | 124 |
| 110 virtual ~PlatformVerificationFlow(); | |
| 111 | |
| 112 // Invokes an asynchronous operation to challenge a platform key. Any user | 125 // Invokes an asynchronous operation to challenge a platform key. Any user |
| 113 // interaction will be associated with |web_contents|. The |service_id| is an | 126 // interaction will be associated with |web_contents|. The |service_id| is an |
| 114 // arbitrary value but it should uniquely identify the origin of the request | 127 // arbitrary value but it should uniquely identify the origin of the request |
| 115 // and should not be determined by that origin; its purpose is to prevent | 128 // and should not be determined by that origin; its purpose is to prevent |
| 116 // collusion between multiple services. The |challenge| is also an arbitrary | 129 // collusion between multiple services. The |challenge| is also an arbitrary |
| 117 // value but it should be time sensitive or associated to some kind of session | 130 // value but it should be time sensitive or associated to some kind of session |
| 118 // because its purpose is to prevent certificate replay. The |callback| will | 131 // because its purpose is to prevent certificate replay. The |callback| will |
| 119 // be called when the operation completes. The duration of the operation can | 132 // be called when the operation completes. The duration of the operation can |
| 120 // vary depending on system state, hardware capabilities, and interaction with | 133 // vary depending on system state, hardware capabilities, and interaction with |
| 121 // the user. | 134 // the user. |
| 122 void ChallengePlatformKey(content::WebContents* web_contents, | 135 void ChallengePlatformKey(content::WebContents* web_contents, |
| 123 const std::string& service_id, | 136 const std::string& service_id, |
| 124 const std::string& challenge, | 137 const std::string& challenge, |
| 125 const ChallengeCallback& callback); | 138 const ChallengeCallback& callback); |
| 126 | 139 |
| 127 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs); | 140 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs); |
| 128 | 141 |
| 142 void set_timeout_delay(const base::TimeDelta& timeout_delay) { |
| 143 timeout_delay_ = timeout_delay; |
| 144 } |
| 145 |
| 129 private: | 146 private: |
| 147 friend class base::RefCountedThreadSafe<PlatformVerificationFlow>; |
| 130 friend class PlatformVerificationFlowTest; | 148 friend class PlatformVerificationFlowTest; |
| 131 | 149 |
| 150 // Holds the arguments of a ChallengePlatformKey call. This is convenient for |
| 151 // use with base::Bind so we don't get too many arguments. |
| 152 struct ChallengeContext { |
| 153 ChallengeContext(content::WebContents* web_contents, |
| 154 const std::string& service_id, |
| 155 const std::string& challenge, |
| 156 const ChallengeCallback& callback); |
| 157 ~ChallengeContext(); |
| 158 |
| 159 content::WebContents* web_contents; |
| 160 std::string service_id; |
| 161 std::string challenge; |
| 162 ChallengeCallback callback; |
| 163 }; |
| 164 |
| 165 ~PlatformVerificationFlow(); |
| 166 |
| 132 // Checks whether we need to prompt the user for consent before proceeding and | 167 // Checks whether we need to prompt the user for consent before proceeding and |
| 133 // invokes the consent UI if so. All parameters are the same as in | 168 // invokes the consent UI if so. The arguments to ChallengePlatformKey are |
| 134 // ChallengePlatformKey except for the additional |attestation_enrolled| which | 169 // in |context| and |attestation_enrolled| specifies whether attestation has |
| 135 // specifies whether attestation has been enrolled for this device. | 170 // been enrolled for this device. |
| 136 void CheckConsent(content::WebContents* web_contents, | 171 void CheckConsent(const ChallengeContext& context, |
| 137 const std::string& service_id, | |
| 138 const std::string& challenge, | |
| 139 const ChallengeCallback& callback, | |
| 140 bool attestation_enrolled); | 172 bool attestation_enrolled); |
| 141 | 173 |
| 142 // A callback called when the user has given their consent response. All | 174 // A callback called when the user has given their consent response. The |
| 143 // parameters are the same as in ChallengePlatformKey except for the | 175 // arguments to ChallengePlatformKey are in |context|. |consent_required| and |
| 144 // additional |consent_required| and |consent_response| which indicate that | 176 // |consent_response| indicate whether consent was required and user response, |
| 145 // user interaction was required and the user response, respectively. If the | 177 // respectively. If the response indicates that the operation should proceed, |
| 146 // response indicates that the operation should proceed, this method invokes a | 178 // this method invokes a certificate request. |
| 147 // certificate request. | 179 void OnConsentResponse(const ChallengeContext& context, |
| 148 void OnConsentResponse(content::WebContents* web_contents, | |
| 149 const std::string& service_id, | |
| 150 const std::string& challenge, | |
| 151 const ChallengeCallback& callback, | |
| 152 bool consent_required, | 180 bool consent_required, |
| 153 ConsentResponse consent_response); | 181 ConsentResponse consent_response); |
| 154 | 182 |
| 155 // A callback called when an attestation certificate request operation | 183 // A callback called when an attestation certificate request operation |
| 156 // completes. |service_id|, |challenge|, and |callback| are the same as in | 184 // completes. The arguments to ChallengePlatformKey are in |context|. |
| 157 // ChallengePlatformKey. |user_id| identifies the user for which the | 185 // |user_id| identifies the user for which the certificate was requested. |
| 158 // certificate was requested. |operation_success| is true iff the certificate | 186 // |operation_success| is true iff the certificate request operation |
| 159 // request operation succeeded. |certificate| holds the certificate for the | 187 // succeeded. |certificate| holds the certificate for the platform key on |
| 160 // platform key on success. If the certificate request was successful, this | 188 // success. If the certificate request was successful, this method invokes a |
| 161 // method invokes a request to sign the challenge. | 189 // request to sign the challenge. If the operation timed out prior to this |
| 162 void OnCertificateReady(const std::string& user_id, | 190 // method being called, this method does nothing - notably, the callback is |
| 163 const std::string& service_id, | 191 // not invoked. |
| 164 const std::string& challenge, | 192 void OnCertificateReady(const ChallengeContext& context, |
| 165 const ChallengeCallback& callback, | 193 const std::string& user_id, |
| 194 scoped_ptr<base::Timer> timer, |
| 166 bool operation_success, | 195 bool operation_success, |
| 167 const std::string& certificate); | 196 const std::string& certificate); |
| 168 | 197 |
| 198 // A callback run after a constant delay to handle timeouts for lengthy |
| 199 // certificate requests. |context.callback| will be invoked with a TIMEOUT |
| 200 // result. |
| 201 void OnCertificateTimeout(const ChallengeContext& context); |
| 202 |
| 169 // A callback called when a challenge signing request has completed. The | 203 // A callback called when a challenge signing request has completed. The |
| 170 // |certificate| is the platform certificate for the key which signed the | 204 // |certificate| is the platform certificate for the key which signed the |
| 171 // |challenge|. |callback| is the same as in ChallengePlatformKey. | 205 // |challenge|. The arguments to ChallengePlatformKey are in |context|. |
| 172 // |operation_success| is true iff the challenge signing operation was | 206 // |operation_success| is true iff the challenge signing operation was |
| 173 // successful. If it was successful, |response_data| holds the challenge | 207 // successful. If it was successful, |response_data| holds the challenge |
| 174 // response and the method will invoke |callback|. | 208 // response and the method will invoke |context.callback|. |
| 175 void OnChallengeReady(const std::string& certificate, | 209 void OnChallengeReady(const ChallengeContext& context, |
| 176 const std::string& challenge, | 210 const std::string& certificate, |
| 177 const ChallengeCallback& callback, | |
| 178 bool operation_success, | 211 bool operation_success, |
| 179 const std::string& response_data); | 212 const std::string& response_data); |
| 180 | 213 |
| 181 // Gets prefs associated with the given |web_contents|. If prefs have been | 214 // Gets prefs associated with the given |web_contents|. If prefs have been |
| 182 // set explicitly using set_testing_prefs(), then these are always returned. | 215 // set explicitly using set_testing_prefs(), then these are always returned. |
| 183 // If no prefs are associated with |web_contents| then NULL is returned. | 216 // If no prefs are associated with |web_contents| then NULL is returned. |
| 184 PrefService* GetPrefs(content::WebContents* web_contents); | 217 PrefService* GetPrefs(content::WebContents* web_contents); |
| 185 | 218 |
| 186 // Gets the URL associated with the given |web_contents|. If a URL as been | 219 // Gets the URL associated with the given |web_contents|. If a URL as been |
| 187 // set explicitly using set_testing_url(), then this value is always returned. | 220 // set explicitly using set_testing_url(), then this value is always returned. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 AttestationFlow* attestation_flow_; | 267 AttestationFlow* attestation_flow_; |
| 235 scoped_ptr<AttestationFlow> default_attestation_flow_; | 268 scoped_ptr<AttestationFlow> default_attestation_flow_; |
| 236 cryptohome::AsyncMethodCaller* async_caller_; | 269 cryptohome::AsyncMethodCaller* async_caller_; |
| 237 CryptohomeClient* cryptohome_client_; | 270 CryptohomeClient* cryptohome_client_; |
| 238 UserManager* user_manager_; | 271 UserManager* user_manager_; |
| 239 Delegate* delegate_; | 272 Delegate* delegate_; |
| 240 scoped_ptr<Delegate> default_delegate_; | 273 scoped_ptr<Delegate> default_delegate_; |
| 241 PrefService* testing_prefs_; | 274 PrefService* testing_prefs_; |
| 242 GURL testing_url_; | 275 GURL testing_url_; |
| 243 HostContentSettingsMap* testing_content_settings_; | 276 HostContentSettingsMap* testing_content_settings_; |
| 244 | 277 base::TimeDelta timeout_delay_; |
| 245 // Note: This should remain the last member so it'll be destroyed and | |
| 246 // invalidate the weak pointers before any other members are destroyed. | |
| 247 base::WeakPtrFactory<PlatformVerificationFlow> weak_factory_; | |
| 248 | 278 |
| 249 DISALLOW_COPY_AND_ASSIGN(PlatformVerificationFlow); | 279 DISALLOW_COPY_AND_ASSIGN(PlatformVerificationFlow); |
| 250 }; | 280 }; |
| 251 | 281 |
| 252 } // namespace attestation | 282 } // namespace attestation |
| 253 } // namespace chromeos | 283 } // namespace chromeos |
| 254 | 284 |
| 255 #endif // CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_ | 285 #endif // CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_ |
| OLD | NEW |