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

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

Issue 2828713002: Enable client certificate patterns in device ONC policy (Closed)
Patch Set: Use BindOnce, PostTaskWithTraitsAndReplyWithResult. Created 3 years, 7 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 4
5 #include "chromeos/network/client_cert_resolver.h" 5 #include "chromeos/network/client_cert_resolver.h"
6 6
7 #include <cert.h> 7 #include <cert.h>
8 #include <certt.h> // for (SECCertUsageEnum) certUsageAnyCA 8 #include <certt.h> // for (SECCertUsageEnum) certUsageAnyCA
9 #include <pk11pub.h> 9 #include <pk11pub.h>
10 10
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 client_certs.push_back(CertAndIssuer(*it, GetPEMEncodedIssuer(cert))); 184 client_certs.push_back(CertAndIssuer(*it, GetPEMEncodedIssuer(cert)));
185 } 185 }
186 186
187 std::sort(client_certs.begin(), client_certs.end(), &CompareCertExpiration); 187 std::sort(client_certs.begin(), client_certs.end(), &CompareCertExpiration);
188 return client_certs; 188 return client_certs;
189 } 189 }
190 190
191 // Searches for matches between |networks| and |certs| and writes matches to 191 // Searches for matches between |networks| and |certs| and writes matches to
192 // |matches|. Because this calls NSS functions and is potentially slow, it must 192 // |matches|. Because this calls NSS functions and is potentially slow, it must
193 // be run on a worker thread. 193 // be run on a worker thread.
194 void FindCertificateMatches(const net::CertificateList& certs, 194 void FindCertificateMatches(const net::CertificateList& all_certs,
195 const net::CertificateList& system_certs,
195 std::vector<NetworkAndCertPattern>* networks, 196 std::vector<NetworkAndCertPattern>* networks,
196 base::Time now, 197 base::Time now,
197 NetworkCertMatches* matches) { 198 NetworkCertMatches* matches) {
198 std::vector<CertAndIssuer> client_certs( 199 std::vector<CertAndIssuer> all_client_certs(
199 CreateSortedCertAndIssuerList(certs, now)); 200 CreateSortedCertAndIssuerList(all_certs, now));
201 std::vector<CertAndIssuer> system_client_certs(
202 CreateSortedCertAndIssuerList(system_certs, now));
200 203
201 for (std::vector<NetworkAndCertPattern>::const_iterator it = 204 for (std::vector<NetworkAndCertPattern>::const_iterator it =
202 networks->begin(); 205 networks->begin();
203 it != networks->end(); ++it) { 206 it != networks->end(); ++it) {
204 std::vector<CertAndIssuer>::iterator cert_it = 207 // Use only certs from the system token if the source of the client cert
205 std::find_if(client_certs.begin(), 208 // pattern is device policy.
206 client_certs.end(), 209 std::vector<CertAndIssuer>* client_certs =
207 MatchCertWithPattern(it->cert_config.pattern)); 210 it->cert_config.onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY
211 ? &system_client_certs
212 : &all_client_certs;
213 auto cert_it = std::find_if(client_certs->begin(), client_certs->end(),
214 MatchCertWithPattern(it->cert_config.pattern));
208 std::string pkcs11_id; 215 std::string pkcs11_id;
209 int slot_id = -1; 216 int slot_id = -1;
210 std::string identity; 217 std::string identity;
211 218
212 if (cert_it == client_certs.end()) { 219 if (cert_it == client_certs->end()) {
213 VLOG(1) << "Couldn't find a matching client cert for network " 220 VLOG(1) << "Couldn't find a matching client cert for network "
214 << it->service_path; 221 << it->service_path;
215 // Leave |pkcs11_id| empty to indicate that no cert was found for this 222 // Leave |pkcs11_id| empty to indicate that no cert was found for this
216 // network. 223 // network.
217 } else { 224 } else {
218 pkcs11_id = 225 pkcs11_id =
219 CertLoader::GetPkcs11IdAndSlotForCert(*cert_it->cert, &slot_id); 226 CertLoader::GetPkcs11IdAndSlotForCert(*cert_it->cert, &slot_id);
220 if (pkcs11_id.empty()) { 227 if (pkcs11_id.empty()) {
221 LOG(ERROR) << "Couldn't determine PKCS#11 ID."; 228 LOG(ERROR) << "Couldn't determine PKCS#11 ID.";
222 // So far this error is not expected to happen. We can just continue, in 229 // So far this error is not expected to happen. We can just continue, in
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 observers_.RemoveObserver(observer); 325 observers_.RemoveObserver(observer);
319 } 326 }
320 327
321 bool ClientCertResolver::IsAnyResolveTaskRunning() const { 328 bool ClientCertResolver::IsAnyResolveTaskRunning() const {
322 return resolve_task_running_; 329 return resolve_task_running_;
323 } 330 }
324 331
325 // static 332 // static
326 bool ClientCertResolver::ResolveCertificatePatternSync( 333 bool ClientCertResolver::ResolveCertificatePatternSync(
327 const client_cert::ConfigType client_cert_type, 334 const client_cert::ConfigType client_cert_type,
328 const CertificatePattern& pattern, 335 const client_cert::ClientCertConfig& client_cert_config,
329 base::DictionaryValue* shill_properties) { 336 base::DictionaryValue* shill_properties) {
330 // Prepare and sort the list of known client certs. 337 // Prepare and sort the list of known client certs. Use only certs from the
331 std::vector<CertAndIssuer> client_certs(CreateSortedCertAndIssuerList( 338 // system token if the source of the client cert pattern is device policy.
332 CertLoader::Get()->cert_list(), base::Time::Now())); 339 std::vector<CertAndIssuer> client_certs;
340 if (client_cert_config.onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY) {
341 client_certs = CreateSortedCertAndIssuerList(
342 CertLoader::Get()->system_certs(), base::Time::Now());
343 } else {
344 client_certs = CreateSortedCertAndIssuerList(CertLoader::Get()->all_certs(),
345 base::Time::Now());
346 }
333 347
334 // Search for a certificate matching the pattern. 348 // Search for a certificate matching the pattern.
335 std::vector<CertAndIssuer>::iterator cert_it = std::find_if( 349 std::vector<CertAndIssuer>::iterator cert_it =
336 client_certs.begin(), client_certs.end(), MatchCertWithPattern(pattern)); 350 std::find_if(client_certs.begin(), client_certs.end(),
351 MatchCertWithPattern(client_cert_config.pattern));
337 352
338 if (cert_it == client_certs.end()) { 353 if (cert_it == client_certs.end()) {
339 VLOG(1) << "Couldn't find a matching client cert"; 354 VLOG(1) << "Couldn't find a matching client cert";
340 client_cert::SetEmptyShillProperties(client_cert_type, shill_properties); 355 client_cert::SetEmptyShillProperties(client_cert_type, shill_properties);
341 return false; 356 return false;
342 } 357 }
343 358
344 int slot_id = -1; 359 int slot_id = -1;
345 std::string pkcs11_id = 360 std::string pkcs11_id =
346 CertLoader::GetPkcs11IdAndSlotForCert(*cert_it->cert, &slot_id); 361 CertLoader::GetPkcs11IdAndSlotForCert(*cert_it->cert, &slot_id);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 networks.begin(); it != networks.end(); ++it) { 460 networks.begin(); it != networks.end(); ++it) {
446 const NetworkState* network = *it; 461 const NetworkState* network = *it;
447 462
448 // In any case, don't check this network again in NetworkListChanged. 463 // In any case, don't check this network again in NetworkListChanged.
449 resolved_networks_.insert(network->path()); 464 resolved_networks_.insert(network->path());
450 465
451 // If this network is not configured, it cannot have a ClientCertPattern. 466 // If this network is not configured, it cannot have a ClientCertPattern.
452 if (network->profile_path().empty()) 467 if (network->profile_path().empty())
453 continue; 468 continue;
454 469
470 onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
455 const base::DictionaryValue* policy = 471 const base::DictionaryValue* policy =
456 managed_network_config_handler_->FindPolicyByGuidAndProfile( 472 managed_network_config_handler_->FindPolicyByGuidAndProfile(
457 network->guid(), network->profile_path()); 473 network->guid(), network->profile_path(), &onc_source);
458 474
459 if (!policy) { 475 if (!policy) {
460 VLOG(1) << "The policy for network " << network->path() << " with GUID " 476 VLOG(1) << "The policy for network " << network->path() << " with GUID "
461 << network->guid() << " is not available yet."; 477 << network->guid() << " is not available yet.";
462 // Skip this network for now. Once the policy is loaded, PolicyApplied() 478 // Skip this network for now. Once the policy is loaded, PolicyApplied()
463 // will retry. 479 // will retry.
464 continue; 480 continue;
465 } 481 }
466 482
467 VLOG(2) << "Inspecting network " << network->path(); 483 VLOG(2) << "Inspecting network " << network->path();
468 client_cert::ClientCertConfig cert_config; 484 client_cert::ClientCertConfig cert_config;
469 OncToClientCertConfig(*policy, &cert_config); 485 OncToClientCertConfig(onc_source, *policy, &cert_config);
470 486
471 // Skip networks that don't have a ClientCertPattern. 487 // Skip networks that don't have a ClientCertPattern.
472 if (cert_config.client_cert_type != ::onc::client_cert::kPattern) 488 if (cert_config.client_cert_type != ::onc::client_cert::kPattern)
473 continue; 489 continue;
474 490
475 networks_to_resolve->push_back( 491 networks_to_resolve->push_back(
476 NetworkAndCertPattern(network->path(), cert_config)); 492 NetworkAndCertPattern(network->path(), cert_config));
477 } 493 }
478 494
479 if (networks_to_resolve->empty()) { 495 if (networks_to_resolve->empty()) {
480 VLOG(1) << "No networks to resolve."; 496 VLOG(1) << "No networks to resolve.";
481 NotifyResolveRequestCompleted(); 497 NotifyResolveRequestCompleted();
482 return; 498 return;
483 } 499 }
484 500
485 if (resolve_task_running_) { 501 if (resolve_task_running_) {
486 VLOG(1) << "A resolve task is already running. Queue this request."; 502 VLOG(1) << "A resolve task is already running. Queue this request.";
487 for (const NetworkAndCertPattern& network_and_pattern : 503 for (const NetworkAndCertPattern& network_and_pattern :
488 *networks_to_resolve) { 504 *networks_to_resolve) {
489 queued_networks_to_resolve_.insert(network_and_pattern.service_path); 505 queued_networks_to_resolve_.insert(network_and_pattern.service_path);
490 } 506 }
491 return; 507 return;
492 } 508 }
493 509
494 VLOG(2) << "Start task for resolving client cert patterns."; 510 VLOG(2) << "Start task for resolving client cert patterns.";
495 resolve_task_running_ = true; 511 resolve_task_running_ = true;
496 NetworkCertMatches* matches = new NetworkCertMatches; 512 NetworkCertMatches* matches = new NetworkCertMatches;
497 base::PostTaskWithTraitsAndReply( 513 base::PostTaskWithTraitsAndReply(
fdoray 2017/04/26 13:11:36 PostTaskWithTraitsAndReplyWithResult() could be us
pmarko 2017/04/27 08:51:56 Done.
498 FROM_HERE, base::TaskTraits() 514 FROM_HERE,
499 .WithShutdownBehavior( 515 base::TaskTraits()
500 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) 516 .WithShutdownBehavior(
501 .MayBlock(), 517 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)
502 base::Bind(&FindCertificateMatches, CertLoader::Get()->cert_list(), 518 .MayBlock(),
519 base::Bind(&FindCertificateMatches, CertLoader::Get()->all_certs(),
520 CertLoader::Get()->system_certs(),
503 base::Owned(networks_to_resolve.release()), Now(), matches), 521 base::Owned(networks_to_resolve.release()), Now(), matches),
504 base::Bind(&ClientCertResolver::ConfigureCertificates, 522 base::Bind(&ClientCertResolver::ConfigureCertificates,
505 weak_ptr_factory_.GetWeakPtr(), base::Owned(matches))); 523 weak_ptr_factory_.GetWeakPtr(), base::Owned(matches)));
506 } 524 }
507 525
508 void ClientCertResolver::ResolvePendingNetworks() { 526 void ClientCertResolver::ResolvePendingNetworks() {
509 NetworkStateHandler::NetworkStateList networks; 527 NetworkStateHandler::NetworkStateList networks;
510 network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(), 528 network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(),
511 true /* configured_only */, 529 true /* configured_only */,
512 false /* visible_only */, 530 false /* visible_only */,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 observer.ResolveRequestCompleted(changed); 583 observer.ResolveRequestCompleted(changed);
566 } 584 }
567 585
568 base::Time ClientCertResolver::Now() const { 586 base::Time ClientCertResolver::Now() const {
569 if (testing_clock_) 587 if (testing_clock_)
570 return testing_clock_->Now(); 588 return testing_clock_->Now();
571 return base::Time::Now(); 589 return base::Time::Now();
572 } 590 }
573 591
574 } // namespace chromeos 592 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698