| Index: net/cert/nss_cert_database.cc
|
| diff --git a/net/cert/nss_cert_database.cc b/net/cert/nss_cert_database.cc
|
| index 9c2a3f1ffc50e2ec278c88a2a74c90bced2b44b8..8984d5902815449448593cd8c93b5856c27b8a7c 100644
|
| --- a/net/cert/nss_cert_database.cc
|
| +++ b/net/cert/nss_cert_database.cc
|
| @@ -10,9 +10,9 @@
|
| #include <pk11pub.h>
|
| #include <secmod.h>
|
|
|
| +#include "base/lazy_instance.h"
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| -#include "base/memory/singleton.h"
|
| #include "base/observer_list_threadsafe.h"
|
| #include "crypto/nss_util.h"
|
| #include "crypto/nss_util_internal.h"
|
| @@ -35,6 +35,12 @@ namespace psm = mozilla_security_manager;
|
|
|
| namespace net {
|
|
|
| +namespace {
|
| +base::LazyInstance<NSSCertDatabase>::Leaky
|
| + g_nss_cert_database = LAZY_INSTANCE_INITIALIZER;
|
| +} // namespace
|
| +
|
| +
|
| NSSCertDatabase::ImportCertFailure::ImportCertFailure(
|
| const scoped_refptr<X509Certificate>& cert,
|
| int err)
|
| @@ -42,15 +48,55 @@ NSSCertDatabase::ImportCertFailure::ImportCertFailure(
|
|
|
| NSSCertDatabase::ImportCertFailure::~ImportCertFailure() {}
|
|
|
| +// Helper that observes events from a CertDatabaseSource and forwards them to
|
| +// the given CertDatabase.
|
| +class NSSCertDatabase::Notifier : public CertDatabaseSource::Observer {
|
| + public:
|
| + Notifier(NSSCertDatabase* cert_db) : cert_db_(cert_db) {}
|
| +
|
| + virtual ~Notifier() {}
|
| +
|
| + // CertDatabaseSource::Observer implementation:
|
| + virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE {
|
| + cert_db_->NotifyObserversOfCertAdded(cert);
|
| + }
|
| +
|
| + virtual void OnCertRemoved(const X509Certificate* cert) OVERRIDE {
|
| + cert_db_->NotifyObserversOfCertRemoved(cert);
|
| + }
|
| +
|
| + virtual void OnCACertChanged(const X509Certificate* cert) OVERRIDE {
|
| + cert_db_->NotifyObserversOfCACertChanged(cert);
|
| + }
|
| +
|
| + private:
|
| + NSSCertDatabase* cert_db_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Notifier);
|
| +};
|
| +
|
| +// static
|
| +NSSCertDatabase* NSSCertDatabase::GetInstanceNoWarn() {
|
| + return &g_nss_cert_database.Get();
|
| + //return Singleton<NSSCertDatabase,
|
| + // LeakySingletonTraits<NSSCertDatabase> >::get();
|
| +}
|
| +
|
| // static
|
| NSSCertDatabase* NSSCertDatabase::GetInstance() {
|
| - return Singleton<NSSCertDatabase,
|
| - LeakySingletonTraits<NSSCertDatabase> >::get();
|
| +#if defined(OS_CHROMEOS)
|
| + LOG(WARNING) << "Using global NSSCertDatabase. Consider using "
|
| + << "NSSCertDatabaseChromeOS::GetForUser instead.";
|
| +#endif
|
| + return NSSCertDatabase::GetInstanceNoWarn();
|
| }
|
|
|
| NSSCertDatabase::NSSCertDatabase()
|
| - : observer_list_(new ObserverListThreadSafe<Observer>) {
|
| - crypto::EnsureNSSInit();
|
| + : observer_list_(new ObserverListThreadSafe<Observer>),
|
| + notifier_(new Notifier(this)) {
|
| + // This also makes sure that NSS has been initialized.
|
| + CertDatabase::GetInstance()->AddSource(this);
|
| +
|
| psm::EnsurePKCS12Init();
|
| }
|
|
|
| @@ -71,25 +117,27 @@ void NSSCertDatabase::ListCerts(CertificateList* certs) {
|
| }
|
|
|
| CryptoModule* NSSCertDatabase::GetPublicModule() const {
|
| - CryptoModule* module =
|
| - CryptoModule::CreateFromHandle(crypto::GetPublicNSSKeySlot());
|
| - // The module is already referenced when returned from
|
| - // GetPublicNSSKeySlot, so we need to deref it once.
|
| - PK11_FreeSlot(module->os_module_handle());
|
| + crypto::ScopedPK11Slot slot(GetPublicSlot());
|
| + CryptoModule* module = CryptoModule::CreateFromHandle(slot.get());
|
|
|
| return module;
|
| }
|
|
|
| CryptoModule* NSSCertDatabase::GetPrivateModule() const {
|
| - CryptoModule* module =
|
| - CryptoModule::CreateFromHandle(crypto::GetPrivateNSSKeySlot());
|
| - // The module is already referenced when returned from
|
| - // GetPrivateNSSKeySlot, so we need to deref it once.
|
| - PK11_FreeSlot(module->os_module_handle());
|
| + crypto::ScopedPK11Slot slot(GetPrivateSlot());
|
| + CryptoModule* module = CryptoModule::CreateFromHandle(slot.get());
|
|
|
| return module;
|
| }
|
|
|
| +crypto::ScopedPK11Slot NSSCertDatabase::GetPublicSlot() const {
|
| + return crypto::ScopedPK11Slot(crypto::GetPublicNSSKeySlot());
|
| +}
|
| +
|
| +crypto::ScopedPK11Slot NSSCertDatabase::GetPrivateSlot() const {
|
| + return crypto::ScopedPK11Slot(crypto::GetPrivateNSSKeySlot());
|
| +}
|
| +
|
| void NSSCertDatabase::ListModules(CryptoModuleList* modules,
|
| bool need_rw) const {
|
| modules->clear();
|
| @@ -119,6 +167,9 @@ int NSSCertDatabase::ImportFromPKCS12(
|
| const base::string16& password,
|
| bool is_extractable,
|
| net::CertificateList* imported_certs) {
|
| + DVLOG(1) << __func__ << " "
|
| + << PK11_GetModuleID(module->os_module_handle()) << ":"
|
| + << PK11_GetSlotID(module->os_module_handle());
|
| int result = psm::nsPKCS12Blob_Import(module->os_module_handle(),
|
| data.data(), data.size(),
|
| password,
|
| @@ -156,7 +207,7 @@ X509Certificate* NSSCertDatabase::FindRootInList(
|
| &certn_1->os_cert_handle()->subject) == SECEqual)
|
| return certn_1;
|
|
|
| - VLOG(1) << "certificate list is not a hierarchy";
|
| + DVLOG(1) << "certificate list is not a hierarchy";
|
| return cert0;
|
| }
|
|
|
| @@ -164,8 +215,12 @@ bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates,
|
| TrustBits trust_bits,
|
| ImportCertFailureList* not_imported) {
|
| X509Certificate* root = FindRootInList(certificates);
|
| - bool success = psm::ImportCACerts(certificates, root, trust_bits,
|
| - not_imported);
|
| + bool success = psm::ImportCACerts(
|
| + GetPublicSlot(),
|
| + certificates,
|
| + root,
|
| + trust_bits,
|
| + not_imported);
|
| if (success)
|
| NotifyObserversOfCACertChanged(NULL);
|
|
|
| @@ -175,7 +230,11 @@ bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates,
|
| bool NSSCertDatabase::ImportServerCert(const CertificateList& certificates,
|
| TrustBits trust_bits,
|
| ImportCertFailureList* not_imported) {
|
| - return psm::ImportServerCert(certificates, trust_bits, not_imported);
|
| + return psm::ImportServerCert(
|
| + GetPublicSlot(),
|
| + certificates,
|
| + trust_bits,
|
| + not_imported);
|
| }
|
|
|
| NSSCertDatabase::TrustBits NSSCertDatabase::GetCertTrust(
|
| @@ -331,6 +390,10 @@ void NSSCertDatabase::RemoveObserver(Observer* observer) {
|
| observer_list_->RemoveObserver(observer);
|
| }
|
|
|
| +void NSSCertDatabase::AddSource(CertDatabaseSource* source) {
|
| + source->AddObserver(this->notifier_.get());
|
| +}
|
| +
|
| void NSSCertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) {
|
| observer_list_->Notify(&Observer::OnCertAdded, make_scoped_refptr(cert));
|
| }
|
|
|