Implement Enterprise Key API.
Proposal: https://docs.google.com/a/google.com/document/d/1KxtQCk4SJdAZId8WxtnCxR3kS2KvhFDsU0SdAeP18Xc/edit
The logic of the API is implemented. Add prefernces and policies are added.
The underlying cryptohome_client will be implemented in another CL.
BUG=chromium:219963
TEST=unit_tests
Review URL: https://chromiumcodereview.appspot.com/13132004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195043 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/app/policy/policy_templates.json b/chrome/app/policy/policy_templates.json
index 6a129369..dad016ad 100644
--- a/chrome/app/policy/policy_templates.json
+++ b/chrome/app/policy/policy_templates.json
@@ -112,7 +112,7 @@
# persistent IDs for all fields (but not for groups!) are needed. These are
# specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
# because doing so would break the deployed wire format!
-# For your editing convenience: highest ID currently used: 199
+# For your editing convenience: highest ID currently used: 201
#
# Placeholders:
# The following placeholder strings are automatically substituted:
@@ -4520,6 +4520,49 @@
If not specified, will not modify the Variations seed URL.''',
},
+ {
+ 'name': 'Attestation',
+ 'type': 'group',
+ 'caption': 'Remote Attestation',
+ 'desc': 'Configure the remote attestation with TPM mechanism.',
+ 'policies': [
+ {
+ 'name': 'AttestationEnabledForUser',
+ 'type': 'main',
+ 'schema': { 'type': 'boolean' },
+ 'supported_on': ['chrome_os:28-'],
+ 'features': {
+ 'dynamic_refresh': True,
+ 'per_profile': True,
+ },
+ 'example_value': True,
+ 'id': 200,
+ 'caption': '''Enable remote attestation for the user.''',
+ 'desc': '''If true, the user can use the hardware on Chrome devices to remote attest its identity to the privacy CA via the Enterprise Platform Keys API chrome.enterprise.platformKeysPrivate.challengeUserKey().
+
+ If it is set to false, or if it is not set, calls to the API will fail with an error code.''',
+ },
+ {
+ 'name': 'AttestationExtensionWhitelist',
+ 'type': 'list',
+ 'schema': {
+ 'type': 'array',
+ 'items': { 'type': 'string' },
+ },
+ 'supported_on': ['chrome_os:28-'],
+ 'features': {
+ 'dynamic_refresh': True,
+ 'per_profile': True,
+ },
+ 'example_value': ['ghdilpkmfbfdnomkmaiogjhjnggaggoi'],
+ 'id': 201,
+ 'caption': '''Extensions allowed to to use the remote attestation API.''',
+ 'desc': '''This policy specifies the allowed extensions to use Enterprise Platform Keys API chrome.enterprise.platformKeysPrivate.challengeUserKey() for remote attestation. Extensions must be added to this list to use the API.
+
+ If an extension is not in the list, or the list is not set, the call to the API will fail with an error code.''',
+ },
+ ],
+ },
],
'messages': {
# Messages that are not associated to any policies.
diff --git a/chrome/browser/chromeos/settings/cros_settings_names.cc b/chrome/browser/chromeos/settings/cros_settings_names.cc
index 6d9989c..7a0a93b 100644
--- a/chrome/browser/chromeos/settings/cros_settings_names.cc
+++ b/chrome/browser/chromeos/settings/cros_settings_names.cc
@@ -120,4 +120,7 @@
// when pinging the Variations server.
const char kVariationsRestrictParameter[] =
"cros.variations_restrict_parameter";
+
+// A boolean pref that indicates whether attestation is enabled for the device.
+const char kDeviceAttestationEnabled[] = "cros.device.attestation_enabled";
} // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/cros_settings_names.h b/chrome/browser/chromeos/settings/cros_settings_names.h
index 67b0592..72810555 100644
--- a/chrome/browser/chromeos/settings/cros_settings_names.h
+++ b/chrome/browser/chromeos/settings/cros_settings_names.h
@@ -60,6 +60,8 @@
extern const char kKioskDisableBailoutShortcut[];
extern const char kVariationsRestrictParameter[];
+
+extern const char kDeviceAttestationEnabled[];
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_SETTINGS_CROS_SETTINGS_NAMES_H_
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
new file mode 100644
index 0000000..336dbf6
--- /dev/null
+++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
@@ -0,0 +1,340 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h"
+
+#include <string>
+
+#include "base/base64.h"
+#include "base/callback.h"
+#include "base/message_loop.h"
+#include "base/prefs/pref_service.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/settings/cros_settings_names.h"
+#include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/common/extensions/api/enterprise_platform_keys_private.h"
+#include "chrome/common/pref_names.h"
+#include "chromeos/cryptohome/async_method_caller.h"
+#include "chromeos/dbus/cryptohome_client.h"
+#include "chromeos/dbus/dbus_method_call_status.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "components/user_prefs/pref_registry_syncable.h"
+#include "google_apis/gaia/gaia_auth_util.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace extensions {
+
+namespace api_epkp = api::enterprise_platform_keys_private;
+
+// Base class
+
+EPKPChallengeKeyBase::EPKPChallengeKeyBase()
+ : cryptohome_client_(
+ chromeos::DBusThreadManager::Get()->GetCryptohomeClient()),
+ async_caller_(cryptohome::AsyncMethodCaller::GetInstance()),
+ install_attributes_(g_browser_process->browser_policy_connector()->
+ GetInstallAttributes()) {
+}
+
+EPKPChallengeKeyBase::~EPKPChallengeKeyBase() {
+}
+
+void EPKPChallengeKeyBase::GetDeviceAttestationEnabled(
+ const base::Callback<void(bool)>& callback) const {
+ chromeos::CrosSettings* settings = chromeos::CrosSettings::Get();
+ chromeos::CrosSettingsProvider::TrustedStatus status =
+ settings->PrepareTrustedValues(
+ base::Bind(&EPKPChallengeKeyBase::GetDeviceAttestationEnabled, this,
+ callback));
+
+ bool value = false;
+ switch (status) {
+ case chromeos::CrosSettingsProvider::TRUSTED:
+ if (!settings->GetBoolean(chromeos::kDeviceAttestationEnabled, &value))
+ value = false;
+ break;
+ case chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED:
+ // Do nothing. This function will be called again when the values are
+ // ready.
+ return;
+ case chromeos::CrosSettingsProvider::PERMANENTLY_UNTRUSTED:
+ // If the value cannot be trusted, we assume that the device attestation
+ // is false to be on the safe side.
+ break;
+ }
+
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, value));
+}
+
+bool EPKPChallengeKeyBase::IsEnterpriseDevice() const {
+ return install_attributes_->IsEnterpriseDevice();
+}
+
+std::string EPKPChallengeKeyBase::GetEnterpriseDomain() const {
+ return install_attributes_->GetDomain();
+}
+
+std::string EPKPChallengeKeyBase::GetDeviceId() const {
+ return install_attributes_->GetDeviceId();
+}
+
+// Implementation of ChallengeMachineKey()
+
+const char EPKPChallengeMachineKey::kKeyName[] = "attest-ent-machine";
+
+EPKPChallengeMachineKey::~EPKPChallengeMachineKey() {
+}
+
+bool EPKPChallengeMachineKey::RunImpl() {
+ scoped_ptr<api_epkp::ChallengeMachineKey::Params>
+ params(api_epkp::ChallengeMachineKey::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+
+ std::string challenge;
+ if (!base::Base64Decode(params->challenge, &challenge)) {
+ SetError("Challenge is not base64 encoded.");
+ SendResponse(false);
+ return false;
+ }
+
+ // Check if the device is enterprise enrolled.
+ if (!IsEnterpriseDevice()) {
+ SetError("The device is not enterprise enrolled.");
+ SendResponse(false);
+ return false;
+ }
+
+ // Check if RA is enabled in the device policy.
+ GetDeviceAttestationEnabled(
+ base::Bind(&EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback,
+ this, challenge));
+
+ return true;
+}
+
+void EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback(
+ const std::string& challenge, bool enabled) {
+ if (!enabled) {
+ SetError("Remote attestation is not enabled for your device.");
+ SendResponse(false);
+ return;
+ }
+
+ // Everything is checked. Sign the challenge.
+ async_caller_->TpmAttestationSignEnterpriseChallenge(
+ chromeos::CryptohomeClient::DEVICE_KEY,
+ kKeyName,
+ GetEnterpriseDomain(),
+ GetDeviceId(),
+ chromeos::CryptohomeClient::CHALLENGE_RESPONSE_OPTION_NONE,
+ challenge,
+ base::Bind(&EPKPChallengeMachineKey::SignChallengeCallback, this));
+}
+
+void EPKPChallengeMachineKey::SignChallengeCallback(
+ bool success, const std::string& response) {
+ if (!success) {
+ SetError("Challenge failed.");
+ SendResponse(false);
+ return;
+ }
+
+ std::string encoded_response;
+ if (!base::Base64Encode(response, &encoded_response)) {
+ SetError("Response cannot be encoded in base64.");
+ SendResponse(false);
+ return;
+ }
+
+ results_ = api_epkp::ChallengeMachineKey::Results::Create(encoded_response);
+ SendResponse(true);
+}
+
+// Implementation of ChallengeUserKey()
+
+const char EPKPChallengeUserKey::kKeyName[] = "attest-ent-user";
+
+EPKPChallengeUserKey::~EPKPChallengeUserKey() {
+}
+
+void EPKPChallengeUserKey::RegisterUserPrefs(PrefRegistrySyncable* registry) {
+ registry->RegisterBooleanPref(prefs::kAttestationEnabled, false,
+ PrefRegistrySyncable::UNSYNCABLE_PREF);
+ registry->RegisterListPref(prefs::kAttestationExtensionWhitelist,
+ PrefRegistrySyncable::UNSYNCABLE_PREF);
+}
+
+bool EPKPChallengeUserKey::RunImpl() {
+ scoped_ptr<api_epkp::ChallengeUserKey::Params> params(
+ api_epkp::ChallengeUserKey::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+
+ std::string challenge;
+ if (!base::Base64Decode(params->challenge, &challenge)) {
+ SetError("Challenge is not base64 encoded.");
+ SendResponse(false);
+ return false;
+ }
+
+ // Check if RA is enabled in the user policy.
+ if (!IsRemoteAttestationEnabledForUser()) {
+ SetError("Remote attestation is not enabled for your account.");
+ SendResponse(false);
+ return false;
+ }
+
+ // Check if the extension is whitelisted in the user policy.
+ if (!IsExtensionWhitelisted()) {
+ SetError("The extension does not have permission to call this function.");
+ SendResponse(false);
+ return false;
+ }
+
+ std::string user_domain = GetUserDomain();
+
+ if (IsEnterpriseDevice()) {
+ // Check if the user domain is the same as the enrolled enterprise domain.
+ std::string enterprise_domain = GetEnterpriseDomain();
+ if (user_domain != enterprise_domain) {
+ SetError("User domain " + user_domain + " and Enterprise domain " +
+ enterprise_domain + " don't match");
+ SendResponse(false);
+ return false;
+ }
+
+ // Check if RA is enabled in the device policy.
+ GetDeviceAttestationEnabled(
+ base::Bind(&EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback,
+ this, challenge, params->register_key, user_domain));
+ } else {
+ // If this is a personal device, we should explicitly ask the user before
+ // we use the key.
+ AskForUserConsent(
+ base::Bind(&EPKPChallengeUserKey::UserConsentCallback, this,
+ challenge, params->register_key, user_domain));
+ }
+
+ return true;
+}
+
+void EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback(
+ const std::string& challenge,
+ bool register_key,
+ const std::string& domain,
+ bool enabled) {
+ if (!enabled) {
+ SetError("Remote attestation is not enabled for your device.");
+ SendResponse(false);
+ return;
+ }
+
+ // If remote attestation is enabled at the device level, we don't need to
+ // ask for user consent.
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&EPKPChallengeUserKey::UserConsentCallback, this,
+ challenge, register_key, domain, true));
+}
+
+void EPKPChallengeUserKey::UserConsentCallback(const std::string& challenge,
+ bool register_key,
+ const std::string& domain,
+ bool action) {
+ if (!action) {
+ SetError("User rejects the action.");
+ SendResponse(false);
+ return;
+ }
+
+ // Everything is checked. Sign the challenge.
+ async_caller_->TpmAttestationSignEnterpriseChallenge(
+ chromeos::CryptohomeClient::USER_KEY,
+ kKeyName,
+ domain,
+ GetDeviceId(),
+ register_key ? chromeos::CryptohomeClient::INCLUDE_SIGNED_PUBLIC_KEY :
+ chromeos::CryptohomeClient::CHALLENGE_RESPONSE_OPTION_NONE,
+ challenge,
+ base::Bind(&EPKPChallengeUserKey::SignChallengeCallback, this,
+ register_key));
+}
+
+void EPKPChallengeUserKey::SignChallengeCallback(bool register_key,
+ bool success,
+ const std::string& response) {
+ if (!success) {
+ SetError("Challenge failed.");
+ SendResponse(false);
+ return;
+ }
+
+ if (register_key) {
+ async_caller_->TpmAttestationRegisterKey(
+ chromeos::CryptohomeClient::USER_KEY,
+ kKeyName,
+ base::Bind(&EPKPChallengeUserKey::RegisterKeyCallback, this, response));
+ } else {
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&EPKPChallengeUserKey::RegisterKeyCallback, this,
+ response, true, cryptohome::MOUNT_ERROR_NONE));
+ }
+}
+
+void EPKPChallengeUserKey::RegisterKeyCallback(
+ const std::string& response,
+ bool success,
+ cryptohome::MountError return_code) {
+ if (!success || return_code != cryptohome::MOUNT_ERROR_NONE) {
+ SetError("Key registration failed.");
+ SendResponse(false);
+ return;
+ }
+
+ std::string encoded_response;
+ if (!base::Base64Encode(response, &encoded_response)) {
+ SetError("Response cannot be encoded in base64.");
+ SendResponse(false);
+ return;
+ }
+
+ results_ = api_epkp::ChallengeUserKey::Results::Create(encoded_response);
+ SendResponse(true);
+}
+
+void EPKPChallengeUserKey::AskForUserConsent(
+ const base::Callback<void(bool)>& callback) {
+ // TODO(davidyu): right now we just simply reject the request before we have
+ // a way to ask for user consent.
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, false));
+}
+
+bool EPKPChallengeUserKey::IsExtensionWhitelisted() const {
+ const base::ListValue* list =
+ profile()->GetPrefs()->GetList(prefs::kAttestationExtensionWhitelist);
+ StringValue value(extension_->id());
+ return list->Find(value) != list->end();
+}
+
+bool EPKPChallengeUserKey::IsRemoteAttestationEnabledForUser() const {
+ return profile()->GetPrefs()->GetBoolean(prefs::kAttestationEnabled);
+}
+
+std::string EPKPChallengeUserKey::GetUserDomain() const {
+ SigninManager* signin_manager =
+ SigninManagerFactory::GetForProfile(profile());
+ if (!signin_manager)
+ return "";
+
+ return gaia::ExtractDomainName(
+ gaia::CanonicalizeEmail(signin_manager->GetAuthenticatedUsername()));
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
new file mode 100644
index 0000000..a0194a2c
--- /dev/null
+++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
@@ -0,0 +1,123 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_PRIVATE_ENTERPRISE_PLATFORM_KEYS_PRIVATE_API_H__
+#define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_PRIVATE_ENTERPRISE_PLATFORM_KEYS_PRIVATE_API_H__
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "chrome/browser/extensions/extension_function.h"
+#include "chrome/common/extensions/api/enterprise_platform_keys_private.h"
+#include "chromeos/dbus/dbus_method_call_status.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+class PrefRegistrySyncable;
+class PrefService;
+
+namespace chromeos {
+class CryptohomeClient;
+} // namespace chromeos
+
+namespace cryptohome {
+class AsyncMethodCaller;
+} // namespace cryptohome
+
+namespace policy {
+class EnterpriseInstallAttributes;
+} // namespace policy
+
+namespace extensions {
+
+class EPKPChallengeKeyBase : public AsyncExtensionFunction {
+ protected:
+ EPKPChallengeKeyBase();
+ virtual ~EPKPChallengeKeyBase();
+
+ // Returns a trusted value from CroSettings indicating if the device
+ // attestation is enabled.
+ void GetDeviceAttestationEnabled(
+ const base::Callback<void(bool)>& callback) const;
+
+ // Returns true if the device is enterprise managed.
+ bool IsEnterpriseDevice() const;
+
+ // Returns the enterprise domain the device is enrolled to.
+ std::string GetEnterpriseDomain() const;
+
+ // Returns the enterprise virtual device ID.
+ std::string GetDeviceId() const;
+
+ chromeos::CryptohomeClient* cryptohome_client_;
+ cryptohome::AsyncMethodCaller* async_caller_;
+
+ private:
+ policy::EnterpriseInstallAttributes* install_attributes_;
+};
+
+class EPKPChallengeMachineKey : public EPKPChallengeKeyBase {
+ protected:
+ virtual bool RunImpl() OVERRIDE;
+
+ private:
+ static const char kKeyName[];
+
+ virtual ~EPKPChallengeMachineKey();
+
+ void GetDeviceAttestationEnabledCallback(const std::string& challenge,
+ bool enabled);
+ void SignChallengeCallback(bool success, const std::string& response);
+
+ DECLARE_EXTENSION_FUNCTION(
+ "enterprise.platformKeysPrivate.challengeMachineKey",
+ ENTERPRISE_PLATFORMKEYSPRIVATE_CHALLENGEMACHINEKEY);
+};
+
+typedef EPKPChallengeMachineKey
+ EnterprisePlatformKeysPrivateChallengeMachineKeyFunction;
+
+class EPKPChallengeUserKey : public EPKPChallengeKeyBase {
+ public:
+ static void RegisterUserPrefs(PrefRegistrySyncable* registry);
+
+ protected:
+ virtual bool RunImpl() OVERRIDE;
+
+ private:
+ static const char kKeyName[];
+
+ virtual ~EPKPChallengeUserKey();
+
+ void GetDeviceAttestationEnabledCallback(const std::string& challenge,
+ bool register_key,
+ const std::string& domain,
+ bool enabled);
+ void UserConsentCallback(const std::string& challenge,
+ bool register_key,
+ const std::string& domain,
+ bool action);
+ void SignChallengeCallback(bool register_key,
+ bool success,
+ const std::string& response);
+ void RegisterKeyCallback(const std::string& response,
+ bool success,
+ cryptohome::MountError return_code);
+
+ void AskForUserConsent(const base::Callback<void(bool)>& callback);
+ bool IsExtensionWhitelisted() const;
+ bool IsRemoteAttestationEnabledForUser() const;
+ std::string GetUserDomain() const;
+
+ DECLARE_EXTENSION_FUNCTION(
+ "enterprise.platformKeysPrivate.challengeUserKey",
+ ENTERPRISE_PLATFORMKEYSPRIVATE_CHALLENGEUSERKEY);
+};
+
+typedef EPKPChallengeUserKey
+ EnterprisePlatformKeysPrivateChallengeUserKeyFunction;
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_PRIVATE_ENTERPRISE_PLATFORM_KEYS_PRIVATE_API_H__
diff --git a/chrome/browser/extensions/extension_function_histogram_value.h b/chrome/browser/extensions/extension_function_histogram_value.h
index 91c244e..0d0fa22 100644
--- a/chrome/browser/extensions/extension_function_histogram_value.h
+++ b/chrome/browser/extensions/extension_function_histogram_value.h
@@ -503,6 +503,8 @@
APP_CURRENTWINDOWINTERNAL_FULLSCREEN,
DEVELOPERPRIVATE_LOADUNPACKEDCROS,
NETWORKINGPRIVATE_REQUESTNETWORKSCAN,
+ ENTERPRISE_PLATFORMKEYSPRIVATE_CHALLENGEMACHINEKEY,
+ ENTERPRISE_PLATFORMKEYSPRIVATE_CHALLENGEUSERKEY,
ENUM_BOUNDARY // Last entry: Add new entries above.
};
diff --git a/chrome/browser/policy/configuration_policy_handler_list.cc b/chrome/browser/policy/configuration_policy_handler_list.cc
index 7465b76c..4c071fd 100644
--- a/chrome/browser/policy/configuration_policy_handler_list.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list.cc
@@ -374,6 +374,9 @@
{ key::kRebootAfterUpdate,
prefs::kRebootAfterUpdate,
Value::TYPE_BOOLEAN },
+ { key::kAttestationEnabledForUser,
+ prefs::kAttestationEnabled,
+ Value::TYPE_BOOLEAN },
#endif // defined(OS_CHROMEOS)
#if !defined(OS_MACOSX) && !defined(OS_CHROMEOS)
@@ -432,6 +435,12 @@
key::kExtensionAllowedTypes, prefs::kExtensionAllowedTypes,
kExtensionAllowedTypesMap,
kExtensionAllowedTypesMap + arraysize(kExtensionAllowedTypesMap)));
+#if defined(OS_CHROMEOS)
+ handlers_.push_back(
+ new ExtensionListPolicyHandler(key::kAttestationExtensionWhitelist,
+ prefs::kAttestationExtensionWhitelist,
+ false));
+#endif // defined(OS_CHROMEOS)
#if !defined(OS_CHROMEOS)
handlers_.push_back(new DownloadDirPolicyHandler());
diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
index f91c87e..507c118 100644
--- a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
@@ -308,7 +308,9 @@
PolicyAndPref(key::kAudioOutputAllowed,
prefs::kAudioOutputAllowed),
PolicyAndPref(key::kAudioCaptureAllowed,
- prefs::kAudioCaptureAllowed)));
+ prefs::kAudioCaptureAllowed),
+ PolicyAndPref(key::kAttestationEnabledForUser,
+ prefs::kAttestationEnabled)));
#endif // defined(OS_CHROMEOS)
// Test cases for integer-valued policy settings.
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 52389b2..611914f1 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -133,6 +133,7 @@
#include "chrome/browser/chromeos/settings/device_settings_cache.h"
#include "chrome/browser/chromeos/status/data_promo_notification.h"
#include "chrome/browser/chromeos/system/automatic_reboot_manager.h"
+#include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h"
#else
#include "chrome/browser/extensions/default_apps.h"
#endif
@@ -354,6 +355,8 @@
chromeos::OAuth2LoginManager::RegisterUserPrefs(registry);
chromeos::Preferences::RegisterUserPrefs(registry);
chromeos::ProxyConfigServiceImpl::RegisterUserPrefs(registry);
+ extensions::EnterprisePlatformKeysPrivateChallengeUserKeyFunction::
+ RegisterUserPrefs(registry);
FlagsUI::RegisterUserPrefs(registry);
#endif
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index 84a6c0a0..d67de53 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -754,6 +754,8 @@
'browser/extensions/default_apps.h',
],
'sources': [
+ 'browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc',
+ 'browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h',
'browser/extensions/api/input_ime/input_ime_api.cc',
'browser/extensions/api/input_ime/input_ime_api.h',
'browser/extensions/api/rtc_private/rtc_private_api.cc',
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 4d7e941..77263ba 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -154,6 +154,12 @@
"16CA7A47AAE4BE49B1E75A6B960C3875E945B264" // Release
]
},
+ "enterprise.platformKeysPrivate": {
+ "channel": "dev",
+ "extension_types": ["extension", "packaged_app"],
+ "whitelist": [
+ ]
+ },
"experimental": {
"channel": "stable",
"extension_types": [
diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp
index a89e95c..d7020623 100644
--- a/chrome/common/extensions/api/api.gyp
+++ b/chrome/common/extensions/api/api.gyp
@@ -38,6 +38,7 @@
'downloads.idl',
'echo_private.json',
'downloads_internal.idl',
+ 'enterprise_platform_keys_private.json',
'events.json',
'experimental_accessibility.json',
'experimental_discovery.idl',
diff --git a/chrome/common/extensions/api/enterprise_platform_keys_private.json b/chrome/common/extensions/api/enterprise_platform_keys_private.json
new file mode 100644
index 0000000..483586c
--- /dev/null
+++ b/chrome/common/extensions/api/enterprise_platform_keys_private.json
@@ -0,0 +1,67 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ {
+ "namespace": "enterprise.platformKeysPrivate",
+ "nodoc": true,
+ "platforms": ["chromeos"],
+ "types": [],
+ "functions": [
+ {
+ "name": "challengeMachineKey",
+ "type": "function",
+ "description": "Challenge a machine key.",
+ "parameters": [
+ {
+ "type": "string",
+ "name": "challenge",
+ "description": "Challenge to be signed in base64."
+ },
+ {
+ "type": "function",
+ "name": "callback",
+ "description": "Callback function.",
+ "parameters": [
+ {
+ "name": "response",
+ "description": "Response in base64.",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "challengeUserKey",
+ "type": "function",
+ "description": "Challenge an user key.",
+ "parameters": [
+ {
+ "type": "string",
+ "name": "challenge",
+ "description": "Challenge to be signed in base64."
+ },
+ {
+ "type": "boolean",
+ "name": "registerKey",
+ "description": "If true, the key will be registered."
+ },
+ {
+ "type": "function",
+ "name": "callback",
+ "description": "Callback function.",
+ "parameters": [
+ {
+ "name": "response",
+ "description": "Response in base64.",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+]
diff --git a/chrome/common/extensions/permissions/api_permission.h b/chrome/common/extensions/permissions/api_permission.h
index f9719f3..7500e002 100644
--- a/chrome/common/extensions/permissions/api_permission.h
+++ b/chrome/common/extensions/permissions/api_permission.h
@@ -66,6 +66,7 @@
kDownloads,
kDownloadsInternal,
kEchoPrivate,
+ kEnterprisePlatformKeysPrivate,
kExperimental,
kFileBrowserHandler,
kFileBrowserHandlerInternal,
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc
index 531fc79..a9abe97 100644
--- a/chrome/common/extensions/permissions/chrome_api_permissions.cc
+++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -165,6 +165,9 @@
APIPermissionInfo::kFlagCannotBeOptional },
{ APIPermission::kStreamsPrivate, "streamsPrivate",
APIPermissionInfo::kFlagCannotBeOptional },
+ { APIPermission::kEnterprisePlatformKeysPrivate,
+ "enterprise.platformKeysPrivate",
+ APIPermissionInfo::kFlagCannotBeOptional },
// Full url access permissions.
{ APIPermission::kDebugger, "debugger",
diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc
index 4b23daf..e71db7ed 100644
--- a/chrome/common/extensions/permissions/permission_set_unittest.cc
+++ b/chrome/common/extensions/permissions/permission_set_unittest.cc
@@ -719,6 +719,7 @@
skip.insert(APIPermission::kDial);
skip.insert(APIPermission::kDownloadsInternal);
skip.insert(APIPermission::kEchoPrivate);
+ skip.insert(APIPermission::kEnterprisePlatformKeysPrivate);
skip.insert(APIPermission::kFileBrowserHandlerInternal);
skip.insert(APIPermission::kFileBrowserPrivate);
skip.insert(APIPermission::kInputMethodPrivate);
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 9d275e7..820868f 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -871,6 +871,12 @@
// show a warning indicating that the organization may track the browsing
// session.
const char kUsedPolicyCertificatesOnce[] = "used_policy_certificates_once";
+
+// Indicates whether the remote attestation is enabled for the user.
+const char kAttestationEnabled[] = "attestation.enabled";
+// The list of extensions allowed to use the platformKeysPrivate API for
+// remote attestation.
+const char kAttestationExtensionWhitelist[] = "attestation.extension_whitelist";
#endif // defined(OS_CHROMEOS)
// The disabled messages in IPC logging.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 534b899f..222af2d 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -313,6 +313,8 @@
extern const char kPowerPresentationIdleDelayFactor[];
extern const char kTermsOfServiceURL[];
extern const char kUsedPolicyCertificatesOnce[];
+extern const char kAttestationEnabled[];
+extern const char kAttestationExtensionWhitelist[];
#endif // defined(OS_CHROMEOS)
extern const char kIpcDisabledMessages[];
extern const char kShowHomeButton[];
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 9df2eff..460b11b16 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -1735,6 +1735,22 @@
]
},
+ "AttestationEnabledForUser": {
+ "os": ["chromeos"],
+ "test_policy": { "AttestationEnabledForUser": true },
+ "pref_mappings": [
+ { "pref": "attestation.enabled" }
+ ]
+ },
+
+ "AttestationExtensionWhitelist": {
+ "os": ["chromeos"],
+ "test_policy": { "AttestationExtensionWhitelist": ["test_ext_id1", "test_ext_id2"] },
+ "pref_mappings": [
+ { "pref": "attestation.extension_whitelist" }
+ ]
+ },
+
"----- Chrome OS device policies ---------------------------------------": {},
"DevicePolicyRefreshRate": {