Index: net/base/nss_cert_database.cc |
diff --git a/net/base/nss_cert_database.cc b/net/base/nss_cert_database.cc |
deleted file mode 100644 |
index 1cfb212a4f6bfd4eadfb1b8127dde306c10a6b83..0000000000000000000000000000000000000000 |
--- a/net/base/nss_cert_database.cc |
+++ /dev/null |
@@ -1,344 +0,0 @@ |
-// Copyright (c) 2012 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 "net/base/nss_cert_database.h" |
- |
-#include <cert.h> |
-#include <certdb.h> |
-#include <keyhi.h> |
-#include <pk11pub.h> |
-#include <secmod.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" |
-#include "net/base/cert_database.h" |
-#include "net/base/crypto_module.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/x509_certificate.h" |
-#include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h" |
-#include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h" |
- |
-// In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use |
-// the new name of the macro. |
-#if !defined(CERTDB_TERMINAL_RECORD) |
-#define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER |
-#endif |
- |
-// PSM = Mozilla's Personal Security Manager. |
-namespace psm = mozilla_security_manager; |
- |
-namespace net { |
- |
-NSSCertDatabase::ImportCertFailure::ImportCertFailure( |
- X509Certificate* cert, int err) |
- : certificate(cert), |
- net_error(err) {} |
- |
-NSSCertDatabase::ImportCertFailure::~ImportCertFailure() {} |
- |
-// static |
-NSSCertDatabase* NSSCertDatabase::GetInstance() { |
- return Singleton<NSSCertDatabase>::get(); |
-} |
- |
-NSSCertDatabase::NSSCertDatabase() |
- : observer_list_(new ObserverListThreadSafe<Observer>) { |
- crypto::EnsureNSSInit(); |
- psm::EnsurePKCS12Init(); |
-} |
- |
-NSSCertDatabase::~NSSCertDatabase() {} |
- |
-void NSSCertDatabase::ListCerts(CertificateList* certs) { |
- certs->clear(); |
- |
- CERTCertList* cert_list = PK11_ListCerts(PK11CertListUnique, NULL); |
- CERTCertListNode* node; |
- for (node = CERT_LIST_HEAD(cert_list); |
- !CERT_LIST_END(node, cert_list); |
- node = CERT_LIST_NEXT(node)) { |
- certs->push_back(X509Certificate::CreateFromHandle( |
- node->cert, X509Certificate::OSCertHandles())); |
- } |
- CERT_DestroyCertList(cert_list); |
-} |
- |
-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()); |
- |
- 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()); |
- |
- return module; |
-} |
- |
-void NSSCertDatabase::ListModules(CryptoModuleList* modules, |
- bool need_rw) const { |
- modules->clear(); |
- |
- PK11SlotList* slot_list = NULL; |
- // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc. |
- slot_list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, |
- need_rw ? PR_TRUE : PR_FALSE, // needRW |
- PR_TRUE, // loadCerts (unused) |
- NULL); // wincx |
- if (!slot_list) { |
- LOG(ERROR) << "PK11_GetAllTokens failed: " << PORT_GetError(); |
- return; |
- } |
- |
- PK11SlotListElement* slot_element = PK11_GetFirstSafe(slot_list); |
- while (slot_element) { |
- modules->push_back(CryptoModule::CreateFromHandle(slot_element->slot)); |
- slot_element = PK11_GetNextSafe(slot_list, slot_element, |
- PR_FALSE); // restart |
- } |
- |
- PK11_FreeSlotList(slot_list); |
-} |
- |
-int NSSCertDatabase::ImportFromPKCS12( |
- CryptoModule* module, |
- const std::string& data, |
- const base::string16& password, |
- bool is_extractable, |
- net::CertificateList* imported_certs) { |
- int result = psm::nsPKCS12Blob_Import(module->os_module_handle(), |
- data.data(), data.size(), |
- password, |
- is_extractable, |
- imported_certs); |
- if (result == net::OK) |
- NotifyObserversOfCertAdded(NULL); |
- |
- return result; |
-} |
- |
-int NSSCertDatabase::ExportToPKCS12( |
- const CertificateList& certs, |
- const base::string16& password, |
- std::string* output) const { |
- return psm::nsPKCS12Blob_Export(output, certs, password); |
-} |
- |
-X509Certificate* NSSCertDatabase::FindRootInList( |
- const CertificateList& certificates) const { |
- DCHECK_GT(certificates.size(), 0U); |
- |
- if (certificates.size() == 1) |
- return certificates[0].get(); |
- |
- X509Certificate* cert0 = certificates[0]; |
- X509Certificate* cert1 = certificates[1]; |
- X509Certificate* certn_2 = certificates[certificates.size() - 2]; |
- X509Certificate* certn_1 = certificates[certificates.size() - 1]; |
- |
- if (CERT_CompareName(&cert1->os_cert_handle()->issuer, |
- &cert0->os_cert_handle()->subject) == SECEqual) |
- return cert0; |
- if (CERT_CompareName(&certn_2->os_cert_handle()->issuer, |
- &certn_1->os_cert_handle()->subject) == SECEqual) |
- return certn_1; |
- |
- VLOG(1) << "certificate list is not a hierarchy"; |
- return cert0; |
-} |
- |
-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); |
- if (success) |
- NotifyObserversOfCertTrustChanged(NULL); |
- |
- return success; |
-} |
- |
-bool NSSCertDatabase::ImportServerCert(const CertificateList& certificates, |
- TrustBits trust_bits, |
- ImportCertFailureList* not_imported) { |
- return psm::ImportServerCert(certificates, trust_bits, not_imported); |
-} |
- |
-NSSCertDatabase::TrustBits NSSCertDatabase::GetCertTrust( |
- const X509Certificate* cert, |
- CertType type) const { |
- CERTCertTrust trust; |
- SECStatus srv = CERT_GetCertTrust(cert->os_cert_handle(), &trust); |
- if (srv != SECSuccess) { |
- LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError(); |
- return TRUST_DEFAULT; |
- } |
- // We define our own more "friendly" TrustBits, which means we aren't able to |
- // round-trip all possible NSS trust flag combinations. We try to map them in |
- // a sensible way. |
- switch (type) { |
- case CA_CERT: { |
- const unsigned kTrustedCA = CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; |
- const unsigned kCAFlags = kTrustedCA | CERTDB_TERMINAL_RECORD; |
- |
- TrustBits trust_bits = TRUST_DEFAULT; |
- if ((trust.sslFlags & kCAFlags) == CERTDB_TERMINAL_RECORD) |
- trust_bits |= DISTRUSTED_SSL; |
- else if (trust.sslFlags & kTrustedCA) |
- trust_bits |= TRUSTED_SSL; |
- |
- if ((trust.emailFlags & kCAFlags) == CERTDB_TERMINAL_RECORD) |
- trust_bits |= DISTRUSTED_EMAIL; |
- else if (trust.emailFlags & kTrustedCA) |
- trust_bits |= TRUSTED_EMAIL; |
- |
- if ((trust.objectSigningFlags & kCAFlags) == CERTDB_TERMINAL_RECORD) |
- trust_bits |= DISTRUSTED_OBJ_SIGN; |
- else if (trust.objectSigningFlags & kTrustedCA) |
- trust_bits |= TRUSTED_OBJ_SIGN; |
- |
- return trust_bits; |
- } |
- case SERVER_CERT: |
- if (trust.sslFlags & CERTDB_TERMINAL_RECORD) { |
- if (trust.sslFlags & CERTDB_TRUSTED) |
- return TRUSTED_SSL; |
- return DISTRUSTED_SSL; |
- } |
- return TRUST_DEFAULT; |
- default: |
- return TRUST_DEFAULT; |
- } |
-} |
- |
-bool NSSCertDatabase::IsUntrusted(const X509Certificate* cert) const { |
- CERTCertTrust nsstrust; |
- SECStatus rv = CERT_GetCertTrust(cert->os_cert_handle(), &nsstrust); |
- if (rv != SECSuccess) { |
- LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError(); |
- return false; |
- } |
- |
- // The CERTCertTrust structure contains three trust records: |
- // sslFlags, emailFlags, and objectSigningFlags. The three |
- // trust records are independent of each other. |
- // |
- // If the CERTDB_TERMINAL_RECORD bit in a trust record is set, |
- // then that trust record is a terminal record. A terminal |
- // record is used for explicit trust and distrust of an |
- // end-entity or intermediate CA cert. |
- // |
- // In a terminal record, if neither CERTDB_TRUSTED_CA nor |
- // CERTDB_TRUSTED is set, then the terminal record means |
- // explicit distrust. On the other hand, if the terminal |
- // record has either CERTDB_TRUSTED_CA or CERTDB_TRUSTED bit |
- // set, then the terminal record means explicit trust. |
- // |
- // For a root CA, the trust record does not have |
- // the CERTDB_TERMINAL_RECORD bit set. |
- |
- static const unsigned int kTrusted = CERTDB_TRUSTED_CA | CERTDB_TRUSTED; |
- if ((nsstrust.sslFlags & CERTDB_TERMINAL_RECORD) != 0 && |
- (nsstrust.sslFlags & kTrusted) == 0) { |
- return true; |
- } |
- if ((nsstrust.emailFlags & CERTDB_TERMINAL_RECORD) != 0 && |
- (nsstrust.emailFlags & kTrusted) == 0) { |
- return true; |
- } |
- if ((nsstrust.objectSigningFlags & CERTDB_TERMINAL_RECORD) != 0 && |
- (nsstrust.objectSigningFlags & kTrusted) == 0) { |
- return true; |
- } |
- |
- // Self-signed certificates that don't have any trust bits set are untrusted. |
- // Other certificates that don't have any trust bits set may still be trusted |
- // if they chain up to a trust anchor. |
- if (CERT_CompareName(&cert->os_cert_handle()->issuer, |
- &cert->os_cert_handle()->subject) == SECEqual) { |
- return (nsstrust.sslFlags & kTrusted) == 0 && |
- (nsstrust.emailFlags & kTrusted) == 0 && |
- (nsstrust.objectSigningFlags & kTrusted) == 0; |
- } |
- |
- return false; |
-} |
- |
-bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert, |
- CertType type, |
- TrustBits trust_bits) { |
- bool success = psm::SetCertTrust(cert, type, trust_bits); |
- if (success) |
- NotifyObserversOfCertTrustChanged(cert); |
- |
- return success; |
-} |
- |
-bool NSSCertDatabase::DeleteCertAndKey(const X509Certificate* cert) { |
- // For some reason, PK11_DeleteTokenCertAndKey only calls |
- // SEC_DeletePermCertificate if the private key is found. So, we check |
- // whether a private key exists before deciding which function to call to |
- // delete the cert. |
- SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert->os_cert_handle(), |
- NULL); |
- if (privKey) { |
- SECKEY_DestroyPrivateKey(privKey); |
- if (PK11_DeleteTokenCertAndKey(cert->os_cert_handle(), NULL)) { |
- LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError(); |
- return false; |
- } |
- } else { |
- if (SEC_DeletePermCertificate(cert->os_cert_handle())) { |
- LOG(ERROR) << "SEC_DeletePermCertificate failed: " << PORT_GetError(); |
- return false; |
- } |
- } |
- |
- NotifyObserversOfCertRemoved(cert); |
- |
- return true; |
-} |
- |
-bool NSSCertDatabase::IsReadOnly(const X509Certificate* cert) const { |
- PK11SlotInfo* slot = cert->os_cert_handle()->slot; |
- return slot && PK11_IsReadOnly(slot); |
-} |
- |
-void NSSCertDatabase::AddObserver(Observer* observer) { |
- observer_list_->AddObserver(observer); |
-} |
- |
-void NSSCertDatabase::RemoveObserver(Observer* observer) { |
- observer_list_->RemoveObserver(observer); |
-} |
- |
-void NSSCertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) { |
- observer_list_->Notify(&Observer::OnCertAdded, make_scoped_refptr(cert)); |
-} |
- |
-void NSSCertDatabase::NotifyObserversOfCertRemoved( |
- const X509Certificate* cert) { |
- observer_list_->Notify(&Observer::OnCertRemoved, make_scoped_refptr(cert)); |
-} |
- |
-void NSSCertDatabase::NotifyObserversOfCertTrustChanged( |
- const X509Certificate* cert) { |
- observer_list_->Notify( |
- &Observer::OnCertTrustChanged, make_scoped_refptr(cert)); |
-} |
- |
-} // namespace net |