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 |