blob: c251f29a65109cc45d27c93047447fe378f82f20 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/network/network_certificate_handler.h"
#include "base/strings/stringprintf.h"
#include "chromeos/network/certificate_helper.h"
#include "net/base/hash_value.h"
#include "net/cert/x509_util_nss.h"
namespace chromeos {
namespace {
NetworkCertificateHandler::Certificate GetCertificate(CERTCertificate* cert,
net::CertType type,
bool is_device_wide) {
NetworkCertificateHandler::Certificate result;
result.hash =
net::HashValue(net::x509_util::CalculateFingerprint256(cert)).ToString();
result.issued_by = certificate::GetIssuerDisplayName(cert);
result.issued_to = certificate::GetCertNameOrNickname(cert);
result.issued_to_ascii = certificate::GetCertAsciiNameOrNickname(cert);
if (type == net::USER_CERT) {
int slot_id;
std::string pkcs11_id =
NetworkCertLoader::GetPkcs11IdAndSlotForCert(cert, &slot_id);
result.pkcs11_id = base::StringPrintf("%i:%s", slot_id, pkcs11_id.c_str());
} else if (type == net::CA_CERT) {
if (!net::x509_util::GetPEMEncoded(cert, &result.pem)) {
LOG(ERROR) << "Unable to PEM-encode CA";
}
} else {
NOTREACHED();
}
result.hardware_backed = NetworkCertLoader::IsCertificateHardwareBacked(cert);
result.device_wide = is_device_wide;
return result;
}
} // namespace
NetworkCertificateHandler::Certificate::Certificate() = default;
NetworkCertificateHandler::Certificate::~Certificate() = default;
NetworkCertificateHandler::Certificate::Certificate(const Certificate& other) =
default;
NetworkCertificateHandler::NetworkCertificateHandler() {
NetworkCertLoader::Get()->AddObserver(this);
if (NetworkCertLoader::Get()->initial_load_finished())
OnCertificatesLoaded();
}
NetworkCertificateHandler::~NetworkCertificateHandler() {
NetworkCertLoader::Get()->RemoveObserver(this);
}
void NetworkCertificateHandler::AddObserver(
NetworkCertificateHandler::Observer* observer) {
observer_list_.AddObserver(observer);
}
void NetworkCertificateHandler::RemoveObserver(
NetworkCertificateHandler::Observer* observer) {
observer_list_.RemoveObserver(observer);
}
void NetworkCertificateHandler::AddAuthorityCertificateForTest(
const std::string& issued_to) {
Certificate cert;
cert.issued_to = issued_to;
cert.issued_to_ascii = issued_to;
server_ca_certificates_.push_back(cert);
for (auto& observer : observer_list_)
observer.OnCertificatesChanged();
}
void NetworkCertificateHandler::OnCertificatesLoaded() {
ProcessCertificates(NetworkCertLoader::Get()->authority_certs(),
NetworkCertLoader::Get()->client_certs());
}
void NetworkCertificateHandler::ProcessCertificates(
const NetworkCertLoader::NetworkCertList& authority_certs,
const NetworkCertLoader::NetworkCertList& client_certs) {
client_certificates_.clear();
server_ca_certificates_.clear();
// Add certificates to the appropriate list.
for (const auto& network_cert : authority_certs) {
server_ca_certificates_.push_back(GetCertificate(
network_cert.cert(), net::CA_CERT, network_cert.is_device_wide()));
}
for (const auto& network_cert : client_certs) {
client_certificates_.push_back(GetCertificate(
network_cert.cert(), net::USER_CERT, network_cert.is_device_wide()));
}
for (auto& observer : observer_list_)
observer.OnCertificatesChanged();
}
} // namespace chromeos