| 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/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.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_profile_client.h" | 17 #include "chromeos/dbus/shill_profile_client.h" |
| 18 #include "chromeos/dbus/shill_service_client.h" | 18 #include "chromeos/dbus/shill_service_client.h" |
| 19 #include "chromeos/login/login_state.h" | 19 #include "chromeos/login/login_state.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" | 24 #include "chromeos/tpm_token_loader.h" |
| 25 #include "crypto/nss_util.h" | 25 #include "crypto/nss_util.h" |
| 26 #include "crypto/nss_util_internal.h" |
| 26 #include "net/base/crypto_module.h" | 27 #include "net/base/crypto_module.h" |
| 27 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
| 28 #include "net/base/test_data_directory.h" | 29 #include "net/base/test_data_directory.h" |
| 29 #include "net/cert/nss_cert_database.h" | 30 #include "net/cert/nss_cert_database_chromeos.h" |
| 30 #include "net/cert/x509_certificate.h" | 31 #include "net/cert/x509_certificate.h" |
| 31 #include "net/test/cert_test_util.h" | 32 #include "net/test/cert_test_util.h" |
| 32 #include "testing/gtest/include/gtest/gtest.h" | 33 #include "testing/gtest/include/gtest/gtest.h" |
| 33 #include "third_party/cros_system_api/dbus/service_constants.h" | 34 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 34 | 35 |
| 35 namespace chromeos { | 36 namespace chromeos { |
| 36 | 37 |
| 37 namespace { | 38 namespace { |
| 38 | 39 |
| 39 const char* kWifiStub = "wifi_stub"; | 40 const char* kWifiStub = "wifi_stub"; |
| 40 const char* kWifiSSID = "wifi_ssid"; | 41 const char* kWifiSSID = "wifi_ssid"; |
| 41 const char* kUserProfilePath = "user_profile"; | 42 const char* kUserProfilePath = "user_profile"; |
| 42 const char* kUserHash = "user_hash"; | 43 const char* kUserHash = "user_hash"; |
| 43 | 44 |
| 44 } // namespace | 45 } // namespace |
| 45 | 46 |
| 46 class ClientCertResolverTest : public testing::Test { | 47 class ClientCertResolverTest : public testing::Test { |
| 47 public: | 48 public: |
| 48 ClientCertResolverTest() {} | 49 ClientCertResolverTest() : service_test_(NULL), |
| 50 profile_test_(NULL), |
| 51 user_(kUserHash) { |
| 52 } |
| 49 virtual ~ClientCertResolverTest() {} | 53 virtual ~ClientCertResolverTest() {} |
| 50 | 54 |
| 51 virtual void SetUp() OVERRIDE { | 55 virtual void SetUp() OVERRIDE { |
| 52 ASSERT_TRUE(test_nssdb_.is_open()); | 56 // Initialize NSS db for the user. |
| 53 slot_ = net::NSSCertDatabase::GetInstance()->GetPublicModule(); | 57 ASSERT_TRUE(user_.constructed_successfully()); |
| 54 ASSERT_TRUE(slot_->os_module_handle()); | 58 user_.FinishInit(); |
| 55 | 59 slot_ = crypto::GetPrivateSlotForChromeOSUser( |
| 56 LoginState::Initialize(); | 60 user_.username_hash(), |
| 61 base::Callback<void(crypto::ScopedPK11Slot)>()); |
| 62 ASSERT_TRUE(slot_.get()); |
| 63 test_nssdb_.reset(new net::NSSCertDatabaseChromeOS( |
| 64 crypto::GetPublicSlotForChromeOSUser(user_.username_hash()), |
| 65 crypto::GetPrivateSlotForChromeOSUser( |
| 66 user_.username_hash(), |
| 67 base::Callback<void(crypto::ScopedPK11Slot)>()))); |
| 57 | 68 |
| 58 DBusThreadManager::InitializeWithStub(); | 69 DBusThreadManager::InitializeWithStub(); |
| 59 service_test_ = | 70 service_test_ = |
| 60 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); | 71 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); |
| 61 profile_test_ = | 72 profile_test_ = |
| 62 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface(); | 73 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface(); |
| 63 message_loop_.RunUntilIdle(); | 74 base::RunLoop().RunUntilIdle(); |
| 64 service_test_->ClearServices(); | 75 service_test_->ClearServices(); |
| 65 message_loop_.RunUntilIdle(); | 76 base::RunLoop().RunUntilIdle(); |
| 66 | |
| 67 TPMTokenLoader::Initialize(); | |
| 68 TPMTokenLoader* tpm_token_loader = TPMTokenLoader::Get(); | |
| 69 tpm_token_loader->InitializeTPMForTest(); | |
| 70 tpm_token_loader->SetCryptoTaskRunner(message_loop_.message_loop_proxy()); | |
| 71 | 77 |
| 72 CertLoader::Initialize(); | 78 CertLoader::Initialize(); |
| 73 CertLoader::Get()->SetSlowTaskRunnerForTest( | 79 CertLoader* cert_loader_ = CertLoader::Get(); |
| 74 message_loop_.message_loop_proxy()); | 80 cert_loader_->SetSlowTaskRunnerForTest(message_loop_.message_loop_proxy()); |
| 81 cert_loader_->SetCryptoTaskRunner(message_loop_.message_loop_proxy()); |
| 82 cert_loader_->set_hardware_backed_for_test(); |
| 83 cert_loader_->StartWithUser(user_.username_hash()); |
| 75 } | 84 } |
| 76 | 85 |
| 77 virtual void TearDown() OVERRIDE { | 86 virtual void TearDown() OVERRIDE { |
| 78 client_cert_resolver_.reset(); | 87 client_cert_resolver_.reset(); |
| 79 managed_config_handler_.reset(); | 88 managed_config_handler_.reset(); |
| 80 network_config_handler_.reset(); | 89 network_config_handler_.reset(); |
| 81 network_profile_handler_.reset(); | 90 network_profile_handler_.reset(); |
| 82 network_state_handler_.reset(); | 91 network_state_handler_.reset(); |
| 83 CertLoader::Shutdown(); | 92 CertLoader::Shutdown(); |
| 84 TPMTokenLoader::Shutdown(); | |
| 85 DBusThreadManager::Shutdown(); | 93 DBusThreadManager::Shutdown(); |
| 86 LoginState::Shutdown(); | |
| 87 CleanupSlotContents(); | 94 CleanupSlotContents(); |
| 88 } | 95 } |
| 89 | 96 |
| 90 protected: | 97 protected: |
| 91 // Imports a CA cert (stored as PEM in test_ca_cert_pem_) and a client | 98 // Imports a CA cert (stored as PEM in test_ca_cert_pem_) and a client |
| 92 // certificate signed by that CA. Its PKCS#11 ID is stored in | 99 // certificate signed by that CA. Its PKCS#11 ID is stored in |
| 93 // |test_pkcs11_id_|. | 100 // |test_pkcs11_id_|. |
| 94 void SetupTestCerts() { | 101 void SetupTestCerts() { |
| 95 // Import a CA cert. | 102 // Import a CA cert. |
| 96 net::NSSCertDatabase* cert_db = net::NSSCertDatabase::GetInstance(); | |
| 97 net::CertificateList ca_cert_list = | 103 net::CertificateList ca_cert_list = |
| 98 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(), | 104 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(), |
| 99 "websocket_cacert.pem", | 105 "websocket_cacert.pem", |
| 100 net::X509Certificate::FORMAT_AUTO); | 106 net::X509Certificate::FORMAT_AUTO); |
| 101 ASSERT_TRUE(!ca_cert_list.empty()); | 107 ASSERT_TRUE(!ca_cert_list.empty()); |
| 102 net::NSSCertDatabase::ImportCertFailureList failures; | 108 net::NSSCertDatabase::ImportCertFailureList failures; |
| 103 EXPECT_TRUE(cert_db->ImportCACerts( | 109 EXPECT_TRUE(test_nssdb_->ImportCACerts( |
| 104 ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures)); | 110 ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures)); |
| 105 ASSERT_TRUE(failures.empty()) << net::ErrorToString(failures[0].net_error); | 111 ASSERT_TRUE(failures.empty()) << net::ErrorToString(failures[0].net_error); |
| 106 | 112 |
| 107 net::X509Certificate::GetPEMEncoded(ca_cert_list[0]->os_cert_handle(), | 113 net::X509Certificate::GetPEMEncoded(ca_cert_list[0]->os_cert_handle(), |
| 108 &test_ca_cert_pem_); | 114 &test_ca_cert_pem_); |
| 109 ASSERT_TRUE(!test_ca_cert_pem_.empty()); | 115 ASSERT_TRUE(!test_ca_cert_pem_.empty()); |
| 110 | 116 |
| 111 // Import a client cert signed by that CA. | 117 // Import a client cert signed by that CA. |
| 112 scoped_refptr<net::CryptoModule> crypt_module = cert_db->GetPrivateModule(); | |
| 113 std::string pkcs12_data; | 118 std::string pkcs12_data; |
| 114 ASSERT_TRUE(base::ReadFileToString( | 119 ASSERT_TRUE(base::ReadFileToString( |
| 115 net::GetTestCertsDirectory().Append("websocket_client_cert.p12"), | 120 net::GetTestCertsDirectory().Append("websocket_client_cert.p12"), |
| 116 &pkcs12_data)); | 121 &pkcs12_data)); |
| 117 | 122 |
| 118 net::CertificateList client_cert_list; | 123 net::CertificateList client_cert_list; |
| 119 ASSERT_EQ(net::OK, | 124 scoped_refptr<net::CryptoModule> module( |
| 120 cert_db->ImportFromPKCS12(crypt_module.get(), | 125 net::CryptoModule::CreateFromHandle(slot_.get())); |
| 121 pkcs12_data, | 126 ASSERT_EQ( |
| 122 base::string16(), | 127 net::OK, |
| 123 false, | 128 test_nssdb_->ImportFromPKCS12( |
| 124 &client_cert_list)); | 129 module, pkcs12_data, base::string16(), false, &client_cert_list)); |
| 125 ASSERT_TRUE(!client_cert_list.empty()); | 130 ASSERT_TRUE(!client_cert_list.empty()); |
| 126 test_pkcs11_id_ = CertLoader::GetPkcs11IdForCert(*client_cert_list[0]); | 131 test_pkcs11_id_ = CertLoader::GetPkcs11IdForCert(*client_cert_list[0]); |
| 127 ASSERT_TRUE(!test_pkcs11_id_.empty()); | 132 ASSERT_TRUE(!test_pkcs11_id_.empty()); |
| 128 } | 133 } |
| 129 | 134 |
| 130 void SetupNetworkHandlers() { | 135 void SetupNetworkHandlers() { |
| 131 network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); | 136 network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); |
| 132 network_profile_handler_.reset(new NetworkProfileHandler()); | 137 network_profile_handler_.reset(new NetworkProfileHandler()); |
| 133 network_config_handler_.reset(new NetworkConfigurationHandler()); | 138 network_config_handler_.reset(new NetworkConfigurationHandler()); |
| 134 managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl()); | 139 managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl()); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 | 217 |
| 213 ShillServiceClient::TestInterface* service_test_; | 218 ShillServiceClient::TestInterface* service_test_; |
| 214 ShillProfileClient::TestInterface* profile_test_; | 219 ShillProfileClient::TestInterface* profile_test_; |
| 215 std::string test_pkcs11_id_; | 220 std::string test_pkcs11_id_; |
| 216 scoped_refptr<net::X509Certificate> test_ca_cert_; | 221 scoped_refptr<net::X509Certificate> test_ca_cert_; |
| 217 std::string test_ca_cert_pem_; | 222 std::string test_ca_cert_pem_; |
| 218 base::MessageLoop message_loop_; | 223 base::MessageLoop message_loop_; |
| 219 | 224 |
| 220 private: | 225 private: |
| 221 void CleanupSlotContents() { | 226 void CleanupSlotContents() { |
| 222 CERTCertList* cert_list = PK11_ListCertsInSlot(slot_->os_module_handle()); | 227 CERTCertList* cert_list = PK11_ListCertsInSlot(slot_.get()); |
| 228 |
| 223 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); | 229 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); |
| 224 !CERT_LIST_END(node, cert_list); | 230 !CERT_LIST_END(node, cert_list); |
| 225 node = CERT_LIST_NEXT(node)) { | 231 node = CERT_LIST_NEXT(node)) { |
| 226 scoped_refptr<net::X509Certificate> cert( | 232 scoped_refptr<net::X509Certificate> cert( |
| 227 net::X509Certificate::CreateFromHandle( | 233 net::X509Certificate::CreateFromHandle( |
| 228 node->cert, net::X509Certificate::OSCertHandles())); | 234 node->cert, net::X509Certificate::OSCertHandles())); |
| 229 net::NSSCertDatabase::GetInstance()->DeleteCertAndKey(cert.get()); | 235 test_nssdb_->DeleteCertAndKey(cert.get()); |
| 230 } | 236 } |
| 237 |
| 231 CERT_DestroyCertList(cert_list); | 238 CERT_DestroyCertList(cert_list); |
| 232 } | 239 } |
| 233 | 240 |
| 234 scoped_ptr<NetworkStateHandler> network_state_handler_; | 241 scoped_ptr<NetworkStateHandler> network_state_handler_; |
| 235 scoped_ptr<NetworkProfileHandler> network_profile_handler_; | 242 scoped_ptr<NetworkProfileHandler> network_profile_handler_; |
| 236 scoped_ptr<NetworkConfigurationHandler> network_config_handler_; | 243 scoped_ptr<NetworkConfigurationHandler> network_config_handler_; |
| 237 scoped_ptr<ManagedNetworkConfigurationHandlerImpl> managed_config_handler_; | 244 scoped_ptr<ManagedNetworkConfigurationHandlerImpl> managed_config_handler_; |
| 238 scoped_ptr<ClientCertResolver> client_cert_resolver_; | 245 scoped_ptr<ClientCertResolver> client_cert_resolver_; |
| 239 scoped_refptr<net::CryptoModule> slot_; | 246 crypto::ScopedTestNSSChromeOSUser user_; |
| 240 crypto::ScopedTestNSSDB test_nssdb_; | 247 scoped_ptr<net::NSSCertDatabaseChromeOS> test_nssdb_; |
| 248 crypto::ScopedPK11Slot slot_; |
| 241 | 249 |
| 242 DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest); | 250 DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest); |
| 243 }; | 251 }; |
| 244 | 252 |
| 245 TEST_F(ClientCertResolverTest, NoMatchingCertificates) { | 253 TEST_F(ClientCertResolverTest, NoMatchingCertificates) { |
| 246 SetupNetworkHandlers(); | 254 SetupNetworkHandlers(); |
| 247 SetupPolicy(); | 255 SetupPolicy(); |
| 248 message_loop_.RunUntilIdle(); | 256 base::RunLoop().RunUntilIdle(); |
| 249 | 257 |
| 250 SetupWifi(); | 258 SetupWifi(); |
| 251 message_loop_.RunUntilIdle(); | 259 base::RunLoop().RunUntilIdle(); |
| 252 | 260 |
| 253 // Verify that no client certificate was configured. | 261 // Verify that no client certificate was configured. |
| 254 std::string pkcs11_id; | 262 std::string pkcs11_id; |
| 255 GetClientCertProperties(&pkcs11_id); | 263 GetClientCertProperties(&pkcs11_id); |
| 256 EXPECT_TRUE(pkcs11_id.empty()); | 264 EXPECT_TRUE(pkcs11_id.empty()); |
| 257 } | 265 } |
| 258 | 266 |
| 259 TEST_F(ClientCertResolverTest, ResolveOnInitialization) { | 267 TEST_F(ClientCertResolverTest, ResolveOnInitialization) { |
| 260 SetupTestCerts(); | 268 SetupTestCerts(); |
| 261 SetupNetworkHandlers(); | 269 SetupNetworkHandlers(); |
| 262 SetupPolicy(); | 270 SetupPolicy(); |
| 263 message_loop_.RunUntilIdle(); | 271 base::RunLoop().RunUntilIdle(); |
| 264 | 272 |
| 265 SetupWifi(); | 273 SetupWifi(); |
| 266 message_loop_.RunUntilIdle(); | 274 base::RunLoop().RunUntilIdle(); |
| 267 | 275 |
| 268 // Verify that the resolver positively matched the pattern in the policy with | 276 // Verify that the resolver positively matched the pattern in the policy with |
| 269 // the test client cert and configured the network. | 277 // the test client cert and configured the network. |
| 270 std::string pkcs11_id; | 278 std::string pkcs11_id; |
| 271 GetClientCertProperties(&pkcs11_id); | 279 GetClientCertProperties(&pkcs11_id); |
| 272 EXPECT_EQ(test_pkcs11_id_, pkcs11_id); | 280 EXPECT_EQ(test_pkcs11_id_, pkcs11_id); |
| 273 } | 281 } |
| 274 | 282 |
| 275 TEST_F(ClientCertResolverTest, ResolveAfterPolicyApplication) { | 283 TEST_F(ClientCertResolverTest, ResolveAfterPolicyApplication) { |
| 276 SetupTestCerts(); | 284 SetupTestCerts(); |
| 277 SetupNetworkHandlers(); | 285 SetupNetworkHandlers(); |
| 278 message_loop_.RunUntilIdle(); | 286 base::RunLoop().RunUntilIdle(); |
| 279 | 287 |
| 280 // The policy will trigger the creation of a new wifi service. | 288 // The policy will trigger the creation of a new wifi service. |
| 281 SetupPolicy(); | 289 SetupPolicy(); |
| 282 message_loop_.RunUntilIdle(); | 290 base::RunLoop().RunUntilIdle(); |
| 283 | 291 |
| 284 // Verify that the resolver positively matched the pattern in the policy with | 292 // Verify that the resolver positively matched the pattern in the policy with |
| 285 // the test client cert and configured the network. | 293 // the test client cert and configured the network. |
| 286 std::string pkcs11_id; | 294 std::string pkcs11_id; |
| 287 GetClientCertProperties(&pkcs11_id); | 295 GetClientCertProperties(&pkcs11_id); |
| 288 EXPECT_EQ(test_pkcs11_id_, pkcs11_id); | 296 EXPECT_EQ(test_pkcs11_id_, pkcs11_id); |
| 289 } | 297 } |
| 290 | 298 |
| 291 } // namespace chromeos | 299 } // namespace chromeos |
| OLD | NEW |