13240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 23240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 33240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// found in the LICENSE file. 43240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 53240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chromeos/network/network_cert_migrator.h" 63240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 73240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <cert.h> 83240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <string> 93240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/location.h" 113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/metrics/histogram.h" 123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chromeos/dbus/dbus_thread_manager.h" 133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chromeos/dbus/shill_service_client.h" 143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chromeos/network/network_handler_callbacks.h" 153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chromeos/network/network_state.h" 163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chromeos/network/network_state_handler.h" 173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "dbus/object_path.h" 183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "third_party/cros_system_api/dbus/service_constants.h" 193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochnamespace chromeos { 213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochnamespace { 233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochenum UMANetworkType { 253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch UMA_NETWORK_TYPE_EAP, 263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch UMA_NETWORK_TYPE_OPENVPN, 273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch UMA_NETWORK_TYPE_IPSEC, 283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch UMA_NETWORK_TYPE_SIZE, 293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}; 303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Copied from x509_certificate_model_nss.cc 323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::string GetNickname(const net::X509Certificate& cert) { 333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!cert.os_cert_handle()->nickname) 343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return std::string(); 353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch std::string name = cert.os_cert_handle()->nickname; 363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // Hack copied from mozilla: Cut off text before first :, which seems to 373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // just be the token name. 383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch size_t colon_pos = name.find(':'); 393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (colon_pos != std::string::npos) 403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch name = name.substr(colon_pos + 1); 413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return name; 423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} // namespace 453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Checks which of the given |networks| has one of the deprecated 473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// CaCertNssProperties set. If such a network already has a CaCertPEM property, 483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// then the NssProperty is cleared. Otherwise, the NssProperty is compared with 493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// the nickname of each certificate of |certs|. If a match is found, then the 503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// CaCertPemProperty is set and the NssProperty is cleared. Otherwise, the 513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// network is not modified. 523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochclass NetworkCertMigrator::MigrationTask 533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch : public base::RefCounted<MigrationTask> { 543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch public: 553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch MigrationTask(const net::CertificateList& certs, 563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const base::WeakPtr<NetworkCertMigrator>& cert_migrator) 573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch : certs_(certs), 583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch cert_migrator_(cert_migrator) { 593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch void Run(const NetworkStateHandler::NetworkStateList& networks) { 623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // Request properties for each network that has a CaCertNssProperty set 633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // according to the NetworkStateHandler. 643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch for (NetworkStateHandler::NetworkStateList::const_iterator it = 653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch networks.begin(); it != networks.end(); ++it) { 663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!(*it)->HasCACertNSS()) 673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const std::string& service_path = (*it)->path(); 693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch DBusThreadManager::Get()->GetShillServiceClient()->GetProperties( 703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch dbus::ObjectPath(service_path), 713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch base::Bind(&network_handler::GetPropertiesCallback, 723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch base::Bind(&MigrationTask::MigrateNetwork, this), 733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch network_handler::ErrorCallback(), 743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch service_path)); 753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch void MigrateNetwork(const std::string& service_path, 793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const base::DictionaryValue& properties) { 803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!cert_migrator_) { 813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch VLOG(2) << "NetworkCertMigrator already destroyed. Aborting migration."; 823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return; 833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch std::string nss_key, pem_key, nickname; 863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const base::ListValue* pem_property = NULL; 873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch UMANetworkType uma_type = UMA_NETWORK_TYPE_SIZE; 883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch GetNssAndPemProperties( 903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch properties, &nss_key, &pem_key, &pem_property, &nickname, &uma_type); 913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (nickname.empty()) 923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return; // Didn't find any nickname. 933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch VLOG(2) << "Found NSS nickname to migrate. Property: " << nss_key 953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch << ", network: " << service_path; 963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch UMA_HISTOGRAM_ENUMERATION( 973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch "Network.MigrationNssToPem", uma_type, UMA_NETWORK_TYPE_SIZE); 983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (pem_property && !pem_property->empty()) { 1003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch VLOG(2) << "PEM already exists, clearing NSS property."; 1013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ClearNssProperty(service_path, nss_key); 1023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return; 1033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch scoped_refptr<net::X509Certificate> cert = 1063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch FindCertificateWithNickname(nickname); 1073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!cert) { 1083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch VLOG(2) << "No matching cert found."; 1093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return; 1103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch std::string pem_encoded; 1133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!net::X509Certificate::GetPEMEncoded(cert->os_cert_handle(), 1143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch &pem_encoded)) { 1153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch LOG(ERROR) << "PEM encoding failed."; 1163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return; 1173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch SetNssAndPemProperties(service_path, nss_key, pem_key, pem_encoded); 1203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch void GetNssAndPemProperties(const base::DictionaryValue& shill_properties, 1233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch std::string* nss_key, 1243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch std::string* pem_key, 1253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const base::ListValue** pem_property, 1263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch std::string* nickname, 1273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch UMANetworkType* uma_type) { 1283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch struct NssPem { 1293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const char* read_prefix; 1303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const char* nss_key; 1313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const char* pem_key; 1323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch UMANetworkType uma_type; 1333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } const kNssPemMap[] = { 13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) { NULL, shill::kEapCaCertNssProperty, shill::kEapCaCertPemProperty, 1353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch UMA_NETWORK_TYPE_EAP }, 13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) { shill::kProviderProperty, shill::kL2tpIpsecCaCertNssProperty, 1373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch shill::kL2tpIpsecCaCertPemProperty, UMA_NETWORK_TYPE_IPSEC }, 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) { shill::kProviderProperty, shill::kOpenVPNCaCertNSSProperty, 1393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch shill::kOpenVPNCaCertPemProperty, UMA_NETWORK_TYPE_OPENVPN }, 1403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch }; 1413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kNssPemMap); ++i) { 1433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const base::DictionaryValue* dict = &shill_properties; 1443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (kNssPemMap[i].read_prefix) { 1453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch shill_properties.GetDictionaryWithoutPathExpansion( 1463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch kNssPemMap[i].read_prefix, &dict); 1473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!dict) 1483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 1493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch dict->GetStringWithoutPathExpansion(kNssPemMap[i].nss_key, nickname); 1513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!nickname->empty()) { 1523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch *nss_key = kNssPemMap[i].nss_key; 1533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch *pem_key = kNssPemMap[i].pem_key; 1543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch *uma_type = kNssPemMap[i].uma_type; 1553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch dict->GetListWithoutPathExpansion(kNssPemMap[i].pem_key, pem_property); 1563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return; 1573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch void ClearNssProperty(const std::string& service_path, 1623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const std::string& nss_key) { 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dbus::ObjectPath(service_path), 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) nss_key, 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::StringValue(std::string()), 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind( 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &MigrationTask::NotifyNetworkStateHandler, this, service_path), 1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&network_handler::ShillErrorCallbackFunction, 1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "MigrationTask.SetProperty failed", 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_path, 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) network_handler::ErrorCallback())); 1733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch scoped_refptr<net::X509Certificate> FindCertificateWithNickname( 1763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const std::string& nickname) { 1773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch for (net::CertificateList::iterator it = certs_.begin(); it != certs_.end(); 1783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ++it) { 1793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (nickname == GetNickname(**it)) 1803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return *it; 1813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return NULL; 1833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 1843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch void SetNssAndPemProperties(const std::string& service_path, 1863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const std::string& nss_key, 1873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const std::string& pem_key, 1883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const std::string& pem_encoded_cert) { 1893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch base::DictionaryValue new_properties; 1903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch new_properties.SetStringWithoutPathExpansion(nss_key, std::string()); 1913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch scoped_ptr<base::ListValue> ca_cert_pems(new base::ListValue); 1923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ca_cert_pems->AppendString(pem_encoded_cert); 1933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch new_properties.SetWithoutPathExpansion(pem_key, ca_cert_pems.release()); 1943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DBusThreadManager::Get()->GetShillServiceClient()->SetProperties( 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dbus::ObjectPath(service_path), 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new_properties, 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind( 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &MigrationTask::NotifyNetworkStateHandler, this, service_path), 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&MigrationTask::LogErrorAndNotifyNetworkStateHandler, 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_path)); 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void LogErrorAndNotifyNetworkStateHandler(const std::string& service_path, 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& error_name, 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& error_message) { 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) network_handler::ShillErrorCallbackFunction( 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "MigrationTask.SetProperties failed", 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_path, 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) network_handler::ErrorCallback(), 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) error_name, 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) error_message); 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NotifyNetworkStateHandler(service_path); 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void NotifyNetworkStateHandler(const std::string& service_path) { 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!cert_migrator_) { 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(2) << "NetworkCertMigrator already destroyed. Aborting migration."; 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) cert_migrator_->network_state_handler_->RequestUpdateForNetwork( 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_path); 2243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 2253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 2263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch private: 2273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch friend class base::RefCounted<MigrationTask>; 2283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch virtual ~MigrationTask() { 2293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 2303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 2313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch net::CertificateList certs_; 2323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch base::WeakPtr<NetworkCertMigrator> cert_migrator_; 2333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}; 2343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 2353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochNetworkCertMigrator::NetworkCertMigrator() 2363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch : network_state_handler_(NULL), 2373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch weak_ptr_factory_(this) { 2383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 2393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 2403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochNetworkCertMigrator::~NetworkCertMigrator() { 2413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch network_state_handler_->RemoveObserver(this, FROM_HERE); 2423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (CertLoader::IsInitialized()) 2433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch CertLoader::Get()->RemoveObserver(this); 2443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 2453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 2463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid NetworkCertMigrator::Init(NetworkStateHandler* network_state_handler) { 2473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch DCHECK(network_state_handler); 2483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch network_state_handler_ = network_state_handler; 2493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch network_state_handler_->AddObserver(this, FROM_HERE); 2503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 2513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch DCHECK(CertLoader::IsInitialized()); 2523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch CertLoader::Get()->AddObserver(this); 2533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 2543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 2553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid NetworkCertMigrator::NetworkListChanged() { 2563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!CertLoader::Get()->certificates_loaded()) { 2573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch VLOG(2) << "Certs not loaded yet."; 2583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return; 2593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 2603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // Run the migration process from deprecated CaCertNssProperties to CaCertPem. 2613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch VLOG(2) << "Start NSS nickname to PEM migration."; 2623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch scoped_refptr<MigrationTask> helper(new MigrationTask( 2633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch CertLoader::Get()->cert_list(), weak_ptr_factory_.GetWeakPtr())); 2643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch NetworkStateHandler::NetworkStateList networks; 2653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch network_state_handler_->GetNetworkList(&networks); 2663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch helper->Run(networks); 2673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 2683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 2693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid NetworkCertMigrator::OnCertificatesLoaded( 2703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const net::CertificateList& cert_list, 2713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch bool initial_load) { 2723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // Maybe there are networks referring to certs (by NSS nickname) that were not 2733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // loaded before but are now. 2743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch NetworkListChanged(); 2753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 2763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 2773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} // namespace chromeos 278