13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chromeos/network/client_cert_resolver.h" 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <cert.h> 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <certt.h> // for (SECCertUsageEnum) certUsageAnyCA 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <pk11pub.h> 103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <algorithm> 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <string> 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/location.h" 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/stl_util.h" 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/task_runner.h" 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/threading/worker_pool.h" 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/time/time.h" 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chromeos/cert_loader.h" 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chromeos/dbus/shill_service_client.h" 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chromeos/network/managed_network_configuration_handler.h" 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chromeos/network/network_state.h" 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "components/onc/onc_constants.h" 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "dbus/object_path.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/cert/scoped_nss_types.h" 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/cert/x509_certificate.h" 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace chromeos { 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Describes a network |network_path| for which a matching certificate |cert_id| 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// was found or for which no certificate was found (|cert_id| will be empty). 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct ClientCertResolver::NetworkAndMatchingCert { 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NetworkAndMatchingCert(const std::string& network_path, 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_cert::ConfigType config_type, 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& cert_id, 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int slot_id) 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : service_path(network_path), 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) cert_config_type(config_type), 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pkcs11_id(cert_id), 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) key_slot_id(slot_id) {} 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string service_path; 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_cert::ConfigType cert_config_type; 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The id of the matching certificate or empty if no certificate was found. 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string pkcs11_id; 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The id of the slot containing the certificate and the private key. 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int key_slot_id; 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)typedef std::vector<ClientCertResolver::NetworkAndMatchingCert> 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NetworkCertMatches; 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace { 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Returns true if |vector| contains |value|. 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)template <class T> 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ContainsValue(const std::vector<T>& vector, const T& value) { 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return find(vector.begin(), vector.end(), value) != vector.end(); 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Returns true if a private key for certificate |cert| is installed. 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool HasPrivateKey(const net::X509Certificate& cert) { 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PK11SlotInfo* slot = PK11_KeyForCertExists(cert.os_cert_handle(), NULL, NULL); 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!slot) 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PK11_FreeSlot(slot); 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Describes a certificate which is issued by |issuer| (encoded as PEM). 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct CertAndIssuer { 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CertAndIssuer(const scoped_refptr<net::X509Certificate>& certificate, 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& issuer) 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : cert(certificate), 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pem_encoded_issuer(issuer) {} 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<net::X509Certificate> cert; 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string pem_encoded_issuer; 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool CompareCertExpiration(const CertAndIssuer& a, 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const CertAndIssuer& b) { 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (a.cert->valid_expiry() > b.cert->valid_expiry()); 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Describes a network that is configured with the certificate pattern 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// |client_cert_pattern|. 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct NetworkAndCertPattern { 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NetworkAndCertPattern(const std::string& network_path, 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const client_cert::ClientCertConfig& client_cert_config) 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : service_path(network_path), 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cert_config(client_cert_config) {} 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string service_path; 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_cert::ClientCertConfig cert_config; 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// A unary predicate that returns true if the given CertAndIssuer matches the 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// given certificate pattern. 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct MatchCertWithPattern { 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) explicit MatchCertWithPattern(const CertificatePattern& cert_pattern) 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : pattern(cert_pattern) {} 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool operator()(const CertAndIssuer& cert_and_issuer) { 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!pattern.issuer().Empty() && 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !client_cert::CertPrincipalMatches(pattern.issuer(), 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) cert_and_issuer.cert->issuer())) { 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!pattern.subject().Empty() && 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !client_cert::CertPrincipalMatches(pattern.subject(), 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) cert_and_issuer.cert->subject())) { 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::vector<std::string>& issuer_ca_pems = pattern.issuer_ca_pems(); 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!issuer_ca_pems.empty() && 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !ContainsValue(issuer_ca_pems, cert_and_issuer.pem_encoded_issuer)) { 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CertificatePattern pattern; 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::vector<CertAndIssuer> CreateSortedCertAndIssuerList( 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const net::CertificateList& certs) { 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Filter all client certs and determines each certificate's issuer, which is 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // required for the pattern matching. 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::vector<CertAndIssuer> client_certs; 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (net::CertificateList::const_iterator it = certs.begin(); 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) it != certs.end(); ++it) { 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const net::X509Certificate& cert = **it; 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (cert.valid_expiry().is_null() || cert.HasExpired() || 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !HasPrivateKey(cert)) { 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::ScopedCERTCertificate issuer_handle( 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CERT_FindCertIssuer(cert.os_cert_handle(), PR_Now(), certUsageAnyCA)); 146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!issuer_handle) { 147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LOG(ERROR) << "Couldn't find an issuer."; 148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) continue; 149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<net::X509Certificate> issuer = 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::X509Certificate::CreateFromHandle( 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) issuer_handle.get(), 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) net::X509Certificate::OSCertHandles() /* no intermediate certs */); 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!issuer.get()) { 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LOG(ERROR) << "Couldn't create issuer cert."; 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string pem_encoded_issuer; 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!net::X509Certificate::GetPEMEncoded(issuer->os_cert_handle(), 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &pem_encoded_issuer)) { 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LOG(ERROR) << "Couldn't PEM-encode certificate."; 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_certs.push_back(CertAndIssuer(*it, pem_encoded_issuer)); 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::sort(client_certs.begin(), client_certs.end(), &CompareCertExpiration); 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return client_certs; 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Searches for matches between |networks| and |certs| and writes matches to 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |matches|. Because this calls NSS functions and is potentially slow, it must 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// be run on a worker thread. 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void FindCertificateMatches(const net::CertificateList& certs, 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<NetworkAndCertPattern>* networks, 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NetworkCertMatches* matches) { 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<CertAndIssuer> client_certs(CreateSortedCertAndIssuerList(certs)); 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (std::vector<NetworkAndCertPattern>::const_iterator it = 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) networks->begin(); 1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) it != networks->end(); ++it) { 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<CertAndIssuer>::iterator cert_it = 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::find_if(client_certs.begin(), 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_certs.end(), 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MatchCertWithPattern(it->cert_config.pattern)); 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string pkcs11_id; 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int slot_id = -1; 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (cert_it == client_certs.end()) { 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VLOG(1) << "Couldn't find a matching client cert for network " 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << it->service_path; 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Leave |pkcs11_id| empty to indicate that no cert was found for this 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // network. 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pkcs11_id = 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CertLoader::GetPkcs11IdAndSlotForCert(*cert_it->cert, &slot_id); 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (pkcs11_id.empty()) { 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Couldn't determine PKCS#11 ID."; 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // So far this error is not expected to happen. We can just continue, in 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the worst case the user can remove the problematic cert. 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch continue; 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) matches->push_back(ClientCertResolver::NetworkAndMatchingCert( 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) it->service_path, it->cert_config.location, pkcs11_id, slot_id)); 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void LogError(const std::string& service_path, 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& dbus_error_name, 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& dbus_error_message) { 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) network_handler::ShillErrorCallbackFunction( 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "ClientCertResolver.SetProperties failed", 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_path, 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) network_handler::ErrorCallback(), 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dbus_error_name, 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dbus_error_message); 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ClientCertificatesLoaded() { 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!CertLoader::Get()->certificates_loaded()) { 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(1) << "Certificates not loaded yet."; 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!CertLoader::Get()->IsHardwareBacked()) { 2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(1) << "TPM is not available."; 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace 2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ClientCertResolver::ClientCertResolver() 2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : network_state_handler_(NULL), 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) managed_network_config_handler_(NULL), 2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) weak_ptr_factory_(this) { 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ClientCertResolver::~ClientCertResolver() { 2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (network_state_handler_) 2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) network_state_handler_->RemoveObserver(this, FROM_HERE); 2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (CertLoader::IsInitialized()) 2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CertLoader::Get()->RemoveObserver(this); 2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (managed_network_config_handler_) 2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) managed_network_config_handler_->RemoveObserver(this); 2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClientCertResolver::Init( 2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NetworkStateHandler* network_state_handler, 2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ManagedNetworkConfigurationHandler* managed_network_config_handler) { 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(network_state_handler); 2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) network_state_handler_ = network_state_handler; 2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) network_state_handler_->AddObserver(this, FROM_HERE); 2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(managed_network_config_handler); 2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) managed_network_config_handler_ = managed_network_config_handler; 2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) managed_network_config_handler_->AddObserver(this); 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CertLoader::Get()->AddObserver(this); 2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClientCertResolver::SetSlowTaskRunnerForTest( 2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const scoped_refptr<base::TaskRunner>& task_runner) { 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) slow_task_runner_for_test_ = task_runner; 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static 2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ClientCertResolver::ResolveCertificatePatternSync( 2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const client_cert::ConfigType client_cert_type, 2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CertificatePattern& pattern, 2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::DictionaryValue* shill_properties) { 2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Prepare and sort the list of known client certs. 2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<CertAndIssuer> client_certs( 2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CreateSortedCertAndIssuerList(CertLoader::Get()->cert_list())); 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Search for a certificate matching the pattern. 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<CertAndIssuer>::iterator cert_it = std::find_if( 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_certs.begin(), client_certs.end(), MatchCertWithPattern(pattern)); 2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (cert_it == client_certs.end()) { 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) VLOG(1) << "Couldn't find a matching client cert"; 2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_cert::SetEmptyShillProperties(client_cert_type, shill_properties); 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int slot_id = -1; 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string pkcs11_id = 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CertLoader::GetPkcs11IdAndSlotForCert(*cert_it->cert, &slot_id); 2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (pkcs11_id.empty()) { 2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Couldn't determine PKCS#11 ID."; 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // So far this error is not expected to happen. We can just continue, in 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the worst case the user can remove the problematic cert. 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_cert::SetShillProperties( 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_cert_type, slot_id, pkcs11_id, shill_properties); 2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClientCertResolver::NetworkListChanged() { 3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(2) << "NetworkListChanged."; 3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ClientCertificatesLoaded()) 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Configure only networks that were not configured before. 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // We'll drop networks from |resolved_networks_|, which are not known anymore. 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::set<std::string> old_resolved_networks; 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) old_resolved_networks.swap(resolved_networks_); 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NetworkStateHandler::NetworkStateList networks; 311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) network_state_handler_->GetNetworkListByType( 312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NetworkTypePattern::Default(), 313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) true /* configured_only */, 314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) false /* visible_only */, 315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 0 /* no limit */, 316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &networks); 317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NetworkStateHandler::NetworkStateList networks_to_check; 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (NetworkStateHandler::NetworkStateList::const_iterator it = 320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) networks.begin(); it != networks.end(); ++it) { 3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& service_path = (*it)->path(); 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (ContainsKey(old_resolved_networks, service_path)) { 3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) resolved_networks_.insert(service_path); 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) networks_to_check.push_back(*it); 3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ResolveNetworks(networks_to_check); 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClientCertResolver::OnCertificatesLoaded( 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const net::CertificateList& cert_list, 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool initial_load) { 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(2) << "OnCertificatesLoaded."; 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ClientCertificatesLoaded()) 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Compare all networks with all certificates. 339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NetworkStateHandler::NetworkStateList networks; 340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) network_state_handler_->GetNetworkListByType( 341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NetworkTypePattern::Default(), 342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) true /* configured_only */, 343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) false /* visible_only */, 344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 0 /* no limit */, 345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &networks); 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ResolveNetworks(networks); 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClientCertResolver::PolicyApplied(const std::string& service_path) { 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(2) << "PolicyApplied " << service_path; 3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ClientCertificatesLoaded()) 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Compare this network with all certificates. 354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const NetworkState* network = 355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) network_state_handler_->GetNetworkStateFromServicePath( 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) service_path, true /* configured_only */); 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!network) { 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LOG(ERROR) << "service path '" << service_path << "' unknown."; 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NetworkStateHandler::NetworkStateList networks; 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) networks.push_back(network); 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ResolveNetworks(networks); 3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ClientCertResolver::ResolveNetworks( 367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const NetworkStateHandler::NetworkStateList& networks) { 3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<std::vector<NetworkAndCertPattern> > networks_with_pattern( 3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new std::vector<NetworkAndCertPattern>); 3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Filter networks with ClientCertPattern. As ClientCertPatterns can only be 3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // set by policy, we check there. 373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (NetworkStateHandler::NetworkStateList::const_iterator it = 374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) networks.begin(); it != networks.end(); ++it) { 375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const NetworkState* network = *it; 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // In any case, don't check this network again in NetworkListChanged. 3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) resolved_networks_.insert(network->path()); 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If this network is not configured, it cannot have a ClientCertPattern. 381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (network->profile_path().empty()) 3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::DictionaryValue* policy = 3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) managed_network_config_handler_->FindPolicyByGuidAndProfile( 3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) network->guid(), network->profile_path()); 3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!policy) { 3893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(1) << "The policy for network " << network->path() << " with GUID " 3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << network->guid() << " is not available yet."; 3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Skip this network for now. Once the policy is loaded, PolicyApplied() 3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // will retry. 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(2) << "Inspecting network " << network->path(); 397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_cert::ClientCertConfig cert_config; 398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OncToClientCertConfig(*policy, &cert_config); 3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Skip networks that don't have a ClientCertPattern. 401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (cert_config.client_cert_type != ::onc::client_cert::kPattern) 4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch networks_with_pattern->push_back( 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NetworkAndCertPattern(network->path(), cert_config)); 4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (networks_with_pattern->empty()) 4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(2) << "Start task for resolving client cert patterns."; 4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TaskRunner* task_runner = slow_task_runner_for_test_.get(); 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!task_runner) 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner = 4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WorkerPool::GetTaskRunner(true /* task is slow */).get(); 4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NetworkCertMatches* matches = new NetworkCertMatches; 4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) task_runner->PostTaskAndReply( 4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FROM_HERE, 4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&FindCertificateMatches, 4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CertLoader::Get()->cert_list(), 4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Owned(networks_with_pattern.release()), 4223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) matches), 4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&ClientCertResolver::ConfigureCertificates, 4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Owned(matches))); 4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClientCertResolver::ConfigureCertificates(NetworkCertMatches* matches) { 4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (NetworkCertMatches::const_iterator it = matches->begin(); 4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) it != matches->end(); ++it) { 4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(1) << "Configuring certificate of network " << it->service_path; 4323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::DictionaryValue shill_properties; 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (it->pkcs11_id.empty()) { 4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_cert::SetEmptyShillProperties(it->cert_config_type, 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &shill_properties); 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_cert::SetShillProperties(it->cert_config_type, 4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) it->key_slot_id, 4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) it->pkcs11_id, 4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &shill_properties); 4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DBusThreadManager::Get()->GetShillServiceClient()-> 4433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetProperties(dbus::ObjectPath(it->service_path), 4443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) shill_properties, 4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&base::DoNothing), 4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&LogError, it->service_path)); 4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) network_state_handler_->RequestUpdateForNetwork(it->service_path); 4483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace chromeos 452