Commit de25c91f authored by dkrahn@chromium.org's avatar dkrahn@chromium.org

Added prefs for content protection attestation.

The prefs are integrated into the PlatformVerificationFlow class.

BUG=chromium:270316
TEST=unit

Review URL: https://chromiumcodereview.appspot.com/23765004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221614 0039d316-1c4b-4281-b951-d872f2087c98
parent 8609621a
...@@ -5,14 +5,19 @@ ...@@ -5,14 +5,19 @@
#include "platform_verification_flow.h" #include "platform_verification_flow.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/chromeos/attestation/attestation_ca_client.h" #include "chrome/browser/chromeos/attestation/attestation_ca_client.h"
#include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/system/statistics_provider.h" #include "chrome/browser/chromeos/system/statistics_provider.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/common/pref_names.h"
#include "chromeos/attestation/attestation_flow.h" #include "chromeos/attestation/attestation_flow.h"
#include "chromeos/cryptohome/async_method_caller.h" #include "chromeos/cryptohome/async_method_caller.h"
#include "chromeos/dbus/cryptohome_client.h" #include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
...@@ -60,7 +65,7 @@ void PlatformVerificationFlow::ChallengePlatformKey( ...@@ -60,7 +65,7 @@ void PlatformVerificationFlow::ChallengePlatformKey(
const std::string& challenge, const std::string& challenge,
const ChallengeCallback& callback) { const ChallengeCallback& callback) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (delegate_->IsAttestationDisabled()) { if (!IsAttestationEnabled(web_contents)) {
LOG(INFO) << "PlatformVerificationFlow: Feature disabled."; LOG(INFO) << "PlatformVerificationFlow: Feature disabled.";
callback.Run(POLICY_REJECTED, std::string(), std::string()); callback.Run(POLICY_REJECTED, std::string(), std::string());
return; return;
...@@ -105,11 +110,9 @@ void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents, ...@@ -105,11 +110,9 @@ void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents,
const ChallengeCallback& callback, const ChallengeCallback& callback,
bool attestation_enrolled) { bool attestation_enrolled) {
ConsentType consent_type = CONSENT_TYPE_NONE; ConsentType consent_type = CONSENT_TYPE_NONE;
if (!attestation_enrolled) { if (!attestation_enrolled || IsFirstUse(web_contents)) {
consent_type = CONSENT_TYPE_ATTESTATION; consent_type = CONSENT_TYPE_ATTESTATION;
} else if (delegate_->IsOriginConsentRequired(web_contents)) { } else if (IsAlwaysAskRequired(web_contents)) {
consent_type = CONSENT_TYPE_ORIGIN;
} else if (delegate_->IsAlwaysAskRequired(web_contents)) {
consent_type = CONSENT_TYPE_ALWAYS; consent_type = CONSENT_TYPE_ALWAYS;
} }
Delegate::ConsentCallback consent_callback = base::Bind( Delegate::ConsentCallback consent_callback = base::Bind(
...@@ -129,6 +132,19 @@ void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents, ...@@ -129,6 +132,19 @@ void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents,
} }
} }
void PlatformVerificationFlow::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* prefs) {
prefs->RegisterBooleanPref(prefs::kRAConsentFirstTime,
false,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
prefs->RegisterDictionaryPref(
prefs::kRAConsentDomains,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
prefs->RegisterBooleanPref(prefs::kRAConsentAlways,
false,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
}
void PlatformVerificationFlow::OnConsentResponse( void PlatformVerificationFlow::OnConsentResponse(
content::WebContents* web_contents, content::WebContents* web_contents,
const std::string& service_id, const std::string& service_id,
...@@ -143,9 +159,7 @@ void PlatformVerificationFlow::OnConsentResponse( ...@@ -143,9 +159,7 @@ void PlatformVerificationFlow::OnConsentResponse(
callback.Run(USER_REJECTED, std::string(), std::string()); callback.Run(USER_REJECTED, std::string(), std::string());
return; return;
} }
if (!delegate_->UpdateSettings(web_contents, if (!UpdateSettings(web_contents, consent_type, consent_response)) {
consent_type,
consent_response)) {
callback.Run(INTERNAL_ERROR, std::string(), std::string()); callback.Run(INTERNAL_ERROR, std::string(), std::string());
return; return;
} }
...@@ -210,5 +224,130 @@ void PlatformVerificationFlow::OnChallengeReady( ...@@ -210,5 +224,130 @@ void PlatformVerificationFlow::OnChallengeReady(
callback.Run(SUCCESS, response_data, certificate); callback.Run(SUCCESS, response_data, certificate);
} }
PrefService* PlatformVerificationFlow::GetPrefs(
content::WebContents* web_contents) {
if (testing_prefs_)
return testing_prefs_;
return user_prefs::UserPrefs::Get(web_contents->GetBrowserContext());
}
const GURL& PlatformVerificationFlow::GetURL(
content::WebContents* web_contents) {
if (!testing_url_.is_empty())
return testing_url_;
return web_contents->GetLastCommittedURL();
}
bool PlatformVerificationFlow::IsAttestationEnabled(
content::WebContents* web_contents) {
// Check the device policy for the feature.
bool enabled_for_device = false;
if (!CrosSettings::Get()->GetBoolean(kAttestationForContentProtectionEnabled,
&enabled_for_device)) {
LOG(ERROR) << "Failed to get device setting.";
return false;
}
if (!enabled_for_device)
return false;
// Check the user preference for the feature.
PrefService* pref_service = GetPrefs(web_contents);
if (!pref_service) {
LOG(ERROR) << "Failed to get user prefs.";
return false;
}
if (!pref_service->GetBoolean(prefs::kEnableDRM))
return false;
// Check the user preference for this domain.
bool enabled_for_domain = false;
bool found = GetDomainPref(web_contents, &enabled_for_domain);
return (!found || enabled_for_domain);
}
bool PlatformVerificationFlow::IsFirstUse(content::WebContents* web_contents) {
PrefService* pref_service = GetPrefs(web_contents);
if (!pref_service) {
LOG(ERROR) << "Failed to get user prefs.";
return true;
}
return !pref_service->GetBoolean(prefs::kRAConsentFirstTime);
}
bool PlatformVerificationFlow::IsAlwaysAskRequired(
content::WebContents* web_contents) {
PrefService* pref_service = GetPrefs(web_contents);
if (!pref_service) {
LOG(ERROR) << "Failed to get user prefs.";
return true;
}
if (!pref_service->GetBoolean(prefs::kRAConsentAlways))
return false;
// Show the consent UI if the user has not already explicitly allowed or
// denied for this domain.
return !GetDomainPref(web_contents, NULL);
}
bool PlatformVerificationFlow::UpdateSettings(
content::WebContents* web_contents,
ConsentType consent_type,
ConsentResponse consent_response) {
PrefService* pref_service = GetPrefs(web_contents);
if (!pref_service) {
LOG(ERROR) << "Failed to get user prefs.";
return false;
}
if (consent_type == CONSENT_TYPE_ATTESTATION) {
if (consent_response == CONSENT_RESPONSE_DENY) {
pref_service->SetBoolean(prefs::kEnableDRM, false);
} else if (consent_response == CONSENT_RESPONSE_ALLOW) {
pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
RecordDomainConsent(web_contents, true);
} else if (consent_response == CONSENT_RESPONSE_ALWAYS_ASK) {
pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
pref_service->SetBoolean(prefs::kRAConsentAlways, true);
RecordDomainConsent(web_contents, true);
}
} else if (consent_type == CONSENT_TYPE_ALWAYS) {
bool allowed = (consent_response == CONSENT_RESPONSE_ALLOW ||
consent_response == CONSENT_RESPONSE_ALWAYS_ASK);
RecordDomainConsent(web_contents, allowed);
}
return true;
}
bool PlatformVerificationFlow::GetDomainPref(
content::WebContents* web_contents,
bool* pref_value) {
PrefService* pref_service = GetPrefs(web_contents);
CHECK(pref_service);
base::DictionaryValue::Iterator iter(
*pref_service->GetDictionary(prefs::kRAConsentDomains));
const GURL& url = GetURL(web_contents);
while (!iter.IsAtEnd()) {
if (url.DomainIs(iter.key().c_str())) {
if (pref_value) {
if (!iter.value().GetAsBoolean(pref_value)) {
LOG(ERROR) << "Unexpected pref type.";
*pref_value = false;
}
}
return true;
}
iter.Advance();
}
return false;
}
void PlatformVerificationFlow::RecordDomainConsent(
content::WebContents* web_contents,
bool allow_domain) {
PrefService* pref_service = GetPrefs(web_contents);
CHECK(pref_service);
DictionaryPrefUpdate updater(pref_service, prefs::kRAConsentDomains);
const GURL& url = GetURL(web_contents);
updater->SetBoolean(url.host(), allow_domain);
}
} // namespace attestation } // namespace attestation
} // namespace chromeos } // namespace chromeos
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "url/gurl.h"
class PrefService;
namespace content { namespace content {
class WebContents; class WebContents;
...@@ -20,6 +23,10 @@ namespace cryptohome { ...@@ -20,6 +23,10 @@ namespace cryptohome {
class AsyncMethodCaller; class AsyncMethodCaller;
} }
namespace user_prefs {
class PrefRegistrySyncable;
}
namespace chromeos { namespace chromeos {
class CryptohomeClient; class CryptohomeClient;
...@@ -54,7 +61,6 @@ class PlatformVerificationFlow { ...@@ -54,7 +61,6 @@ class PlatformVerificationFlow {
enum ConsentType { enum ConsentType {
CONSENT_TYPE_NONE, // No consent necessary. CONSENT_TYPE_NONE, // No consent necessary.
CONSENT_TYPE_ATTESTATION, // Consent to use attestation. CONSENT_TYPE_ATTESTATION, // Consent to use attestation.
CONSENT_TYPE_ORIGIN, // Consent to proceed with an unfamiliar origin.
CONSENT_TYPE_ALWAYS, // Consent because 'Always Ask' was requested. CONSENT_TYPE_ALWAYS, // Consent because 'Always Ask' was requested.
}; };
...@@ -80,23 +86,6 @@ class PlatformVerificationFlow { ...@@ -80,23 +86,6 @@ class PlatformVerificationFlow {
virtual void ShowConsentPrompt(ConsentType type, virtual void ShowConsentPrompt(ConsentType type,
content::WebContents* web_contents, content::WebContents* web_contents,
const ConsentCallback& callback) = 0; const ConsentCallback& callback) = 0;
// Returns true if settings indicate that attestation should be disabled.
virtual bool IsAttestationDisabled() = 0;
// Checks if the web origin represented by |web_contents| is unfamiliar and
// requires special user consent.
virtual bool IsOriginConsentRequired(
content::WebContents* web_contents) = 0;
// Checks if settings indicate that consent is required for the web origin
// represented by |web_contents| because the user requested to be prompted.
virtual bool IsAlwaysAskRequired(content::WebContents* web_contents) = 0;
// Updates user settings based on their response to the consent request.
virtual bool UpdateSettings(content::WebContents* web_contents,
ConsentType consent_type,
ConsentResponse consent_response) = 0;
}; };
// This callback will be called when a challenge operation completes. If // This callback will be called when a challenge operation completes. If
...@@ -150,6 +139,16 @@ class PlatformVerificationFlow { ...@@ -150,6 +139,16 @@ class PlatformVerificationFlow {
// or false. If an error occurs, |result| will be false. // or false. If an error occurs, |result| will be false.
void CheckPlatformState(const base::Callback<void(bool result)>& callback); void CheckPlatformState(const base::Callback<void(bool result)>& callback);
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs);
void set_testing_prefs(PrefService* testing_prefs) {
testing_prefs_ = testing_prefs;
}
void set_testing_url(const GURL& testing_url) {
testing_url_ = testing_url;
}
private: private:
// Checks whether we need to prompt the user for consent before proceeding and // Checks whether we need to prompt the user for consent before proceeding and
// invokes the consent UI if so. All parameters are the same as in // invokes the consent UI if so. All parameters are the same as in
...@@ -196,6 +195,47 @@ class PlatformVerificationFlow { ...@@ -196,6 +195,47 @@ class PlatformVerificationFlow {
bool operation_success, bool operation_success,
const std::string& response_data); const std::string& response_data);
// Gets prefs associated with the given |web_contents|. If prefs have been
// set explicitly using set_testing_prefs(), then these are always returned.
// If no prefs are associated with |web_contents| then NULL is returned.
PrefService* GetPrefs(content::WebContents* web_contents);
// Gets the URL associated with the given |web_contents|. If a URL as been
// set explicitly using set_testing_url(), then this value is always returned.
const GURL& GetURL(content::WebContents* web_contents);
// Checks whether policy or profile settings associated with |web_contents|
// have attestation for content protection explicitly disabled.
bool IsAttestationEnabled(content::WebContents* web_contents);
// Checks whether this is the first use on this device for the user associated
// with |web_contents|.
bool IsFirstUse(content::WebContents* web_contents);
// Checks if settings indicate that consent is required for the web origin
// represented by |web_contents| because the user requested to be prompted.
bool IsAlwaysAskRequired(content::WebContents* web_contents);
// Updates user settings for the profile associated with |web_contents| based
// on the |consent_response| to the request of type |consent_type|.
bool UpdateSettings(content::WebContents* web_contents,
ConsentType consent_type,
ConsentResponse consent_response);
// Finds the domain-specific consent pref for the domain associated with
// |web_contents|. If a pref exists for the domain, returns true and sets
// |pref_value| if it is not NULL.
//
// Precondition: A valid PrefService must be available via GetPrefs().
bool GetDomainPref(content::WebContents* web_contents, bool* pref_value);
// Records the domain-specific consent pref for the domain associated with
// |web_contents|. The pref will be set to |allow_domain|.
//
// Precondition: A valid PrefService must be available via GetPrefs().
void RecordDomainConsent(content::WebContents* web_contents,
bool allow_domain);
AttestationFlow* attestation_flow_; AttestationFlow* attestation_flow_;
scoped_ptr<AttestationFlow> default_attestation_flow_; scoped_ptr<AttestationFlow> default_attestation_flow_;
cryptohome::AsyncMethodCaller* async_caller_; cryptohome::AsyncMethodCaller* async_caller_;
...@@ -204,6 +244,8 @@ class PlatformVerificationFlow { ...@@ -204,6 +244,8 @@ class PlatformVerificationFlow {
system::StatisticsProvider* statistics_provider_; system::StatisticsProvider* statistics_provider_;
Delegate* delegate_; Delegate* delegate_;
scoped_ptr<Delegate> default_delegate_; scoped_ptr<Delegate> default_delegate_;
PrefService* testing_prefs_;
GURL testing_url_;
// Note: This should remain the last member so it'll be destroyed and // Note: This should remain the last member so it'll be destroyed and
// invalidate the weak pointers before any other members are destroyed. // invalidate the weak pointers before any other members are destroyed.
......
...@@ -6,10 +6,17 @@ ...@@ -6,10 +6,17 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/testing_pref_service.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "chrome/browser/chromeos/attestation/platform_verification_flow.h" #include "chrome/browser/chromeos/attestation/platform_verification_flow.h"
#include "chrome/browser/chromeos/login/mock_user_manager.h" #include "chrome/browser/chromeos/login/mock_user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h"
#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
#include "chrome/browser/chromeos/system/mock_statistics_provider.h" #include "chrome/browser/chromeos/system/mock_statistics_provider.h"
#include "chrome/common/pref_names.h"
#include "chromeos/attestation/mock_attestation_flow.h" #include "chromeos/attestation/mock_attestation_flow.h"
#include "chromeos/cryptohome/mock_async_method_caller.h" #include "chromeos/cryptohome/mock_async_method_caller.h"
#include "chromeos/dbus/fake_cryptohome_client.h" #include "chromeos/dbus/fake_cryptohome_client.h"
...@@ -34,15 +41,13 @@ const char kTestChallenge[] = "test_challenge"; ...@@ -34,15 +41,13 @@ const char kTestChallenge[] = "test_challenge";
const char kTestResponse[] = "test_challenge_response"; const char kTestResponse[] = "test_challenge_response";
const char kTestCertificate[] = "test_certificate"; const char kTestCertificate[] = "test_certificate";
const char kTestEmail[] = "test_email@chromium.org"; const char kTestEmail[] = "test_email@chromium.org";
const char kTestURL[] = "http://mytestdomain/test";
const char kTestDomain[] = "mytestdomain";
class FakeDelegate : public PlatformVerificationFlow::Delegate { class FakeDelegate : public PlatformVerificationFlow::Delegate {
public: public:
FakeDelegate() : response_(PlatformVerificationFlow::CONSENT_RESPONSE_ALLOW), FakeDelegate() : response_(PlatformVerificationFlow::CONSENT_RESPONSE_ALLOW),
num_consent_calls_(0), num_consent_calls_(0) {}
attestation_disabled_(false),
origin_consent_required_(false),
always_ask_required_(false),
update_settings_result_(true) {}
virtual ~FakeDelegate() {} virtual ~FakeDelegate() {}
virtual void ShowConsentPrompt( virtual void ShowConsentPrompt(
...@@ -54,27 +59,6 @@ class FakeDelegate : public PlatformVerificationFlow::Delegate { ...@@ -54,27 +59,6 @@ class FakeDelegate : public PlatformVerificationFlow::Delegate {
callback.Run(response_); callback.Run(response_);
} }
virtual bool IsAttestationDisabled() OVERRIDE {
return attestation_disabled_;
}
virtual bool IsOriginConsentRequired(
content::WebContents* web_contents) OVERRIDE {
return origin_consent_required_;
}
virtual bool IsAlwaysAskRequired(
content::WebContents* web_contents) OVERRIDE {
return always_ask_required_;
}
virtual bool UpdateSettings(
content::WebContents* web_contents,
PlatformVerificationFlow::ConsentType consent_type,
PlatformVerificationFlow::ConsentResponse consent_response) OVERRIDE {
return update_settings_result_;
}
void set_response(PlatformVerificationFlow::ConsentResponse response) { void set_response(PlatformVerificationFlow::ConsentResponse response) {
response_ = response; response_ = response;
} }
...@@ -83,29 +67,9 @@ class FakeDelegate : public PlatformVerificationFlow::Delegate { ...@@ -83,29 +67,9 @@ class FakeDelegate : public PlatformVerificationFlow::Delegate {
return num_consent_calls_; return num_consent_calls_;
} }
void set_attestation_disabled(bool attestation_disabled) {
attestation_disabled_ = attestation_disabled;
}
void set_origin_consent_required(bool origin_consent_required) {
origin_consent_required_ = origin_consent_required;
}
void set_always_ask_required(bool always_ask_required) {
always_ask_required_ = always_ask_required;
}
void set_update_settings_result(bool update_settings_result) {
update_settings_result_ = update_settings_result;
}
private: private:
PlatformVerificationFlow::ConsentResponse response_; PlatformVerificationFlow::ConsentResponse response_;
int num_consent_calls_; int num_consent_calls_;
bool attestation_disabled_;
bool origin_consent_required_;
bool always_ask_required_;
bool update_settings_result_;
DISALLOW_COPY_AND_ASSIGN(FakeDelegate); DISALLOW_COPY_AND_ASSIGN(FakeDelegate);
}; };
...@@ -185,10 +149,34 @@ class PlatformVerificationFlowTest : public ::testing::Test { ...@@ -185,10 +149,34 @@ class PlatformVerificationFlowTest : public ::testing::Test {
check_state_callback_ = base::Bind( check_state_callback_ = base::Bind(
&PlatformVerificationFlowTest::FakeCheckStateCallback, &PlatformVerificationFlowTest::FakeCheckStateCallback,
base::Unretained(this)); base::Unretained(this));
// Configure the test pref service.
pref_service_.registry()->RegisterBooleanPref(prefs::kEnableDRM, true);
pref_service_.registry()->RegisterBooleanPref(prefs::kRAConsentFirstTime,
true);
pref_service_.registry()->RegisterBooleanPref(prefs::kRAConsentAlways,
false);
pref_service_.registry()->RegisterDictionaryPref(prefs::kRAConsentDomains);
verifier_->set_testing_prefs(&pref_service_);
// Configure the global cros_settings.
CrosSettings* cros_settings = CrosSettings::Get();
device_settings_provider_ =
cros_settings->GetProvider(kAttestationForContentProtectionEnabled);
cros_settings->RemoveSettingsProvider(device_settings_provider_);
cros_settings->AddSettingsProvider(&stub_settings_provider_);
cros_settings->SetBoolean(kAttestationForContentProtectionEnabled, true);
// Configure a test URL to shortcut the dependency on WebContents.
verifier_->set_testing_url(GURL(kTestURL));
} }
void TearDown() { void TearDown() {
verifier_.reset(); verifier_.reset();
// Restore the real DeviceSettingsProvider.
CrosSettings* cros_settings = CrosSettings::Get();
cros_settings->RemoveSettingsProvider(&stub_settings_provider_);
cros_settings->AddSettingsProvider(device_settings_provider_);
} }
void ExpectAttestationFlow() { void ExpectAttestationFlow() {
...@@ -250,6 +238,11 @@ class PlatformVerificationFlowTest : public ::testing::Test { ...@@ -250,6 +238,11 @@ class PlatformVerificationFlowTest : public ::testing::Test {
MockUserManager mock_user_manager_; MockUserManager mock_user_manager_;
system::MockStatisticsProvider mock_statistics_provider_; system::MockStatisticsProvider mock_statistics_provider_;
FakeDelegate fake_delegate_; FakeDelegate fake_delegate_;
TestingPrefServiceSimple pref_service_;
CrosSettingsProvider* device_settings_provider_;
StubCrosSettingsProvider stub_settings_provider_;
ScopedTestDeviceSettingsService test_device_settings_service_;
ScopedTestCrosSettings test_cros_settings_;
scoped_ptr<PlatformVerificationFlow> verifier_; scoped_ptr<PlatformVerificationFlow> verifier_;
// Controls result of FakeGetCertificate. // Controls result of FakeGetCertificate.
...@@ -279,10 +272,9 @@ TEST_F(PlatformVerificationFlowTest, SuccessNoConsent) { ...@@ -279,10 +272,9 @@ TEST_F(PlatformVerificationFlowTest, SuccessNoConsent) {
EXPECT_EQ(0, fake_delegate_.num_consent_calls()); EXPECT_EQ(0, fake_delegate_.num_consent_calls());
} }
TEST_F(PlatformVerificationFlowTest, SuccessWithOriginConsent) { TEST_F(PlatformVerificationFlowTest, SuccessWithAlwaysAskConsent) {
// Enable two conditions and make sure consent is not requested twice. pref_service_.SetUserPref(prefs::kRAConsentAlways,
fake_delegate_.set_origin_consent_required(true); new base::FundamentalValue(true));
fake_delegate_.set_always_ask_required(true);
ExpectAttestationFlow(); ExpectAttestationFlow();
verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_); verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -292,8 +284,8 @@ TEST_F(PlatformVerificationFlowTest, SuccessWithOriginConsent) { ...@@ -292,8 +284,8 @@ TEST_F(PlatformVerificationFlowTest, SuccessWithOriginConsent) {
EXPECT_EQ(1, fake_delegate_.num_consent_calls()); EXPECT_EQ(1, fake_delegate_.num_consent_calls());
} }
TEST_F(PlatformVerificationFlowTest, SuccessWithAlwaysAskConsent) { TEST_F(PlatformVerificationFlowTest, SuccessWithAttestationConsent) {
fake_delegate_.set_always_ask_required(true); fake_cryptohome_client_.set_attestation_enrolled(false);
ExpectAttestationFlow(); ExpectAttestationFlow();
verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_); verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -303,8 +295,9 @@ TEST_F(PlatformVerificationFlowTest, SuccessWithAlwaysAskConsent) { ...@@ -303,8 +295,9 @@ TEST_F(PlatformVerificationFlowTest, SuccessWithAlwaysAskConsent) {
EXPECT_EQ(1, fake_delegate_.num_consent_calls()); EXPECT_EQ(1, fake_delegate_.num_consent_calls());
} }
TEST_F(PlatformVerificationFlowTest, SuccessWithAttestationConsent) { TEST_F(PlatformVerificationFlowTest, SuccessWithFirstTimeConsent) {
fake_cryptohome_client_.set_attestation_enrolled(false); pref_service_.SetUserPref(prefs::kRAConsentFirstTime,
new base::FundamentalValue(false));
ExpectAttestationFlow(); ExpectAttestationFlow();
verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_); verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -315,7 +308,8 @@ TEST_F(PlatformVerificationFlowTest, SuccessWithAttestationConsent) { ...@@ -315,7 +308,8 @@ TEST_F(PlatformVerificationFlowTest, SuccessWithAttestationConsent) {
} }
TEST_F(PlatformVerificationFlowTest, ConsentRejected) { TEST_F(PlatformVerificationFlowTest, ConsentRejected) {
fake_delegate_.set_always_ask_required(true); pref_service_.SetUserPref(prefs::kRAConsentAlways,
new base::FundamentalValue(true));
fake_delegate_.set_response(PlatformVerificationFlow::CONSENT_RESPONSE_DENY); fake_delegate_.set_response(PlatformVerificationFlow::CONSENT_RESPONSE_DENY);
verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_); verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -324,7 +318,27 @@ TEST_F(PlatformVerificationFlowTest, ConsentRejected) { ...@@ -324,7 +318,27 @@ TEST_F(PlatformVerificationFlowTest, ConsentRejected) {
} }
TEST_F(PlatformVerificationFlowTest, FeatureDisabled) { TEST_F(PlatformVerificationFlowTest, FeatureDisabled) {
fake_delegate_.set_attestation_disabled(true); CrosSettings::Get()->SetBoolean(kAttestationForContentProtectionEnabled,
false);
verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(PlatformVerificationFlow::POLICY_REJECTED, result_);
EXPECT_EQ(0, fake_delegate_.num_consent_calls());
}
TEST_F(PlatformVerificationFlowTest, FeatureDisabledByUser) {
pref_service_.SetUserPref(prefs::kEnableDRM,
new base::FundamentalValue(false));
verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(PlatformVerificationFlow::POLICY_REJECTED, result_);
EXPECT_EQ(0, fake_delegate_.num_consent_calls());
}
TEST_F(PlatformVerificationFlowTest, FeatureDisabledByUserForDomain) {
base::DictionaryValue* domains = new base::DictionaryValue();
domains->SetBoolean(kTestDomain, false);
pref_service_.SetUserPref(prefs::kRAConsentDomains, domains);
verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_); verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(PlatformVerificationFlow::POLICY_REJECTED, result_); EXPECT_EQ(PlatformVerificationFlow::POLICY_REJECTED, result_);
...@@ -354,17 +368,10 @@ TEST_F(PlatformVerificationFlowTest, DBusFailure) { ...@@ -354,17 +368,10 @@ TEST_F(PlatformVerificationFlowTest, DBusFailure) {
EXPECT_EQ(PlatformVerificationFlow::INTERNAL_ERROR, result_); EXPECT_EQ(PlatformVerificationFlow::INTERNAL_ERROR, result_);
} }
TEST_F(PlatformVerificationFlowTest, UpdateSettingsFailure) {
fake_delegate_.set_origin_consent_required(true);
fake_delegate_.set_update_settings_result(false);
verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(PlatformVerificationFlow::INTERNAL_ERROR, result_);
}
TEST_F(PlatformVerificationFlowTest, ConsentNoResponse) { TEST_F(PlatformVerificationFlowTest, ConsentNoResponse) {
fake_delegate_.set_response(PlatformVerificationFlow::CONSENT_RESPONSE_NONE); fake_delegate_.set_response(PlatformVerificationFlow::CONSENT_RESPONSE_NONE);
fake_delegate_.set_origin_consent_required(true); pref_service_.SetUserPref(prefs::kRAConsentAlways,
new base::FundamentalValue(true));
verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_); verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(PlatformVerificationFlow::USER_REJECTED, result_); EXPECT_EQ(PlatformVerificationFlow::USER_REJECTED, result_);
......
...@@ -149,8 +149,6 @@ class Preferences : public PrefServiceSyncableObserver, ...@@ -149,8 +149,6 @@ class Preferences : public PrefServiceSyncableObserver,
IntegerPrefMember xkb_auto_repeat_delay_pref_; IntegerPrefMember xkb_auto_repeat_delay_pref_;
IntegerPrefMember xkb_auto_repeat_interval_pref_; IntegerPrefMember xkb_auto_repeat_interval_pref_;
BooleanPrefMember enable_drm_;
DISALLOW_COPY_AND_ASSIGN(Preferences); DISALLOW_COPY_AND_ASSIGN(Preferences);
}; };
......
...@@ -125,6 +125,7 @@ ...@@ -125,6 +125,7 @@
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
#include "chrome/browser/chromeos/attestation/platform_verification_flow.h"
#include "chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.h" #include "chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.h"
#include "chrome/browser/chromeos/customization_document.h" #include "chrome/browser/chromeos/customization_document.h"
#include "chrome/browser/chromeos/display/display_preferences.h" #include "chrome/browser/chromeos/display/display_preferences.h"
...@@ -387,12 +388,14 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { ...@@ -387,12 +388,14 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
#endif #endif
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
chromeos::attestation::PlatformVerificationFlow::RegisterProfilePrefs(
registry);
chromeos::Preferences::RegisterProfilePrefs(registry); chromeos::Preferences::RegisterProfilePrefs(registry);
chromeos::proxy_config::RegisterProfilePrefs(registry); chromeos::proxy_config::RegisterProfilePrefs(registry);
chromeos::UserImageSyncObserver::RegisterProfilePrefs(registry);
extensions::EnterprisePlatformKeysPrivateChallengeUserKeyFunction:: extensions::EnterprisePlatformKeysPrivateChallengeUserKeyFunction::
RegisterProfilePrefs(registry); RegisterProfilePrefs(registry);
FlagsUI::RegisterProfilePrefs(registry); FlagsUI::RegisterProfilePrefs(registry);
chromeos::UserImageSyncObserver::RegisterProfilePrefs(registry);
#endif #endif
#if defined(OS_WIN) #if defined(OS_WIN)
......
...@@ -65,8 +65,6 @@ bool DeviceIDFetcher::Start(const IDCallback& callback) { ...@@ -65,8 +65,6 @@ bool DeviceIDFetcher::Start(const IDCallback& callback) {
// static // static
void DeviceIDFetcher::RegisterProfilePrefs( void DeviceIDFetcher::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* prefs) { user_prefs::PrefRegistrySyncable* prefs) {
// TODO(wad): Once UI is connected, a final default can be set. At that point
// change this pref from UNSYNCABLE to SYNCABLE.
prefs->RegisterBooleanPref(prefs::kEnableDRM, prefs->RegisterBooleanPref(prefs::kEnableDRM,
true, true,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
......
...@@ -936,6 +936,16 @@ const char kTouchHudProjectionEnabled[] = "touch_hud.projection_enabled"; ...@@ -936,6 +936,16 @@ const char kTouchHudProjectionEnabled[] = "touch_hud.projection_enabled";
// Currently, this pref is only used to store the policy. The user's // Currently, this pref is only used to store the policy. The user's
// configuration is still stored in Shill. // configuration is still stored in Shill.
const char kOpenNetworkConfiguration[] = "onc"; const char kOpenNetworkConfiguration[] = "onc";
// A boolean pref that tracks whether the user has already given consent for
// enabling remote attestation for content protection.
const char kRAConsentFirstTime[] = "settings.privacy.ra_consent";
// A DictionaryValue pref that tracks domains for which the user has explicitly
// allowed or denied.
const char kRAConsentDomains[] = "settings.privacy.ra_consent_domains";
// A boolean pref that tracks whether the user indicated they wish to be asked
// for consent for every site that uses remote attestation.
const char kRAConsentAlways[] = "settings.privacy.ra_consent_always";
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
// The disabled messages in IPC logging. // The disabled messages in IPC logging.
...@@ -2577,7 +2587,8 @@ extern const char kModuleConflictBubbleShown[] = "module_conflict.bubble_shown"; ...@@ -2577,7 +2587,8 @@ extern const char kModuleConflictBubbleShown[] = "module_conflict.bubble_shown";
// A string pref for storing the salt used to compute the pepper device ID. // A string pref for storing the salt used to compute the pepper device ID.
const char kDRMSalt[] = "settings.privacy.drm_salt"; const char kDRMSalt[] = "settings.privacy.drm_salt";
// A boolean pref that enables the (private) pepper GetDeviceID() call. // A boolean pref that enables the (private) pepper GetDeviceID() call and
// enables the use of remote attestation for content protection.
const char kEnableDRM[] = "settings.privacy.drm_enabled"; const char kEnableDRM[] = "settings.privacy.drm_enabled";
// A boolean per-profile pref that signals if the watchdog extension is // A boolean per-profile pref that signals if the watchdog extension is
......
...@@ -328,6 +328,9 @@ extern const char kAttestationEnabled[]; ...@@ -328,6 +328,9 @@ extern const char kAttestationEnabled[];
extern const char kAttestationExtensionWhitelist[]; extern const char kAttestationExtensionWhitelist[];
extern const char kTouchHudProjectionEnabled[]; extern const char kTouchHudProjectionEnabled[];
extern const char kOpenNetworkConfiguration[]; extern const char kOpenNetworkConfiguration[];
extern const char kRAConsentFirstTime[];
extern const char kRAConsentDomains[];
extern const char kRAConsentAlways[];
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
extern const char kIpcDisabledMessages[]; extern const char kIpcDisabledMessages[];
extern const char kShowHomeButton[]; extern const char kShowHomeButton[];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment