| Index: chromeos/network/client_cert_resolver_unittest.cc
|
| diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc
|
| index 8caac7a44c1cd4d72d7bb6148270dc3be46bae26..06576480f7a6c4eb15a87b3965e7bb724550807b 100644
|
| --- a/chromeos/network/client_cert_resolver_unittest.cc
|
| +++ b/chromeos/network/client_cert_resolver_unittest.cc
|
| @@ -53,16 +53,12 @@ const char* kUserHash = "user_hash";
|
| class ClientCertResolverTest : public testing::Test,
|
| public ClientCertResolver::Observer {
|
| public:
|
| - ClientCertResolverTest()
|
| - : network_properties_changed_count_(0),
|
| - service_test_(nullptr),
|
| - profile_test_(nullptr),
|
| - cert_loader_(nullptr),
|
| - scoped_task_scheduler_(&message_loop_) {}
|
| + ClientCertResolverTest() : scoped_task_scheduler_(&message_loop_) {}
|
| ~ClientCertResolverTest() override {}
|
|
|
| void SetUp() override {
|
| ASSERT_TRUE(test_nssdb_.is_open());
|
| + ASSERT_TRUE(test_system_nssdb_.is_open());
|
|
|
| // Use the same DB for public and private slot.
|
| test_nsscertdb_.reset(new net::NSSCertDatabaseChromeOS(
|
| @@ -86,10 +82,12 @@ class ClientCertResolverTest : public testing::Test,
|
| }
|
|
|
| void TearDown() override {
|
| - client_cert_resolver_->RemoveObserver(this);
|
| + if (client_cert_resolver_)
|
| + client_cert_resolver_->RemoveObserver(this);
|
| client_cert_resolver_.reset();
|
| test_clock_.reset();
|
| - network_state_handler_->Shutdown();
|
| + if (network_state_handler_)
|
| + network_state_handler_->Shutdown();
|
| managed_config_handler_.reset();
|
| network_config_handler_.reset();
|
| network_profile_handler_.reset();
|
| @@ -137,6 +135,16 @@ class ClientCertResolverTest : public testing::Test,
|
| ASSERT_TRUE(test_client_cert_.get());
|
| }
|
|
|
| + void SetupTestCertInSystemToken(const std::string& prefix) {
|
| + test_nsscertdb_->SetSystemSlot(
|
| + crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_system_nssdb_.slot())));
|
| +
|
| + test_client_cert_ = net::ImportClientCertAndKeyFromFile(
|
| + net::GetTestCertsDirectory(), prefix + ".pem", prefix + ".pk8",
|
| + test_system_nssdb_.slot());
|
| + ASSERT_TRUE(test_client_cert_.get());
|
| + }
|
| +
|
| void SetupNetworkHandlers() {
|
| network_state_handler_ = NetworkStateHandler::InitializeForTest();
|
| network_profile_handler_.reset(new NetworkProfileHandler());
|
| @@ -184,7 +192,7 @@ class ClientCertResolverTest : public testing::Test,
|
|
|
| // Sets up a policy with a certificate pattern that matches any client cert
|
| // with a certain Issuer CN. It will match the test client cert.
|
| - void SetupPolicyMatchingIssuerCN() {
|
| + void SetupPolicyMatchingIssuerCN(onc::ONCSource onc_source) {
|
| const char* kTestPolicy =
|
| "[ { \"GUID\": \"wifi_stub\","
|
| " \"Name\": \"wifi_stub\","
|
| @@ -213,15 +221,40 @@ class ClientCertResolverTest : public testing::Test,
|
| base::ListValue* policy = nullptr;
|
| ASSERT_TRUE(policy_value->GetAsList(&policy));
|
|
|
| + std::string user_hash =
|
| + onc_source == onc::ONC_SOURCE_USER_POLICY ? kUserHash : "";
|
| managed_config_handler_->SetPolicy(
|
| - onc::ONC_SOURCE_USER_POLICY, kUserHash, *policy,
|
| + onc_source, user_hash, *policy,
|
| base::DictionaryValue() /* no global network config */);
|
| }
|
|
|
| + void SetupCertificateConfigMatchingIssuerCN(
|
| + onc::ONCSource onc_source,
|
| + client_cert::ClientCertConfig* client_cert_config) {
|
| + const char* kTestOncPattern =
|
| + "{"
|
| + " \"Issuer\": {"
|
| + " \"CommonName\": \"B CA\""
|
| + " }"
|
| + "}";
|
| + std::string error;
|
| + std::unique_ptr<base::Value> onc_pattern_value =
|
| + base::JSONReader::ReadAndReturnError(
|
| + kTestOncPattern, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &error);
|
| + ASSERT_TRUE(onc_pattern_value) << error;
|
| +
|
| + base::DictionaryValue* onc_pattern_dict;
|
| + onc_pattern_value->GetAsDictionary(&onc_pattern_dict);
|
| +
|
| + client_cert_config->onc_source = onc_source;
|
| + client_cert_config->pattern.ReadFromONCDictionary(*onc_pattern_dict);
|
| + }
|
| +
|
| // Sets up a policy with a certificate pattern that matches any client cert
|
| // that is signed by the test CA cert (stored in |test_ca_cert_pem_|). In
|
| // particular it will match the test client cert.
|
| - void SetupPolicyMatchingIssuerPEM(const std::string& identity) {
|
| + void SetupPolicyMatchingIssuerPEM(onc::ONCSource onc_source,
|
| + const std::string& identity) {
|
| const char* kTestPolicyTemplate =
|
| "[ { \"GUID\": \"wifi_stub\","
|
| " \"Name\": \"wifi_stub\","
|
| @@ -251,10 +284,10 @@ class ClientCertResolverTest : public testing::Test,
|
| base::ListValue* policy = nullptr;
|
| ASSERT_TRUE(policy_value->GetAsList(&policy));
|
|
|
| + std::string user_hash =
|
| + onc_source == onc::ONC_SOURCE_USER_POLICY ? kUserHash : "";
|
| managed_config_handler_->SetPolicy(
|
| - onc::ONC_SOURCE_USER_POLICY,
|
| - kUserHash,
|
| - *policy,
|
| + onc_source, user_hash, *policy,
|
| base::DictionaryValue() /* no global network config */);
|
| }
|
|
|
| @@ -273,10 +306,11 @@ class ClientCertResolverTest : public testing::Test,
|
| properties->GetStringWithoutPathExpansion(prop_name, prop_value);
|
| }
|
|
|
| - int network_properties_changed_count_;
|
| + int network_properties_changed_count_ = 0;
|
| std::string test_cert_id_;
|
| std::unique_ptr<base::SimpleTestClock> test_clock_;
|
| std::unique_ptr<ClientCertResolver> client_cert_resolver_;
|
| + CertLoader* cert_loader_ = nullptr;
|
|
|
| private:
|
| // ClientCertResolver::Observer:
|
| @@ -285,9 +319,8 @@ class ClientCertResolverTest : public testing::Test,
|
| ++network_properties_changed_count_;
|
| }
|
|
|
| - ShillServiceClient::TestInterface* service_test_;
|
| - ShillProfileClient::TestInterface* profile_test_;
|
| - CertLoader* cert_loader_;
|
| + ShillServiceClient::TestInterface* service_test_ = nullptr;
|
| + ShillProfileClient::TestInterface* profile_test_ = nullptr;
|
| std::unique_ptr<NetworkStateHandler> network_state_handler_;
|
| std::unique_ptr<NetworkProfileHandler> network_profile_handler_;
|
| std::unique_ptr<NetworkConfigurationHandler> network_config_handler_;
|
| @@ -298,6 +331,7 @@ class ClientCertResolverTest : public testing::Test,
|
| scoped_refptr<net::X509Certificate> test_client_cert_;
|
| std::string test_ca_cert_pem_;
|
| crypto::ScopedTestNSSDB test_nssdb_;
|
| + crypto::ScopedTestNSSDB test_system_nssdb_;
|
| std::unique_ptr<net::NSSCertDatabaseChromeOS> test_nsscertdb_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest);
|
| @@ -310,7 +344,7 @@ TEST_F(ClientCertResolverTest, NoMatchingCertificates) {
|
| base::RunLoop().RunUntilIdle();
|
| network_properties_changed_count_ = 0;
|
| SetupNetworkHandlers();
|
| - SetupPolicyMatchingIssuerPEM("");
|
| + SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY, "");
|
| base::RunLoop().RunUntilIdle();
|
|
|
| // Verify that no client certificate was configured.
|
| @@ -327,7 +361,7 @@ TEST_F(ClientCertResolverTest, MatchIssuerCNWithoutIssuerInstalled) {
|
| base::RunLoop().RunUntilIdle();
|
|
|
| SetupNetworkHandlers();
|
| - SetupPolicyMatchingIssuerCN();
|
| + SetupPolicyMatchingIssuerCN(onc::ONC_SOURCE_USER_POLICY);
|
| base::RunLoop().RunUntilIdle();
|
|
|
| network_properties_changed_count_ = 0;
|
| @@ -348,7 +382,7 @@ TEST_F(ClientCertResolverTest, ResolveOnCertificatesLoaded) {
|
| base::RunLoop().RunUntilIdle();
|
|
|
| SetupNetworkHandlers();
|
| - SetupPolicyMatchingIssuerPEM("");
|
| + SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY, "");
|
| base::RunLoop().RunUntilIdle();
|
|
|
| network_properties_changed_count_ = 0;
|
| @@ -373,7 +407,7 @@ TEST_F(ClientCertResolverTest, ResolveAfterPolicyApplication) {
|
|
|
| // Policy application will trigger the ClientCertResolver.
|
| network_properties_changed_count_ = 0;
|
| - SetupPolicyMatchingIssuerPEM("");
|
| + SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY, "");
|
| base::RunLoop().RunUntilIdle();
|
|
|
| // Verify that the resolver positively matched the pattern in the policy with
|
| @@ -390,7 +424,7 @@ TEST_F(ClientCertResolverTest, ExpiringCertificate) {
|
| base::RunLoop().RunUntilIdle();
|
|
|
| SetupNetworkHandlers();
|
| - SetupPolicyMatchingIssuerPEM("");
|
| + SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY, "");
|
| base::RunLoop().RunUntilIdle();
|
|
|
| StartCertLoader();
|
| @@ -414,13 +448,130 @@ TEST_F(ClientCertResolverTest, ExpiringCertificate) {
|
| EXPECT_EQ(std::string(), pkcs11_id);
|
| }
|
|
|
| +TEST_F(ClientCertResolverTest, UserPolicyUsesSystemToken) {
|
| + SetupTestCertInSystemToken("client_1");
|
| + SetupWifi();
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + SetupNetworkHandlers();
|
| + SetupPolicyMatchingIssuerCN(onc::ONC_SOURCE_USER_POLICY);
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + StartCertLoader();
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(1U, cert_loader_->system_certs().size());
|
| +
|
| + // Verify that the resolver positively matched the pattern in the policy with
|
| + // the test client cert and configured the network.
|
| + std::string pkcs11_id;
|
| + GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
|
| + EXPECT_EQ(test_cert_id_, pkcs11_id);
|
| +}
|
| +
|
| +TEST_F(ClientCertResolverTest, UserPolicyUsesSystemTokenSync) {
|
| + SetupTestCertInSystemToken("client_1");
|
| + StartCertLoader();
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + client_cert::ClientCertConfig client_cert_config;
|
| + SetupCertificateConfigMatchingIssuerCN(onc::ONC_SOURCE_USER_POLICY,
|
| + &client_cert_config);
|
| +
|
| + base::DictionaryValue shill_properties;
|
| + ClientCertResolver::ResolveCertificatePatternSync(
|
| + client_cert::CONFIG_TYPE_EAP, client_cert_config, &shill_properties);
|
| + std::string pkcs11_id;
|
| + shill_properties.GetStringWithoutPathExpansion(shill::kEapCertIdProperty,
|
| + &pkcs11_id);
|
| + EXPECT_EQ(test_cert_id_, pkcs11_id);
|
| +}
|
| +
|
| +TEST_F(ClientCertResolverTest, DevicePolicyUsesSystemToken) {
|
| + SetupTestCertInSystemToken("client_1");
|
| + SetupWifi();
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + SetupNetworkHandlers();
|
| + SetupPolicyMatchingIssuerCN(onc::ONC_SOURCE_USER_POLICY);
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + StartCertLoader();
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(1U, cert_loader_->system_certs().size());
|
| +
|
| + // Verify that the resolver positively matched the pattern in the policy with
|
| + // the test client cert and configured the network.
|
| + std::string pkcs11_id;
|
| + GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
|
| + EXPECT_EQ(test_cert_id_, pkcs11_id);
|
| +}
|
| +
|
| +TEST_F(ClientCertResolverTest, DevicePolicyUsesSystemTokenSync) {
|
| + SetupTestCertInSystemToken("client_1");
|
| + StartCertLoader();
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + client_cert::ClientCertConfig client_cert_config;
|
| + SetupCertificateConfigMatchingIssuerCN(onc::ONC_SOURCE_DEVICE_POLICY,
|
| + &client_cert_config);
|
| +
|
| + base::DictionaryValue shill_properties;
|
| + ClientCertResolver::ResolveCertificatePatternSync(
|
| + client_cert::CONFIG_TYPE_EAP, client_cert_config, &shill_properties);
|
| + std::string pkcs11_id;
|
| + shill_properties.GetStringWithoutPathExpansion(shill::kEapCertIdProperty,
|
| + &pkcs11_id);
|
| + EXPECT_EQ(test_cert_id_, pkcs11_id);
|
| +}
|
| +
|
| +TEST_F(ClientCertResolverTest, DevicePolicyDoesNotUseUserToken) {
|
| + SetupTestCerts("client_1", false /* do not import the issuer */);
|
| + SetupWifi();
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + SetupNetworkHandlers();
|
| + SetupPolicyMatchingIssuerCN(onc::ONC_SOURCE_DEVICE_POLICY);
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + network_properties_changed_count_ = 0;
|
| + StartCertLoader();
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(0U, cert_loader_->system_certs().size());
|
| +
|
| + // Verify that no client certificate was configured.
|
| + std::string pkcs11_id;
|
| + GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
|
| + EXPECT_EQ(std::string(), pkcs11_id);
|
| + EXPECT_EQ(1, network_properties_changed_count_);
|
| + EXPECT_FALSE(client_cert_resolver_->IsAnyResolveTaskRunning());
|
| +}
|
| +
|
| +TEST_F(ClientCertResolverTest, DevicePolicyDoesNotUseUserTokenSync) {
|
| + SetupTestCerts("client_1", false /* do not import the issuer */);
|
| + StartCertLoader();
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + client_cert::ClientCertConfig client_cert_config;
|
| + SetupCertificateConfigMatchingIssuerCN(onc::ONC_SOURCE_DEVICE_POLICY,
|
| + &client_cert_config);
|
| +
|
| + base::DictionaryValue shill_properties;
|
| + ClientCertResolver::ResolveCertificatePatternSync(
|
| + client_cert::CONFIG_TYPE_EAP, client_cert_config, &shill_properties);
|
| + std::string pkcs11_id;
|
| + shill_properties.GetStringWithoutPathExpansion(shill::kEapCertIdProperty,
|
| + &pkcs11_id);
|
| + EXPECT_EQ(std::string(), pkcs11_id);
|
| +}
|
| +
|
| TEST_F(ClientCertResolverTest, PopulateIdentityFromCert) {
|
| SetupTestCerts("client_3", true /* import issuer */);
|
| SetupWifi();
|
| base::RunLoop().RunUntilIdle();
|
|
|
| SetupNetworkHandlers();
|
| - SetupPolicyMatchingIssuerPEM("${CERT_SAN_EMAIL}");
|
| + SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY,
|
| + "${CERT_SAN_EMAIL}");
|
| base::RunLoop().RunUntilIdle();
|
|
|
| network_properties_changed_count_ = 0;
|
| @@ -437,7 +588,8 @@ TEST_F(ClientCertResolverTest, PopulateIdentityFromCert) {
|
| // Verify that after changing the ONC policy to request a variant of the
|
| // Microsoft Universal Principal Name field instead, the correct value is
|
| // substituted into the shill service entry.
|
| - SetupPolicyMatchingIssuerPEM("upn-${CERT_SAN_UPN}-suffix");
|
| + SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY,
|
| + "upn-${CERT_SAN_UPN}-suffix");
|
| base::RunLoop().RunUntilIdle();
|
|
|
| GetServiceProperty(shill::kEapIdentityProperty, &identity);
|
|
|