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

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

Issue 1443043002: Execute ClientCertResolver on network disconnection. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix problem with AutoConnectHandler test Created 5 years, 1 month 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
11 #include <algorithm> 11 #include <algorithm>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/task_runner.h" 17 #include "base/task_runner.h"
18 #include "base/threading/worker_pool.h" 18 #include "base/threading/worker_pool.h"
19 #include "base/time/clock.h"
19 #include "chromeos/dbus/dbus_thread_manager.h" 20 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/dbus/shill_service_client.h" 21 #include "chromeos/dbus/shill_service_client.h"
21 #include "chromeos/network/managed_network_configuration_handler.h" 22 #include "chromeos/network/managed_network_configuration_handler.h"
22 #include "chromeos/network/network_state.h" 23 #include "chromeos/network/network_state.h"
23 #include "components/onc/onc_constants.h" 24 #include "components/onc/onc_constants.h"
24 #include "dbus/object_path.h" 25 #include "dbus/object_path.h"
25 #include "net/cert/scoped_nss_types.h" 26 #include "net/cert/scoped_nss_types.h"
26 #include "net/cert/x509_certificate.h" 27 #include "net/cert/x509_certificate.h"
27 28
28 namespace chromeos { 29 namespace chromeos {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 std::string pem_encoded_issuer; 150 std::string pem_encoded_issuer;
150 if (!net::X509Certificate::GetPEMEncoded(issuer->os_cert_handle(), 151 if (!net::X509Certificate::GetPEMEncoded(issuer->os_cert_handle(),
151 &pem_encoded_issuer)) { 152 &pem_encoded_issuer)) {
152 LOG(ERROR) << "Couldn't PEM-encode certificate."; 153 LOG(ERROR) << "Couldn't PEM-encode certificate.";
153 return std::string(); 154 return std::string();
154 } 155 }
155 return pem_encoded_issuer; 156 return pem_encoded_issuer;
156 } 157 }
157 158
158 std::vector<CertAndIssuer> CreateSortedCertAndIssuerList( 159 std::vector<CertAndIssuer> CreateSortedCertAndIssuerList(
159 const net::CertificateList& certs) { 160 const net::CertificateList& certs,
161 base::Time now) {
160 // Filter all client certs and determines each certificate's issuer, which is 162 // Filter all client certs and determines each certificate's issuer, which is
161 // required for the pattern matching. 163 // required for the pattern matching.
162 std::vector<CertAndIssuer> client_certs; 164 std::vector<CertAndIssuer> client_certs;
163 for (net::CertificateList::const_iterator it = certs.begin(); 165 for (net::CertificateList::const_iterator it = certs.begin();
164 it != certs.end(); ++it) { 166 it != certs.end(); ++it) {
165 const net::X509Certificate& cert = **it; 167 const net::X509Certificate& cert = **it;
166 if (cert.valid_expiry().is_null() || cert.HasExpired() || 168 if (cert.valid_expiry().is_null() || now > cert.valid_expiry() ||
167 !HasPrivateKey(cert) || 169 !HasPrivateKey(cert) ||
168 !CertLoader::IsCertificateHardwareBacked(&cert)) { 170 !CertLoader::IsCertificateHardwareBacked(&cert)) {
169 continue; 171 continue;
170 } 172 }
171 client_certs.push_back(CertAndIssuer(*it, GetPEMEncodedIssuer(cert))); 173 client_certs.push_back(CertAndIssuer(*it, GetPEMEncodedIssuer(cert)));
172 } 174 }
173 175
174 std::sort(client_certs.begin(), client_certs.end(), &CompareCertExpiration); 176 std::sort(client_certs.begin(), client_certs.end(), &CompareCertExpiration);
175 return client_certs; 177 return client_certs;
176 } 178 }
177 179
178 // Searches for matches between |networks| and |certs| and writes matches to 180 // Searches for matches between |networks| and |certs| and writes matches to
179 // |matches|. Because this calls NSS functions and is potentially slow, it must 181 // |matches|. Because this calls NSS functions and is potentially slow, it must
180 // be run on a worker thread. 182 // be run on a worker thread.
181 void FindCertificateMatches(const net::CertificateList& certs, 183 void FindCertificateMatches(const net::CertificateList& certs,
182 std::vector<NetworkAndCertPattern>* networks, 184 std::vector<NetworkAndCertPattern>* networks,
185 base::Time now,
183 NetworkCertMatches* matches) { 186 NetworkCertMatches* matches) {
184 std::vector<CertAndIssuer> client_certs(CreateSortedCertAndIssuerList(certs)); 187 std::vector<CertAndIssuer> client_certs(
188 CreateSortedCertAndIssuerList(certs, now));
185 189
186 for (std::vector<NetworkAndCertPattern>::const_iterator it = 190 for (std::vector<NetworkAndCertPattern>::const_iterator it =
187 networks->begin(); 191 networks->begin();
188 it != networks->end(); ++it) { 192 it != networks->end(); ++it) {
189 std::vector<CertAndIssuer>::iterator cert_it = 193 std::vector<CertAndIssuer>::iterator cert_it =
190 std::find_if(client_certs.begin(), 194 std::find_if(client_certs.begin(),
191 client_certs.end(), 195 client_certs.end(),
192 MatchCertWithPattern(it->cert_config.pattern)); 196 MatchCertWithPattern(it->cert_config.pattern));
193 std::string pkcs11_id; 197 std::string pkcs11_id;
194 int slot_id = -1; 198 int slot_id = -1;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 bool ClientCertResolver::IsAnyResolveTaskRunning() const { 284 bool ClientCertResolver::IsAnyResolveTaskRunning() const {
281 return resolve_task_running_; 285 return resolve_task_running_;
282 } 286 }
283 287
284 // static 288 // static
285 bool ClientCertResolver::ResolveCertificatePatternSync( 289 bool ClientCertResolver::ResolveCertificatePatternSync(
286 const client_cert::ConfigType client_cert_type, 290 const client_cert::ConfigType client_cert_type,
287 const CertificatePattern& pattern, 291 const CertificatePattern& pattern,
288 base::DictionaryValue* shill_properties) { 292 base::DictionaryValue* shill_properties) {
289 // Prepare and sort the list of known client certs. 293 // Prepare and sort the list of known client certs.
290 std::vector<CertAndIssuer> client_certs( 294 std::vector<CertAndIssuer> client_certs(CreateSortedCertAndIssuerList(
291 CreateSortedCertAndIssuerList(CertLoader::Get()->cert_list())); 295 CertLoader::Get()->cert_list(), base::Time::Now()));
292 296
293 // Search for a certificate matching the pattern. 297 // Search for a certificate matching the pattern.
294 std::vector<CertAndIssuer>::iterator cert_it = std::find_if( 298 std::vector<CertAndIssuer>::iterator cert_it = std::find_if(
295 client_certs.begin(), client_certs.end(), MatchCertWithPattern(pattern)); 299 client_certs.begin(), client_certs.end(), MatchCertWithPattern(pattern));
296 300
297 if (cert_it == client_certs.end()) { 301 if (cert_it == client_certs.end()) {
298 VLOG(1) << "Couldn't find a matching client cert"; 302 VLOG(1) << "Couldn't find a matching client cert";
299 client_cert::SetEmptyShillProperties(client_cert_type, shill_properties); 303 client_cert::SetEmptyShillProperties(client_cert_type, shill_properties);
300 return false; 304 return false;
301 } 305 }
302 306
303 int slot_id = -1; 307 int slot_id = -1;
304 std::string pkcs11_id = 308 std::string pkcs11_id =
305 CertLoader::GetPkcs11IdAndSlotForCert(*cert_it->cert, &slot_id); 309 CertLoader::GetPkcs11IdAndSlotForCert(*cert_it->cert, &slot_id);
306 if (pkcs11_id.empty()) { 310 if (pkcs11_id.empty()) {
307 LOG(ERROR) << "Couldn't determine PKCS#11 ID."; 311 LOG(ERROR) << "Couldn't determine PKCS#11 ID.";
308 // So far this error is not expected to happen. We can just continue, in 312 // So far this error is not expected to happen. We can just continue, in
309 // the worst case the user can remove the problematic cert. 313 // the worst case the user can remove the problematic cert.
310 return false; 314 return false;
311 } 315 }
312 client_cert::SetShillProperties( 316 client_cert::SetShillProperties(
313 client_cert_type, slot_id, pkcs11_id, shill_properties); 317 client_cert_type, slot_id, pkcs11_id, shill_properties);
314 return true; 318 return true;
315 } 319 }
316 320
321 void ClientCertResolver::SetClockForTesting(scoped_ptr<base::Clock> clock) {
322 testing_clock_ = clock.Pass();
323 }
324
317 void ClientCertResolver::NetworkListChanged() { 325 void ClientCertResolver::NetworkListChanged() {
318 VLOG(2) << "NetworkListChanged."; 326 VLOG(2) << "NetworkListChanged.";
319 if (!ClientCertificatesLoaded()) 327 if (!ClientCertificatesLoaded())
320 return; 328 return;
321 // Configure only networks that were not configured before. 329 // Configure only networks that were not configured before.
322 330
323 // We'll drop networks from |resolved_networks_|, which are not known anymore. 331 // We'll drop networks from |resolved_networks_|, which are not known anymore.
324 std::set<std::string> old_resolved_networks; 332 std::set<std::string> old_resolved_networks;
325 old_resolved_networks.swap(resolved_networks_); 333 old_resolved_networks.swap(resolved_networks_);
326 334
(...skipping 12 matching lines...) Expand all
339 if (ContainsKey(old_resolved_networks, service_path)) { 347 if (ContainsKey(old_resolved_networks, service_path)) {
340 resolved_networks_.insert(service_path); 348 resolved_networks_.insert(service_path);
341 continue; 349 continue;
342 } 350 }
343 networks_to_check.push_back(*it); 351 networks_to_check.push_back(*it);
344 } 352 }
345 353
346 ResolveNetworks(networks_to_check); 354 ResolveNetworks(networks_to_check);
347 } 355 }
348 356
357 void ClientCertResolver::NetworkConnectionStateChanged(
358 const NetworkState* network) {
359 if (!ClientCertificatesLoaded())
360 return;
361 if (!network->IsConnectedState() && !network->IsConnectingState())
362 ResolveNetworks(NetworkStateHandler::NetworkStateList(1, network));
363 }
364
349 void ClientCertResolver::OnCertificatesLoaded( 365 void ClientCertResolver::OnCertificatesLoaded(
350 const net::CertificateList& cert_list, 366 const net::CertificateList& cert_list,
351 bool initial_load) { 367 bool initial_load) {
352 VLOG(2) << "OnCertificatesLoaded."; 368 VLOG(2) << "OnCertificatesLoaded.";
353 if (!ClientCertificatesLoaded()) 369 if (!ClientCertificatesLoaded())
354 return; 370 return;
355 // Compare all networks with all certificates. 371 // Compare all networks with all certificates.
356 NetworkStateHandler::NetworkStateList networks; 372 NetworkStateHandler::NetworkStateList networks;
357 network_state_handler_->GetNetworkListByType( 373 network_state_handler_->GetNetworkListByType(
358 NetworkTypePattern::Default(), 374 NetworkTypePattern::Default(),
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 VLOG(2) << "Start task for resolving client cert patterns."; 457 VLOG(2) << "Start task for resolving client cert patterns.";
442 base::TaskRunner* task_runner = slow_task_runner_for_test_.get(); 458 base::TaskRunner* task_runner = slow_task_runner_for_test_.get();
443 if (!task_runner) 459 if (!task_runner)
444 task_runner = 460 task_runner =
445 base::WorkerPool::GetTaskRunner(true /* task is slow */).get(); 461 base::WorkerPool::GetTaskRunner(true /* task is slow */).get();
446 462
447 resolve_task_running_ = true; 463 resolve_task_running_ = true;
448 NetworkCertMatches* matches = new NetworkCertMatches; 464 NetworkCertMatches* matches = new NetworkCertMatches;
449 task_runner->PostTaskAndReply( 465 task_runner->PostTaskAndReply(
450 FROM_HERE, 466 FROM_HERE,
451 base::Bind(&FindCertificateMatches, 467 base::Bind(&FindCertificateMatches, CertLoader::Get()->cert_list(),
452 CertLoader::Get()->cert_list(), 468 base::Owned(networks_to_resolve.release()), Now(), matches),
453 base::Owned(networks_to_resolve.release()),
454 matches),
455 base::Bind(&ClientCertResolver::ConfigureCertificates, 469 base::Bind(&ClientCertResolver::ConfigureCertificates,
456 weak_ptr_factory_.GetWeakPtr(), 470 weak_ptr_factory_.GetWeakPtr(), base::Owned(matches)));
457 base::Owned(matches)));
458 } 471 }
459 472
460 void ClientCertResolver::ResolvePendingNetworks() { 473 void ClientCertResolver::ResolvePendingNetworks() {
461 NetworkStateHandler::NetworkStateList networks; 474 NetworkStateHandler::NetworkStateList networks;
462 network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(), 475 network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(),
463 true /* configured_only */, 476 true /* configured_only */,
464 false /* visible_only */, 477 false /* visible_only */,
465 0 /* no limit */, 478 0 /* no limit */,
466 &networks); 479 &networks);
467 480
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 518
506 void ClientCertResolver::NotifyResolveRequestCompleted() { 519 void ClientCertResolver::NotifyResolveRequestCompleted() {
507 VLOG(2) << "Notify observers: " << (network_properties_changed_ ? "" : "no ") 520 VLOG(2) << "Notify observers: " << (network_properties_changed_ ? "" : "no ")
508 << "networks changed."; 521 << "networks changed.";
509 resolve_task_running_ = false; 522 resolve_task_running_ = false;
510 const bool changed = network_properties_changed_; 523 const bool changed = network_properties_changed_;
511 network_properties_changed_ = false; 524 network_properties_changed_ = false;
512 FOR_EACH_OBSERVER(Observer, observers_, ResolveRequestCompleted(changed)); 525 FOR_EACH_OBSERVER(Observer, observers_, ResolveRequestCompleted(changed));
513 } 526 }
514 527
528 base::Time ClientCertResolver::Now() const {
529 if (testing_clock_)
530 return testing_clock_->Now();
531 return base::Time::Now();
532 }
533
515 } // namespace chromeos 534 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698