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

Unified Diff: chrome/browser/chromeos/attestation/platform_verification_flow.cc

Issue 1001723002: media: Refactor PlatformVerificationFlow. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments addressed Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/attestation/platform_verification_flow.cc
diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow.cc b/chrome/browser/chromeos/attestation/platform_verification_flow.cc
index 5e03617a663ee3926ee42e0cdc02ae352d4a3695..a1db8b0ab665b241d66fba6db443361ce1834509 100644
--- a/chrome/browser/chromeos/attestation/platform_verification_flow.cc
+++ b/chrome/browser/chromeos/attestation/platform_verification_flow.cc
@@ -8,27 +8,27 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
-#include "base/prefs/pref_service.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/chromeos/attestation/attestation_ca_client.h"
#include "chrome/browser/chromeos/attestation/attestation_signed_data.pb.h"
-#include "chrome/browser/chromeos/attestation/platform_verification_dialog.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/media/protected_media_identifier_permission_context.h"
+#include "chrome/browser/media/protected_media_identifier_permission_context_factory.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/common/pref_names.h"
#include "chromeos/attestation/attestation_flow.h"
#include "chromeos/cryptohome/async_method_caller.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
-#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/content_settings/core/common/permission_request_id.h"
#include "components/user_manager/user.h"
-#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
@@ -36,7 +36,6 @@
namespace {
-const char kDefaultHttpsPort[] = "443";
const int kTimeoutInSeconds = 8;
const char kAttestationResultHistogram[] =
"ChromeOS.PlatformVerification.Result";
@@ -77,19 +76,6 @@ class DefaultDelegate : public PlatformVerificationFlow::Delegate {
DefaultDelegate() {}
~DefaultDelegate() override {}
- void ShowConsentPrompt(
- content::WebContents* web_contents,
- const GURL& requesting_origin,
- const PlatformVerificationFlow::Delegate::ConsentCallback& callback)
- override {
- PlatformVerificationDialog::ShowDialog(web_contents, requesting_origin,
- callback);
- }
-
- PrefService* GetPrefs(content::WebContents* web_contents) override {
- return user_prefs::UserPrefs::Get(web_contents->GetBrowserContext());
- }
-
const GURL& GetURL(content::WebContents* web_contents) override {
const GURL& url = web_contents->GetLastCommittedURL();
if (!url.is_valid())
@@ -103,10 +89,22 @@ class DefaultDelegate : public PlatformVerificationFlow::Delegate {
Profile::FromBrowserContext(web_contents->GetBrowserContext()));
}
- HostContentSettingsMap* GetContentSettings(
- content::WebContents* web_contents) override {
- return Profile::FromBrowserContext(web_contents->GetBrowserContext())->
- GetHostContentSettingsMap();
+ bool IsPermittedByUser(content::WebContents* web_contents) override {
+ ProtectedMediaIdentifierPermissionContext* permission_context =
+ ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(
+ Profile::FromBrowserContext(web_contents->GetBrowserContext()));
+
+ // TODO(xhwang): Using delegate_->GetURL() here is not right. The platform
+ // verification may be requested by a frame from a different origin. This
+ // will be solved when http://crbug.com/454847 is fixed.
+ const GURL& requesting_origin = GetURL(web_contents).GetOrigin();
+
+ GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin();
+
+ ContentSetting content_setting = permission_context->GetPermissionStatus(
+ requesting_origin, embedding_origin);
+
+ return content_setting == CONTENT_SETTING_ALLOW;
}
bool IsGuestOrIncognito(content::WebContents* web_contents) override {
@@ -174,129 +172,61 @@ void PlatformVerificationFlow::ChallengePlatformKey(
const std::string& challenge,
const ChallengeCallback& callback) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
if (!delegate_->GetURL(web_contents).is_valid()) {
LOG(WARNING) << "PlatformVerificationFlow: Invalid URL.";
ReportError(callback, INTERNAL_ERROR);
return;
}
- if (!IsAttestationEnabled(web_contents)) {
+
+ // Note: The following two checks are also checked in GetPermissionStatus.
+ // Checking them here explicitly to report the correct error type.
+
+ if (!IsAttestationAllowedByPolicy()) {
+ VLOG(1) << "Platform verification not allowed by device policy.";
ReportError(callback, POLICY_REJECTED);
return;
}
- // A platform key must be bound to a user. They are not allowed in incognito
+
+ // A platform key must be bound to a user. They are not allowed in incognito
// or guest mode.
+ // TODO(xhwang): Change to DCHECK when prefixed EME support is removed.
+ // See http://crbug.com/249976
if (delegate_->IsGuestOrIncognito(web_contents)) {
VLOG(1) << "Platform verification denied because the current session is "
<< "guest or incognito.";
ReportError(callback, PLATFORM_NOT_VERIFIED);
return;
}
+
+ if (!delegate_->IsPermittedByUser(web_contents)) {
+ VLOG(1) << "Platform verification not permitted by user.";
+ ReportError(callback, USER_REJECTED);
+ return;
+ }
+
ChallengeContext context(web_contents, service_id, challenge, callback);
// Check if the device has been prepared to use attestation.
- BoolDBusMethodCallback dbus_callback = base::Bind(
- &DBusCallback,
- base::Bind(&PlatformVerificationFlow::CheckEnrollment, this, context),
- base::Bind(&ReportError, callback, INTERNAL_ERROR));
+ BoolDBusMethodCallback dbus_callback =
+ base::Bind(&DBusCallback,
+ base::Bind(&PlatformVerificationFlow::OnAttestationPrepared,
+ this, context),
+ base::Bind(&ReportError, callback, INTERNAL_ERROR));
cryptohome_client_->TpmAttestationIsPrepared(dbus_callback);
}
-void PlatformVerificationFlow::CheckEnrollment(const ChallengeContext& context,
- bool attestation_prepared) {
+void PlatformVerificationFlow::OnAttestationPrepared(
+ const ChallengeContext& context,
+ bool attestation_prepared) {
UMA_HISTOGRAM_BOOLEAN(kAttestationAvailableHistogram, attestation_prepared);
+
if (!attestation_prepared) {
// This device is not currently able to use attestation features.
ReportError(context.callback, PLATFORM_NOT_VERIFIED);
return;
}
- BoolDBusMethodCallback dbus_callback = base::Bind(
- &DBusCallback,
- base::Bind(&PlatformVerificationFlow::CheckConsent, this, context),
- base::Bind(&ReportError, context.callback, INTERNAL_ERROR));
- cryptohome_client_->TpmAttestationIsEnrolled(dbus_callback);
-}
-
-void PlatformVerificationFlow::CheckConsent(const ChallengeContext& context,
- bool /* attestation_enrolled */) {
- content::WebContents* web_contents = context.web_contents;
-
- bool enabled_for_origin = false;
- bool found =
- GetOriginPref(delegate_->GetContentSettings(web_contents),
- delegate_->GetURL(web_contents), &enabled_for_origin);
- if (found && !enabled_for_origin) {
- VLOG(1) << "Platform verification denied because the origin has been "
- << "blocked by the user.";
- ReportError(context.callback, USER_REJECTED);
- return;
- }
-
- PrefService* pref_service = delegate_->GetPrefs(web_contents);
- if (!pref_service) {
- LOG(ERROR) << "Failed to get user prefs.";
- ReportError(context.callback, INTERNAL_ERROR);
- return;
- }
-
- // Consent required if user has never given consent for this origin, or if
- // user has never given consent to attestation for content protection on this
- // device.
- bool consent_required =
- !found || !pref_service->GetBoolean(prefs::kRAConsentGranted);
- Delegate::ConsentCallback consent_callback = base::Bind(
- &PlatformVerificationFlow::OnConsentResponse,
- this,
- context,
- consent_required);
- if (consent_required) {
- // TODO(xhwang): Using delegate_->GetURL() here is not right. The consent
- // may be requested by a frame from a different origin. This will be solved
- // when http://crbug.com/454847 is fixed.
- delegate_->ShowConsentPrompt(
- context.web_contents,
- delegate_->GetURL(context.web_contents).GetOrigin(), consent_callback);
- } else {
- consent_callback.Run(CONSENT_RESPONSE_NONE);
- }
-}
-
-void PlatformVerificationFlow::RegisterProfilePrefs(
- user_prefs::PrefRegistrySyncable* prefs) {
- prefs->RegisterBooleanPref(prefs::kRAConsentGranted,
- false, // Default value.
- user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-}
-
-void PlatformVerificationFlow::OnConsentResponse(
- const ChallengeContext& context,
- bool consent_required,
- ConsentResponse consent_response) {
- if (consent_required) {
- if (consent_response == CONSENT_RESPONSE_NONE) {
- // No user response - do not proceed and do not modify any settings.
- LOG(WARNING) << "PlatformVerificationFlow: No response from user.";
- ReportError(context.callback, USER_REJECTED);
- return;
- }
- if (!UpdateSettings(context.web_contents, consent_response)) {
- ReportError(context.callback, INTERNAL_ERROR);
- return;
- }
- if (consent_response == CONSENT_RESPONSE_DENY) {
- content::RecordAction(
- base::UserMetricsAction("PlatformVerificationRejected"));
- VLOG(1) << "Platform verification denied by user.";
- ReportError(context.callback, USER_REJECTED);
- return;
- } else if (consent_response == CONSENT_RESPONSE_ALLOW) {
- content::RecordAction(
- base::UserMetricsAction("PlatformVerificationAccepted"));
- VLOG(1) << "Platform verification accepted by user.";
- }
- }
-
- // At this point all user interaction is complete and we can proceed with the
- // certificate request.
+ // Permission allowed. Now proceed to get certificate.
const user_manager::User* user = delegate_->GetUser(context.web_contents);
if (!user) {
ReportError(context.callback, INTERNAL_ERROR);
@@ -402,8 +332,7 @@ void PlatformVerificationFlow::OnChallengeReady(
certificate);
}
-bool PlatformVerificationFlow::IsAttestationEnabled(
- content::WebContents* web_contents) {
+bool PlatformVerificationFlow::IsAttestationAllowedByPolicy() {
// Check the device policy for the feature.
bool enabled_for_device = false;
if (!CrosSettings::Get()->GetBoolean(kAttestationForContentProtectionEnabled,
@@ -417,102 +346,9 @@ bool PlatformVerificationFlow::IsAttestationEnabled(
return false;
}
- // Check the user preference for the feature.
- PrefService* pref_service = delegate_->GetPrefs(web_contents);
- if (!pref_service) {
- LOG(ERROR) << "Failed to get user prefs.";
- return false;
- }
- if (!pref_service->GetBoolean(prefs::kEnableDRM)) {
- VLOG(1) << "Platform verification denied because content protection "
- << "identifiers have been disabled by the user.";
- return false;
- }
-
- // Check the user preference for this origin.
- bool enabled_for_origin = false;
- bool found =
- GetOriginPref(delegate_->GetContentSettings(web_contents),
- delegate_->GetURL(web_contents), &enabled_for_origin);
- if (found && !enabled_for_origin) {
- VLOG(1) << "Platform verification denied because the origin has been "
- << "blocked by the user.";
- return false;
- }
return true;
}
-bool PlatformVerificationFlow::UpdateSettings(
- content::WebContents* web_contents,
- ConsentResponse consent_response) {
- PrefService* pref_service = delegate_->GetPrefs(web_contents);
- if (!pref_service) {
- LOG(ERROR) << "Failed to get user prefs.";
- return false;
- }
-
- if (consent_response == CONSENT_RESPONSE_ALLOW) {
- pref_service->SetBoolean(prefs::kRAConsentGranted, true);
- }
-
- RecordOriginConsent(delegate_->GetContentSettings(web_contents),
- delegate_->GetURL(web_contents),
- (consent_response == CONSENT_RESPONSE_ALLOW));
- return true;
-}
-
-bool PlatformVerificationFlow::GetOriginPref(
- HostContentSettingsMap* content_settings,
- const GURL& url,
- bool* pref_value) {
- CHECK(content_settings);
- CHECK(url.is_valid());
- ContentSetting setting = content_settings->GetContentSetting(
- url,
- url,
- CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
- std::string());
- if (setting != CONTENT_SETTING_ALLOW && setting != CONTENT_SETTING_BLOCK)
- return false;
- if (pref_value)
- *pref_value = (setting == CONTENT_SETTING_ALLOW);
- return true;
-}
-
-void PlatformVerificationFlow::RecordOriginConsent(
- HostContentSettingsMap* content_settings,
- const GURL& url,
- bool allow_origin) {
- CHECK(content_settings);
- CHECK(url.is_valid());
- // Build a pattern to represent scheme and host.
- scoped_ptr<ContentSettingsPattern::BuilderInterface> builder(
- ContentSettingsPattern::CreateBuilder(false));
- builder->WithScheme(url.scheme())
- ->WithDomainWildcard()
- ->WithHost(url.host())
- ->WithPathWildcard();
- if (!url.port().empty())
- builder->WithPort(url.port());
- else if (url.SchemeIs(url::kHttpsScheme))
- builder->WithPort(kDefaultHttpsPort);
- else if (url.SchemeIs(url::kHttpScheme))
- builder->WithPortWildcard();
- ContentSettingsPattern pattern = builder->Build();
- if (pattern.IsValid()) {
- ContentSetting setting =
- allow_origin ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
- content_settings->SetContentSetting(
- pattern,
- pattern,
- CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
- std::string(),
- setting);
- } else {
- LOG(WARNING) << "Not recording action: invalid URL pattern";
- }
-}
-
bool PlatformVerificationFlow::IsExpired(const std::string& certificate) {
scoped_refptr<net::X509Certificate> x509(
net::X509Certificate::CreateFromBytes(certificate.data(),

Powered by Google App Engine
This is Rietveld 408576698