Commit ad90e72d authored by Omar Morsi's avatar Omar Morsi Committed by Commit Bot

Support functions usage without NSSCertDB instance

Some NSS Certificate Database functions that return information about
certificates are expensive and should not be called on the UI thread.
This CL is part of the effort of normalizing the way of gathering this
certificates information to make sure it is gathered on a worker thread.
To call these functions on a worker thread, they should not depend on
NSSCertDatabase instances, so if the instances goes out of scope, the
code does not run into undefined behaviour.

In this CL some NSS Certificate Database functions that does not depend
on database instances are converted to static to be able to use them
safely inside worker threads.

1- net_unittests --gtest_filter=NSSCertDatabase*
2- unittests --gtest_filter=CertificateManagerModel*

Bug: chromium:1043083, chromium:1012430
Test: 
Change-Id: I63a1157c5d92b44f8d5252e9475104a1adfa8376
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2054090Reviewed-by: default avatarRyan Sleevi <rsleevi@chromium.org>
Reviewed-by: default avatarMatt Mueller <mattm@chromium.org>
Reviewed-by: default avatarPavol Marko <pmarko@chromium.org>
Commit-Queue: Omar Morsi <omorsi@google.com>
Cr-Commit-Position: refs/heads/master@{#743023}
parent 1b1e6dfe
...@@ -232,13 +232,17 @@ class CertsSourcePlatformNSS : public CertificateManagerModel::CertsSource { ...@@ -232,13 +232,17 @@ class CertsSourcePlatformNSS : public CertificateManagerModel::CertsSource {
cert_infos.reserve(certs.size()); cert_infos.reserve(certs.size());
for (auto& cert : certs) { for (auto& cert : certs) {
net::CertType type = x509_certificate_model::GetType(cert.get()); net::CertType type = x509_certificate_model::GetType(cert.get());
bool can_be_deleted = !cert_db_->IsReadOnly(cert.get()); bool can_be_deleted = !net::NSSCertDatabase::IsReadOnly(cert.get());
bool untrusted = cert_db_->IsUntrusted(cert.get()); bool untrusted = net::NSSCertDatabase::IsUntrusted(cert.get());
bool hardware_backed = cert_db_->IsHardwareBacked(cert.get()); bool hardware_backed = net::NSSCertDatabase::IsHardwareBacked(cert.get());
bool web_trust_anchor = cert_db_->IsWebTrustAnchor(cert.get()); bool web_trust_anchor =
net::NSSCertDatabase::IsWebTrustAnchor(cert.get());
bool device_wide = false; bool device_wide = false;
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
device_wide = cert_db_->IsCertificateOnSystemSlot(cert.get());
device_wide = net::NSSCertDatabase::IsCertificateOnSlot(
/*cert=*/cert.get(),
/*slot=*/cert_db_->GetSystemSlot().get());
#endif #endif
base::string16 name = GetName(cert.get(), hardware_backed); base::string16 name = GetName(cert.get(), hardware_backed);
cert_infos.push_back(std::make_unique<CertificateManagerModel::CertInfo>( cert_infos.push_back(std::make_unique<CertificateManagerModel::CertInfo>(
......
...@@ -108,13 +108,13 @@ crypto::ScopedPK11Slot NSSCertDatabase::GetSystemSlot() const { ...@@ -108,13 +108,13 @@ crypto::ScopedPK11Slot NSSCertDatabase::GetSystemSlot() const {
return crypto::ScopedPK11Slot(); return crypto::ScopedPK11Slot();
} }
bool NSSCertDatabase::IsCertificateOnSystemSlot(CERTCertificate* cert) const { // static
crypto::ScopedPK11Slot system_slot = GetSystemSlot(); bool NSSCertDatabase::IsCertificateOnSlot(CERTCertificate* cert,
if (!system_slot) PK11SlotInfo* slot) {
if (!slot)
return false; return false;
return PK11_FindCertInSlot(system_slot.get(), cert, nullptr) != return PK11_FindCertInSlot(slot, cert, nullptr) != CK_INVALID_HANDLE;
CK_INVALID_HANDLE;
} }
#endif #endif
...@@ -299,7 +299,37 @@ NSSCertDatabase::TrustBits NSSCertDatabase::GetCertTrust( ...@@ -299,7 +299,37 @@ NSSCertDatabase::TrustBits NSSCertDatabase::GetCertTrust(
} }
} }
bool NSSCertDatabase::IsUntrusted(const CERTCertificate* cert) const { bool NSSCertDatabase::SetCertTrust(CERTCertificate* cert,
CertType type,
TrustBits trust_bits) {
bool success = psm::SetCertTrust(cert, type, trust_bits);
if (success)
NotifyObserversCertDBChanged();
return success;
}
bool NSSCertDatabase::DeleteCertAndKey(CERTCertificate* cert) {
if (!DeleteCertAndKeyImpl(cert))
return false;
NotifyObserversCertDBChanged();
return true;
}
void NSSCertDatabase::DeleteCertAndKeyAsync(ScopedCERTCertificate cert,
DeleteCertCallback callback) {
base::PostTaskAndReplyWithResult(
FROM_HERE,
{base::ThreadPool(), base::MayBlock(),
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&NSSCertDatabase::DeleteCertAndKeyImplScoped,
std::move(cert)),
base::BindOnce(&NSSCertDatabase::NotifyCertRemovalAndCallBack,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
// static
bool NSSCertDatabase::IsUntrusted(const CERTCertificate* cert) {
CERTCertTrust nsstrust; CERTCertTrust nsstrust;
SECStatus rv = CERT_GetCertTrust(cert, &nsstrust); SECStatus rv = CERT_GetCertTrust(cert, &nsstrust);
if (rv != SECSuccess) { if (rv != SECSuccess) {
...@@ -351,7 +381,8 @@ bool NSSCertDatabase::IsUntrusted(const CERTCertificate* cert) const { ...@@ -351,7 +381,8 @@ bool NSSCertDatabase::IsUntrusted(const CERTCertificate* cert) const {
return false; return false;
} }
bool NSSCertDatabase::IsWebTrustAnchor(const CERTCertificate* cert) const { // static
bool NSSCertDatabase::IsWebTrustAnchor(const CERTCertificate* cert) {
CERTCertTrust nsstrust; CERTCertTrust nsstrust;
SECStatus rv = CERT_GetCertTrust(cert, &nsstrust); SECStatus rv = CERT_GetCertTrust(cert, &nsstrust);
if (rv != SECSuccess) { if (rv != SECSuccess) {
...@@ -371,41 +402,14 @@ bool NSSCertDatabase::IsWebTrustAnchor(const CERTCertificate* cert) const { ...@@ -371,41 +402,14 @@ bool NSSCertDatabase::IsWebTrustAnchor(const CERTCertificate* cert) const {
return false; return false;
} }
bool NSSCertDatabase::SetCertTrust(CERTCertificate* cert, // static
CertType type, bool NSSCertDatabase::IsReadOnly(const CERTCertificate* cert) {
TrustBits trust_bits) {
bool success = psm::SetCertTrust(cert, type, trust_bits);
if (success)
NotifyObserversCertDBChanged();
return success;
}
bool NSSCertDatabase::DeleteCertAndKey(CERTCertificate* cert) {
if (!DeleteCertAndKeyImpl(cert))
return false;
NotifyObserversCertDBChanged();
return true;
}
void NSSCertDatabase::DeleteCertAndKeyAsync(ScopedCERTCertificate cert,
DeleteCertCallback callback) {
base::PostTaskAndReplyWithResult(
FROM_HERE,
{base::ThreadPool(), base::MayBlock(),
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&NSSCertDatabase::DeleteCertAndKeyImplScoped,
std::move(cert)),
base::BindOnce(&NSSCertDatabase::NotifyCertRemovalAndCallBack,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
bool NSSCertDatabase::IsReadOnly(const CERTCertificate* cert) const {
PK11SlotInfo* slot = cert->slot; PK11SlotInfo* slot = cert->slot;
return slot && PK11_IsReadOnly(slot); return slot && PK11_IsReadOnly(slot);
} }
bool NSSCertDatabase::IsHardwareBacked(const CERTCertificate* cert) const { // static
bool NSSCertDatabase::IsHardwareBacked(const CERTCertificate* cert) {
PK11SlotInfo* slot = cert->slot; PK11SlotInfo* slot = cert->slot;
return slot && PK11_IsHW(slot); return slot && PK11_IsHW(slot);
} }
......
...@@ -127,9 +127,8 @@ class NET_EXPORT NSSCertDatabase { ...@@ -127,9 +127,8 @@ class NET_EXPORT NSSCertDatabase {
// See https://crbug.com/399554 . // See https://crbug.com/399554 .
virtual crypto::ScopedPK11Slot GetSystemSlot() const; virtual crypto::ScopedPK11Slot GetSystemSlot() const;
// Check whether the certificate is stored on the system slot (i.e. is a // Checks whether |cert| is stored on |slot|.
// device certificate). static bool IsCertificateOnSlot(CERTCertificate* cert, PK11SlotInfo* slot);
bool IsCertificateOnSystemSlot(CERTCertificate* cert) const;
#endif #endif
// Get the default slot for public key data. // Get the default slot for public key data.
...@@ -204,15 +203,6 @@ class NET_EXPORT NSSCertDatabase { ...@@ -204,15 +203,6 @@ class NET_EXPORT NSSCertDatabase {
// Get trust bits for certificate. // Get trust bits for certificate.
TrustBits GetCertTrust(const CERTCertificate* cert, CertType type) const; TrustBits GetCertTrust(const CERTCertificate* cert, CertType type) const;
// IsUntrusted returns true if |cert| is specifically untrusted. These
// certificates are stored in the database for the specific purpose of
// rejecting them.
bool IsUntrusted(const CERTCertificate* cert) const;
// IsWebTrustAnchor returns true if |cert| is explicitly trusted for web
// navigations according to the trust bits stored in the database.
bool IsWebTrustAnchor(const CERTCertificate* cert) const;
// Set trust values for certificate. // Set trust values for certificate.
// Returns true on success or false on failure. // Returns true on success or false on failure.
bool SetCertTrust(CERTCertificate* cert, CertType type, TrustBits trust_bits); bool SetCertTrust(CERTCertificate* cert, CertType type, TrustBits trust_bits);
...@@ -228,11 +218,20 @@ class NET_EXPORT NSSCertDatabase { ...@@ -228,11 +218,20 @@ class NET_EXPORT NSSCertDatabase {
void DeleteCertAndKeyAsync(ScopedCERTCertificate cert, void DeleteCertAndKeyAsync(ScopedCERTCertificate cert,
DeleteCertCallback callback); DeleteCertCallback callback);
// IsUntrusted returns true if |cert| is specifically untrusted. These
// certificates are stored in the database for the specific purpose of
// rejecting them.
static bool IsUntrusted(const CERTCertificate* cert);
// IsWebTrustAnchor returns true if |cert| is explicitly trusted for web
// navigations according to the trust bits stored in the database.
static bool IsWebTrustAnchor(const CERTCertificate* cert);
// Check whether cert is stored in a readonly slot. // Check whether cert is stored in a readonly slot.
bool IsReadOnly(const CERTCertificate* cert) const; static bool IsReadOnly(const CERTCertificate* cert);
// Check whether cert is stored in a hardware slot. // Check whether cert is stored in a hardware slot.
bool IsHardwareBacked(const CERTCertificate* cert) const; static bool IsHardwareBacked(const CERTCertificate* cert);
protected: protected:
// Certificate listing implementation used by |ListCerts*|. Static so it may // Certificate listing implementation used by |ListCerts*|. Static so it may
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment