Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 #include "chromeos/network/client_cert_resolver.h" | 4 #include "chromeos/network/client_cert_resolver.h" |
| 5 | 5 |
| 6 #include <cert.h> | 6 #include <cert.h> |
| 7 #include <pk11pub.h> | 7 #include <pk11pub.h> |
| 8 | 8 |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| 11 #include "base/json/json_reader.h" | 11 #include "base/json/json_reader.h" |
| 12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
| 13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chromeos/cert_loader.h" | 15 #include "chromeos/cert_loader.h" |
| 16 #include "chromeos/dbus/dbus_thread_manager.h" | 16 #include "chromeos/dbus/dbus_thread_manager.h" |
| 17 #include "chromeos/dbus/shill_manager_client.h" | 17 #include "chromeos/dbus/shill_manager_client.h" |
| 18 #include "chromeos/dbus/shill_profile_client.h" | 18 #include "chromeos/dbus/shill_profile_client.h" |
| 19 #include "chromeos/dbus/shill_service_client.h" | 19 #include "chromeos/dbus/shill_service_client.h" |
| 20 #include "chromeos/network/managed_network_configuration_handler_impl.h" | 20 #include "chromeos/network/managed_network_configuration_handler_impl.h" |
| 21 #include "chromeos/network/network_configuration_handler.h" | 21 #include "chromeos/network/network_configuration_handler.h" |
| 22 #include "chromeos/network/network_profile_handler.h" | 22 #include "chromeos/network/network_profile_handler.h" |
| 23 #include "chromeos/network/network_state_handler.h" | 23 #include "chromeos/network/network_state_handler.h" |
| 24 #include "chromeos/tpm_token_loader.h" | |
| 25 #include "components/onc/onc_constants.h" | 24 #include "components/onc/onc_constants.h" |
| 26 #include "crypto/nss_util_internal.h" | 25 #include "crypto/nss_util_internal.h" |
| 27 #include "crypto/scoped_test_nss_chromeos_user.h" | 26 #include "crypto/scoped_test_nss_chromeos_user.h" |
| 28 #include "net/base/crypto_module.h" | |
| 29 #include "net/base/net_errors.h" | 27 #include "net/base/net_errors.h" |
| 30 #include "net/base/test_data_directory.h" | 28 #include "net/base/test_data_directory.h" |
| 31 #include "net/cert/nss_cert_database_chromeos.h" | 29 #include "net/cert/nss_cert_database_chromeos.h" |
| 32 #include "net/cert/x509_certificate.h" | 30 #include "net/cert/x509_certificate.h" |
| 33 #include "net/test/cert_test_util.h" | 31 #include "net/test/cert_test_util.h" |
| 34 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| 35 #include "third_party/cros_system_api/dbus/service_constants.h" | 33 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 36 | 34 |
| 37 // http://crbug.com/418369 | |
| 38 #ifdef NDEBUG | |
| 39 | |
| 40 namespace chromeos { | 35 namespace chromeos { |
| 41 | 36 |
| 42 namespace { | 37 namespace { |
| 43 | 38 |
| 44 const char* kWifiStub = "wifi_stub"; | 39 const char* kWifiStub = "wifi_stub"; |
| 45 const char* kWifiSSID = "wifi_ssid"; | 40 const char* kWifiSSID = "wifi_ssid"; |
| 46 const char* kUserProfilePath = "user_profile"; | 41 const char* kUserProfilePath = "user_profile"; |
| 47 const char* kUserHash = "user_hash"; | 42 const char* kUserHash = "user_hash"; |
| 48 | 43 |
| 49 } // namespace | 44 } // namespace |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 70 crypto::GetPrivateSlotForChromeOSUser( | 65 crypto::GetPrivateSlotForChromeOSUser( |
| 71 user_.username_hash(), | 66 user_.username_hash(), |
| 72 base::Callback<void(crypto::ScopedPK11Slot)>()))); | 67 base::Callback<void(crypto::ScopedPK11Slot)>()))); |
| 73 test_nssdb_->SetSlowTaskRunnerForTest(message_loop_.message_loop_proxy()); | 68 test_nssdb_->SetSlowTaskRunnerForTest(message_loop_.message_loop_proxy()); |
| 74 | 69 |
| 75 DBusThreadManager::Initialize(); | 70 DBusThreadManager::Initialize(); |
| 76 service_test_ = | 71 service_test_ = |
| 77 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); | 72 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); |
| 78 profile_test_ = | 73 profile_test_ = |
| 79 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface(); | 74 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface(); |
| 75 profile_test_->AddProfile(kUserProfilePath, kUserHash); | |
| 80 base::RunLoop().RunUntilIdle(); | 76 base::RunLoop().RunUntilIdle(); |
| 81 service_test_->ClearServices(); | 77 service_test_->ClearServices(); |
| 82 base::RunLoop().RunUntilIdle(); | 78 base::RunLoop().RunUntilIdle(); |
| 83 | 79 |
| 84 TPMTokenLoader::InitializeForTest(); | |
| 85 | |
| 86 CertLoader::Initialize(); | 80 CertLoader::Initialize(); |
| 87 cert_loader_ = CertLoader::Get(); | 81 cert_loader_ = CertLoader::Get(); |
| 88 cert_loader_->force_hardware_backed_for_test(); | 82 cert_loader_->force_hardware_backed_for_test(); |
| 89 } | 83 } |
| 90 | 84 |
| 91 virtual void TearDown() override { | 85 virtual void TearDown() override { |
| 92 client_cert_resolver_.reset(); | 86 client_cert_resolver_.reset(); |
| 93 managed_config_handler_.reset(); | 87 managed_config_handler_.reset(); |
| 94 network_config_handler_.reset(); | 88 network_config_handler_.reset(); |
| 95 network_profile_handler_.reset(); | 89 network_profile_handler_.reset(); |
| 96 network_state_handler_.reset(); | 90 network_state_handler_.reset(); |
| 97 CertLoader::Shutdown(); | 91 CertLoader::Shutdown(); |
| 98 TPMTokenLoader::Shutdown(); | |
| 99 DBusThreadManager::Shutdown(); | 92 DBusThreadManager::Shutdown(); |
| 100 CleanupSlotContents(); | |
| 101 } | 93 } |
| 102 | 94 |
| 103 protected: | 95 protected: |
| 104 void StartCertLoader() { | 96 void StartCertLoader() { |
| 105 cert_loader_->StartWithNSSDB(test_nssdb_.get()); | 97 cert_loader_->StartWithNSSDB(test_nssdb_.get()); |
| 106 if (test_client_cert_.get()) { | 98 if (test_client_cert_.get()) { |
| 107 int slot_id = 0; | 99 int slot_id = 0; |
| 108 const std::string pkcs11_id = | 100 const std::string pkcs11_id = |
| 109 CertLoader::GetPkcs11IdAndSlotForCert(*test_client_cert_, &slot_id); | 101 CertLoader::GetPkcs11IdAndSlotForCert(*test_client_cert_, &slot_id); |
| 110 test_cert_id_ = base::StringPrintf("%i:%s", slot_id, pkcs11_id.c_str()); | 102 test_cert_id_ = base::StringPrintf("%i:%s", slot_id, pkcs11_id.c_str()); |
| 111 } | 103 } |
| 112 } | 104 } |
| 113 | 105 |
| 114 // Imports a CA cert (stored as PEM in test_ca_cert_pem_) and a client | 106 // Imports a CA cert (stored as PEM in test_ca_cert_pem_) and a client |
| 115 // certificate signed by that CA. Its PKCS#11 ID is stored in | 107 // certificate signed by that CA. Its PKCS#11 ID is stored in |
| 116 // |test_cert_id_|. | 108 // |test_cert_id_|. |
| 117 void SetupTestCerts() { | 109 void SetupTestCerts() { |
| 118 // Import a CA cert. | 110 // Import a CA cert. |
| 119 net::CertificateList ca_cert_list = | 111 net::CertificateList ca_cert_list = |
| 120 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(), | 112 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(), |
| 121 "websocket_cacert.pem", | 113 "client_1_ca.pem", |
| 122 net::X509Certificate::FORMAT_AUTO); | 114 net::X509Certificate::FORMAT_AUTO); |
| 123 ASSERT_TRUE(!ca_cert_list.empty()); | 115 ASSERT_TRUE(!ca_cert_list.empty()); |
| 124 net::NSSCertDatabase::ImportCertFailureList failures; | 116 net::NSSCertDatabase::ImportCertFailureList failures; |
| 125 EXPECT_TRUE(test_nssdb_->ImportCACerts( | 117 EXPECT_TRUE(test_nssdb_->ImportCACerts( |
| 126 ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures)); | 118 ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures)); |
| 127 ASSERT_TRUE(failures.empty()) << net::ErrorToString(failures[0].net_error); | 119 ASSERT_TRUE(failures.empty()) << net::ErrorToString(failures[0].net_error); |
| 128 | 120 |
| 129 net::X509Certificate::GetPEMEncoded(ca_cert_list[0]->os_cert_handle(), | 121 net::X509Certificate::GetPEMEncoded(ca_cert_list[0]->os_cert_handle(), |
| 130 &test_ca_cert_pem_); | 122 &test_ca_cert_pem_); |
| 131 ASSERT_TRUE(!test_ca_cert_pem_.empty()); | 123 ASSERT_TRUE(!test_ca_cert_pem_.empty()); |
| 132 | 124 |
| 133 // Import a client cert signed by that CA. | 125 // Import a client cert signed by that CA. |
| 134 std::string pkcs12_data; | 126 test_client_cert_ = |
| 135 ASSERT_TRUE(base::ReadFileToString( | 127 net::ImportClientCertAndKeyFromFile(net::GetTestCertsDirectory(), |
| 136 net::GetTestCertsDirectory().Append("websocket_client_cert.p12"), | 128 "client_1.pem", |
| 137 &pkcs12_data)); | 129 "client_1.pk8", |
| 138 | 130 private_slot_.get()); |
| 139 net::CertificateList client_cert_list; | 131 ASSERT_TRUE(test_client_cert_.get()); |
| 140 scoped_refptr<net::CryptoModule> module( | |
| 141 net::CryptoModule::CreateFromHandle(private_slot_.get())); | |
| 142 ASSERT_EQ(net::OK, | |
| 143 test_nssdb_->ImportFromPKCS12(module.get(), | |
| 144 pkcs12_data, | |
| 145 base::string16(), | |
| 146 false, | |
| 147 &client_cert_list)); | |
| 148 ASSERT_TRUE(!client_cert_list.empty()); | |
| 149 test_client_cert_ = client_cert_list[0]; | |
| 150 } | 132 } |
| 151 | 133 |
| 152 void SetupNetworkHandlers() { | 134 void SetupNetworkHandlers() { |
| 153 network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); | 135 network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); |
| 154 network_profile_handler_.reset(new NetworkProfileHandler()); | 136 network_profile_handler_.reset(new NetworkProfileHandler()); |
| 155 network_config_handler_.reset(new NetworkConfigurationHandler()); | 137 network_config_handler_.reset(new NetworkConfigurationHandler()); |
| 156 managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl()); | 138 managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl()); |
| 157 client_cert_resolver_.reset(new ClientCertResolver()); | 139 client_cert_resolver_.reset(new ClientCertResolver()); |
| 158 | 140 |
| 159 network_profile_handler_->Init(); | 141 network_profile_handler_->Init(); |
| 160 network_config_handler_->Init(network_state_handler_.get()); | 142 network_config_handler_->Init(network_state_handler_.get()); |
| 161 managed_config_handler_->Init(network_state_handler_.get(), | 143 managed_config_handler_->Init(network_state_handler_.get(), |
| 162 network_profile_handler_.get(), | 144 network_profile_handler_.get(), |
| 163 network_config_handler_.get(), | 145 network_config_handler_.get(), |
| 164 NULL /* network_device_handler */); | 146 NULL /* network_device_handler */); |
| 147 // Run all notifications before starting the cert loader to reduce run time. | |
| 148 base::RunLoop().RunUntilIdle(); | |
| 149 | |
| 165 client_cert_resolver_->Init(network_state_handler_.get(), | 150 client_cert_resolver_->Init(network_state_handler_.get(), |
| 166 managed_config_handler_.get()); | 151 managed_config_handler_.get()); |
| 167 client_cert_resolver_->SetSlowTaskRunnerForTest( | 152 client_cert_resolver_->SetSlowTaskRunnerForTest( |
| 168 message_loop_.message_loop_proxy()); | 153 message_loop_.message_loop_proxy()); |
| 169 | 154 |
| 170 profile_test_->AddProfile(kUserProfilePath, kUserHash); | |
| 171 } | 155 } |
| 172 | 156 |
| 173 void SetupWifi() { | 157 void SetupWifi() { |
| 174 service_test_->SetServiceProperties(kWifiStub, | 158 service_test_->SetServiceProperties(kWifiStub, |
| 175 kWifiStub, | 159 kWifiStub, |
| 176 kWifiSSID, | 160 kWifiSSID, |
| 177 shill::kTypeWifi, | 161 shill::kTypeWifi, |
| 178 shill::kStateOnline, | 162 shill::kStateOnline, |
| 179 true /* visible */); | 163 true /* visible */); |
| 180 // Set an arbitrary cert id, so that we can check afterwards whether we | 164 // Set an arbitrary cert id, so that we can check afterwards whether we |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 } | 222 } |
| 239 | 223 |
| 240 ShillServiceClient::TestInterface* service_test_; | 224 ShillServiceClient::TestInterface* service_test_; |
| 241 ShillProfileClient::TestInterface* profile_test_; | 225 ShillProfileClient::TestInterface* profile_test_; |
| 242 std::string test_cert_id_; | 226 std::string test_cert_id_; |
| 243 scoped_refptr<net::X509Certificate> test_ca_cert_; | 227 scoped_refptr<net::X509Certificate> test_ca_cert_; |
| 244 std::string test_ca_cert_pem_; | 228 std::string test_ca_cert_pem_; |
| 245 base::MessageLoop message_loop_; | 229 base::MessageLoop message_loop_; |
| 246 | 230 |
| 247 private: | 231 private: |
| 248 void CleanupSlotContents() { | |
|
Joao da Silva
2014/10/24 12:01:06
Are you sure this can be removed? Can't it interfe
pneubeck (no reviews)
2014/10/24 12:33:52
Yes. Databases in temporary directories/files are
| |
| 249 CERTCertList* cert_list = PK11_ListCertsInSlot(private_slot_.get()); | |
| 250 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); | |
| 251 !CERT_LIST_END(node, cert_list); | |
| 252 node = CERT_LIST_NEXT(node)) { | |
| 253 scoped_refptr<net::X509Certificate> cert( | |
| 254 net::X509Certificate::CreateFromHandle( | |
| 255 node->cert, net::X509Certificate::OSCertHandles())); | |
| 256 test_nssdb_->DeleteCertAndKey(cert.get()); | |
| 257 } | |
| 258 CERT_DestroyCertList(cert_list); | |
| 259 } | |
| 260 | |
| 261 CertLoader* cert_loader_; | 232 CertLoader* cert_loader_; |
| 262 scoped_refptr<net::X509Certificate> test_client_cert_; | 233 scoped_refptr<net::X509Certificate> test_client_cert_; |
| 263 scoped_ptr<NetworkStateHandler> network_state_handler_; | 234 scoped_ptr<NetworkStateHandler> network_state_handler_; |
| 264 scoped_ptr<NetworkProfileHandler> network_profile_handler_; | 235 scoped_ptr<NetworkProfileHandler> network_profile_handler_; |
| 265 scoped_ptr<NetworkConfigurationHandler> network_config_handler_; | 236 scoped_ptr<NetworkConfigurationHandler> network_config_handler_; |
| 266 scoped_ptr<ManagedNetworkConfigurationHandlerImpl> managed_config_handler_; | 237 scoped_ptr<ManagedNetworkConfigurationHandlerImpl> managed_config_handler_; |
| 267 scoped_ptr<ClientCertResolver> client_cert_resolver_; | 238 scoped_ptr<ClientCertResolver> client_cert_resolver_; |
| 268 crypto::ScopedTestNSSChromeOSUser user_; | 239 crypto::ScopedTestNSSChromeOSUser user_; |
| 269 scoped_ptr<net::NSSCertDatabaseChromeOS> test_nssdb_; | 240 scoped_ptr<net::NSSCertDatabaseChromeOS> test_nssdb_; |
| 270 crypto::ScopedPK11Slot private_slot_; | 241 crypto::ScopedPK11Slot private_slot_; |
| 271 | 242 |
| 272 DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest); | 243 DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest); |
| 273 }; | 244 }; |
| 274 | 245 |
| 275 TEST_F(ClientCertResolverTest, NoMatchingCertificates) { | 246 TEST_F(ClientCertResolverTest, NoMatchingCertificates) { |
| 247 StartCertLoader(); | |
| 248 SetupWifi(); | |
| 249 base::RunLoop().RunUntilIdle(); | |
| 276 SetupNetworkHandlers(); | 250 SetupNetworkHandlers(); |
| 277 SetupWifi(); | |
| 278 StartCertLoader(); | |
| 279 SetupPolicy(); | 251 SetupPolicy(); |
| 280 base::RunLoop().RunUntilIdle(); | 252 base::RunLoop().RunUntilIdle(); |
| 281 | 253 |
| 282 // Verify that no client certificate was configured. | 254 // Verify that no client certificate was configured. |
| 283 std::string pkcs11_id; | 255 std::string pkcs11_id; |
| 284 GetClientCertProperties(&pkcs11_id); | 256 GetClientCertProperties(&pkcs11_id); |
| 285 EXPECT_EQ(std::string(), pkcs11_id); | 257 EXPECT_EQ(std::string(), pkcs11_id); |
| 286 } | 258 } |
| 287 | 259 |
| 288 TEST_F(ClientCertResolverTest, ResolveOnCertificatesLoaded) { | 260 TEST_F(ClientCertResolverTest, ResolveOnCertificatesLoaded) { |
| 261 SetupTestCerts(); | |
| 262 SetupWifi(); | |
| 263 base::RunLoop().RunUntilIdle(); | |
| 264 | |
| 289 SetupNetworkHandlers(); | 265 SetupNetworkHandlers(); |
| 290 SetupWifi(); | |
| 291 SetupTestCerts(); | |
| 292 SetupPolicy(); | 266 SetupPolicy(); |
| 293 base::RunLoop().RunUntilIdle(); | 267 base::RunLoop().RunUntilIdle(); |
| 294 | 268 |
| 295 StartCertLoader(); | 269 StartCertLoader(); |
| 296 base::RunLoop().RunUntilIdle(); | 270 base::RunLoop().RunUntilIdle(); |
| 297 | 271 |
| 298 // Verify that the resolver positively matched the pattern in the policy with | 272 // Verify that the resolver positively matched the pattern in the policy with |
| 299 // the test client cert and configured the network. | 273 // the test client cert and configured the network. |
| 300 std::string pkcs11_id; | 274 std::string pkcs11_id; |
| 301 GetClientCertProperties(&pkcs11_id); | 275 GetClientCertProperties(&pkcs11_id); |
| 302 EXPECT_EQ(test_cert_id_, pkcs11_id); | 276 EXPECT_EQ(test_cert_id_, pkcs11_id); |
| 303 } | 277 } |
| 304 | 278 |
| 305 TEST_F(ClientCertResolverTest, ResolveAfterPolicyApplication) { | 279 TEST_F(ClientCertResolverTest, ResolveAfterPolicyApplication) { |
| 306 SetupTestCerts(); | 280 SetupTestCerts(); |
| 281 SetupWifi(); | |
| 282 base::RunLoop().RunUntilIdle(); | |
| 307 StartCertLoader(); | 283 StartCertLoader(); |
| 308 SetupNetworkHandlers(); | 284 SetupNetworkHandlers(); |
| 309 SetupWifi(); | |
| 310 base::RunLoop().RunUntilIdle(); | 285 base::RunLoop().RunUntilIdle(); |
| 311 | 286 |
| 312 // Policy application will trigger the ClientCertResolver. | 287 // Policy application will trigger the ClientCertResolver. |
| 313 SetupPolicy(); | 288 SetupPolicy(); |
| 314 base::RunLoop().RunUntilIdle(); | 289 base::RunLoop().RunUntilIdle(); |
| 315 | 290 |
| 316 // Verify that the resolver positively matched the pattern in the policy with | 291 // Verify that the resolver positively matched the pattern in the policy with |
| 317 // the test client cert and configured the network. | 292 // the test client cert and configured the network. |
| 318 std::string pkcs11_id; | 293 std::string pkcs11_id; |
| 319 GetClientCertProperties(&pkcs11_id); | 294 GetClientCertProperties(&pkcs11_id); |
| 320 EXPECT_EQ(test_cert_id_, pkcs11_id); | 295 EXPECT_EQ(test_cert_id_, pkcs11_id); |
| 321 } | 296 } |
| 322 | 297 |
| 323 } // namespace chromeos | 298 } // namespace chromeos |
| 324 | |
| 325 #endif | |
| OLD | NEW |