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

Unified Diff: chromeos/network/onc/onc_certificate_importer_impl.cc

Issue 547553005: Make ONCCertificateImporter async. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@nss_util_deadcode
Patch Set: Simplified NSSCertDatabase creation in unit test. Created 6 years, 3 months 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 side-by-side diff with in-line comments
Download patch
Index: chromeos/network/onc/onc_certificate_importer_impl.cc
diff --git a/chromeos/network/onc/onc_certificate_importer_impl.cc b/chromeos/network/onc/onc_certificate_importer_impl.cc
index 7bb18333aee9a004e67d0be61c7c28c671c06fd1..521595acd9ac2e2fbfeb4f60298d6df3bc7fb182 100644
--- a/chromeos/network/onc/onc_certificate_importer_impl.cc
+++ b/chromeos/network/onc/onc_certificate_importer_impl.cc
@@ -9,7 +9,14 @@
#include <pk11pub.h>
#include "base/base64.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/location.h"
#include "base/logging.h"
+#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
#include "base/values.h"
#include "chromeos/network/network_event_log.h"
#include "chromeos/network/onc/onc_utils.h"
@@ -20,64 +27,83 @@
#include "net/cert/nss_cert_database.h"
#include "net/cert/x509_certificate.h"
-#define ONC_LOG_WARNING(message) \
- NET_LOG_DEBUG("ONC Certificate Import Warning", message)
-#define ONC_LOG_ERROR(message) \
- NET_LOG_ERROR("ONC Certificate Import Error", message)
-
namespace chromeos {
namespace onc {
+namespace {
+
+void CallBackOnOriginLoop(
+ const scoped_refptr<base::SingleThreadTaskRunner>& origin_loop,
+ const CertificateImporter::DoneCallback& callback,
+ bool success,
+ const net::CertificateList& onc_trusted_certificates) {
+ origin_loop->PostTask(
+ FROM_HERE, base::Bind(callback, success, onc_trusted_certificates));
+}
+
+} // namespace
+
CertificateImporterImpl::CertificateImporterImpl(
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner,
net::NSSCertDatabase* target_nssdb)
- : target_nssdb_(target_nssdb) {
+ : task_runner_(task_runner),
+ target_nssdb_(target_nssdb),
+ weak_factory_(this) {
CHECK(target_nssdb);
}
-bool CertificateImporterImpl::ImportCertificates(
+CertificateImporterImpl::~CertificateImporterImpl() {
+}
+
+void CertificateImporterImpl::ImportCertificates(
const base::ListValue& certificates,
::onc::ONCSource source,
- net::CertificateList* onc_trusted_certificates) {
+ const DoneCallback& done_callback) {
VLOG(2) << "ONC file has " << certificates.GetSize() << " certificates";
+ DoneCallback callback_on_origin_loop =
+ base::Bind(&CallBackOnOriginLoop,
+ base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&CertificateImporterImpl::RunDoneCallback,
+ weak_factory_.GetWeakPtr(),
+ done_callback));
+
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&ParseAndStoreCertificates,
+ source,
+ callback_on_origin_loop,
+ base::Owned(certificates.DeepCopy()),
+ target_nssdb_));
Joao da Silva 2014/09/15 12:38:24 This is essentially PostTaskAndReply, can you use
pneubeck (no reviews) 2014/09/17 12:44:21 Indeed, in this case something like PostTaskAndRe
+}
+// static
+void CertificateImporterImpl::ParseAndStoreCertificates(
+ ::onc::ONCSource source,
+ const DoneCallback& done_callback,
+ base::ListValue* certificates,
+ net::NSSCertDatabase* nssdb) {
// Web trust is only granted to certificates imported by the user.
bool allow_trust_imports = source == ::onc::ONC_SOURCE_USER_IMPORT;
- if (!ParseAndStoreCertificates(allow_trust_imports,
- certificates,
- onc_trusted_certificates,
- NULL)) {
- LOG(ERROR) << "Cannot parse some of the certificates in the ONC from "
- << onc::GetSourceAsString(source);
- return false;
- }
- return true;
-}
-
-bool CertificateImporterImpl::ParseAndStoreCertificates(
- bool allow_trust_imports,
- const base::ListValue& certificates,
- net::CertificateList* onc_trusted_certificates,
- CertsByGUID* imported_server_and_ca_certs) {
+ net::CertificateList onc_trusted_certificates;
bool success = true;
- for (size_t i = 0; i < certificates.GetSize(); ++i) {
+ for (size_t i = 0; i < certificates->GetSize(); ++i) {
const base::DictionaryValue* certificate = NULL;
- certificates.GetDictionary(i, &certificate);
+ certificates->GetDictionary(i, &certificate);
DCHECK(certificate != NULL);
VLOG(2) << "Parsing certificate at index " << i << ": " << *certificate;
if (!ParseAndStoreCertificate(allow_trust_imports,
*certificate,
- onc_trusted_certificates,
- imported_server_and_ca_certs)) {
+ nssdb,
+ &onc_trusted_certificates)) {
success = false;
- ONC_LOG_ERROR(
- base::StringPrintf("Cannot parse certificate at index %zu", i));
+ LOG(ERROR) << "Cannot parse certificate at index " << i;
} else {
VLOG(2) << "Successfully imported certificate at index " << i;
}
}
- return success;
+
+ done_callback.Run(success, onc_trusted_certificates);
}
// static
@@ -143,11 +169,20 @@ bool CertificateImporterImpl::DeleteCertAndKeyByNickname(
return result;
}
+void CertificateImporterImpl::RunDoneCallback(
+ const CertificateImporter::DoneCallback& callback,
+ bool success,
+ const net::CertificateList& onc_trusted_certificates) {
+ if (!success)
+ NET_LOG_ERROR("ONC Certificate Import Error", "");
+ callback.Run(success, onc_trusted_certificates);
+}
+
bool CertificateImporterImpl::ParseAndStoreCertificate(
bool allow_trust_imports,
const base::DictionaryValue& certificate,
- net::CertificateList* onc_trusted_certificates,
- CertsByGUID* imported_server_and_ca_certs) {
+ net::NSSCertDatabase* nssdb,
+ net::CertificateList* onc_trusted_certificates) {
// Get out the attributes of the given certificate.
std::string guid;
certificate.GetStringWithoutPathExpansion(::onc::certificate::kGUID, &guid);
@@ -156,8 +191,8 @@ bool CertificateImporterImpl::ParseAndStoreCertificate(
bool remove = false;
if (certificate.GetBooleanWithoutPathExpansion(::onc::kRemove, &remove) &&
remove) {
- if (!DeleteCertAndKeyByNickname(guid, target_nssdb_)) {
- ONC_LOG_ERROR("Unable to delete certificate");
+ if (!DeleteCertAndKeyByNickname(guid, nssdb)) {
+ LOG(ERROR) << "Unable to delete certificate";
return false;
} else {
return true;
@@ -174,10 +209,10 @@ bool CertificateImporterImpl::ParseAndStoreCertificate(
cert_type,
guid,
certificate,
- onc_trusted_certificates,
- imported_server_and_ca_certs);
+ nssdb,
+ onc_trusted_certificates);
} else if (cert_type == ::onc::certificate::kClient) {
- return ParseClientCertificate(guid, certificate);
+ return ParseClientCertificate(guid, certificate, nssdb);
}
NOTREACHED();
@@ -189,8 +224,8 @@ bool CertificateImporterImpl::ParseServerOrCaCertificate(
const std::string& cert_type,
const std::string& guid,
const base::DictionaryValue& certificate,
- net::CertificateList* onc_trusted_certificates,
- CertsByGUID* imported_server_and_ca_certs) {
+ net::NSSCertDatabase* nssdb,
+ net::CertificateList* onc_trusted_certificates) {
bool web_trust_flag = false;
const base::ListValue* trust_list = NULL;
if (certificate.GetListWithoutPathExpansion(::onc::certificate::kTrustBits,
@@ -208,8 +243,8 @@ bool CertificateImporterImpl::ParseServerOrCaCertificate(
} else {
// Trust bits should only increase trust and never restrict. Thus,
// ignoring unknown bits should be safe.
- ONC_LOG_WARNING("Certificate contains unknown trust type " +
- trust_type);
+ LOG(WARNING) << "Certificate contains unknown trust type "
+ << trust_type;
}
}
}
@@ -217,7 +252,7 @@ bool CertificateImporterImpl::ParseServerOrCaCertificate(
bool import_with_ssl_trust = false;
if (web_trust_flag) {
if (!allow_trust_imports)
- ONC_LOG_WARNING("Web trust not granted for certificate: " + guid);
+ LOG(WARNING) << "Web trust not granted for certificate: " << guid;
else
import_with_ssl_trust = true;
}
@@ -226,17 +261,16 @@ bool CertificateImporterImpl::ParseServerOrCaCertificate(
if (!certificate.GetStringWithoutPathExpansion(::onc::certificate::kX509,
&x509_data) ||
x509_data.empty()) {
- ONC_LOG_ERROR(
- "Certificate missing appropriate certificate data for type: " +
- cert_type);
+ LOG(ERROR) << "Certificate missing appropriate certificate data for type: "
+ << cert_type;
return false;
}
scoped_refptr<net::X509Certificate> x509_cert =
DecodePEMCertificate(x509_data);
if (!x509_cert.get()) {
- ONC_LOG_ERROR("Unable to create certificate from PEM encoding, type: " +
- cert_type);
+ LOG(ERROR) << "Unable to create certificate from PEM encoding, type: "
+ << cert_type;
return false;
}
@@ -250,21 +284,19 @@ bool CertificateImporterImpl::ParseServerOrCaCertificate(
: net::CA_CERT;
VLOG(1) << "Certificate is already installed.";
net::NSSCertDatabase::TrustBits missing_trust_bits =
- trust & ~target_nssdb_->GetCertTrust(x509_cert.get(), net_cert_type);
+ trust & ~nssdb->GetCertTrust(x509_cert.get(), net_cert_type);
if (missing_trust_bits) {
std::string error_reason;
bool success = false;
- if (target_nssdb_->IsReadOnly(x509_cert.get())) {
+ if (nssdb->IsReadOnly(x509_cert.get())) {
error_reason = " Certificate is stored read-only.";
} else {
- success = target_nssdb_->SetCertTrust(x509_cert.get(),
- net_cert_type,
- trust);
+ success = nssdb->SetCertTrust(x509_cert.get(), net_cert_type, trust);
}
if (!success) {
- ONC_LOG_ERROR("Certificate of type " + cert_type +
- " was already present, but trust couldn't be set." +
- error_reason);
+ LOG(ERROR) << "Certificate of type " << cert_type
+ << " was already present, but trust couldn't be set."
+ << error_reason;
}
}
} else {
@@ -273,21 +305,19 @@ bool CertificateImporterImpl::ParseServerOrCaCertificate(
net::NSSCertDatabase::ImportCertFailureList failures;
bool success = false;
if (cert_type == ::onc::certificate::kServer)
- success = target_nssdb_->ImportServerCert(cert_list, trust, &failures);
+ success = nssdb->ImportServerCert(cert_list, trust, &failures);
else // Authority cert
- success = target_nssdb_->ImportCACerts(cert_list, trust, &failures);
+ success = nssdb->ImportCACerts(cert_list, trust, &failures);
if (!failures.empty()) {
std::string error_string = net::ErrorToString(failures[0].net_error);
- ONC_LOG_ERROR(
- base::StringPrintf("Error ( %s ) importing %s certificate",
- error_string.c_str(),
- cert_type.c_str()));
+ LOG(ERROR) << "Error ( " << error_string
+ << " ) importing certificate of type " << cert_type;
return false;
}
if (!success) {
- ONC_LOG_ERROR("Unknown error importing " + cert_type + " certificate.");
+ LOG(ERROR) << "Unknown error importing " << cert_type << " certificate.";
return false;
}
}
@@ -295,56 +325,53 @@ bool CertificateImporterImpl::ParseServerOrCaCertificate(
if (web_trust_flag && onc_trusted_certificates)
onc_trusted_certificates->push_back(x509_cert);
- if (imported_server_and_ca_certs)
- (*imported_server_and_ca_certs)[guid] = x509_cert;
-
return true;
}
bool CertificateImporterImpl::ParseClientCertificate(
const std::string& guid,
- const base::DictionaryValue& certificate) {
+ const base::DictionaryValue& certificate,
+ net::NSSCertDatabase* nssdb) {
std::string pkcs12_data;
if (!certificate.GetStringWithoutPathExpansion(::onc::certificate::kPKCS12,
&pkcs12_data) ||
pkcs12_data.empty()) {
- ONC_LOG_ERROR("PKCS12 data is missing for client certificate.");
+ LOG(ERROR) << "PKCS12 data is missing for client certificate.";
return false;
}
std::string decoded_pkcs12;
if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) {
- ONC_LOG_ERROR(
- "Unable to base64 decode PKCS#12 data: \"" + pkcs12_data + "\".");
+ LOG(ERROR) << "Unable to base64 decode PKCS#12 data: \"" << pkcs12_data
+ << "\".";
return false;
}
// Since this has a private key, always use the private module.
- crypto::ScopedPK11Slot private_slot(target_nssdb_->GetPrivateSlot());
+ crypto::ScopedPK11Slot private_slot(nssdb->GetPrivateSlot());
if (!private_slot)
return false;
scoped_refptr<net::CryptoModule> module(
net::CryptoModule::CreateFromHandle(private_slot.get()));
net::CertificateList imported_certs;
- int import_result = target_nssdb_->ImportFromPKCS12(
+ int import_result = nssdb->ImportFromPKCS12(
module.get(), decoded_pkcs12, base::string16(), false, &imported_certs);
if (import_result != net::OK) {
std::string error_string = net::ErrorToString(import_result);
- ONC_LOG_ERROR(
- base::StringPrintf("Unable to import client certificate (error %s)",
- error_string.c_str()));
+ LOG(ERROR) << "Unable to import client certificate, error: "
+ << error_string;
return false;
}
if (imported_certs.size() == 0) {
- ONC_LOG_WARNING("PKCS12 data contains no importable certificates.");
+ LOG(WARNING) << "PKCS12 data contains no importable certificates.";
return true;
}
if (imported_certs.size() != 1) {
- ONC_LOG_WARNING("ONC File: PKCS12 data contains more than one certificate. "
- "Only the first one will be imported.");
+ LOG(WARNING) << "ONC File: PKCS12 data contains more than one certificate. "
+ "Only the first one will be imported.";
}
scoped_refptr<net::X509Certificate> cert_result = imported_certs[0];
@@ -359,7 +386,7 @@ bool CertificateImporterImpl::ParseClientCertificate(
PK11_SetPrivateKeyNickname(private_key, const_cast<char*>(guid.c_str()));
SECKEY_DestroyPrivateKey(private_key);
} else {
- ONC_LOG_WARNING("Unable to find private key for certificate.");
+ LOG(WARNING) << "Unable to find private key for certificate.";
}
return true;
}

Powered by Google App Engine
This is Rietveld 408576698