Chromium Code Reviews| 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 |