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