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 | 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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 !CertLoader::IsCertificateHardwareBacked(&cert)) { | 181 !CertLoader::IsCertificateHardwareBacked(&cert)) { |
182 continue; | 182 continue; |
183 } | 183 } |
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 // Chooses which cert list should be used to find certificate matches for a | |
192 // client cert config based on ONC policy source. Device policy certificate | |
emaxx
2017/04/20 20:10:39
nit: I'd prefer to move the second sentence inside
pmarko
2017/04/24 14:49:56
Done. / Moved logic into the call site.
| |
193 // patterns may only match certificates which exist on the system token for | |
194 // privacy reasons. | |
195 const std::vector<CertAndIssuer>& ChooseCertList( | |
emaxx
2017/04/20 20:10:39
Returning a reference that follows the reference r
pmarko
2017/04/24 14:49:56
Done.
Very good point - yes, it would compile and
| |
196 const client_cert::ClientCertConfig& client_cert_config, | |
197 const std::vector<CertAndIssuer>& all_certs, | |
198 const std::vector<CertAndIssuer>& system_certs) { | |
199 if (client_cert_config.source_is_device_policy_) | |
200 return system_certs; | |
201 else | |
emaxx
2017/04/20 20:10:39
nit: Remove else. See here:
https://chromium.googl
pmarko
2017/04/24 14:49:56
Done. / Moved logic into the call site.
| |
202 return all_certs; | |
203 } | |
204 | |
191 // Searches for matches between |networks| and |certs| and writes matches to | 205 // Searches for matches between |networks| and |certs| and writes matches to |
192 // |matches|. Because this calls NSS functions and is potentially slow, it must | 206 // |matches|. Because this calls NSS functions and is potentially slow, it must |
193 // be run on a worker thread. | 207 // be run on a worker thread. |
194 void FindCertificateMatches(const net::CertificateList& certs, | 208 void FindCertificateMatches(const net::CertificateList& all_certs, |
209 const net::CertificateList& system_certs, | |
195 std::vector<NetworkAndCertPattern>* networks, | 210 std::vector<NetworkAndCertPattern>* networks, |
196 base::Time now, | 211 base::Time now, |
197 NetworkCertMatches* matches) { | 212 NetworkCertMatches* matches) { |
198 std::vector<CertAndIssuer> client_certs( | 213 std::vector<CertAndIssuer> all_client_certs( |
199 CreateSortedCertAndIssuerList(certs, now)); | 214 CreateSortedCertAndIssuerList(all_certs, now)); |
215 | |
216 std::vector<CertAndIssuer> system_client_certs( | |
217 CreateSortedCertAndIssuerList(system_certs, now)); | |
200 | 218 |
201 for (std::vector<NetworkAndCertPattern>::const_iterator it = | 219 for (std::vector<NetworkAndCertPattern>::const_iterator it = |
202 networks->begin(); | 220 networks->begin(); |
203 it != networks->end(); ++it) { | 221 it != networks->end(); ++it) { |
204 std::vector<CertAndIssuer>::iterator cert_it = | 222 const std::vector<CertAndIssuer>& client_certs = |
205 std::find_if(client_certs.begin(), | 223 ChooseCertList(it->cert_config, all_client_certs, system_client_certs); |
206 client_certs.end(), | 224 std::vector<CertAndIssuer>::const_iterator cert_it = |
emaxx
2017/04/20 20:10:39
nit: I think "auto" instead of this long iterator
pmarko
2017/04/24 14:49:56
Done.
| |
225 std::find_if(client_certs.begin(), client_certs.end(), | |
207 MatchCertWithPattern(it->cert_config.pattern)); | 226 MatchCertWithPattern(it->cert_config.pattern)); |
208 std::string pkcs11_id; | 227 std::string pkcs11_id; |
209 int slot_id = -1; | 228 int slot_id = -1; |
210 std::string identity; | 229 std::string identity; |
211 | 230 |
212 if (cert_it == client_certs.end()) { | 231 if (cert_it == client_certs.end()) { |
213 VLOG(1) << "Couldn't find a matching client cert for network " | 232 VLOG(1) << "Couldn't find a matching client cert for network " |
214 << it->service_path; | 233 << it->service_path; |
215 // Leave |pkcs11_id| empty to indicate that no cert was found for this | 234 // Leave |pkcs11_id| empty to indicate that no cert was found for this |
216 // network. | 235 // network. |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
445 networks.begin(); it != networks.end(); ++it) { | 464 networks.begin(); it != networks.end(); ++it) { |
446 const NetworkState* network = *it; | 465 const NetworkState* network = *it; |
447 | 466 |
448 // In any case, don't check this network again in NetworkListChanged. | 467 // In any case, don't check this network again in NetworkListChanged. |
449 resolved_networks_.insert(network->path()); | 468 resolved_networks_.insert(network->path()); |
450 | 469 |
451 // If this network is not configured, it cannot have a ClientCertPattern. | 470 // If this network is not configured, it cannot have a ClientCertPattern. |
452 if (network->profile_path().empty()) | 471 if (network->profile_path().empty()) |
453 continue; | 472 continue; |
454 | 473 |
474 onc::ONCSource onc_source; | |
455 const base::DictionaryValue* policy = | 475 const base::DictionaryValue* policy = |
456 managed_network_config_handler_->FindPolicyByGuidAndProfile( | 476 managed_network_config_handler_->FindPolicyByGuidAndProfile( |
457 network->guid(), network->profile_path()); | 477 network->guid(), network->profile_path(), &onc_source); |
458 | 478 |
459 if (!policy) { | 479 if (!policy) { |
460 VLOG(1) << "The policy for network " << network->path() << " with GUID " | 480 VLOG(1) << "The policy for network " << network->path() << " with GUID " |
461 << network->guid() << " is not available yet."; | 481 << network->guid() << " is not available yet."; |
462 // Skip this network for now. Once the policy is loaded, PolicyApplied() | 482 // Skip this network for now. Once the policy is loaded, PolicyApplied() |
463 // will retry. | 483 // will retry. |
464 continue; | 484 continue; |
465 } | 485 } |
466 | 486 |
467 VLOG(2) << "Inspecting network " << network->path(); | 487 VLOG(2) << "Inspecting network " << network->path(); |
468 client_cert::ClientCertConfig cert_config; | 488 client_cert::ClientCertConfig cert_config; |
469 OncToClientCertConfig(*policy, &cert_config); | 489 OncToClientCertConfig(onc_source, *policy, &cert_config); |
470 | 490 |
471 // Skip networks that don't have a ClientCertPattern. | 491 // Skip networks that don't have a ClientCertPattern. |
472 if (cert_config.client_cert_type != ::onc::client_cert::kPattern) | 492 if (cert_config.client_cert_type != ::onc::client_cert::kPattern) |
473 continue; | 493 continue; |
474 | 494 |
475 networks_to_resolve->push_back( | 495 networks_to_resolve->push_back( |
476 NetworkAndCertPattern(network->path(), cert_config)); | 496 NetworkAndCertPattern(network->path(), cert_config)); |
477 } | 497 } |
478 | 498 |
479 if (networks_to_resolve->empty()) { | 499 if (networks_to_resolve->empty()) { |
480 VLOG(1) << "No networks to resolve."; | 500 VLOG(1) << "No networks to resolve."; |
481 NotifyResolveRequestCompleted(); | 501 NotifyResolveRequestCompleted(); |
482 return; | 502 return; |
483 } | 503 } |
484 | 504 |
485 if (resolve_task_running_) { | 505 if (resolve_task_running_) { |
486 VLOG(1) << "A resolve task is already running. Queue this request."; | 506 VLOG(1) << "A resolve task is already running. Queue this request."; |
487 for (const NetworkAndCertPattern& network_and_pattern : | 507 for (const NetworkAndCertPattern& network_and_pattern : |
488 *networks_to_resolve) { | 508 *networks_to_resolve) { |
489 queued_networks_to_resolve_.insert(network_and_pattern.service_path); | 509 queued_networks_to_resolve_.insert(network_and_pattern.service_path); |
490 } | 510 } |
491 return; | 511 return; |
492 } | 512 } |
493 | 513 |
494 VLOG(2) << "Start task for resolving client cert patterns."; | 514 VLOG(2) << "Start task for resolving client cert patterns."; |
495 resolve_task_running_ = true; | 515 resolve_task_running_ = true; |
496 NetworkCertMatches* matches = new NetworkCertMatches; | 516 NetworkCertMatches* matches = new NetworkCertMatches; |
497 base::PostTaskWithTraitsAndReply( | 517 base::PostTaskWithTraitsAndReply( |
498 FROM_HERE, base::TaskTraits() | 518 FROM_HERE, |
499 .WithShutdownBehavior( | 519 base::TaskTraits() |
500 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) | 520 .WithShutdownBehavior( |
501 .MayBlock(), | 521 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) |
522 .MayBlock(), | |
502 base::Bind(&FindCertificateMatches, CertLoader::Get()->cert_list(), | 523 base::Bind(&FindCertificateMatches, CertLoader::Get()->cert_list(), |
524 CertLoader::Get()->system_cert_list(), | |
503 base::Owned(networks_to_resolve.release()), Now(), matches), | 525 base::Owned(networks_to_resolve.release()), Now(), matches), |
504 base::Bind(&ClientCertResolver::ConfigureCertificates, | 526 base::Bind(&ClientCertResolver::ConfigureCertificates, |
505 weak_ptr_factory_.GetWeakPtr(), base::Owned(matches))); | 527 weak_ptr_factory_.GetWeakPtr(), base::Owned(matches))); |
506 } | 528 } |
507 | 529 |
508 void ClientCertResolver::ResolvePendingNetworks() { | 530 void ClientCertResolver::ResolvePendingNetworks() { |
509 NetworkStateHandler::NetworkStateList networks; | 531 NetworkStateHandler::NetworkStateList networks; |
510 network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(), | 532 network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(), |
511 true /* configured_only */, | 533 true /* configured_only */, |
512 false /* visible_only */, | 534 false /* visible_only */, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 observer.ResolveRequestCompleted(changed); | 587 observer.ResolveRequestCompleted(changed); |
566 } | 588 } |
567 | 589 |
568 base::Time ClientCertResolver::Now() const { | 590 base::Time ClientCertResolver::Now() const { |
569 if (testing_clock_) | 591 if (testing_clock_) |
570 return testing_clock_->Now(); | 592 return testing_clock_->Now(); |
571 return base::Time::Now(); | 593 return base::Time::Now(); |
572 } | 594 } |
573 | 595 |
574 } // namespace chromeos | 596 } // namespace chromeos |
OLD | NEW |