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/ref_counted.h" |
| 13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
| 14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 15 #include "base/timer/timer.h" | 15 #include "base/timer/timer.h" |
| 16 #include "url/gurl.h" | 16 #include "url/gurl.h" |
| 17 | 17 |
| 18 class HostContentSettingsMap; | |
| 19 class PrefService; | |
| 20 | |
| 21 namespace content { | 18 namespace content { |
| 22 class WebContents; | 19 class WebContents; |
| 23 } | 20 } |
| 24 | 21 |
| 25 namespace cryptohome { | 22 namespace cryptohome { |
| 26 class AsyncMethodCaller; | 23 class AsyncMethodCaller; |
| 27 } | 24 } |
| 28 | 25 |
| 29 namespace user_manager { | 26 namespace user_manager { |
| 30 class User; | 27 class User; |
| 31 } | 28 } |
| 32 | 29 |
| 33 namespace user_prefs { | |
| 34 class PrefRegistrySyncable; | |
| 35 } | |
| 36 | |
| 37 namespace chromeos { | 30 namespace chromeos { |
| 38 | 31 |
| 39 class CryptohomeClient; | 32 class CryptohomeClient; |
| 40 | 33 |
| 41 namespace attestation { | 34 namespace attestation { |
| 42 | 35 |
| 43 class AttestationFlow; | 36 class AttestationFlow; |
| 44 class PlatformVerificationFlowTest; | 37 class PlatformVerificationFlowTest; |
| 45 | 38 |
| 46 // This class allows platform verification for the content protection use case. | 39 // This class allows platform verification for the content protection use case. |
| 47 // All methods must only be called on the UI thread. Example: | 40 // All methods must only be called on the UI thread. Example: |
| 48 // scoped_refptr<PlatformVerificationFlow> verifier = | 41 // scoped_refptr<PlatformVerificationFlow> verifier = |
| 49 // new PlatformVerificationFlow(); | 42 // new PlatformVerificationFlow(); |
| 50 // PlatformVerificationFlow::Callback callback = base::Bind(&MyCallback); | 43 // PlatformVerificationFlow::Callback callback = base::Bind(&MyCallback); |
| 51 // verifier->ChallengePlatformKey(my_web_contents, "my_id", "some_challenge", | 44 // verifier->ChallengePlatformKey(my_web_contents, "my_id", "some_challenge", |
| 52 // callback); | 45 // callback); |
| 53 // | 46 // |
| 54 // This class is RefCountedThreadSafe because it may need to outlive its caller. | 47 // This class is RefCountedThreadSafe because it may need to outlive its caller. |
| 55 // The attestation flow that needs to happen to establish a certified platform | 48 // The attestation flow that needs to happen to establish a certified platform |
| 56 // key may take minutes on some hardware. This class will timeout after a much | 49 // key may take minutes on some hardware. This class will timeout after a much |
| 57 // shorter time so the caller can proceed without platform verification but it | 50 // shorter time so the caller can proceed without platform verification but it |
| 58 // is important that the pending operation be allowed to finish. If the | 51 // is important that the pending operation be allowed to finish. If the |
| 59 // attestation flow is aborted at any stage, it will need to start over. If we | 52 // attestation flow is aborted at any stage, it will need to start over. If we |
| 60 // use weak pointers, the attestation flow will stop when the next callback is | 53 // use weak pointers, the attestation flow will stop when the next callback is |
| 61 // run. So we need the instance to stay alive until the platform key is fully | 54 // run. So we need the instance to stay alive until the platform key is fully |
| 62 // certified so the next time ChallegePlatformKey() is invoked it will be quick. | 55 // certified so the next time ChallegePlatformKey() is invoked it will be quick. |
| 63 class PlatformVerificationFlow | 56 class PlatformVerificationFlow |
| 64 : public base::RefCountedThreadSafe<PlatformVerificationFlow> { | 57 : public base::RefCountedThreadSafe<PlatformVerificationFlow> { |
| 65 public: | 58 public: |
| 59 // These values are reported to UMA. DO NOT CHANGE THE EXISTING VALUES! | |
| 66 enum Result { | 60 enum Result { |
| 67 SUCCESS, // The operation succeeded. | 61 SUCCESS, // The operation succeeded. |
| 68 INTERNAL_ERROR, // The operation failed unexpectedly. | 62 INTERNAL_ERROR, // The operation failed unexpectedly. |
| 69 PLATFORM_NOT_VERIFIED, // The platform cannot be verified. For example: | 63 PLATFORM_NOT_VERIFIED, // The platform cannot be verified. For example: |
| 70 // - It is not a Chrome device. | 64 // - It is not a Chrome device. |
| 71 // - It is not running a verified OS image. | 65 // - It is not running a verified OS image. |
| 72 USER_REJECTED, // The user explicitly rejected the operation. | 66 USER_REJECTED, // The user explicitly rejected the operation. |
| 73 POLICY_REJECTED, // The operation is not allowed by policy/settings. | 67 POLICY_REJECTED, // The operation is not allowed by policy/settings. |
| 74 TIMEOUT, // The operation timed out. | 68 TIMEOUT, // The operation timed out. |
| 75 }; | 69 }; |
| 76 | 70 |
| 77 enum ConsentResponse { | |
| 78 CONSENT_RESPONSE_NONE, | |
| 79 CONSENT_RESPONSE_ALLOW, | |
| 80 CONSENT_RESPONSE_DENY, | |
| 81 }; | |
| 82 | |
| 83 // An interface which allows settings and UI to be abstracted for testing | 71 // An interface which allows settings and UI to be abstracted for testing |
| 84 // purposes. For normal operation the default implementation should be used. | 72 // purposes. For normal operation the default implementation should be used. |
| 85 class Delegate { | 73 class Delegate { |
| 86 public: | 74 public: |
| 87 virtual ~Delegate() {} | 75 virtual ~Delegate() {} |
| 88 | 76 |
| 89 // This callback will be called when a user has given a |response| to a | |
| 90 // consent request of the specified |type|. | |
| 91 typedef base::Callback<void(ConsentResponse response)> ConsentCallback; | |
| 92 | |
| 93 // Invokes consent UI within the context of |web_contents| and calls | |
| 94 // |callback| when the user responds. | |
| 95 // |requesting_origin| or the extension/app name will be shown on the prompt | |
| 96 // if the request comes from a web page or an extension/app, respectively. | |
| 97 virtual void ShowConsentPrompt(content::WebContents* web_contents, | |
| 98 const GURL& requesting_origin, | |
| 99 const ConsentCallback& callback) = 0; | |
| 100 | |
| 101 // Gets prefs associated with the given |web_contents|. If no prefs are | |
| 102 // associated with |web_contents| then NULL is returned. | |
| 103 virtual PrefService* GetPrefs(content::WebContents* web_contents) = 0; | |
| 104 | |
| 105 // Gets the URL associated with the given |web_contents|. | 77 // Gets the URL associated with the given |web_contents|. |
| 106 virtual const GURL& GetURL(content::WebContents* web_contents) = 0; | 78 virtual const GURL& GetURL(content::WebContents* web_contents) = 0; |
| 107 | 79 |
| 108 // Gets the user associated with the given |web_contents|. NULL may be | 80 // Gets the user associated with the given |web_contents|. NULL may be |
| 109 // returned. | 81 // returned. |
| 110 virtual const user_manager::User* GetUser( | 82 virtual const user_manager::User* GetUser( |
| 111 content::WebContents* web_contents) = 0; | 83 content::WebContents* web_contents) = 0; |
| 112 | 84 |
| 113 // Gets the content settings map associated with the given |web_contents|. | 85 // Checks whether attestation is permitted by user. |
| 114 virtual HostContentSettingsMap* GetContentSettings( | 86 virtual bool IsPermittedByUser(content::WebContents* web_contents) = 0; |
| 115 content::WebContents* web_contents) = 0; | |
| 116 | 87 |
| 117 // Returns true iff |web_contents| belongs to a guest or incognito session. | 88 // Returns true iff |web_contents| belongs to a guest or incognito session. |
| 118 virtual bool IsGuestOrIncognito(content::WebContents* web_contents) = 0; | 89 virtual bool IsGuestOrIncognito(content::WebContents* web_contents) = 0; |
| 119 }; | 90 }; |
| 120 | 91 |
| 121 // This callback will be called when a challenge operation completes. If | 92 // This callback will be called when a challenge operation completes. If |
| 122 // |result| is SUCCESS then |signed_data| holds the data which was signed | 93 // |result| is SUCCESS then |signed_data| holds the data which was signed |
| 123 // by the platform key (this is the original challenge appended with a random | 94 // by the platform key (this is the original challenge appended with a random |
| 124 // nonce) and |signature| holds the RSA-PKCS1-v1.5 signature. The | 95 // nonce) and |signature| holds the RSA-PKCS1-v1.5 signature. The |
| 125 // |platform_key_certificate| certifies the key used to generate the | 96 // |platform_key_certificate| certifies the key used to generate the |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 151 // value but it should be time sensitive or associated to some kind of session | 122 // value but it should be time sensitive or associated to some kind of session |
| 152 // because its purpose is to prevent certificate replay. The |callback| will | 123 // because its purpose is to prevent certificate replay. The |callback| will |
| 153 // be called when the operation completes. The duration of the operation can | 124 // be called when the operation completes. The duration of the operation can |
| 154 // vary depending on system state, hardware capabilities, and interaction with | 125 // vary depending on system state, hardware capabilities, and interaction with |
| 155 // the user. | 126 // the user. |
| 156 void ChallengePlatformKey(content::WebContents* web_contents, | 127 void ChallengePlatformKey(content::WebContents* web_contents, |
| 157 const std::string& service_id, | 128 const std::string& service_id, |
| 158 const std::string& challenge, | 129 const std::string& challenge, |
| 159 const ChallengeCallback& callback); | 130 const ChallengeCallback& callback); |
| 160 | 131 |
| 161 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs); | |
| 162 | |
| 163 void set_timeout_delay(const base::TimeDelta& timeout_delay) { | 132 void set_timeout_delay(const base::TimeDelta& timeout_delay) { |
| 164 timeout_delay_ = timeout_delay; | 133 timeout_delay_ = timeout_delay; |
| 165 } | 134 } |
| 166 | 135 |
| 167 private: | 136 private: |
| 168 friend class base::RefCountedThreadSafe<PlatformVerificationFlow>; | 137 friend class base::RefCountedThreadSafe<PlatformVerificationFlow>; |
| 169 friend class PlatformVerificationFlowTest; | 138 friend class PlatformVerificationFlowTest; |
| 170 | 139 |
| 171 // Holds the arguments of a ChallengePlatformKey call. This is convenient for | 140 // Holds the arguments of a ChallengePlatformKey call. This is convenient for |
| 172 // use with base::Bind so we don't get too many arguments. | 141 // use with base::Bind so we don't get too many arguments. |
| 173 struct ChallengeContext { | 142 struct ChallengeContext { |
| 174 ChallengeContext(content::WebContents* web_contents, | 143 ChallengeContext(content::WebContents* web_contents, |
| 175 const std::string& service_id, | 144 const std::string& service_id, |
| 176 const std::string& challenge, | 145 const std::string& challenge, |
| 177 const ChallengeCallback& callback); | 146 const ChallengeCallback& callback); |
| 178 ~ChallengeContext(); | 147 ~ChallengeContext(); |
| 179 | 148 |
| 180 content::WebContents* web_contents; | 149 content::WebContents* web_contents; |
| 181 std::string service_id; | 150 std::string service_id; |
| 182 std::string challenge; | 151 std::string challenge; |
| 183 ChallengeCallback callback; | 152 ChallengeCallback callback; |
| 184 }; | 153 }; |
| 185 | 154 |
| 186 ~PlatformVerificationFlow(); | 155 ~PlatformVerificationFlow(); |
| 187 | 156 |
| 188 // Checks whether the device has already been enrolled for attestation. The | 157 // Checks whether the device has already been enrolled for attestation. The |
|
ddorwin
2015/03/12 21:38:53
Is this comment still accurate? It seems not.
xhwang
2015/03/13 00:54:42
Done.
| |
| 189 // arguments to ChallengePlatformKey are in |context| and | 158 // arguments to ChallengePlatformKey are in |context| and |
| 190 // |attestation_prepared| specifies whether attestation has been prepared on | 159 // |attestation_prepared| specifies whether attestation has been prepared on |
| 191 // this device. | 160 // this device. |
| 192 void CheckEnrollment(const ChallengeContext& context, | 161 void OnAttestationPrepared(const ChallengeContext& context, |
| 193 bool attestation_prepared); | 162 bool attestation_prepared); |
| 194 | |
| 195 // Checks whether we need to prompt the user for consent before proceeding and | |
| 196 // invokes the consent UI if so. The arguments to ChallengePlatformKey are | |
| 197 // in |context| and |attestation_enrolled| specifies whether attestation has | |
| 198 // been enrolled for this device. | |
| 199 void CheckConsent(const ChallengeContext& context, | |
| 200 bool attestation_enrolled); | |
| 201 | |
| 202 // A callback called when the user has given their consent response. The | |
| 203 // arguments to ChallengePlatformKey are in |context|. |consent_required| and | |
| 204 // |consent_response| indicate whether consent was required and user response, | |
| 205 // respectively. If the response indicates that the operation should proceed, | |
| 206 // this method invokes a certificate request. | |
| 207 void OnConsentResponse(const ChallengeContext& context, | |
| 208 bool consent_required, | |
| 209 ConsentResponse consent_response); | |
| 210 | 163 |
| 211 // Initiates the flow to get a platform key certificate. The arguments to | 164 // Initiates the flow to get a platform key certificate. The arguments to |
| 212 // ChallengePlatformKey are in |context|. |user_id| identifies the user for | 165 // ChallengePlatformKey are in |context|. |user_id| identifies the user for |
| 213 // which to get a certificate. If |force_new_key| is true then any existing | 166 // which to get a certificate. If |force_new_key| is true then any existing |
| 214 // key for the same user and service will be ignored and a new key will be | 167 // key for the same user and service will be ignored and a new key will be |
| 215 // generated and certified. | 168 // generated and certified. |
| 216 void GetCertificate(const ChallengeContext& context, | 169 void GetCertificate(const ChallengeContext& context, |
| 217 const std::string& user_id, | 170 const std::string& user_id, |
| 218 bool force_new_key); | 171 bool force_new_key); |
| 219 | 172 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 241 // |certificate| is the platform certificate for the key which signed the | 194 // |certificate| is the platform certificate for the key which signed the |
| 242 // |challenge|. The arguments to ChallengePlatformKey are in |context|. | 195 // |challenge|. The arguments to ChallengePlatformKey are in |context|. |
| 243 // |operation_success| is true iff the challenge signing operation was | 196 // |operation_success| is true iff the challenge signing operation was |
| 244 // successful. If it was successful, |response_data| holds the challenge | 197 // successful. If it was successful, |response_data| holds the challenge |
| 245 // response and the method will invoke |context.callback|. | 198 // response and the method will invoke |context.callback|. |
| 246 void OnChallengeReady(const ChallengeContext& context, | 199 void OnChallengeReady(const ChallengeContext& context, |
| 247 const std::string& certificate, | 200 const std::string& certificate, |
| 248 bool operation_success, | 201 bool operation_success, |
| 249 const std::string& response_data); | 202 const std::string& response_data); |
| 250 | 203 |
| 251 // Checks whether policy or profile settings associated with |web_contents| | 204 // Checks whether attestation for content protection is allowed by policy. |
| 252 // have attestation for content protection explicitly disabled. | 205 bool IsAttestationAllowedByPolicy(); |
| 253 bool IsAttestationEnabled(content::WebContents* web_contents); | |
| 254 | |
| 255 // Updates user settings for the profile associated with |web_contents| based | |
| 256 // on the |consent_response| to the request of type |consent_type|. | |
| 257 bool UpdateSettings(content::WebContents* web_contents, | |
| 258 ConsentResponse consent_response); | |
| 259 | |
| 260 // Finds the origin-specific consent pref in |content_settings| for |url|. If | |
| 261 // a pref exists for the origin, returns true and sets |pref_value| if it is | |
| 262 // not NULL. | |
| 263 bool GetOriginPref(HostContentSettingsMap* content_settings, | |
| 264 const GURL& url, | |
| 265 bool* pref_value); | |
| 266 | |
| 267 // Records the origin-specific consent pref in |content_settings| for |url|. | |
| 268 // The pref will be set to |allow_origin|. | |
| 269 void RecordOriginConsent(HostContentSettingsMap* content_settings, | |
| 270 const GURL& url, | |
| 271 bool allow_origin); | |
| 272 | 206 |
| 273 // Returns true iff |certificate| is an expired X.509 certificate. | 207 // Returns true iff |certificate| is an expired X.509 certificate. |
| 274 bool IsExpired(const std::string& certificate); | 208 bool IsExpired(const std::string& certificate); |
| 275 | 209 |
| 276 AttestationFlow* attestation_flow_; | 210 AttestationFlow* attestation_flow_; |
| 277 scoped_ptr<AttestationFlow> default_attestation_flow_; | 211 scoped_ptr<AttestationFlow> default_attestation_flow_; |
| 278 cryptohome::AsyncMethodCaller* async_caller_; | 212 cryptohome::AsyncMethodCaller* async_caller_; |
| 279 CryptohomeClient* cryptohome_client_; | 213 CryptohomeClient* cryptohome_client_; |
| 280 Delegate* delegate_; | 214 Delegate* delegate_; |
| 281 scoped_ptr<Delegate> default_delegate_; | 215 scoped_ptr<Delegate> default_delegate_; |
| 282 base::TimeDelta timeout_delay_; | 216 base::TimeDelta timeout_delay_; |
| 283 | 217 |
| 284 DISALLOW_COPY_AND_ASSIGN(PlatformVerificationFlow); | 218 DISALLOW_COPY_AND_ASSIGN(PlatformVerificationFlow); |
| 285 }; | 219 }; |
| 286 | 220 |
| 287 } // namespace attestation | 221 } // namespace attestation |
| 288 } // namespace chromeos | 222 } // namespace chromeos |
| 289 | 223 |
| 290 #endif // CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_ | 224 #endif // CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_ |
| OLD | NEW |