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

Unified Diff: chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc

Issue 1150373002: platformKeys: Add policy and corporate key tagging. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@key_perm
Patch Set: Created 5 years, 6 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/extensions/api/platform_keys/platform_keys_apitest_nss.cc
diff --git a/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc b/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc
index 1d3f181105534a696b7bb272fa34f7ab0f87d5aa..6fdf303ce10d48c28822945ae401df7808b9d952 100644
--- a/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc
+++ b/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc
@@ -5,15 +5,20 @@
#include <cryptohi.h>
#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/strings/stringprintf.h"
+#include "base/json/json_writer.h"
#include "chrome/browser/chromeos/platform_keys/platform_keys_service.h"
#include "chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h"
#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/net/nss_context.h"
+#include "chrome/browser/policy/profile_policy_connector.h"
+#include "chrome/browser/policy/profile_policy_connector_factory.h"
+#include "chrome/browser/profiles/profile.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/login/user_names.h"
-#include "components/policy/core/browser/browser_policy_connector.h"
+#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/core/common/policy_map.h"
#include "content/public/browser/notification_service.h"
#include "content/public/common/content_switches.h"
@@ -27,51 +32,91 @@
#include "net/cert/nss_cert_database.h"
#include "net/cert/test_root_certs.h"
#include "net/test/cert_test_util.h"
-#include "net/test/url_request/url_request_mock_http_job.h"
#include "policy/policy_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
+#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
+#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
+#include "components/policy/core/common/cloud/cloud_policy_manager.h"
+#include "components/policy/core/common/cloud/cloud_policy_core.h"
+#include "components/policy/core/common/cloud/cloud_policy_store.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/chromeos/policy/login_policy_test_base.h"
+
namespace {
enum DeviceStatus { DEVICE_STATUS_ENROLLED, DEVICE_STATUS_NOT_ENROLLED };
-enum UserAffiliation {
- USER_AFFILIATION_ENROLLED_DOMAIN,
- USER_AFFILIATION_UNRELATED
+enum UserStatus {
+ USER_STATUS_MANAGED_AFFILIATED_DOMAIN,
+ USER_STATUS_MANAGED_OTHER_DOMAIN,
+ USER_STATUS_UNMANAGED
};
-struct Params {
- Params(DeviceStatus device_status, UserAffiliation user_affiliation)
- : device_status_(device_status), user_affiliation_(user_affiliation) {}
+class PlatformKeysTest : public ExtensionApiTest {
+ public:
+ PlatformKeysTest(DeviceStatus device_status,
+ UserStatus user_status,
+ bool key_permission_policy)
+ : device_status_(device_status),
+ user_status_(user_status),
+ key_permission_policy_(key_permission_policy) {
+ if (user_status_ != USER_STATUS_UNMANAGED) {
+ SetupInitialEmptyPolicy();
+ }
+ }
- DeviceStatus device_status_;
- UserAffiliation user_affiliation_;
-};
+ void SetupInitialEmptyPolicy() {
+ policy_helper_.reset(new policy::PolicyTestHelper(
+ chromeos::login::kStubUser,
+ base::DictionaryValue() /* empty mandatory policy */,
+ base::DictionaryValue() /* empty recommended policy */));
+ }
-class PlatformKeysTest : public ExtensionApiTest,
- public ::testing::WithParamInterface<Params> {
- public:
- PlatformKeysTest() {}
+ void SetupKeyPermissionPolicy() {
+ // Set up the test policy that gives |extension_| the permission to access
+ // corporate keys.
+ base::DictionaryValue key_permissions_policy;
+ {
+ scoped_ptr<base::DictionaryValue> cert1_key_permission(
+ new base::DictionaryValue);
+ cert1_key_permission->SetBooleanWithoutPathExpansion(
+ "allowCorporateKeyUsage", true);
+ key_permissions_policy.SetWithoutPathExpansion(
+ extension_->id(), cert1_key_permission.release());
+ }
+
+ std::string key_permissions_policy_str;
+ base::JSONWriter::Write(key_permissions_policy, &key_permissions_policy_str);
+
+ base::DictionaryValue user_policy;
+ user_policy.SetStringWithoutPathExpansion(policy::key::kKeyPermissions,
+ key_permissions_policy_str);
+
+ policy_helper_->UpdatePolicy(
+ browser()->profile(), user_policy,
+ base::DictionaryValue() /* empty recommended policy */);
+ }
void SetUpCommandLine(base::CommandLine* command_line) override {
ExtensionApiTest::SetUpCommandLine(command_line);
- std::string user_email = "someuser@anydomain.com";
-
- // The command line flag kLoginUser determines the user's email and thus
- // his affiliation to the domain that the device is enrolled to.
- if (GetParam().user_affiliation_ == USER_AFFILIATION_ENROLLED_DOMAIN)
- user_email = chromeos::login::kStubUser;
+ if (policy_helper_)
+ policy_helper_->UpdateCommandLine(command_line);
- command_line->AppendSwitchASCII(chromeos::switches::kLoginUser, user_email);
+ command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
+ chromeos::login::kStubUser);
}
void SetUpInProcessBrowserTestFixture() override {
ExtensionApiTest::SetUpInProcessBrowserTestFixture();
- if (GetParam().device_status_ == DEVICE_STATUS_ENROLLED) {
+ if (device_status_ == DEVICE_STATUS_ENROLLED) {
device_policy_test_helper_.device_policy()->policy_data().set_username(
- chromeos::login::kStubUser);
+ user_status_ == USER_STATUS_MANAGED_AFFILIATED_DOMAIN
+ ? chromeos::login::kStubUser
+ : "someuser@anydomain.com");
device_policy_test_helper_.device_policy()->Build();
device_policy_test_helper_.MarkAsEnterpriseOwned();
@@ -79,6 +124,9 @@ class PlatformKeysTest : public ExtensionApiTest,
}
void SetUpOnMainThread() override {
+ if (policy_helper_)
+ policy_helper_->WaitForInitialPolicy(browser()->profile());
+
{
base::RunLoop loop;
content::BrowserThread::PostTask(
@@ -103,6 +151,9 @@ class PlatformKeysTest : public ExtensionApiTest,
base::FilePath extension_path = test_data_dir_.AppendASCII("platform_keys");
extension_ = LoadExtension(extension_path);
+
+ if (key_permission_policy_)
+ SetupKeyPermissionPolicy();
}
void TearDownOnMainThread() override {
@@ -127,23 +178,58 @@ class PlatformKeysTest : public ExtensionApiTest,
// Only if the current user is of the same domain as the device is enrolled
// to, the system token is available to the extension.
- if (GetParam().device_status_ == DEVICE_STATUS_ENROLLED &&
- GetParam().user_affiliation_ == USER_AFFILIATION_ENROLLED_DOMAIN) {
+ if (device_status_ == DEVICE_STATUS_ENROLLED &&
+ user_status_ == USER_STATUS_MANAGED_AFFILIATED_DOMAIN) {
system_token_availability = "systemTokenEnabled";
}
GURL url = extension_->GetResourceURL(base::StringPrintf(
"basic.html?%s#%s", system_token_availability.c_str(),
test_suite_name.c_str()));
- return RunExtensionSubtest("platform_keys", url.spec());
+ return RunExtensionSubtest("", url.spec());
+ }
+
+ void RegisterClient1AsCorporateKey() {
+ const extensions::Extension* const fake_gen_extension =
+ LoadExtension(test_data_dir_.AppendASCII("platform_keys_genkey"));
+
+ policy::ProfilePolicyConnector* const policy_connector =
+ policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile());
+
+ extensions::StateStore* const state_store =
+ extensions::ExtensionSystem::Get(profile())->state_store();
+
+ chromeos::KeyPermissions permissions(profile()->GetPrefs(), true,
+ policy_connector->policy_service(),
+ state_store);
+
+ base::RunLoop run_loop;
+ permissions.GetPermissionsForExtension(
+ fake_gen_extension->id(),
+ base::Bind(&PlatformKeysTest::GotPermissionsForExtension,
+ base::Unretained(this), run_loop.QuitClosure()));
+ run_loop.Run();
}
protected:
+ const DeviceStatus device_status_;
+ const UserStatus user_status_;
+
scoped_refptr<net::X509Certificate> client_cert1_;
scoped_refptr<net::X509Certificate> client_cert2_;
const extensions::Extension* extension_;
private:
+ void GotPermissionsForExtension(
+ const base::Closure& done_callback,
+ scoped_ptr<chromeos::KeyPermissions::PermissionsForExtension>
+ permissions_for_ext) {
+ std::string client_cert1_spki =
+ chromeos::platform_keys::GetSubjectPublicKeyInfo(client_cert1_);
+ permissions_for_ext->RegisterKeyForCorporateUsage(client_cert1_spki );
+ done_callback.Run();
+ }
+
void SetupTestCerts(const base::Closure& done_callback,
net::NSSCertDatabase* cert_db) {
SetupTestClientCerts(cert_db);
@@ -192,6 +278,8 @@ class PlatformKeysTest : public ExtensionApiTest,
done_callback);
}
+ const bool key_permission_policy_;
+ scoped_ptr<policy::PolicyTestHelper> policy_helper_;
policy::DevicePolicyCrosTestHelper device_policy_test_helper_;
scoped_ptr<crypto::ScopedTestSystemNSSKeySlot> test_system_slot_;
};
@@ -199,11 +287,12 @@ class PlatformKeysTest : public ExtensionApiTest,
class TestSelectDelegate
: public chromeos::PlatformKeysService::SelectDelegate {
public:
- // On each Select call, selects the next entry in |cert_to_select| from back
+ // On each Select call, selects the next entry in |certs_to_select| from back
// to front. Once the first entry is reached, that one will be selected
// repeatedly.
// Entries of |certs_to_select| can be null in which case no certificate will
// be selected.
+ // If |certs_to_select| is empty, any invocation of |Select| will fail.
explicit TestSelectDelegate(net::CertificateList certs_to_select)
: certs_to_select_(certs_to_select) {}
@@ -235,13 +324,51 @@ class TestSelectDelegate
net::CertificateList certs_to_select_;
};
+class UnmanagedPlatformKeysTest
+ : public PlatformKeysTest,
+ public ::testing::WithParamInterface<DeviceStatus> {
+ public:
+ UnmanagedPlatformKeysTest()
+ : PlatformKeysTest(GetParam(),
+ USER_STATUS_UNMANAGED,
+ false /* unused */) {}
+};
+
+struct Params {
+ Params(DeviceStatus device_status, UserStatus user_status)
+ : device_status_(device_status), user_status_(user_status) {}
+
+ DeviceStatus device_status_;
+ UserStatus user_status_;
+};
+
+class ManagedWithPermissionPlatformKeysTest
+ : public PlatformKeysTest,
+ public ::testing::WithParamInterface<Params> {
+ public:
+ ManagedWithPermissionPlatformKeysTest()
+ : PlatformKeysTest(GetParam().device_status_,
+ GetParam().user_status_,
+ true /* grant the extension key permission */) {}
+};
+
+class ManagedWithoutPermissionPlatformKeysTest
+ : public PlatformKeysTest,
+ public ::testing::WithParamInterface<Params> {
+ public:
+ ManagedWithoutPermissionPlatformKeysTest()
+ : PlatformKeysTest(GetParam().device_status_,
+ GetParam().user_status_,
+ false /* do not grant key permission */) {}
+};
+
} // namespace
// At first interactively selects |client_cert1_| and |client_cert2_| to grant
// permissions and afterwards runs more basic tests.
// After the initial two interactive calls, the simulated user does not select
// any cert.
-IN_PROC_BROWSER_TEST_P(PlatformKeysTest, Basic) {
+IN_PROC_BROWSER_TEST_P(UnmanagedPlatformKeysTest, Basic) {
net::CertificateList certs;
certs.push_back(nullptr);
certs.push_back(client_cert2_);
@@ -255,7 +382,7 @@ IN_PROC_BROWSER_TEST_P(PlatformKeysTest, Basic) {
// On interactive calls, the simulated user always selects |client_cert1_| if
// matching.
-IN_PROC_BROWSER_TEST_P(PlatformKeysTest, Permissions) {
+IN_PROC_BROWSER_TEST_P(UnmanagedPlatformKeysTest, Permissions) {
net::CertificateList certs;
certs.push_back(client_cert1_);
@@ -265,10 +392,74 @@ IN_PROC_BROWSER_TEST_P(PlatformKeysTest, Permissions) {
ASSERT_TRUE(RunExtensionTest("permissionTests")) << message_;
}
+INSTANTIATE_TEST_CASE_P(Unmanaged,
+ UnmanagedPlatformKeysTest,
+ ::testing::Values(DEVICE_STATUS_ENROLLED,
+ DEVICE_STATUS_NOT_ENROLLED));
+
+IN_PROC_BROWSER_TEST_P(ManagedWithoutPermissionPlatformKeysTest,
+ UserPermissionsBlocked) {
+ // To verify that the user is not prompted for any certificate selection,
+ // set up a delegate that fails on any invocation.
+ GetPlatformKeysService()->SetSelectDelegate(
+ make_scoped_ptr(new TestSelectDelegate(net::CertificateList())));
+
+ ASSERT_TRUE(RunExtensionTest("managedProfile")) << message_;
+}
+
+// A corporate key must not be useable if there is no policy permitting it.
+IN_PROC_BROWSER_TEST_P(ManagedWithoutPermissionPlatformKeysTest,
+ CorporateKeyAccessBlocked) {
+ RegisterClient1AsCorporateKey();
+
+ // To verify that the user is not prompted for any certificate selection,
+ // set up a delegate that fails on any invocation.
+ GetPlatformKeysService()->SetSelectDelegate(
+ make_scoped_ptr(new TestSelectDelegate(net::CertificateList())));
+
+ ASSERT_TRUE(RunExtensionTest("corporateKeyWithoutPermissionTests"))
+ << message_;
+}
+
+INSTANTIATE_TEST_CASE_P(
+ ManagedWithoutPermission,
+ ManagedWithoutPermissionPlatformKeysTest,
+ ::testing::Values(
+ Params(DEVICE_STATUS_ENROLLED, USER_STATUS_MANAGED_AFFILIATED_DOMAIN),
+ Params(DEVICE_STATUS_ENROLLED, USER_STATUS_MANAGED_OTHER_DOMAIN),
+ Params(DEVICE_STATUS_NOT_ENROLLED, USER_STATUS_MANAGED_OTHER_DOMAIN)));
+
+IN_PROC_BROWSER_TEST_P(ManagedWithPermissionPlatformKeysTest,
+ PolicyGrantsAccessToCorporateKey) {
+ RegisterClient1AsCorporateKey();
+
+ // Set up the test SelectDelegate to select |client_cert1_| if available for
+ // selection.
+ net::CertificateList certs;
+ certs.push_back(client_cert1_);
+
+ GetPlatformKeysService()->SetSelectDelegate(
+ make_scoped_ptr(new TestSelectDelegate(certs)));
+
+ ASSERT_TRUE(RunExtensionTest("corporateKeyWithPermissionTests")) << message_;
+}
+
+IN_PROC_BROWSER_TEST_P(ManagedWithPermissionPlatformKeysTest,
+ PolicyDoesGrantAccessToNonCorporateKey) {
+
+ // As the profile is managed, the user must not be able to grant any
+ // certificate permission. Set up a delegate that fails on any invocation.
+ GetPlatformKeysService()->SetSelectDelegate(
+ make_scoped_ptr(new TestSelectDelegate(net::CertificateList())));
+
+ ASSERT_TRUE(RunExtensionTest("untaggedKeyWithUnrelatedPermissionTests"))
+ << message_;
+}
+
INSTANTIATE_TEST_CASE_P(
- CheckSystemTokenAvailability,
- PlatformKeysTest,
+ ManagedWithPermission,
+ ManagedWithPermissionPlatformKeysTest,
::testing::Values(
- Params(DEVICE_STATUS_ENROLLED, USER_AFFILIATION_ENROLLED_DOMAIN),
- Params(DEVICE_STATUS_ENROLLED, USER_AFFILIATION_UNRELATED),
- Params(DEVICE_STATUS_NOT_ENROLLED, USER_AFFILIATION_UNRELATED)));
+ Params(DEVICE_STATUS_ENROLLED, USER_STATUS_MANAGED_AFFILIATED_DOMAIN),
+ Params(DEVICE_STATUS_ENROLLED, USER_STATUS_MANAGED_OTHER_DOMAIN),
+ Params(DEVICE_STATUS_NOT_ENROLLED, USER_STATUS_MANAGED_OTHER_DOMAIN)));

Powered by Google App Engine
This is Rietveld 408576698