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

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: 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"
9 #include "base/strings/utf_string_conversions.h"
Mattias Nissler (ping if slow) 2013/09/03 14:31:25 required?
Darren Krahn 2013/09/04 12:35:05 Done.
8 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h" 10 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h"
9 #include "chrome/browser/chromeos/login/user_manager.h" 11 #include "chrome/browser/chromeos/login/user_manager.h"
10 #include "chrome/browser/chromeos/settings/cros_settings.h" 12 #include "chrome/browser/chromeos/settings/cros_settings.h"
13 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
Mattias Nissler (ping if slow) 2013/09/03 14:31:25 required?
Darren Krahn 2013/09/04 12:35:05 Done.
14 #include "chrome/browser/prefs/scoped_user_pref_update.h"
15 #include "chrome/common/pref_names.h"
11 #include "chromeos/attestation/attestation_flow.h" 16 #include "chromeos/attestation/attestation_flow.h"
12 #include "chromeos/cryptohome/async_method_caller.h" 17 #include "chromeos/cryptohome/async_method_caller.h"
13 #include "chromeos/dbus/cryptohome_client.h" 18 #include "chromeos/dbus/cryptohome_client.h"
14 #include "chromeos/dbus/dbus_thread_manager.h" 19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "components/user_prefs/pref_registry_syncable.h"
21 #include "components/user_prefs/user_prefs.h"
15 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/web_contents.h" 23 #include "content/public/browser/web_contents.h"
17 24
18 namespace { 25 namespace {
19 // A callback method to handle DBus errors. 26 // A callback method to handle DBus errors.
20 void DBusCallback(const base::Callback<void(bool)>& on_success, 27 void DBusCallback(const base::Callback<void(bool)>& on_success,
21 const base::Closure& on_failure, 28 const base::Closure& on_failure,
22 chromeos::DBusMethodCallStatus call_status, 29 chromeos::DBusMethodCallStatus call_status,
23 bool result) { 30 bool result) {
24 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS) { 31 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS) {
(...skipping 25 matching lines...) Expand all
50 57
51 PlatformVerificationFlow::~PlatformVerificationFlow() { 58 PlatformVerificationFlow::~PlatformVerificationFlow() {
52 } 59 }
53 60
54 void PlatformVerificationFlow::ChallengePlatformKey( 61 void PlatformVerificationFlow::ChallengePlatformKey(
55 content::WebContents* web_contents, 62 content::WebContents* web_contents,
56 const std::string& service_id, 63 const std::string& service_id,
57 const std::string& challenge, 64 const std::string& challenge,
58 const ChallengeCallback& callback) { 65 const ChallengeCallback& callback) {
59 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 66 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
60 if (delegate_->IsAttestationDisabled()) { 67 if (!IsAttestationEnabled(web_contents)) {
61 LOG(INFO) << "PlatformVerificationFlow: Feature disabled."; 68 LOG(INFO) << "PlatformVerificationFlow: Feature disabled.";
62 callback.Run(POLICY_REJECTED, std::string(), std::string()); 69 callback.Run(POLICY_REJECTED, std::string(), std::string());
63 return; 70 return;
64 } 71 }
65 BoolDBusMethodCallback dbus_callback = base::Bind( 72 BoolDBusMethodCallback dbus_callback = base::Bind(
66 &DBusCallback, 73 &DBusCallback,
67 base::Bind(&PlatformVerificationFlow::CheckConsent, 74 base::Bind(&PlatformVerificationFlow::CheckConsent,
68 weak_factory_.GetWeakPtr(), 75 weak_factory_.GetWeakPtr(),
69 web_contents, 76 web_contents,
70 service_id, 77 service_id,
71 challenge, 78 challenge,
72 callback), 79 callback),
73 base::Bind(callback, INTERNAL_ERROR, std::string(), std::string())); 80 base::Bind(callback, INTERNAL_ERROR, std::string(), std::string()));
74 cryptohome_client_->TpmAttestationIsEnrolled(dbus_callback); 81 cryptohome_client_->TpmAttestationIsEnrolled(dbus_callback);
75 } 82 }
76 83
77 void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents, 84 void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents,
78 const std::string& service_id, 85 const std::string& service_id,
79 const std::string& challenge, 86 const std::string& challenge,
80 const ChallengeCallback& callback, 87 const ChallengeCallback& callback,
81 bool attestation_enrolled) { 88 bool attestation_enrolled) {
82 ConsentType consent_type = CONSENT_TYPE_NONE; 89 ConsentType consent_type = CONSENT_TYPE_NONE;
83 if (!attestation_enrolled) { 90 if (!attestation_enrolled || IsFirstUse(web_contents)) {
84 consent_type = CONSENT_TYPE_ATTESTATION; 91 consent_type = CONSENT_TYPE_ATTESTATION;
85 } else if (delegate_->IsOriginConsentRequired(web_contents)) { 92 } else if (IsAlwaysAskRequired(web_contents)) {
86 consent_type = CONSENT_TYPE_ORIGIN;
87 } else if (delegate_->IsAlwaysAskRequired(web_contents)) {
88 consent_type = CONSENT_TYPE_ALWAYS; 93 consent_type = CONSENT_TYPE_ALWAYS;
89 } 94 }
90 Delegate::ConsentCallback consent_callback = base::Bind( 95 Delegate::ConsentCallback consent_callback = base::Bind(
91 &PlatformVerificationFlow::OnConsentResponse, 96 &PlatformVerificationFlow::OnConsentResponse,
92 weak_factory_.GetWeakPtr(), 97 weak_factory_.GetWeakPtr(),
93 web_contents, 98 web_contents,
94 service_id, 99 service_id,
95 challenge, 100 challenge,
96 callback, 101 callback,
97 consent_type); 102 consent_type);
98 if (consent_type == CONSENT_TYPE_NONE) { 103 if (consent_type == CONSENT_TYPE_NONE) {
99 consent_callback.Run(CONSENT_RESPONSE_NONE); 104 consent_callback.Run(CONSENT_RESPONSE_NONE);
100 } else { 105 } else {
101 delegate_->ShowConsentPrompt(consent_type, 106 delegate_->ShowConsentPrompt(consent_type,
102 web_contents, 107 web_contents,
103 consent_callback); 108 consent_callback);
104 } 109 }
105 } 110 }
106 111
112 void PlatformVerificationFlow::RegisterProfilePrefs(
113 user_prefs::PrefRegistrySyncable* prefs) {
114 prefs->RegisterBooleanPref(prefs::kRAConsentFirstTime,
115 false,
116 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
117 prefs->RegisterDictionaryPref(
118 prefs::kRAConsentDomains,
119 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
120 prefs->RegisterBooleanPref(prefs::kRAConsentAlways,
121 false,
122 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
123 }
124
107 void PlatformVerificationFlow::OnConsentResponse( 125 void PlatformVerificationFlow::OnConsentResponse(
108 content::WebContents* web_contents, 126 content::WebContents* web_contents,
109 const std::string& service_id, 127 const std::string& service_id,
110 const std::string& challenge, 128 const std::string& challenge,
111 const ChallengeCallback& callback, 129 const ChallengeCallback& callback,
112 ConsentType consent_type, 130 ConsentType consent_type,
113 ConsentResponse consent_response) { 131 ConsentResponse consent_response) {
114 if (consent_type != CONSENT_TYPE_NONE) { 132 if (consent_type != CONSENT_TYPE_NONE) {
115 if (consent_response == CONSENT_RESPONSE_NONE) { 133 if (consent_response == CONSENT_RESPONSE_NONE) {
116 // No user response - do not proceed and do not modify any settings. 134 // No user response - do not proceed and do not modify any settings.
117 LOG(WARNING) << "PlatformVerificationFlow: No response from user."; 135 LOG(WARNING) << "PlatformVerificationFlow: No response from user.";
118 callback.Run(USER_REJECTED, std::string(), std::string()); 136 callback.Run(USER_REJECTED, std::string(), std::string());
119 return; 137 return;
120 } 138 }
121 if (!delegate_->UpdateSettings(web_contents, 139 if (!UpdateSettings(web_contents, consent_type, consent_response)) {
122 consent_type,
123 consent_response)) {
124 callback.Run(INTERNAL_ERROR, std::string(), std::string()); 140 callback.Run(INTERNAL_ERROR, std::string(), std::string());
125 return; 141 return;
126 } 142 }
127 if (consent_response == CONSENT_RESPONSE_DENY) { 143 if (consent_response == CONSENT_RESPONSE_DENY) {
128 LOG(INFO) << "PlatformVerificationFlow: User rejected request."; 144 LOG(INFO) << "PlatformVerificationFlow: User rejected request.";
129 callback.Run(USER_REJECTED, std::string(), std::string()); 145 callback.Run(USER_REJECTED, std::string(), std::string());
130 return; 146 return;
131 } 147 }
132 } 148 }
133 149
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 const std::string& response_data) { 194 const std::string& response_data) {
179 if (!operation_success) { 195 if (!operation_success) {
180 LOG(ERROR) << "PlatformVerificationFlow: Failed to sign challenge."; 196 LOG(ERROR) << "PlatformVerificationFlow: Failed to sign challenge.";
181 callback.Run(INTERNAL_ERROR, std::string(), std::string()); 197 callback.Run(INTERNAL_ERROR, std::string(), std::string());
182 return; 198 return;
183 } 199 }
184 LOG(INFO) << "PlatformVerificationFlow: Platform successfully verified."; 200 LOG(INFO) << "PlatformVerificationFlow: Platform successfully verified.";
185 callback.Run(SUCCESS, response_data, certificate); 201 callback.Run(SUCCESS, response_data, certificate);
186 } 202 }
187 203
204 PrefService* PlatformVerificationFlow::GetPrefs(
205 content::WebContents* web_contents) {
206 if (testing_prefs_)
207 return testing_prefs_;
208 return user_prefs::UserPrefs::Get(web_contents->GetBrowserContext());
209 }
210
211 const GURL& PlatformVerificationFlow::GetURL(
212 content::WebContents* web_contents) {
213 if (!testing_url_.is_empty())
214 return testing_url_;
215 return web_contents->GetLastCommittedURL();
216 }
217
218 bool PlatformVerificationFlow::IsAttestationEnabled(
219 content::WebContents* web_contents) {
220 // Check the device policy for the feature.
221 bool enabled_for_device = false;
222 if (!CrosSettings::Get()->GetBoolean(kAttestationForContentProtectionEnabled,
223 &enabled_for_device)) {
224 LOG(ERROR) << "Failed to get device setting.";
225 return false;
226 }
227 if (!enabled_for_device)
228 return false;
229
230 // Check the user preference for the feature.
231 PrefService* pref_service = GetPrefs(web_contents);
232 if (!pref_service) {
233 LOG(ERROR) << "Failed to get user prefs.";
234 return false;
235 }
236 if (!pref_service->GetBoolean(prefs::kEnableDRM))
237 return false;
238
239 // Check the user preference for this domain.
240 bool enabled_for_domain = false;
241 bool found = FindDomainPref(web_contents, &enabled_for_domain);
242 return (!found || enabled_for_domain);
243 }
244
245 bool PlatformVerificationFlow::IsFirstUse(content::WebContents* web_contents) {
246 PrefService* pref_service = GetPrefs(web_contents);
247 if (!pref_service) {
248 LOG(ERROR) << "Failed to get user prefs.";
249 return true;
250 }
251 return !pref_service->GetBoolean(prefs::kRAConsentFirstTime);
252 }
253
254 bool PlatformVerificationFlow::IsAlwaysAskRequired(
255 content::WebContents* web_contents) {
256 PrefService* pref_service = GetPrefs(web_contents);
257 if (!pref_service) {
258 LOG(ERROR) << "Failed to get user prefs.";
259 return false;
Mattias Nissler (ping if slow) 2013/09/03 14:31:25 Shouldn't we default to true here?
Darren Krahn 2013/09/04 12:35:05 Done.
260 }
261 if (!pref_service->GetBoolean(prefs::kRAConsentAlways))
262 return false;
263 // Show the consent UI if the user has not already explicitly allowed or
264 // denied for this domain.
265 return !FindDomainPref(web_contents, NULL);
266 }
267
268 bool PlatformVerificationFlow::UpdateSettings(
269 content::WebContents* web_contents,
270 ConsentType consent_type,
271 ConsentResponse consent_response) {
272 PrefService* pref_service = GetPrefs(web_contents);
273 if (!pref_service) {
274 LOG(ERROR) << "Failed to get user prefs.";
275 return false;
276 }
277 if (consent_type == CONSENT_TYPE_ATTESTATION) {
278 if (consent_response == CONSENT_RESPONSE_DENY) {
279 pref_service->SetBoolean(prefs::kEnableDRM, false);
280 } else if (consent_response == CONSENT_RESPONSE_ALLOW) {
281 pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
282 RecordDomainConsent(web_contents, true);
283 } else if (consent_response == CONSENT_RESPONSE_ALWAYS_ASK) {
284 pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
285 pref_service->SetBoolean(prefs::kRAConsentAlways, true);
286 RecordDomainConsent(web_contents, true);
287 }
288 } else if (consent_type == CONSENT_TYPE_ALWAYS) {
289 bool allowed = (consent_response == CONSENT_RESPONSE_ALLOW ||
290 consent_response == CONSENT_RESPONSE_ALWAYS_ASK);
291 RecordDomainConsent(web_contents, allowed);
292 }
293 return true;
294 }
295
296 bool PlatformVerificationFlow::FindDomainPref(
Mattias Nissler (ping if slow) 2013/09/03 14:31:25 This should probably be GetDomainPref
Darren Krahn 2013/09/04 12:35:05 Done.
297 content::WebContents* web_contents,
298 bool* pref_value) {
299 PrefService* pref_service = GetPrefs(web_contents);
300 CHECK(pref_service);
301 base::DictionaryValue::Iterator iter(
302 *pref_service->GetDictionary(prefs::kRAConsentDomains));
303 const GURL& url = GetURL(web_contents);
304 while (!iter.IsAtEnd()) {
305 if (url.DomainIs(iter.key().c_str())) {
306 if (pref_value) {
307 if (!iter.value().GetAsBoolean(pref_value)) {
308 LOG(ERROR) << "Unexpected pref type.";
309 *pref_value = false;
310 }
311 }
312 return true;
313 }
314 iter.Advance();
315 }
316 return false;
317 }
318
319 void PlatformVerificationFlow::RecordDomainConsent(
320 content::WebContents* web_contents,
321 bool allow_domain) {
322 PrefService* pref_service = GetPrefs(web_contents);
323 CHECK(pref_service);
324 DictionaryPrefUpdate updater(pref_service, prefs::kRAConsentDomains);
325 const GURL& url = GetURL(web_contents);
326 updater->SetBoolean(url.host(), allow_domain);
327 }
328
188 } // namespace attestation 329 } // namespace attestation
189 } // namespace chromeos 330 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698