Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: chromeos/network/client_cert_resolver_unittest.cc

Issue 1717123002: Allow ${CERT_SAN_EMAIL} and ${CERT_SAN_UPN} in the ONC Identity field (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: incorporate code review feedback Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 int slot_id = 0; 101 int slot_id = 0;
102 const std::string pkcs11_id = 102 const std::string pkcs11_id =
103 CertLoader::GetPkcs11IdAndSlotForCert(*test_client_cert_, &slot_id); 103 CertLoader::GetPkcs11IdAndSlotForCert(*test_client_cert_, &slot_id);
104 test_cert_id_ = base::StringPrintf("%i:%s", slot_id, pkcs11_id.c_str()); 104 test_cert_id_ = base::StringPrintf("%i:%s", slot_id, pkcs11_id.c_str());
105 } 105 }
106 } 106 }
107 107
108 // Imports a client certificate. Its PKCS#11 ID is stored in |test_cert_id_|. 108 // Imports a client certificate. Its PKCS#11 ID is stored in |test_cert_id_|.
109 // If |import_issuer| is true, also imports the CA cert (stored as PEM in 109 // If |import_issuer| is true, also imports the CA cert (stored as PEM in
110 // test_ca_cert_pem_) that issued the client certificate. 110 // test_ca_cert_pem_) that issued the client certificate.
111 void SetupTestCerts(bool import_issuer) { 111 void SetupTestCerts(const std::string& prefix, bool import_issuer) {
112 // Load a CA cert. 112 // Load a CA cert.
113 net::CertificateList ca_cert_list = net::CreateCertificateListFromFile( 113 net::CertificateList ca_cert_list = net::CreateCertificateListFromFile(
114 net::GetTestCertsDirectory(), "client_1_ca.pem", 114 net::GetTestCertsDirectory(), prefix + "_ca.pem",
115 net::X509Certificate::FORMAT_AUTO); 115 net::X509Certificate::FORMAT_AUTO);
116 ASSERT_TRUE(!ca_cert_list.empty()); 116 ASSERT_TRUE(!ca_cert_list.empty());
117 net::X509Certificate::GetPEMEncoded(ca_cert_list[0]->os_cert_handle(), 117 net::X509Certificate::GetPEMEncoded(ca_cert_list[0]->os_cert_handle(),
118 &test_ca_cert_pem_); 118 &test_ca_cert_pem_);
119 ASSERT_TRUE(!test_ca_cert_pem_.empty()); 119 ASSERT_TRUE(!test_ca_cert_pem_.empty());
120 120
121 if (import_issuer) { 121 if (import_issuer) {
122 net::NSSCertDatabase::ImportCertFailureList failures; 122 net::NSSCertDatabase::ImportCertFailureList failures;
123 EXPECT_TRUE(test_nsscertdb_->ImportCACerts( 123 EXPECT_TRUE(test_nsscertdb_->ImportCACerts(
124 ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures)); 124 ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures));
125 ASSERT_TRUE(failures.empty()) 125 ASSERT_TRUE(failures.empty())
126 << net::ErrorToString(failures[0].net_error); 126 << net::ErrorToString(failures[0].net_error);
127 } 127 }
128 128
129 // Import a client cert signed by that CA. 129 // Import a client cert signed by that CA.
130 test_client_cert_ = 130 test_client_cert_ = net::ImportClientCertAndKeyFromFile(
131 net::ImportClientCertAndKeyFromFile(net::GetTestCertsDirectory(), 131 net::GetTestCertsDirectory(), prefix + ".pem", prefix + ".pk8",
132 "client_1.pem", 132 test_nssdb_.slot());
133 "client_1.pk8",
134 test_nssdb_.slot());
135 ASSERT_TRUE(test_client_cert_.get()); 133 ASSERT_TRUE(test_client_cert_.get());
136 } 134 }
137 135
138 void SetupNetworkHandlers() { 136 void SetupNetworkHandlers() {
139 network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); 137 network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
140 network_profile_handler_.reset(new NetworkProfileHandler()); 138 network_profile_handler_.reset(new NetworkProfileHandler());
141 network_config_handler_.reset(new NetworkConfigurationHandler()); 139 network_config_handler_.reset(new NetworkConfigurationHandler());
142 managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl()); 140 managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl());
143 client_cert_resolver_.reset(new ClientCertResolver()); 141 client_cert_resolver_.reset(new ClientCertResolver());
144 142
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 ASSERT_TRUE(policy_value->GetAsList(&policy)); 211 ASSERT_TRUE(policy_value->GetAsList(&policy));
214 212
215 managed_config_handler_->SetPolicy( 213 managed_config_handler_->SetPolicy(
216 onc::ONC_SOURCE_USER_POLICY, kUserHash, *policy, 214 onc::ONC_SOURCE_USER_POLICY, kUserHash, *policy,
217 base::DictionaryValue() /* no global network config */); 215 base::DictionaryValue() /* no global network config */);
218 } 216 }
219 217
220 // Sets up a policy with a certificate pattern that matches any client cert 218 // Sets up a policy with a certificate pattern that matches any client cert
221 // that is signed by the test CA cert (stored in |test_ca_cert_pem_|). In 219 // that is signed by the test CA cert (stored in |test_ca_cert_pem_|). In
222 // particular it will match the test client cert. 220 // particular it will match the test client cert.
223 void SetupPolicyMatchingIssuerPEM() { 221 void SetupPolicyMatchingIssuerPEM(const std::string& identity) {
224 const char* kTestPolicyTemplate = 222 const char* kTestPolicyTemplate =
225 "[ { \"GUID\": \"wifi_stub\"," 223 "[ { \"GUID\": \"wifi_stub\","
226 " \"Name\": \"wifi_stub\"," 224 " \"Name\": \"wifi_stub\","
227 " \"Type\": \"WiFi\"," 225 " \"Type\": \"WiFi\","
228 " \"WiFi\": {" 226 " \"WiFi\": {"
229 " \"Security\": \"WPA-EAP\"," 227 " \"Security\": \"WPA-EAP\","
230 " \"SSID\": \"wifi_ssid\"," 228 " \"SSID\": \"wifi_ssid\","
231 " \"EAP\": {" 229 " \"EAP\": {"
230 " \"Identity\": \"%s\","
232 " \"Outer\": \"EAP-TLS\"," 231 " \"Outer\": \"EAP-TLS\","
233 " \"ClientCertType\": \"Pattern\"," 232 " \"ClientCertType\": \"Pattern\","
234 " \"ClientCertPattern\": {" 233 " \"ClientCertPattern\": {"
235 " \"IssuerCAPEMs\": [ \"%s\" ]" 234 " \"IssuerCAPEMs\": [ \"%s\" ]"
236 " }" 235 " }"
237 " }" 236 " }"
238 " }" 237 " }"
239 "} ]"; 238 "} ]";
240 std::string policy_json = 239 std::string policy_json = base::StringPrintf(
241 base::StringPrintf(kTestPolicyTemplate, test_ca_cert_pem_.c_str()); 240 kTestPolicyTemplate, identity.c_str(), test_ca_cert_pem_.c_str());
242 241
243 std::string error; 242 std::string error;
244 scoped_ptr<base::Value> policy_value = base::JSONReader::ReadAndReturnError( 243 scoped_ptr<base::Value> policy_value = base::JSONReader::ReadAndReturnError(
245 policy_json, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &error); 244 policy_json, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &error);
246 ASSERT_TRUE(policy_value) << error; 245 ASSERT_TRUE(policy_value) << error;
247 246
248 base::ListValue* policy = nullptr; 247 base::ListValue* policy = nullptr;
249 ASSERT_TRUE(policy_value->GetAsList(&policy)); 248 ASSERT_TRUE(policy_value->GetAsList(&policy));
250 249
251 managed_config_handler_->SetPolicy( 250 managed_config_handler_->SetPolicy(
252 onc::ONC_SOURCE_USER_POLICY, 251 onc::ONC_SOURCE_USER_POLICY,
253 kUserHash, 252 kUserHash,
254 *policy, 253 *policy,
255 base::DictionaryValue() /* no global network config */); 254 base::DictionaryValue() /* no global network config */);
256 } 255 }
257 256
258 void SetWifiState(const std::string& state) { 257 void SetWifiState(const std::string& state) {
259 ASSERT_TRUE(service_test_->SetServiceProperty( 258 ASSERT_TRUE(service_test_->SetServiceProperty(
260 kWifiStub, shill::kStateProperty, base::StringValue(state))); 259 kWifiStub, shill::kStateProperty, base::StringValue(state)));
261 } 260 }
262 261
263 void GetClientCertProperties(std::string* pkcs11_id) { 262 void GetServiceProperty(const std::string& prop_name,
264 pkcs11_id->clear(); 263 std::string* prop_value) {
264 prop_value->clear();
265 const base::DictionaryValue* properties = 265 const base::DictionaryValue* properties =
266 service_test_->GetServiceProperties(kWifiStub); 266 service_test_->GetServiceProperties(kWifiStub);
267 if (!properties) 267 if (!properties)
268 return; 268 return;
269 properties->GetStringWithoutPathExpansion(shill::kEapCertIdProperty, 269 properties->GetStringWithoutPathExpansion(prop_name, prop_value);
270 pkcs11_id);
271 } 270 }
272 271
273 int network_properties_changed_count_; 272 int network_properties_changed_count_;
274 std::string test_cert_id_; 273 std::string test_cert_id_;
275 scoped_ptr<base::SimpleTestClock> test_clock_; 274 scoped_ptr<base::SimpleTestClock> test_clock_;
276 scoped_ptr<ClientCertResolver> client_cert_resolver_; 275 scoped_ptr<ClientCertResolver> client_cert_resolver_;
277 276
278 private: 277 private:
279 // ClientCertResolver::Observer: 278 // ClientCertResolver::Observer:
280 void ResolveRequestCompleted(bool network_properties_changed) override { 279 void ResolveRequestCompleted(bool network_properties_changed) override {
(...skipping 11 matching lines...) Expand all
292 base::MessageLoop message_loop_; 291 base::MessageLoop message_loop_;
293 scoped_refptr<net::X509Certificate> test_client_cert_; 292 scoped_refptr<net::X509Certificate> test_client_cert_;
294 std::string test_ca_cert_pem_; 293 std::string test_ca_cert_pem_;
295 crypto::ScopedTestNSSDB test_nssdb_; 294 crypto::ScopedTestNSSDB test_nssdb_;
296 scoped_ptr<net::NSSCertDatabaseChromeOS> test_nsscertdb_; 295 scoped_ptr<net::NSSCertDatabaseChromeOS> test_nsscertdb_;
297 296
298 DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest); 297 DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest);
299 }; 298 };
300 299
301 TEST_F(ClientCertResolverTest, NoMatchingCertificates) { 300 TEST_F(ClientCertResolverTest, NoMatchingCertificates) {
302 SetupTestCerts(false /* do not import the issuer */); 301 SetupTestCerts("client_1", false /* do not import the issuer */);
303 StartCertLoader(); 302 StartCertLoader();
304 SetupWifi(); 303 SetupWifi();
305 base::RunLoop().RunUntilIdle(); 304 base::RunLoop().RunUntilIdle();
306 network_properties_changed_count_ = 0; 305 network_properties_changed_count_ = 0;
307 SetupNetworkHandlers(); 306 SetupNetworkHandlers();
308 SetupPolicyMatchingIssuerPEM(); 307 SetupPolicyMatchingIssuerPEM("");
309 base::RunLoop().RunUntilIdle(); 308 base::RunLoop().RunUntilIdle();
310 309
311 // Verify that no client certificate was configured. 310 // Verify that no client certificate was configured.
312 std::string pkcs11_id; 311 std::string pkcs11_id;
313 GetClientCertProperties(&pkcs11_id); 312 GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
314 EXPECT_EQ(std::string(), pkcs11_id); 313 EXPECT_EQ(std::string(), pkcs11_id);
315 EXPECT_EQ(1, network_properties_changed_count_); 314 EXPECT_EQ(1, network_properties_changed_count_);
316 EXPECT_FALSE(client_cert_resolver_->IsAnyResolveTaskRunning()); 315 EXPECT_FALSE(client_cert_resolver_->IsAnyResolveTaskRunning());
317 } 316 }
318 317
319 TEST_F(ClientCertResolverTest, MatchIssuerCNWithoutIssuerInstalled) { 318 TEST_F(ClientCertResolverTest, MatchIssuerCNWithoutIssuerInstalled) {
320 SetupTestCerts(false /* do not import the issuer */); 319 SetupTestCerts("client_1", false /* do not import the issuer */);
321 SetupWifi(); 320 SetupWifi();
322 base::RunLoop().RunUntilIdle(); 321 base::RunLoop().RunUntilIdle();
323 322
324 SetupNetworkHandlers(); 323 SetupNetworkHandlers();
325 SetupPolicyMatchingIssuerCN(); 324 SetupPolicyMatchingIssuerCN();
326 base::RunLoop().RunUntilIdle(); 325 base::RunLoop().RunUntilIdle();
327 326
328 network_properties_changed_count_ = 0; 327 network_properties_changed_count_ = 0;
329 StartCertLoader(); 328 StartCertLoader();
330 base::RunLoop().RunUntilIdle(); 329 base::RunLoop().RunUntilIdle();
331 330
332 // Verify that the resolver positively matched the pattern in the policy with 331 // Verify that the resolver positively matched the pattern in the policy with
333 // the test client cert and configured the network. 332 // the test client cert and configured the network.
334 std::string pkcs11_id; 333 std::string pkcs11_id;
335 GetClientCertProperties(&pkcs11_id); 334 GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
336 EXPECT_EQ(test_cert_id_, pkcs11_id); 335 EXPECT_EQ(test_cert_id_, pkcs11_id);
337 EXPECT_EQ(1, network_properties_changed_count_); 336 EXPECT_EQ(1, network_properties_changed_count_);
338 } 337 }
339 338
340 TEST_F(ClientCertResolverTest, ResolveOnCertificatesLoaded) { 339 TEST_F(ClientCertResolverTest, ResolveOnCertificatesLoaded) {
341 SetupTestCerts(true /* import issuer */); 340 SetupTestCerts("client_1", true /* import issuer */);
342 SetupWifi(); 341 SetupWifi();
343 base::RunLoop().RunUntilIdle(); 342 base::RunLoop().RunUntilIdle();
344 343
345 SetupNetworkHandlers(); 344 SetupNetworkHandlers();
346 SetupPolicyMatchingIssuerPEM(); 345 SetupPolicyMatchingIssuerPEM("");
347 base::RunLoop().RunUntilIdle(); 346 base::RunLoop().RunUntilIdle();
348 347
349 network_properties_changed_count_ = 0; 348 network_properties_changed_count_ = 0;
350 StartCertLoader(); 349 StartCertLoader();
351 base::RunLoop().RunUntilIdle(); 350 base::RunLoop().RunUntilIdle();
352 351
353 // Verify that the resolver positively matched the pattern in the policy with 352 // Verify that the resolver positively matched the pattern in the policy with
354 // the test client cert and configured the network. 353 // the test client cert and configured the network.
355 std::string pkcs11_id; 354 std::string pkcs11_id;
356 GetClientCertProperties(&pkcs11_id); 355 GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
357 EXPECT_EQ(test_cert_id_, pkcs11_id); 356 EXPECT_EQ(test_cert_id_, pkcs11_id);
358 EXPECT_EQ(1, network_properties_changed_count_); 357 EXPECT_EQ(1, network_properties_changed_count_);
359 } 358 }
360 359
361 TEST_F(ClientCertResolverTest, ResolveAfterPolicyApplication) { 360 TEST_F(ClientCertResolverTest, ResolveAfterPolicyApplication) {
362 SetupTestCerts(true /* import issuer */); 361 SetupTestCerts("client_1", true /* import issuer */);
363 SetupWifi(); 362 SetupWifi();
364 base::RunLoop().RunUntilIdle(); 363 base::RunLoop().RunUntilIdle();
365 StartCertLoader(); 364 StartCertLoader();
366 SetupNetworkHandlers(); 365 SetupNetworkHandlers();
367 base::RunLoop().RunUntilIdle(); 366 base::RunLoop().RunUntilIdle();
368 367
369 // Policy application will trigger the ClientCertResolver. 368 // Policy application will trigger the ClientCertResolver.
370 network_properties_changed_count_ = 0; 369 network_properties_changed_count_ = 0;
371 SetupPolicyMatchingIssuerPEM(); 370 SetupPolicyMatchingIssuerPEM("");
372 base::RunLoop().RunUntilIdle(); 371 base::RunLoop().RunUntilIdle();
373 372
374 // Verify that the resolver positively matched the pattern in the policy with 373 // Verify that the resolver positively matched the pattern in the policy with
375 // the test client cert and configured the network. 374 // the test client cert and configured the network.
376 std::string pkcs11_id; 375 std::string pkcs11_id;
377 GetClientCertProperties(&pkcs11_id); 376 GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
378 EXPECT_EQ(test_cert_id_, pkcs11_id); 377 EXPECT_EQ(test_cert_id_, pkcs11_id);
379 EXPECT_EQ(1, network_properties_changed_count_); 378 EXPECT_EQ(1, network_properties_changed_count_);
380 } 379 }
381 380
382 TEST_F(ClientCertResolverTest, ExpiringCertificate) { 381 TEST_F(ClientCertResolverTest, ExpiringCertificate) {
383 SetupTestCerts(true /* import issuer */); 382 SetupTestCerts("client_1", true /* import issuer */);
384 SetupWifi(); 383 SetupWifi();
385 base::RunLoop().RunUntilIdle(); 384 base::RunLoop().RunUntilIdle();
386 385
387 SetupNetworkHandlers(); 386 SetupNetworkHandlers();
388 SetupPolicyMatchingIssuerPEM(); 387 SetupPolicyMatchingIssuerPEM("");
389 base::RunLoop().RunUntilIdle(); 388 base::RunLoop().RunUntilIdle();
390 389
391 StartCertLoader(); 390 StartCertLoader();
392 base::RunLoop().RunUntilIdle(); 391 base::RunLoop().RunUntilIdle();
393 392
394 SetWifiState(shill::kStateOnline); 393 SetWifiState(shill::kStateOnline);
395 base::RunLoop().RunUntilIdle(); 394 base::RunLoop().RunUntilIdle();
396 395
397 // Verify that the resolver positively matched the pattern in the policy with 396 // Verify that the resolver positively matched the pattern in the policy with
398 // the test client cert and configured the network. 397 // the test client cert and configured the network.
399 std::string pkcs11_id; 398 std::string pkcs11_id;
400 GetClientCertProperties(&pkcs11_id); 399 GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
401 EXPECT_EQ(test_cert_id_, pkcs11_id); 400 EXPECT_EQ(test_cert_id_, pkcs11_id);
402 401
403 // Verify that, after the certificate expired and the network disconnection 402 // Verify that, after the certificate expired and the network disconnection
404 // happens, no client certificate was configured. 403 // happens, no client certificate was configured.
405 test_clock_->SetNow(base::Time::Max()); 404 test_clock_->SetNow(base::Time::Max());
406 SetWifiState(shill::kStateOffline); 405 SetWifiState(shill::kStateOffline);
407 base::RunLoop().RunUntilIdle(); 406 base::RunLoop().RunUntilIdle();
408 GetClientCertProperties(&pkcs11_id); 407 GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
409 EXPECT_EQ(std::string(), pkcs11_id); 408 EXPECT_EQ(std::string(), pkcs11_id);
410 } 409 }
411 410
411 TEST_F(ClientCertResolverTest, PopulateIdentityFromCert) {
412 SetupTestCerts("client_3", true /* import issuer */);
413 SetupWifi();
414 base::RunLoop().RunUntilIdle();
415
416 SetupNetworkHandlers();
417 SetupPolicyMatchingIssuerPEM("${CERT_SAN_EMAIL}");
418 base::RunLoop().RunUntilIdle();
419
420 network_properties_changed_count_ = 0;
421 StartCertLoader();
422 base::RunLoop().RunUntilIdle();
423
424 // Verify that the resolver read the subjectAltName email field from the
425 // cert, and wrote it into the shill service entry.
426 std::string identity;
427 GetServiceProperty(shill::kEapIdentityProperty, &identity);
428 EXPECT_EQ("santest@example.com", identity);
429 EXPECT_EQ(1, network_properties_changed_count_);
430
431 // Verify that after changing the ONC policy to request a variant of the
432 // Microsoft Universal Principal Name field instead, the correct value is
433 // substituted into the shill service entry.
434 SetupPolicyMatchingIssuerPEM("upn-${CERT_SAN_UPN}-suffix");
435 base::RunLoop().RunUntilIdle();
436
437 GetServiceProperty(shill::kEapIdentityProperty, &identity);
438 EXPECT_EQ("upn-santest@ad.corp.example.com-suffix", identity);
439 EXPECT_EQ(2, network_properties_changed_count_);
440 }
441
412 } // namespace chromeos 442 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698