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 |