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

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

Issue 23765004: Added prefs for content protection attestation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 7 years, 3 months 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 #include "platform_verification_flow.h" 5 #include "platform_verification_flow.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h" 9 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h"
9 #include "chrome/browser/chromeos/login/user_manager.h" 10 #include "chrome/browser/chromeos/login/user_manager.h"
10 #include "chrome/browser/chromeos/settings/cros_settings.h" 11 #include "chrome/browser/chromeos/settings/cros_settings.h"
11 #include "chrome/browser/chromeos/system/statistics_provider.h" 12 #include "chrome/browser/chromeos/system/statistics_provider.h"
13 #include "chrome/browser/prefs/scoped_user_pref_update.h"
14 #include "chrome/common/pref_names.h"
12 #include "chromeos/attestation/attestation_flow.h" 15 #include "chromeos/attestation/attestation_flow.h"
13 #include "chromeos/cryptohome/async_method_caller.h" 16 #include "chromeos/cryptohome/async_method_caller.h"
14 #include "chromeos/dbus/cryptohome_client.h" 17 #include "chromeos/dbus/cryptohome_client.h"
15 #include "chromeos/dbus/dbus_thread_manager.h" 18 #include "chromeos/dbus/dbus_thread_manager.h"
19 #include "components/user_prefs/pref_registry_syncable.h"
20 #include "components/user_prefs/user_prefs.h"
16 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/web_contents.h" 22 #include "content/public/browser/web_contents.h"
18 23
19 namespace { 24 namespace {
20 // A callback method to handle DBus errors. 25 // A callback method to handle DBus errors.
21 void DBusCallback(const base::Callback<void(bool)>& on_success, 26 void DBusCallback(const base::Callback<void(bool)>& on_success,
22 const base::Closure& on_failure, 27 const base::Closure& on_failure,
23 chromeos::DBusMethodCallStatus call_status, 28 chromeos::DBusMethodCallStatus call_status,
24 bool result) { 29 bool result) {
25 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS) { 30 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS) {
(...skipping 27 matching lines...) Expand all
53 58
54 PlatformVerificationFlow::~PlatformVerificationFlow() { 59 PlatformVerificationFlow::~PlatformVerificationFlow() {
55 } 60 }
56 61
57 void PlatformVerificationFlow::ChallengePlatformKey( 62 void PlatformVerificationFlow::ChallengePlatformKey(
58 content::WebContents* web_contents, 63 content::WebContents* web_contents,
59 const std::string& service_id, 64 const std::string& service_id,
60 const std::string& challenge, 65 const std::string& challenge,
61 const ChallengeCallback& callback) { 66 const ChallengeCallback& callback) {
62 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 67 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
63 if (delegate_->IsAttestationDisabled()) { 68 if (!IsAttestationEnabled(web_contents)) {
64 LOG(INFO) << "PlatformVerificationFlow: Feature disabled."; 69 LOG(INFO) << "PlatformVerificationFlow: Feature disabled.";
65 callback.Run(POLICY_REJECTED, std::string(), std::string()); 70 callback.Run(POLICY_REJECTED, std::string(), std::string());
66 return; 71 return;
67 } 72 }
68 BoolDBusMethodCallback dbus_callback = base::Bind( 73 BoolDBusMethodCallback dbus_callback = base::Bind(
69 &DBusCallback, 74 &DBusCallback,
70 base::Bind(&PlatformVerificationFlow::CheckConsent, 75 base::Bind(&PlatformVerificationFlow::CheckConsent,
71 weak_factory_.GetWeakPtr(), 76 weak_factory_.GetWeakPtr(),
72 web_contents, 77 web_contents,
73 service_id, 78 service_id,
(...skipping 24 matching lines...) Expand all
98 base::Bind(callback, false)); 103 base::Bind(callback, false));
99 cryptohome_client_->TpmAttestationIsPrepared(dbus_callback); 104 cryptohome_client_->TpmAttestationIsPrepared(dbus_callback);
100 } 105 }
101 106
102 void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents, 107 void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents,
103 const std::string& service_id, 108 const std::string& service_id,
104 const std::string& challenge, 109 const std::string& challenge,
105 const ChallengeCallback& callback, 110 const ChallengeCallback& callback,
106 bool attestation_enrolled) { 111 bool attestation_enrolled) {
107 ConsentType consent_type = CONSENT_TYPE_NONE; 112 ConsentType consent_type = CONSENT_TYPE_NONE;
108 if (!attestation_enrolled) { 113 if (!attestation_enrolled || IsFirstUse(web_contents)) {
109 consent_type = CONSENT_TYPE_ATTESTATION; 114 consent_type = CONSENT_TYPE_ATTESTATION;
110 } else if (delegate_->IsOriginConsentRequired(web_contents)) { 115 } else if (IsAlwaysAskRequired(web_contents)) {
111 consent_type = CONSENT_TYPE_ORIGIN;
112 } else if (delegate_->IsAlwaysAskRequired(web_contents)) {
113 consent_type = CONSENT_TYPE_ALWAYS; 116 consent_type = CONSENT_TYPE_ALWAYS;
114 } 117 }
115 Delegate::ConsentCallback consent_callback = base::Bind( 118 Delegate::ConsentCallback consent_callback = base::Bind(
116 &PlatformVerificationFlow::OnConsentResponse, 119 &PlatformVerificationFlow::OnConsentResponse,
117 weak_factory_.GetWeakPtr(), 120 weak_factory_.GetWeakPtr(),
118 web_contents, 121 web_contents,
119 service_id, 122 service_id,
120 challenge, 123 challenge,
121 callback, 124 callback,
122 consent_type); 125 consent_type);
123 if (consent_type == CONSENT_TYPE_NONE) { 126 if (consent_type == CONSENT_TYPE_NONE) {
124 consent_callback.Run(CONSENT_RESPONSE_NONE); 127 consent_callback.Run(CONSENT_RESPONSE_NONE);
125 } else { 128 } else {
126 delegate_->ShowConsentPrompt(consent_type, 129 delegate_->ShowConsentPrompt(consent_type,
127 web_contents, 130 web_contents,
128 consent_callback); 131 consent_callback);
129 } 132 }
130 } 133 }
131 134
135 void PlatformVerificationFlow::RegisterProfilePrefs(
136 user_prefs::PrefRegistrySyncable* prefs) {
137 prefs->RegisterBooleanPref(prefs::kRAConsentFirstTime,
138 false,
139 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
140 prefs->RegisterDictionaryPref(
141 prefs::kRAConsentDomains,
142 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
143 prefs->RegisterBooleanPref(prefs::kRAConsentAlways,
144 false,
145 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
146 }
147
132 void PlatformVerificationFlow::OnConsentResponse( 148 void PlatformVerificationFlow::OnConsentResponse(
133 content::WebContents* web_contents, 149 content::WebContents* web_contents,
134 const std::string& service_id, 150 const std::string& service_id,
135 const std::string& challenge, 151 const std::string& challenge,
136 const ChallengeCallback& callback, 152 const ChallengeCallback& callback,
137 ConsentType consent_type, 153 ConsentType consent_type,
138 ConsentResponse consent_response) { 154 ConsentResponse consent_response) {
139 if (consent_type != CONSENT_TYPE_NONE) { 155 if (consent_type != CONSENT_TYPE_NONE) {
140 if (consent_response == CONSENT_RESPONSE_NONE) { 156 if (consent_response == CONSENT_RESPONSE_NONE) {
141 // No user response - do not proceed and do not modify any settings. 157 // No user response - do not proceed and do not modify any settings.
142 LOG(WARNING) << "PlatformVerificationFlow: No response from user."; 158 LOG(WARNING) << "PlatformVerificationFlow: No response from user.";
143 callback.Run(USER_REJECTED, std::string(), std::string()); 159 callback.Run(USER_REJECTED, std::string(), std::string());
144 return; 160 return;
145 } 161 }
146 if (!delegate_->UpdateSettings(web_contents, 162 if (!UpdateSettings(web_contents, consent_type, consent_response)) {
147 consent_type,
148 consent_response)) {
149 callback.Run(INTERNAL_ERROR, std::string(), std::string()); 163 callback.Run(INTERNAL_ERROR, std::string(), std::string());
150 return; 164 return;
151 } 165 }
152 if (consent_response == CONSENT_RESPONSE_DENY) { 166 if (consent_response == CONSENT_RESPONSE_DENY) {
153 LOG(INFO) << "PlatformVerificationFlow: User rejected request."; 167 LOG(INFO) << "PlatformVerificationFlow: User rejected request.";
154 callback.Run(USER_REJECTED, std::string(), std::string()); 168 callback.Run(USER_REJECTED, std::string(), std::string());
155 return; 169 return;
156 } 170 }
157 } 171 }
158 172
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 const std::string& response_data) { 217 const std::string& response_data) {
204 if (!operation_success) { 218 if (!operation_success) {
205 LOG(ERROR) << "PlatformVerificationFlow: Failed to sign challenge."; 219 LOG(ERROR) << "PlatformVerificationFlow: Failed to sign challenge.";
206 callback.Run(INTERNAL_ERROR, std::string(), std::string()); 220 callback.Run(INTERNAL_ERROR, std::string(), std::string());
207 return; 221 return;
208 } 222 }
209 LOG(INFO) << "PlatformVerificationFlow: Platform successfully verified."; 223 LOG(INFO) << "PlatformVerificationFlow: Platform successfully verified.";
210 callback.Run(SUCCESS, response_data, certificate); 224 callback.Run(SUCCESS, response_data, certificate);
211 } 225 }
212 226
227 PrefService* PlatformVerificationFlow::GetPrefs(
228 content::WebContents* web_contents) {
229 if (testing_prefs_)
230 return testing_prefs_;
231 return user_prefs::UserPrefs::Get(web_contents->GetBrowserContext());
232 }
233
234 const GURL& PlatformVerificationFlow::GetURL(
235 content::WebContents* web_contents) {
236 if (!testing_url_.is_empty())
237 return testing_url_;
238 return web_contents->GetLastCommittedURL();
239 }
240
241 bool PlatformVerificationFlow::IsAttestationEnabled(
242 content::WebContents* web_contents) {
243 // Check the device policy for the feature.
244 bool enabled_for_device = false;
245 if (!CrosSettings::Get()->GetBoolean(kAttestationForContentProtectionEnabled,
246 &enabled_for_device)) {
247 LOG(ERROR) << "Failed to get device setting.";
248 return false;
249 }
250 if (!enabled_for_device)
251 return false;
252
253 // Check the user preference for the feature.
254 PrefService* pref_service = GetPrefs(web_contents);
255 if (!pref_service) {
256 LOG(ERROR) << "Failed to get user prefs.";
257 return false;
258 }
259 if (!pref_service->GetBoolean(prefs::kEnableDRM))
260 return false;
261
262 // Check the user preference for this domain.
263 bool enabled_for_domain = false;
264 bool found = GetDomainPref(web_contents, &enabled_for_domain);
265 return (!found || enabled_for_domain);
266 }
267
268 bool PlatformVerificationFlow::IsFirstUse(content::WebContents* web_contents) {
269 PrefService* pref_service = GetPrefs(web_contents);
270 if (!pref_service) {
271 LOG(ERROR) << "Failed to get user prefs.";
272 return true;
273 }
274 return !pref_service->GetBoolean(prefs::kRAConsentFirstTime);
275 }
276
277 bool PlatformVerificationFlow::IsAlwaysAskRequired(
278 content::WebContents* web_contents) {
279 PrefService* pref_service = GetPrefs(web_contents);
280 if (!pref_service) {
281 LOG(ERROR) << "Failed to get user prefs.";
282 return true;
283 }
284 if (!pref_service->GetBoolean(prefs::kRAConsentAlways))
285 return false;
286 // Show the consent UI if the user has not already explicitly allowed or
287 // denied for this domain.
288 return !GetDomainPref(web_contents, NULL);
289 }
290
291 bool PlatformVerificationFlow::UpdateSettings(
292 content::WebContents* web_contents,
293 ConsentType consent_type,
294 ConsentResponse consent_response) {
295 PrefService* pref_service = GetPrefs(web_contents);
296 if (!pref_service) {
297 LOG(ERROR) << "Failed to get user prefs.";
298 return false;
299 }
300 if (consent_type == CONSENT_TYPE_ATTESTATION) {
301 if (consent_response == CONSENT_RESPONSE_DENY) {
302 pref_service->SetBoolean(prefs::kEnableDRM, false);
303 } else if (consent_response == CONSENT_RESPONSE_ALLOW) {
304 pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
305 RecordDomainConsent(web_contents, true);
306 } else if (consent_response == CONSENT_RESPONSE_ALWAYS_ASK) {
307 pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
308 pref_service->SetBoolean(prefs::kRAConsentAlways, true);
309 RecordDomainConsent(web_contents, true);
310 }
311 } else if (consent_type == CONSENT_TYPE_ALWAYS) {
312 bool allowed = (consent_response == CONSENT_RESPONSE_ALLOW ||
313 consent_response == CONSENT_RESPONSE_ALWAYS_ASK);
314 RecordDomainConsent(web_contents, allowed);
315 }
316 return true;
317 }
318
319 bool PlatformVerificationFlow::GetDomainPref(
320 content::WebContents* web_contents,
321 bool* pref_value) {
322 PrefService* pref_service = GetPrefs(web_contents);
323 CHECK(pref_service);
324 base::DictionaryValue::Iterator iter(
325 *pref_service->GetDictionary(prefs::kRAConsentDomains));
326 const GURL& url = GetURL(web_contents);
327 while (!iter.IsAtEnd()) {
328 if (url.DomainIs(iter.key().c_str())) {
329 if (pref_value) {
330 if (!iter.value().GetAsBoolean(pref_value)) {
331 LOG(ERROR) << "Unexpected pref type.";
332 *pref_value = false;
333 }
334 }
335 return true;
336 }
337 iter.Advance();
338 }
339 return false;
340 }
341
342 void PlatformVerificationFlow::RecordDomainConsent(
343 content::WebContents* web_contents,
344 bool allow_domain) {
345 PrefService* pref_service = GetPrefs(web_contents);
346 CHECK(pref_service);
347 DictionaryPrefUpdate updater(pref_service, prefs::kRAConsentDomains);
348 const GURL& url = GetURL(web_contents);
349 updater->SetBoolean(url.host(), allow_domain);
350 }
351
213 } // namespace attestation 352 } // namespace attestation
214 } // namespace chromeos 353 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698