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 #include "chrome/browser/chromeos/attestation/platform_verification_flow.h" | 5 #include "chrome/browser/chromeos/attestation/platform_verification_flow.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "base/prefs/pref_service.h" | |
| 12 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 13 #include "base/timer/timer.h" | 12 #include "base/timer/timer.h" |
| 14 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h" | 13 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h" |
| 15 #include "chrome/browser/chromeos/attestation/attestation_signed_data.pb.h" | 14 #include "chrome/browser/chromeos/attestation/attestation_signed_data.pb.h" |
| 16 #include "chrome/browser/chromeos/attestation/platform_verification_dialog.h" | |
| 17 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 15 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 18 #include "chrome/browser/chromeos/settings/cros_settings.h" | 16 #include "chrome/browser/chromeos/settings/cros_settings.h" |
| 17 #include "chrome/browser/media/protected_media_identifier_permission_context.h" | |
| 18 #include "chrome/browser/media/protected_media_identifier_permission_context_fac tory.h" | |
| 19 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
| 20 #include "chrome/common/pref_names.h" | |
| 21 #include "chromeos/attestation/attestation_flow.h" | 20 #include "chromeos/attestation/attestation_flow.h" |
| 22 #include "chromeos/cryptohome/async_method_caller.h" | 21 #include "chromeos/cryptohome/async_method_caller.h" |
| 23 #include "chromeos/dbus/cryptohome_client.h" | 22 #include "chromeos/dbus/cryptohome_client.h" |
| 24 #include "chromeos/dbus/dbus_thread_manager.h" | 23 #include "chromeos/dbus/dbus_thread_manager.h" |
| 25 #include "components/content_settings/core/browser/host_content_settings_map.h" | 24 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 26 #include "components/content_settings/core/common/content_settings_pattern.h" | 25 #include "components/content_settings/core/common/content_settings_pattern.h" |
| 27 #include "components/pref_registry/pref_registry_syncable.h" | 26 #include "components/content_settings/core/common/permission_request_id.h" |
| 28 #include "components/user_manager/user.h" | 27 #include "components/user_manager/user.h" |
| 29 #include "components/user_prefs/user_prefs.h" | |
| 30 #include "content/public/browser/browser_context.h" | 28 #include "content/public/browser/browser_context.h" |
| 31 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
| 30 #include "content/public/browser/render_process_host.h" | |
| 31 #include "content/public/browser/render_view_host.h" | |
| 32 #include "content/public/browser/user_metrics.h" | 32 #include "content/public/browser/user_metrics.h" |
| 33 #include "content/public/browser/web_contents.h" | 33 #include "content/public/browser/web_contents.h" |
| 34 #include "content/public/common/url_constants.h" | 34 #include "content/public/common/url_constants.h" |
| 35 #include "net/cert/x509_certificate.h" | 35 #include "net/cert/x509_certificate.h" |
| 36 | 36 |
| 37 namespace { | 37 namespace { |
| 38 | 38 |
| 39 const char kDefaultHttpsPort[] = "443"; | |
| 40 const int kTimeoutInSeconds = 8; | 39 const int kTimeoutInSeconds = 8; |
| 41 const char kAttestationResultHistogram[] = | 40 const char kAttestationResultHistogram[] = |
| 42 "ChromeOS.PlatformVerification.Result"; | 41 "ChromeOS.PlatformVerification.Result"; |
| 43 const char kAttestationAvailableHistogram[] = | 42 const char kAttestationAvailableHistogram[] = |
| 44 "ChromeOS.PlatformVerification.Available"; | 43 "ChromeOS.PlatformVerification.Available"; |
| 45 const int kAttestationResultHistogramMax = 10; | 44 const int kAttestationResultHistogramMax = 10; |
|
xhwang
2015/03/12 17:35:26
This is used for UMA reporting instead of a "LAST"
| |
| 46 | 45 |
| 47 // A callback method to handle DBus errors. | 46 // A callback method to handle DBus errors. |
| 48 void DBusCallback(const base::Callback<void(bool)>& on_success, | 47 void DBusCallback(const base::Callback<void(bool)>& on_success, |
| 49 const base::Closure& on_failure, | 48 const base::Closure& on_failure, |
| 50 chromeos::DBusMethodCallStatus call_status, | 49 chromeos::DBusMethodCallStatus call_status, |
| 51 bool result) { | 50 bool result) { |
| 52 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS) { | 51 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS) { |
| 53 on_success.Run(result); | 52 on_success.Run(result); |
| 54 } else { | 53 } else { |
| 55 LOG(ERROR) << "PlatformVerificationFlow: DBus call failed!"; | 54 LOG(ERROR) << "PlatformVerificationFlow: DBus call failed!"; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 70 | 69 |
| 71 namespace chromeos { | 70 namespace chromeos { |
| 72 namespace attestation { | 71 namespace attestation { |
| 73 | 72 |
| 74 // A default implementation of the Delegate interface. | 73 // A default implementation of the Delegate interface. |
| 75 class DefaultDelegate : public PlatformVerificationFlow::Delegate { | 74 class DefaultDelegate : public PlatformVerificationFlow::Delegate { |
| 76 public: | 75 public: |
| 77 DefaultDelegate() {} | 76 DefaultDelegate() {} |
| 78 ~DefaultDelegate() override {} | 77 ~DefaultDelegate() override {} |
| 79 | 78 |
| 80 void ShowConsentPrompt( | |
| 81 content::WebContents* web_contents, | |
| 82 const GURL& requesting_origin, | |
| 83 const PlatformVerificationFlow::Delegate::ConsentCallback& callback) | |
| 84 override { | |
| 85 PlatformVerificationDialog::ShowDialog(web_contents, requesting_origin, | |
| 86 callback); | |
| 87 } | |
| 88 | |
| 89 PrefService* GetPrefs(content::WebContents* web_contents) override { | |
| 90 return user_prefs::UserPrefs::Get(web_contents->GetBrowserContext()); | |
| 91 } | |
| 92 | |
| 93 const GURL& GetURL(content::WebContents* web_contents) override { | 79 const GURL& GetURL(content::WebContents* web_contents) override { |
| 94 const GURL& url = web_contents->GetLastCommittedURL(); | 80 const GURL& url = web_contents->GetLastCommittedURL(); |
| 95 if (!url.is_valid()) | 81 if (!url.is_valid()) |
| 96 return web_contents->GetVisibleURL(); | 82 return web_contents->GetVisibleURL(); |
| 97 return url; | 83 return url; |
| 98 } | 84 } |
| 99 | 85 |
| 100 const user_manager::User* GetUser( | 86 const user_manager::User* GetUser( |
| 101 content::WebContents* web_contents) override { | 87 content::WebContents* web_contents) override { |
| 102 return ProfileHelper::Get()->GetUserByProfile( | 88 return ProfileHelper::Get()->GetUserByProfile( |
| 103 Profile::FromBrowserContext(web_contents->GetBrowserContext())); | 89 Profile::FromBrowserContext(web_contents->GetBrowserContext())); |
| 104 } | 90 } |
| 105 | 91 |
| 106 HostContentSettingsMap* GetContentSettings( | 92 bool IsPermittedByUser(content::WebContents* web_contents) override { |
| 107 content::WebContents* web_contents) override { | 93 ProtectedMediaIdentifierPermissionContext* permission_context = |
| 108 return Profile::FromBrowserContext(web_contents->GetBrowserContext())-> | 94 ProtectedMediaIdentifierPermissionContextFactory::GetForProfile( |
| 109 GetHostContentSettingsMap(); | 95 Profile::FromBrowserContext(web_contents->GetBrowserContext())); |
| 96 | |
| 97 // TODO(xhwang): Using delegate_->GetURL() here is not right. The platform | |
|
ddorwin
2015/03/12 03:58:11
What URL does this give us? GLCURL below gets us t
xhwang
2015/03/12 17:35:26
It's up to the delegate's implementation. For non-
ddorwin
2015/03/12 21:38:53
Existing CPs probably aren't iframed, except maybe
xhwang
2015/03/13 21:31:15
Acknowledged.
| |
| 98 // verification may be requested by a frame from a different origin. This | |
| 99 // will | |
| 100 // be solved when http://crbug.com/454847 is fixed. | |
| 101 const GURL& requesting_origin = GetURL(web_contents).GetOrigin(); | |
| 102 | |
| 103 GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin(); | |
| 104 | |
| 105 ContentSetting content_setting = permission_context->GetPermissionStatus( | |
| 106 requesting_origin, embedding_origin); | |
| 107 | |
| 108 return content_setting == CONTENT_SETTING_ALLOW; | |
| 110 } | 109 } |
| 111 | 110 |
| 112 bool IsGuestOrIncognito(content::WebContents* web_contents) override { | 111 bool IsGuestOrIncognito(content::WebContents* web_contents) override { |
| 113 Profile* profile = | 112 Profile* profile = |
| 114 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 113 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 115 return (profile->IsOffTheRecord() || profile->IsGuestSession()); | 114 return (profile->IsOffTheRecord() || profile->IsGuestSession()); |
| 116 } | 115 } |
| 117 | 116 |
| 118 private: | 117 private: |
| 119 DISALLOW_COPY_AND_ASSIGN(DefaultDelegate); | 118 DISALLOW_COPY_AND_ASSIGN(DefaultDelegate); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 167 | 166 |
| 168 PlatformVerificationFlow::~PlatformVerificationFlow() { | 167 PlatformVerificationFlow::~PlatformVerificationFlow() { |
| 169 } | 168 } |
| 170 | 169 |
| 171 void PlatformVerificationFlow::ChallengePlatformKey( | 170 void PlatformVerificationFlow::ChallengePlatformKey( |
| 172 content::WebContents* web_contents, | 171 content::WebContents* web_contents, |
| 173 const std::string& service_id, | 172 const std::string& service_id, |
| 174 const std::string& challenge, | 173 const std::string& challenge, |
| 175 const ChallengeCallback& callback) { | 174 const ChallengeCallback& callback) { |
| 176 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 175 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 176 | |
| 177 if (!delegate_->GetURL(web_contents).is_valid()) { | 177 if (!delegate_->GetURL(web_contents).is_valid()) { |
| 178 LOG(WARNING) << "PlatformVerificationFlow: Invalid URL."; | 178 LOG(WARNING) << "PlatformVerificationFlow: Invalid URL."; |
| 179 ReportError(callback, INTERNAL_ERROR); | 179 ReportError(callback, INTERNAL_ERROR); |
| 180 return; | 180 return; |
| 181 } | 181 } |
| 182 if (!IsAttestationEnabled(web_contents)) { | 182 |
| 183 // Note: The following two checks are also checked in GetPermissionStatus. | |
| 184 // Checking them here explicitly to report the correct error type. | |
|
xhwang
2015/03/12 00:25:00
The results are reported to UMA, that's why I have
| |
| 185 | |
| 186 if (!IsAttestationAllowedByPolicy()) { | |
| 187 VLOG(1) << "Platform verification not allowed by device policy."; | |
| 183 ReportError(callback, POLICY_REJECTED); | 188 ReportError(callback, POLICY_REJECTED); |
| 184 return; | 189 return; |
| 185 } | 190 } |
| 186 // A platform key must be bound to a user. They are not allowed in incognito | 191 |
| 192 // A platform key must be bound to a user. They are not allowed in incognito | |
| 187 // or guest mode. | 193 // or guest mode. |
| 188 if (delegate_->IsGuestOrIncognito(web_contents)) { | 194 if (delegate_->IsGuestOrIncognito(web_contents)) { |
| 189 VLOG(1) << "Platform verification denied because the current session is " | 195 VLOG(1) << "Platform verification denied because the current session is " |
| 190 << "guest or incognito."; | 196 << "guest or incognito."; |
| 191 ReportError(callback, PLATFORM_NOT_VERIFIED); | 197 ReportError(callback, PLATFORM_NOT_VERIFIED); |
|
ddorwin
2015/03/12 03:58:11
Should we DCHECK here? Unlike user settings, it's
xhwang
2015/03/12 17:35:26
Well, for prefixed EME, we are not stopping the pl
ddorwin
2015/03/12 21:38:53
Oh, so TODO to DCHECK after removing prefixed (249
xhwang
2015/03/13 21:31:15
Done.
| |
| 192 return; | 198 return; |
| 193 } | 199 } |
| 200 | |
| 201 if (!delegate_->IsPermittedByUser(web_contents)) { | |
| 202 VLOG(1) << "Platform verification not permitted by user."; | |
| 203 ReportError(callback, USER_REJECTED); | |
| 204 return; | |
| 205 } | |
| 206 | |
| 194 ChallengeContext context(web_contents, service_id, challenge, callback); | 207 ChallengeContext context(web_contents, service_id, challenge, callback); |
| 195 // Check if the device has been prepared to use attestation. | 208 // Check if the device has been prepared to use attestation. |
| 196 BoolDBusMethodCallback dbus_callback = base::Bind( | 209 BoolDBusMethodCallback dbus_callback = |
| 197 &DBusCallback, | 210 base::Bind(&DBusCallback, |
| 198 base::Bind(&PlatformVerificationFlow::CheckEnrollment, this, context), | 211 base::Bind(&PlatformVerificationFlow::OnAttestationPrepared, |
| 199 base::Bind(&ReportError, callback, INTERNAL_ERROR)); | 212 this, context), |
| 213 base::Bind(&ReportError, callback, INTERNAL_ERROR)); | |
| 200 cryptohome_client_->TpmAttestationIsPrepared(dbus_callback); | 214 cryptohome_client_->TpmAttestationIsPrepared(dbus_callback); |
| 201 } | 215 } |
| 202 | 216 |
| 203 void PlatformVerificationFlow::CheckEnrollment(const ChallengeContext& context, | 217 void PlatformVerificationFlow::OnAttestationPrepared( |
| 204 bool attestation_prepared) { | 218 const ChallengeContext& context, |
| 219 bool attestation_prepared) { | |
| 205 UMA_HISTOGRAM_BOOLEAN(kAttestationAvailableHistogram, attestation_prepared); | 220 UMA_HISTOGRAM_BOOLEAN(kAttestationAvailableHistogram, attestation_prepared); |
| 221 | |
| 206 if (!attestation_prepared) { | 222 if (!attestation_prepared) { |
| 207 // This device is not currently able to use attestation features. | 223 // This device is not currently able to use attestation features. |
| 208 ReportError(context.callback, PLATFORM_NOT_VERIFIED); | 224 ReportError(context.callback, PLATFORM_NOT_VERIFIED); |
| 209 return; | 225 return; |
| 210 } | 226 } |
| 211 BoolDBusMethodCallback dbus_callback = base::Bind( | |
| 212 &DBusCallback, | |
| 213 base::Bind(&PlatformVerificationFlow::CheckConsent, this, context), | |
| 214 base::Bind(&ReportError, context.callback, INTERNAL_ERROR)); | |
| 215 cryptohome_client_->TpmAttestationIsEnrolled(dbus_callback); | |
| 216 } | |
| 217 | 227 |
| 218 void PlatformVerificationFlow::CheckConsent(const ChallengeContext& context, | 228 // Permission allowed. Now proceed to get certificate. |
| 219 bool /* attestation_enrolled */) { | |
| 220 content::WebContents* web_contents = context.web_contents; | |
| 221 | |
| 222 bool enabled_for_origin = false; | |
| 223 bool found = | |
| 224 GetOriginPref(delegate_->GetContentSettings(web_contents), | |
| 225 delegate_->GetURL(web_contents), &enabled_for_origin); | |
| 226 if (found && !enabled_for_origin) { | |
| 227 VLOG(1) << "Platform verification denied because the origin has been " | |
| 228 << "blocked by the user."; | |
| 229 ReportError(context.callback, USER_REJECTED); | |
| 230 return; | |
| 231 } | |
| 232 | |
| 233 PrefService* pref_service = delegate_->GetPrefs(web_contents); | |
| 234 if (!pref_service) { | |
| 235 LOG(ERROR) << "Failed to get user prefs."; | |
| 236 ReportError(context.callback, INTERNAL_ERROR); | |
| 237 return; | |
| 238 } | |
| 239 | |
| 240 // Consent required if user has never given consent for this origin, or if | |
| 241 // user has never given consent to attestation for content protection on this | |
| 242 // device. | |
| 243 bool consent_required = | |
| 244 !found || !pref_service->GetBoolean(prefs::kRAConsentGranted); | |
| 245 | |
| 246 Delegate::ConsentCallback consent_callback = base::Bind( | |
| 247 &PlatformVerificationFlow::OnConsentResponse, | |
| 248 this, | |
| 249 context, | |
| 250 consent_required); | |
| 251 if (consent_required) { | |
| 252 // TODO(xhwang): Using delegate_->GetURL() here is not right. The consent | |
| 253 // may be requested by a frame from a different origin. This will be solved | |
| 254 // when http://crbug.com/454847 is fixed. | |
| 255 delegate_->ShowConsentPrompt( | |
| 256 context.web_contents, | |
| 257 delegate_->GetURL(context.web_contents).GetOrigin(), consent_callback); | |
| 258 } else { | |
| 259 consent_callback.Run(CONSENT_RESPONSE_NONE); | |
| 260 } | |
| 261 } | |
| 262 | |
| 263 void PlatformVerificationFlow::RegisterProfilePrefs( | |
| 264 user_prefs::PrefRegistrySyncable* prefs) { | |
| 265 prefs->RegisterBooleanPref(prefs::kRAConsentGranted, | |
| 266 false, // Default value. | |
| 267 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | |
| 268 } | |
| 269 | |
| 270 void PlatformVerificationFlow::OnConsentResponse( | |
| 271 const ChallengeContext& context, | |
| 272 bool consent_required, | |
| 273 ConsentResponse consent_response) { | |
| 274 if (consent_required) { | |
| 275 if (consent_response == CONSENT_RESPONSE_NONE) { | |
| 276 // No user response - do not proceed and do not modify any settings. | |
| 277 LOG(WARNING) << "PlatformVerificationFlow: No response from user."; | |
| 278 ReportError(context.callback, USER_REJECTED); | |
| 279 return; | |
| 280 } | |
| 281 if (!UpdateSettings(context.web_contents, consent_response)) { | |
| 282 ReportError(context.callback, INTERNAL_ERROR); | |
| 283 return; | |
| 284 } | |
| 285 if (consent_response == CONSENT_RESPONSE_DENY) { | |
| 286 content::RecordAction( | |
| 287 base::UserMetricsAction("PlatformVerificationRejected")); | |
| 288 VLOG(1) << "Platform verification denied by user."; | |
| 289 ReportError(context.callback, USER_REJECTED); | |
| 290 return; | |
| 291 } else if (consent_response == CONSENT_RESPONSE_ALLOW) { | |
| 292 content::RecordAction( | |
| 293 base::UserMetricsAction("PlatformVerificationAccepted")); | |
| 294 VLOG(1) << "Platform verification accepted by user."; | |
| 295 } | |
| 296 } | |
| 297 | |
| 298 // At this point all user interaction is complete and we can proceed with the | |
| 299 // certificate request. | |
| 300 const user_manager::User* user = delegate_->GetUser(context.web_contents); | 229 const user_manager::User* user = delegate_->GetUser(context.web_contents); |
| 301 if (!user) { | 230 if (!user) { |
| 302 ReportError(context.callback, INTERNAL_ERROR); | 231 ReportError(context.callback, INTERNAL_ERROR); |
| 303 LOG(ERROR) << "Profile does not map to a valid user."; | 232 LOG(ERROR) << "Profile does not map to a valid user."; |
| 304 return; | 233 return; |
| 305 } | 234 } |
| 306 | 235 |
| 307 GetCertificate(context, user->email(), false /* Don't force a new key */); | 236 GetCertificate(context, user->email(), false /* Don't force a new key */); |
| 308 } | 237 } |
| 309 | 238 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 } | 324 } |
| 396 VLOG(1) << "Platform verification successful."; | 325 VLOG(1) << "Platform verification successful."; |
| 397 UMA_HISTOGRAM_ENUMERATION(kAttestationResultHistogram, SUCCESS, | 326 UMA_HISTOGRAM_ENUMERATION(kAttestationResultHistogram, SUCCESS, |
| 398 kAttestationResultHistogramMax); | 327 kAttestationResultHistogramMax); |
| 399 context.callback.Run(SUCCESS, | 328 context.callback.Run(SUCCESS, |
| 400 signed_data_pb.data(), | 329 signed_data_pb.data(), |
| 401 signed_data_pb.signature(), | 330 signed_data_pb.signature(), |
| 402 certificate); | 331 certificate); |
| 403 } | 332 } |
| 404 | 333 |
| 405 bool PlatformVerificationFlow::IsAttestationEnabled( | 334 bool PlatformVerificationFlow::IsAttestationAllowedByPolicy() { |
| 406 content::WebContents* web_contents) { | |
| 407 // Check the device policy for the feature. | 335 // Check the device policy for the feature. |
| 408 bool enabled_for_device = false; | 336 bool enabled_for_device = false; |
| 409 if (!CrosSettings::Get()->GetBoolean(kAttestationForContentProtectionEnabled, | 337 if (!CrosSettings::Get()->GetBoolean(kAttestationForContentProtectionEnabled, |
| 410 &enabled_for_device)) { | 338 &enabled_for_device)) { |
| 411 LOG(ERROR) << "Failed to get device setting."; | 339 LOG(ERROR) << "Failed to get device setting."; |
| 412 return false; | 340 return false; |
| 413 } | 341 } |
| 414 if (!enabled_for_device) { | 342 if (!enabled_for_device) { |
| 415 VLOG(1) << "Platform verification denied because Verified Access is " | 343 VLOG(1) << "Platform verification denied because Verified Access is " |
| 416 << "disabled for the device."; | 344 << "disabled for the device."; |
| 417 return false; | 345 return false; |
| 418 } | 346 } |
| 419 | 347 |
| 420 // Check the user preference for the feature. | |
| 421 PrefService* pref_service = delegate_->GetPrefs(web_contents); | |
| 422 if (!pref_service) { | |
| 423 LOG(ERROR) << "Failed to get user prefs."; | |
| 424 return false; | |
| 425 } | |
| 426 if (!pref_service->GetBoolean(prefs::kEnableDRM)) { | |
| 427 VLOG(1) << "Platform verification denied because content protection " | |
| 428 << "identifiers have been disabled by the user."; | |
| 429 return false; | |
| 430 } | |
| 431 | |
| 432 // Check the user preference for this origin. | |
| 433 bool enabled_for_origin = false; | |
| 434 bool found = | |
| 435 GetOriginPref(delegate_->GetContentSettings(web_contents), | |
| 436 delegate_->GetURL(web_contents), &enabled_for_origin); | |
| 437 if (found && !enabled_for_origin) { | |
| 438 VLOG(1) << "Platform verification denied because the origin has been " | |
| 439 << "blocked by the user."; | |
| 440 return false; | |
| 441 } | |
| 442 return true; | 348 return true; |
| 443 } | 349 } |
| 444 | 350 |
| 445 bool PlatformVerificationFlow::UpdateSettings( | |
| 446 content::WebContents* web_contents, | |
| 447 ConsentResponse consent_response) { | |
| 448 PrefService* pref_service = delegate_->GetPrefs(web_contents); | |
| 449 if (!pref_service) { | |
| 450 LOG(ERROR) << "Failed to get user prefs."; | |
| 451 return false; | |
| 452 } | |
| 453 | |
| 454 if (consent_response == CONSENT_RESPONSE_ALLOW) { | |
| 455 pref_service->SetBoolean(prefs::kRAConsentGranted, true); | |
| 456 } | |
| 457 | |
| 458 RecordOriginConsent(delegate_->GetContentSettings(web_contents), | |
| 459 delegate_->GetURL(web_contents), | |
| 460 (consent_response == CONSENT_RESPONSE_ALLOW)); | |
| 461 return true; | |
| 462 } | |
| 463 | |
| 464 bool PlatformVerificationFlow::GetOriginPref( | |
| 465 HostContentSettingsMap* content_settings, | |
| 466 const GURL& url, | |
| 467 bool* pref_value) { | |
| 468 CHECK(content_settings); | |
| 469 CHECK(url.is_valid()); | |
| 470 ContentSetting setting = content_settings->GetContentSetting( | |
| 471 url, | |
| 472 url, | |
| 473 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, | |
| 474 std::string()); | |
| 475 if (setting != CONTENT_SETTING_ALLOW && setting != CONTENT_SETTING_BLOCK) | |
| 476 return false; | |
| 477 if (pref_value) | |
| 478 *pref_value = (setting == CONTENT_SETTING_ALLOW); | |
| 479 return true; | |
| 480 } | |
| 481 | |
| 482 void PlatformVerificationFlow::RecordOriginConsent( | |
| 483 HostContentSettingsMap* content_settings, | |
| 484 const GURL& url, | |
| 485 bool allow_origin) { | |
| 486 CHECK(content_settings); | |
| 487 CHECK(url.is_valid()); | |
| 488 // Build a pattern to represent scheme and host. | |
| 489 scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( | |
| 490 ContentSettingsPattern::CreateBuilder(false)); | |
| 491 builder->WithScheme(url.scheme()) | |
| 492 ->WithDomainWildcard() | |
| 493 ->WithHost(url.host()) | |
| 494 ->WithPathWildcard(); | |
| 495 if (!url.port().empty()) | |
| 496 builder->WithPort(url.port()); | |
| 497 else if (url.SchemeIs(url::kHttpsScheme)) | |
| 498 builder->WithPort(kDefaultHttpsPort); | |
| 499 else if (url.SchemeIs(url::kHttpScheme)) | |
| 500 builder->WithPortWildcard(); | |
| 501 ContentSettingsPattern pattern = builder->Build(); | |
| 502 if (pattern.IsValid()) { | |
| 503 ContentSetting setting = | |
| 504 allow_origin ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; | |
| 505 content_settings->SetContentSetting( | |
| 506 pattern, | |
| 507 pattern, | |
| 508 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, | |
| 509 std::string(), | |
| 510 setting); | |
| 511 } else { | |
| 512 LOG(WARNING) << "Not recording action: invalid URL pattern"; | |
| 513 } | |
| 514 } | |
| 515 | |
| 516 bool PlatformVerificationFlow::IsExpired(const std::string& certificate) { | 351 bool PlatformVerificationFlow::IsExpired(const std::string& certificate) { |
| 517 scoped_refptr<net::X509Certificate> x509( | 352 scoped_refptr<net::X509Certificate> x509( |
| 518 net::X509Certificate::CreateFromBytes(certificate.data(), | 353 net::X509Certificate::CreateFromBytes(certificate.data(), |
| 519 certificate.length())); | 354 certificate.length())); |
| 520 if (!x509.get() || x509->valid_expiry().is_null()) { | 355 if (!x509.get() || x509->valid_expiry().is_null()) { |
| 521 LOG(WARNING) << "Failed to parse certificate, cannot check expiry."; | 356 LOG(WARNING) << "Failed to parse certificate, cannot check expiry."; |
| 522 return false; | 357 return false; |
| 523 } | 358 } |
| 524 return (base::Time::Now() > x509->valid_expiry()); | 359 return (base::Time::Now() > x509->valid_expiry()); |
| 525 } | 360 } |
| 526 | 361 |
| 527 } // namespace attestation | 362 } // namespace attestation |
| 528 } // namespace chromeos | 363 } // namespace chromeos |
| OLD | NEW |