diff options
author | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-10 14:11:07 +0000 |
---|---|---|
committer | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-10 14:11:07 +0000 |
commit | 7fda9a408391ef66ba65bdb734bdcce28e624930 (patch) | |
tree | 02d274a5c4aa0b1fa338058eda4e00191b9608d0 | |
parent | 92c20da406d882936b345122545fd7b295fce91f (diff) | |
download | chromium_src-7fda9a408391ef66ba65bdb734bdcce28e624930.zip chromium_src-7fda9a408391ef66ba65bdb734bdcce28e624930.tar.gz chromium_src-7fda9a408391ef66ba65bdb734bdcce28e624930.tar.bz2 |
Move the NSS functions out of CertDatabase into a new NSSCertDatabase class.
BUG=chromium-os:33872
Review URL: https://chromiumcodereview.appspot.com/10916094
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@155720 0039d316-1c4b-4281-b951-d872f2087c98
37 files changed, 961 insertions, 807 deletions
diff --git a/chrome/browser/certificate_manager_model.cc b/chrome/browser/certificate_manager_model.cc index e44a0b6..9d4f2d2 100644 --- a/chrome/browser/certificate_manager_model.cc +++ b/chrome/browser/certificate_manager_model.cc @@ -23,7 +23,8 @@ #endif CertificateManagerModel::CertificateManagerModel(Observer* observer) - : observer_(observer) { + : cert_db_(net::NSSCertDatabase::GetInstance()), + observer_(observer) { } CertificateManagerModel::~CertificateManagerModel() { @@ -32,7 +33,7 @@ CertificateManagerModel::~CertificateManagerModel() { void CertificateManagerModel::Refresh() { VLOG(1) << "refresh started"; net::CryptoModuleList modules; - cert_db_.ListModules(&modules, false); + cert_db_->ListModules(&modules, false); VLOG(1) << "refresh waiting for unlocking..."; browser::UnlockSlotsIfNecessary( modules, @@ -44,7 +45,7 @@ void CertificateManagerModel::Refresh() { void CertificateManagerModel::RefreshSlotsUnlocked() { VLOG(1) << "refresh listing certs..."; - cert_db_.ListCerts(&cert_list_); + cert_db_->ListCerts(&cert_list_); observer_->CertificatesRefreshed(); VLOG(1) << "refresh finished"; } @@ -112,8 +113,8 @@ int CertificateManagerModel::ImportFromPKCS12(net::CryptoModule* module, const std::string& data, const string16& password, bool is_extractable) { - int result = cert_db_.ImportFromPKCS12(module, data, password, - is_extractable, NULL); + int result = cert_db_->ImportFromPKCS12(module, data, password, + is_extractable, NULL); if (result == net::OK) Refresh(); return result; @@ -121,9 +122,9 @@ int CertificateManagerModel::ImportFromPKCS12(net::CryptoModule* module, bool CertificateManagerModel::ImportCACerts( const net::CertificateList& certificates, - net::CertDatabase::TrustBits trust_bits, - net::CertDatabase::ImportCertFailureList* not_imported) { - bool result = cert_db_.ImportCACerts(certificates, trust_bits, not_imported); + net::NSSCertDatabase::TrustBits trust_bits, + net::NSSCertDatabase::ImportCertFailureList* not_imported) { + bool result = cert_db_->ImportCACerts(certificates, trust_bits, not_imported); if (result && not_imported->size() != certificates.size()) Refresh(); return result; @@ -131,10 +132,10 @@ bool CertificateManagerModel::ImportCACerts( bool CertificateManagerModel::ImportServerCert( const net::CertificateList& certificates, - net::CertDatabase::TrustBits trust_bits, - net::CertDatabase::ImportCertFailureList* not_imported) { - bool result = cert_db_.ImportServerCert(certificates, trust_bits, - not_imported); + net::NSSCertDatabase::TrustBits trust_bits, + net::NSSCertDatabase::ImportCertFailureList* not_imported) { + bool result = cert_db_->ImportServerCert(certificates, trust_bits, + not_imported); if (result && not_imported->size() != certificates.size()) Refresh(); return result; @@ -143,12 +144,12 @@ bool CertificateManagerModel::ImportServerCert( bool CertificateManagerModel::SetCertTrust( const net::X509Certificate* cert, net::CertType type, - net::CertDatabase::TrustBits trust_bits) { - return cert_db_.SetCertTrust(cert, type, trust_bits); + net::NSSCertDatabase::TrustBits trust_bits) { + return cert_db_->SetCertTrust(cert, type, trust_bits); } bool CertificateManagerModel::Delete(net::X509Certificate* cert) { - bool result = cert_db_.DeleteCertAndKey(cert); + bool result = cert_db_->DeleteCertAndKey(cert); if (result) Refresh(); return result; @@ -159,7 +160,7 @@ bool CertificateManagerModel::IsHardwareBacked( #if defined(OS_CHROMEOS) return crypto::IsTPMTokenReady() && cert->os_cert_handle()->slot == - cert_db().GetPrivateModule()->os_module_handle(); + cert_db_->GetPrivateModule()->os_module_handle(); #else return false; #endif diff --git a/chrome/browser/certificate_manager_model.h b/chrome/browser/certificate_manager_model.h index b111aa2..6e21f67 100644 --- a/chrome/browser/certificate_manager_model.h +++ b/chrome/browser/certificate_manager_model.h @@ -10,7 +10,7 @@ #include "base/memory/ref_counted.h" #include "base/string16.h" -#include "net/base/cert_database.h" +#include "net/base/nss_cert_database.h" // CertificateManagerModel provides the data to be displayed in the certificate // manager dialog, and processes changes from the view. @@ -40,8 +40,8 @@ class CertificateManagerModel { explicit CertificateManagerModel(Observer* observer); ~CertificateManagerModel(); - // Accessor for read-only access to the underlying CertDatabase. - const net::CertDatabase& cert_db() const { return cert_db_; } + // Accessor for read-only access to the underlying NSSCertDatabase. + const net::NSSCertDatabase* cert_db() const { return cert_db_; } // Trigger a refresh of the list of certs, unlock any slots if necessary. // Following this call, the observer CertificatesRefreshed method will be @@ -67,13 +67,13 @@ class CertificateManagerModel { // Tries to import all the certificates given. The root will be trusted // according to |trust_bits|. Any certificates that could not be imported // will be listed in |not_imported|. - // |trust_bits| should be a bit field of TRUST* values from CertDatabase. + // |trust_bits| should be a bit field of TRUST* values from NSSCertDatabase. // Returns false if there is an internal error, otherwise true is returned and // |not_imported| should be checked for any certificates that were not // imported. bool ImportCACerts(const net::CertificateList& certificates, - net::CertDatabase::TrustBits trust_bits, - net::CertDatabase::ImportCertFailureList* not_imported); + net::NSSCertDatabase::TrustBits trust_bits, + net::NSSCertDatabase::ImportCertFailureList* not_imported); // Import server certificate. The first cert should be the server cert. Any // additional certs should be intermediate/CA certs and will be imported but @@ -87,15 +87,15 @@ class CertificateManagerModel { // imported. bool ImportServerCert( const net::CertificateList& certificates, - net::CertDatabase::TrustBits trust_bits, - net::CertDatabase::ImportCertFailureList* not_imported); + net::NSSCertDatabase::TrustBits trust_bits, + net::NSSCertDatabase::ImportCertFailureList* not_imported); // Set trust values for certificate. - // |trust_bits| should be a bit field of TRUST* values from CertDatabase. + // |trust_bits| should be a bit field of TRUST* values from NSSCertDatabase. // Returns true on success or false on failure. bool SetCertTrust(const net::X509Certificate* cert, net::CertType type, - net::CertDatabase::TrustBits trust_bits); + net::NSSCertDatabase::TrustBits trust_bits); // Delete the cert. Returns true on success. |cert| is still valid when this // function returns. @@ -111,7 +111,7 @@ class CertificateManagerModel { // This method does the actual refreshing. void RefreshSlotsUnlocked(); - net::CertDatabase cert_db_; + net::NSSCertDatabase* cert_db_; net::CertificateList cert_list_; // The observer to notify when certificate list is refreshed. diff --git a/chrome/browser/chromeos/cros/cert_library.cc b/chrome/browser/chromeos/cros/cert_library.cc index ea9ff68..111da9e 100644 --- a/chrome/browser/chromeos/cros/cert_library.cc +++ b/chrome/browser/chromeos/cros/cert_library.cc @@ -28,6 +28,7 @@ #include "crypto/symmetric_key.h" #include "grit/generated_resources.h" #include "net/base/cert_database.h" +#include "net/base/nss_cert_database.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_collator.h" #include "unicode/coll.h" // icu::Collator @@ -128,12 +129,12 @@ class CertLibraryImpl ALLOW_THIS_IN_INITIALIZER_LIST(server_ca_certs_(this)), ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - net::CertDatabase::AddObserver(this); + net::CertDatabase::GetInstance()->AddObserver(this); } ~CertLibraryImpl() { DCHECK(request_task_.is_null()); - net::CertDatabase::RemoveObserver(this); + net::CertDatabase::GetInstance()->RemoveObserver(this); } // CertLibrary implementation. @@ -242,7 +243,7 @@ class CertLibraryImpl CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); } - virtual void OnUserCertAdded(const net::X509Certificate* cert) OVERRIDE { + virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // Only load certificates if we have completed an initial request. if (certificates_loaded_) { @@ -253,7 +254,7 @@ class CertLibraryImpl } } - virtual void OnUserCertRemoved(const net::X509Certificate* cert) OVERRIDE { + virtual void OnCertRemoved(const net::X509Certificate* cert) OVERRIDE { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // Only load certificates if we have completed an initial request. if (certificates_loaded_) { @@ -273,9 +274,8 @@ class CertLibraryImpl VLOG(1) << " Loading Certificates."; // Certificate fetch occurs on the DB thread. CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - net::CertDatabase cert_db; net::CertificateList* cert_list = new net::CertificateList(); - cert_db.ListCerts(cert_list); + net::NSSCertDatabase::GetInstance()->ListCerts(cert_list); // Pass the list to the UI thread to safely update the local lists. BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, diff --git a/chrome/browser/chromeos/cros/cert_library.h b/chrome/browser/chromeos/cros/cert_library.h index bbc760b..da360e7 100644 --- a/chrome/browser/chromeos/cros/cert_library.h +++ b/chrome/browser/chromeos/cros/cert_library.h @@ -8,7 +8,6 @@ #include <string> #include "base/string16.h" -#include "net/base/cert_database.h" #include "net/base/x509_certificate.h" namespace crypto { diff --git a/chrome/browser/chromeos/cros/certificate_pattern.cc b/chrome/browser/chromeos/cros/certificate_pattern.cc index 72f6e01..df1e28a 100644 --- a/chrome/browser/chromeos/cros/certificate_pattern.cc +++ b/chrome/browser/chromeos/cros/certificate_pattern.cc @@ -16,6 +16,7 @@ #include "base/values.h" #include "net/base/cert_database.h" #include "net/base/net_errors.h" +#include "net/base/nss_cert_database.h" #include "net/base/x509_cert_types.h" #include "net/base/x509_certificate.h" @@ -110,7 +111,7 @@ class IssuerCaRefFilter { bool operator()(const scoped_refptr<net::X509Certificate>& cert) const { // Find the certificate issuer for each certificate. // TODO(gspencer): this functionality should be available from - // X509Certificate or CertDatabase. + // X509Certificate or NSSCertDatabase. CERTCertificate* issuer_cert = CERT_FindCertIssuer( cert.get()->os_cert_handle(), PR_Now(), certUsageAnyCA); @@ -244,8 +245,7 @@ scoped_refptr<net::X509Certificate> CertificatePattern::GetMatch() const { // Start with all the certs, and narrow it down from there. net::CertificateList all_certs; CertificateStlList matching_certs; - net::CertDatabase cert_db; - cert_db.ListCerts(&all_certs); + net::NSSCertDatabase::GetInstance()->ListCerts(&all_certs); if (all_certs.empty()) return NULL; @@ -278,7 +278,7 @@ scoped_refptr<net::X509Certificate> CertificatePattern::GetMatch() const { // them. The CheckUserCert call in the filter is a little slow (because of // underlying PKCS11 calls), so we do this last to reduce the number of times // we have to call it. - PrivateKeyFilter private_filter(&cert_db); + PrivateKeyFilter private_filter(net::CertDatabase::GetInstance()); matching_certs.remove_if(private_filter); if (matching_certs.empty()) diff --git a/chrome/browser/chromeos/cros/network_library_unittest.cc b/chrome/browser/chromeos/cros/network_library_unittest.cc index 74635cc..751e22c 100644 --- a/chrome/browser/chromeos/cros/network_library_unittest.cc +++ b/chrome/browser/chromeos/cros/network_library_unittest.cc @@ -19,8 +19,8 @@ #include "chrome/browser/chromeos/cros/onc_network_parser.h" #include "chrome/common/chrome_paths.h" #include "crypto/nss_util.h" -#include "net/base/cert_database.h" #include "net/base/crypto_module.h" +#include "net/base/nss_cert_database.h" #include "net/base/x509_certificate.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -152,7 +152,7 @@ class NetworkLibraryStubTest : public testing::Test { protected: virtual void SetUp() { - slot_ = cert_db_.GetPublicModule(); + slot_ = net::NSSCertDatabase::GetInstance()->GetPublicModule(); cros_ = CrosLibrary::Get()->GetNetworkLibrary(); ASSERT_TRUE(cros_) << "GetNetworkLibrary() Failed!"; @@ -200,13 +200,12 @@ class NetworkLibraryStubTest : public testing::Test { bool ok = true; net::CertificateList certs = ListCertsInSlot(slot); for (size_t i = 0; i < certs.size(); ++i) { - if (!cert_db_.DeleteCertAndKey(certs[i])) + if (!net::NSSCertDatabase::GetInstance()->DeleteCertAndKey(certs[i])) ok = false; } return ok; } - net::CertDatabase cert_db_; scoped_refptr<net::CryptoModule> slot_; }; diff --git a/chrome/browser/chromeos/cros/onc_network_parser.cc b/chrome/browser/chromeos/cros/onc_network_parser.cc index 25dea7f..86083ee 100644 --- a/chrome/browser/chromeos/cros/onc_network_parser.cc +++ b/chrome/browser/chromeos/cros/onc_network_parser.cc @@ -28,9 +28,9 @@ #include "crypto/scoped_nss_types.h" #include "crypto/symmetric_key.h" #include "grit/generated_resources.h" -#include "net/base/cert_database.h" #include "net/base/crypto_module.h" #include "net/base/net_errors.h" +#include "net/base/nss_cert_database.h" #include "net/base/pem_tokenizer.h" #include "net/base/x509_certificate.h" #include "net/proxy/proxy_bypass_rules.h" @@ -526,7 +526,6 @@ scoped_refptr<net::X509Certificate> OncNetworkParser::ParseCertificate( if (!certificate->GetBoolean("Remove", &remove)) remove = false; - net::CertDatabase cert_database; if (remove) { if (!DeleteCertAndKeyByNickname(guid)) { parse_error_ = l10n_util::GetStringUTF8( @@ -930,9 +929,9 @@ OncNetworkParser::ParseServerOrCaCertificate( // TODO(mnissler, gspencer): We should probably switch to a mode where we // keep our own database for mapping GUIDs to certs in order to enable several // GUIDs to map to the same cert. See http://crosbug.com/26073. - net::CertDatabase cert_database; + net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance(); if (x509_cert->os_cert_handle()->isperm) { - if (!cert_database.DeleteCertAndKey(x509_cert.get())) { + if (!cert_database->DeleteCertAndKey(x509_cert.get())) { parse_error_ = l10n_util::GetStringUTF8( IDS_NETWORK_CONFIG_ERROR_CERT_DELETE); return NULL; @@ -967,15 +966,15 @@ OncNetworkParser::ParseServerOrCaCertificate( net::CertificateList cert_list; cert_list.push_back(x509_cert); - net::CertDatabase::ImportCertFailureList failures; + net::NSSCertDatabase::ImportCertFailureList failures; bool success = false; - net::CertDatabase::TrustBits trust = web_trust ? - net::CertDatabase::TRUSTED_SSL : - net::CertDatabase::TRUST_DEFAULT; + net::NSSCertDatabase::TrustBits trust = web_trust ? + net::NSSCertDatabase::TRUSTED_SSL : + net::NSSCertDatabase::TRUST_DEFAULT; if (cert_type == "Server") { - success = cert_database.ImportServerCert(cert_list, trust, &failures); + success = cert_database->ImportServerCert(cert_list, trust, &failures); } else { // Authority cert - success = cert_database.ImportCACerts(cert_list, trust, &failures); + success = cert_database->ImportCACerts(cert_list, trust, &failures); } if (!failures.empty()) { LOG(WARNING) << "ONC File: Error (" @@ -1003,7 +1002,6 @@ scoped_refptr<net::X509Certificate> OncNetworkParser::ParseClientCertificate( int cert_index, const std::string& guid, base::DictionaryValue* certificate) { - net::CertDatabase cert_database; std::string pkcs12_data; if (!certificate->GetString("PKCS12", &pkcs12_data) || pkcs12_data.empty()) { @@ -1024,10 +1022,11 @@ scoped_refptr<net::X509Certificate> OncNetworkParser::ParseClientCertificate( } // Since this has a private key, always use the private module. - scoped_refptr<net::CryptoModule> module(cert_database.GetPrivateModule()); + net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance(); + scoped_refptr<net::CryptoModule> module(cert_database->GetPrivateModule()); net::CertificateList imported_certs; - int result = cert_database.ImportFromPKCS12( + int result = cert_database->ImportFromPKCS12( module.get(), decoded_pkcs12, string16(), false, &imported_certs); if (result != net::OK) { LOG(WARNING) << "ONC File: Unable to import Client certificate at index " @@ -1088,8 +1087,7 @@ ClientCertType OncNetworkParser::ParseClientCertType( void OncNetworkParser::ListCertsWithNickname(const std::string& label, net::CertificateList* result) { net::CertificateList all_certs; - net::CertDatabase cert_db; - cert_db.ListCerts(&all_certs); + net::NSSCertDatabase::GetInstance()->ListCerts(&all_certs); result->clear(); for (net::CertificateList::iterator iter = all_certs.begin(); iter != all_certs.end(); ++iter) { @@ -1127,7 +1125,6 @@ void OncNetworkParser::ListCertsWithNickname(const std::string& label, bool OncNetworkParser::DeleteCertAndKeyByNickname(const std::string& label) { net::CertificateList cert_list; ListCertsWithNickname(label, &cert_list); - net::CertDatabase cert_db; bool result = true; for (net::CertificateList::iterator iter = cert_list.begin(); iter != cert_list.end(); ++iter) { @@ -1138,7 +1135,7 @@ bool OncNetworkParser::DeleteCertAndKeyByNickname(const std::string& label) { // label, and the cert not being found is one of the few reasons the // delete could fail, but still... The other choice is to return // failure immediately, but that doesn't seem to do what is intended. - if (!cert_db.DeleteCertAndKey(iter->get())) + if (!net::NSSCertDatabase::GetInstance()->DeleteCertAndKey(iter->get())) result = false; } return result; diff --git a/chrome/browser/chromeos/cros/onc_network_parser.h b/chrome/browser/chromeos/cros/onc_network_parser.h index f6502c0..1b558ec 100644 --- a/chrome/browser/chromeos/cros/onc_network_parser.h +++ b/chrome/browser/chromeos/cros/onc_network_parser.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_CROS_ONC_NETWORK_PARSER_H_ #include <string> +#include <vector> #include "base/compiler_specific.h" // for OVERRIDE #include "base/gtest_prod_util.h" diff --git a/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc b/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc index 86914f9..664a1ab 100644 --- a/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc +++ b/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc @@ -28,9 +28,9 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "content/public/test/test_browser_thread.h" #include "crypto/nss_util.h" -#include "net/base/cert_database.h" #include "net/base/cert_type.h" #include "net/base/crypto_module.h" +#include "net/base/nss_cert_database.h" #include "net/base/x509_certificate.h" #include "net/proxy/proxy_config.h" #include "testing/gtest/include/gtest/gtest.h" @@ -67,7 +67,7 @@ class OncNetworkParserTest : public testing::Test { } virtual void SetUp() { - slot_ = cert_db_.GetPublicModule(); + slot_ = net::NSSCertDatabase::GetInstance()->GetPublicModule(); // Don't run the test if the setup failed. ASSERT_TRUE(slot_->os_module_handle()); @@ -108,7 +108,6 @@ class OncNetworkParserTest : public testing::Test { protected: scoped_refptr<net::CryptoModule> slot_; - net::CertDatabase cert_db_; private: net::CertificateList ListCertsInSlot(PK11SlotInfo* slot) { @@ -131,7 +130,7 @@ class OncNetworkParserTest : public testing::Test { bool ok = true; net::CertificateList certs = ListCertsInSlot(slot); for (size_t i = 0; i < certs.size(); ++i) { - if (!cert_db_.DeleteCertAndKey(certs[i])) + if (!net::NSSCertDatabase::GetInstance()->DeleteCertAndKey(certs[i])) ok = false; } return ok; diff --git a/chrome/browser/chromeos/enrollment_dialog_view.h b/chrome/browser/chromeos/enrollment_dialog_view.h index 6ba08ad..130ef60 100644 --- a/chrome/browser/chromeos/enrollment_dialog_view.h +++ b/chrome/browser/chromeos/enrollment_dialog_view.h @@ -5,9 +5,8 @@ #ifndef CHROME_BROWSER_CHROMEOS_ENROLLMENT_DIALOG_VIEW_H_ #define CHROME_BROWSER_CHROMEOS_ENROLLMENT_DIALOG_VIEW_H_ -#include "base/callback.h" -#include "googleurl/src/gurl.h" -#include "net/base/cert_database.h" +#include <string> + #include "ui/gfx/native_widget_types.h" #include "ui/views/window/dialog_delegate.h" diff --git a/chrome/browser/chromeos/options/vpn_config_view.cc b/chrome/browser/chromeos/options/vpn_config_view.cc index 6a95150..e468c72 100644 --- a/chrome/browser/chromeos/options/vpn_config_view.cc +++ b/chrome/browser/chromeos/options/vpn_config_view.cc @@ -16,8 +16,6 @@ #include "grit/generated_resources.h" #include "grit/locale_settings.h" #include "grit/theme_resources.h" -#include "net/base/cert_database.h" -#include "net/base/x509_certificate.h" #include "ui/base/events/event.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/combobox_model.h" diff --git a/chrome/browser/ssl/ssl_add_cert_handler.cc b/chrome/browser/ssl/ssl_add_cert_handler.cc index 4cae2d4..07ce962 100644 --- a/chrome/browser/ssl/ssl_add_cert_handler.cc +++ b/chrome/browser/ssl/ssl_add_cert_handler.cc @@ -39,11 +39,7 @@ SSLAddCertHandler::SSLAddCertHandler(net::URLRequest* request, SSLAddCertHandler::~SSLAddCertHandler() {} void SSLAddCertHandler::Run() { - int cert_error; - { - net::CertDatabase db; - cert_error = db.CheckUserCert(cert_); - } + int cert_error = net::CertDatabase::GetInstance()->CheckUserCert(cert_); if (cert_error != net::OK) { LOG_IF(ERROR, cert_error == net::ERR_NO_PRIVATE_KEY_FOR_CERT) << "No corresponding private key in store for cert: " @@ -74,10 +70,8 @@ void SSLAddCertHandler::AskToAddCert() { void SSLAddCertHandler::Finished(bool add_cert) { int cert_error = net::OK; - if (add_cert) { - net::CertDatabase db; - cert_error = db.AddUserCert(cert_); - } + if (add_cert) + cert_error = net::CertDatabase::GetInstance()->AddUserCert(cert_); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, diff --git a/chrome/browser/ui/webui/options/certificate_manager_handler.cc b/chrome/browser/ui/webui/options/certificate_manager_handler.cc index 85d6d0f..5902af7 100644 --- a/chrome/browser/ui/webui/options/certificate_manager_handler.cc +++ b/chrome/browser/ui/webui/options/certificate_manager_handler.cc @@ -525,14 +525,14 @@ void CertificateManagerHandler::GetCATrust(const ListValue* args) { return; } - net::CertDatabase::TrustBits trust_bits = - certificate_manager_model_->cert_db().GetCertTrust(cert, net::CA_CERT); + net::NSSCertDatabase::TrustBits trust_bits = + certificate_manager_model_->cert_db()->GetCertTrust(cert, net::CA_CERT); base::FundamentalValue ssl_value( - static_cast<bool>(trust_bits & net::CertDatabase::TRUSTED_SSL)); + static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_SSL)); base::FundamentalValue email_value( - static_cast<bool>(trust_bits & net::CertDatabase::TRUSTED_EMAIL)); + static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_EMAIL)); base::FundamentalValue obj_sign_value( - static_cast<bool>(trust_bits & net::CertDatabase::TRUSTED_OBJ_SIGN)); + static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_OBJ_SIGN)); web_ui()->CallJavascriptFunction( "CertificateEditCaTrustOverlay.populateTrust", ssl_value, email_value, obj_sign_value); @@ -556,9 +556,9 @@ void CertificateManagerHandler::EditCATrust(const ListValue* args) { bool result = certificate_manager_model_->SetCertTrust( cert, net::CA_CERT, - trust_ssl * net::CertDatabase::TRUSTED_SSL + - trust_email * net::CertDatabase::TRUSTED_EMAIL + - trust_obj_sign * net::CertDatabase::TRUSTED_OBJ_SIGN); + trust_ssl * net::NSSCertDatabase::TRUSTED_SSL + + trust_email * net::NSSCertDatabase::TRUSTED_EMAIL + + trust_obj_sign * net::NSSCertDatabase::TRUSTED_OBJ_SIGN); web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss"); if (!result) { // TODO(mattm): better error messages? @@ -629,7 +629,7 @@ void CertificateManagerHandler::ExportPersonalPasswordSelected( void CertificateManagerHandler::ExportPersonalSlotsUnlocked() { std::string output; - int num_exported = certificate_manager_model_->cert_db().ExportToPKCS12( + int num_exported = certificate_manager_model_->cert_db()->ExportToPKCS12( selected_cert_list_, password_, &output); @@ -720,9 +720,9 @@ void CertificateManagerHandler::ImportPersonalFileRead( file_data_ = data; if (use_hardware_backed_) { - module_ = certificate_manager_model_->cert_db().GetPrivateModule(); + module_ = certificate_manager_model_->cert_db()->GetPrivateModule(); } else { - module_ = certificate_manager_model_->cert_db().GetPublicModule(); + module_ = certificate_manager_model_->cert_db()->GetPublicModule(); } net::CryptoModuleList modules; @@ -833,11 +833,11 @@ void CertificateManagerHandler::ImportServerFileRead(int read_errno, return; } - net::CertDatabase::ImportCertFailureList not_imported; + net::NSSCertDatabase::ImportCertFailureList not_imported; // TODO(mattm): Add UI for trust. http://crbug.com/76274 bool result = certificate_manager_model_->ImportServerCert( selected_cert_list_, - net::CertDatabase::TRUST_DEFAULT, + net::NSSCertDatabase::TRUST_DEFAULT, ¬_imported); if (!result) { ShowError( @@ -892,7 +892,8 @@ void CertificateManagerHandler::ImportCAFileRead(int read_errno, } scoped_refptr<net::X509Certificate> root_cert = - certificate_manager_model_->cert_db().FindRootInList(selected_cert_list_); + certificate_manager_model_->cert_db()->FindRootInList( + selected_cert_list_); // TODO(mattm): check here if root_cert is not a CA cert and show error. @@ -918,12 +919,12 @@ void CertificateManagerHandler::ImportCATrustSelected(const ListValue* args) { // TODO(mattm): add UI for setting explicit distrust, too. // http://crbug.com/128411 - net::CertDatabase::ImportCertFailureList not_imported; + net::NSSCertDatabase::ImportCertFailureList not_imported; bool result = certificate_manager_model_->ImportCACerts( selected_cert_list_, - trust_ssl * net::CertDatabase::TRUSTED_SSL + - trust_email * net::CertDatabase::TRUSTED_EMAIL + - trust_obj_sign * net::CertDatabase::TRUSTED_OBJ_SIGN, + trust_ssl * net::NSSCertDatabase::TRUSTED_SSL + + trust_email * net::NSSCertDatabase::TRUSTED_EMAIL + + trust_obj_sign * net::NSSCertDatabase::TRUSTED_OBJ_SIGN, ¬_imported); web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss"); if (!result) { @@ -1000,10 +1001,10 @@ void CertificateManagerHandler::PopulateTree(const std::string& tab_name, *cert, CertificateManagerModel::COL_SUBJECT_NAME)); cert_dict->SetBoolean( kReadOnlyId, - certificate_manager_model_->cert_db().IsReadOnly(cert)); + certificate_manager_model_->cert_db()->IsReadOnly(cert)); cert_dict->SetBoolean( kUntrustedId, - certificate_manager_model_->cert_db().IsUntrusted(cert)); + certificate_manager_model_->cert_db()->IsUntrusted(cert)); // TODO(hshi): This should be determined by testing for PKCS #11 // CKA_EXTRACTABLE attribute. We may need to use the NSS function // PK11_ReadRawAttribute to do that. @@ -1041,7 +1042,7 @@ void CertificateManagerHandler::ShowError(const std::string& title, void CertificateManagerHandler::ShowImportErrors( const std::string& title, - const net::CertDatabase::ImportCertFailureList& not_imported) const { + const net::NSSCertDatabase::ImportCertFailureList& not_imported) const { std::string error; if (selected_cert_list_.size() == 1) error = l10n_util::GetStringUTF8( @@ -1053,7 +1054,7 @@ void CertificateManagerHandler::ShowImportErrors( ListValue cert_error_list; for (size_t i = 0; i < not_imported.size(); ++i) { - const net::CertDatabase::ImportCertFailure& failure = not_imported[i]; + const net::NSSCertDatabase::ImportCertFailure& failure = not_imported[i]; DictionaryValue* dict = new DictionaryValue; dict->SetString(kNameId, failure.certificate->subject().GetDisplayName()); dict->SetString(kErrorId, NetErrorToString(failure.net_error)); diff --git a/chrome/browser/ui/webui/options/certificate_manager_handler.h b/chrome/browser/ui/webui/options/certificate_manager_handler.h index 4489771..be12ad5 100644 --- a/chrome/browser/ui/webui/options/certificate_manager_handler.h +++ b/chrome/browser/ui/webui/options/certificate_manager_handler.h @@ -13,7 +13,7 @@ #include "chrome/browser/cancelable_request.h" #include "chrome/browser/certificate_manager_model.h" #include "chrome/browser/ui/webui/options/options_ui.h" -#include "net/base/cert_database.h" +#include "net/base/nss_cert_database.h" #include "ui/base/dialogs/select_file_dialog.h" #include "ui/gfx/native_widget_types.h" @@ -146,7 +146,7 @@ class CertificateManagerHandler // attempted to import. void ShowImportErrors( const std::string& title, - const net::CertDatabase::ImportCertFailureList& not_imported) const; + const net::NSSCertDatabase::ImportCertFailureList& not_imported) const; #if defined(OS_CHROMEOS) // Check whether Tpm token is ready and notifiy JS side. diff --git a/chrome/common/net/x509_certificate_model.h b/chrome/common/net/x509_certificate_model.h index f748996..6c4e31c 100644 --- a/chrome/common/net/x509_certificate_model.h +++ b/chrome/common/net/x509_certificate_model.h @@ -5,7 +5,6 @@ #ifndef CHROME_COMMON_NET_X509_CERTIFICATE_MODEL_H_ #define CHROME_COMMON_NET_X509_CERTIFICATE_MODEL_H_ -#include "net/base/cert_database.h" #include "net/base/cert_type.h" #include "net/base/x509_certificate.h" diff --git a/chrome/common/net/x509_certificate_model_unittest.cc b/chrome/common/net/x509_certificate_model_unittest.cc index 929185f..6140841b 100644 --- a/chrome/common/net/x509_certificate_model_unittest.cc +++ b/chrome/common/net/x509_certificate_model_unittest.cc @@ -7,8 +7,8 @@ #include "base/file_path.h" #include "base/file_util.h" #include "base/path_service.h" -#include "net/base/cert_database.h" #include "net/base/cert_test_util.h" +#include "net/base/nss_cert_database.h" #include "testing/gtest/include/gtest/gtest.h" TEST(X509CertificateModelTest, GetTypeCA) { @@ -27,9 +27,8 @@ TEST(X509CertificateModelTest, GetTypeCA) { // Test that explicitly distrusted CA certs are still returned as CA_CERT // type. See http://crbug.com/96654. - net::CertDatabase cert_db; - EXPECT_TRUE(cert_db.SetCertTrust(cert, net::CA_CERT, - net::CertDatabase::DISTRUSTED_SSL)); + EXPECT_TRUE(net::NSSCertDatabase::GetInstance()->SetCertTrust( + cert, net::CA_CERT, net::NSSCertDatabase::DISTRUSTED_SSL)); EXPECT_EQ(net::CA_CERT, x509_certificate_model::GetType(cert->os_cert_handle())); @@ -54,17 +53,17 @@ TEST(X509CertificateModelTest, GetTypeServer) { EXPECT_EQ(net::UNKNOWN_CERT, x509_certificate_model::GetType(cert->os_cert_handle())); - net::CertDatabase cert_db; + net::NSSCertDatabase* cert_db = net::NSSCertDatabase::GetInstance(); // Test GetCertType with server certs and explicit trust. - EXPECT_TRUE(cert_db.SetCertTrust(cert, net::SERVER_CERT, - net::CertDatabase::TRUSTED_SSL)); + EXPECT_TRUE(cert_db->SetCertTrust( + cert, net::SERVER_CERT, net::NSSCertDatabase::TRUSTED_SSL)); EXPECT_EQ(net::SERVER_CERT, x509_certificate_model::GetType(cert->os_cert_handle())); // Test GetCertType with server certs and explicit distrust. - EXPECT_TRUE(cert_db.SetCertTrust(cert, net::SERVER_CERT, - net::CertDatabase::DISTRUSTED_SSL)); + EXPECT_TRUE(cert_db->SetCertTrust( + cert, net::SERVER_CERT, net::NSSCertDatabase::DISTRUSTED_SSL)); EXPECT_EQ(net::SERVER_CERT, x509_certificate_model::GetType(cert->os_cert_handle())); diff --git a/net/base/cert_database.cc b/net/base/cert_database.cc index 7930750..8d7475c 100644 --- a/net/base/cert_database.cc +++ b/net/base/cert_database.cc @@ -7,59 +7,81 @@ #include "base/memory/singleton.h" #include "base/observer_list_threadsafe.h" +#if defined(USE_NSS) +#include "net/base/nss_cert_database.h" +#endif + namespace net { -CertDatabase::ImportCertFailure::ImportCertFailure( - X509Certificate* cert, int err) - : certificate(cert), net_error(err) { -} +#if defined(USE_NSS) +// Helper that observes events from the NSSCertDatabase and forwards them to +// the given CertDatabase. +class CertDatabase::Notifier : public NSSCertDatabase::Observer { + public: + explicit Notifier(CertDatabase* cert_db) : cert_db_(cert_db) { + NSSCertDatabase::GetInstance()->AddObserver(this); + } -CertDatabase::ImportCertFailure::~ImportCertFailure() { -} + virtual ~Notifier() { + NSSCertDatabase::GetInstance()->RemoveObserver(this); + } -// CertDatabaseNotifier notifies registered observers when new user certificates -// are added to the database. -class CertDatabaseNotifier { - public: - CertDatabaseNotifier() - : observer_list_(new ObserverListThreadSafe<CertDatabase::Observer>) { + // NSSCertDatabase::Observer implementation: + virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE { + cert_db_->NotifyObserversOfCertAdded(cert); } - static CertDatabaseNotifier* GetInstance() { - return Singleton<CertDatabaseNotifier>::get(); + virtual void OnCertRemoved(const X509Certificate* cert) OVERRIDE { + cert_db_->NotifyObserversOfCertRemoved(cert); } - friend struct DefaultSingletonTraits<CertDatabaseNotifier>; - friend class CertDatabase; + virtual void OnCertTrustChanged(const X509Certificate* cert) OVERRIDE { + cert_db_->NotifyObserversOfCertTrustChanged(cert); + } private: - const scoped_refptr<ObserverListThreadSafe<CertDatabase::Observer> > - observer_list_; + CertDatabase* cert_db_; + + DISALLOW_COPY_AND_ASSIGN(Notifier); }; +#endif + +// static +CertDatabase* CertDatabase::GetInstance() { + return Singleton<CertDatabase>::get(); +} + +CertDatabase::CertDatabase() + : observer_list_(new ObserverListThreadSafe<Observer>) { +#if defined(USE_NSS) + // Observe NSSCertDatabase events and forward them to observers of + // CertDatabase. This also makes sure that NSS has been initialized. + notifier_.reset(new Notifier(this)); +#endif +} + +CertDatabase::~CertDatabase() {} void CertDatabase::AddObserver(Observer* observer) { - CertDatabaseNotifier::GetInstance()->observer_list_->AddObserver(observer); + observer_list_->AddObserver(observer); } void CertDatabase::RemoveObserver(Observer* observer) { - CertDatabaseNotifier::GetInstance()->observer_list_->RemoveObserver(observer); + observer_list_->RemoveObserver(observer); } -void CertDatabase::NotifyObserversOfUserCertAdded(const X509Certificate* cert) { - CertDatabaseNotifier::GetInstance()->observer_list_->Notify( - &CertDatabase::Observer::OnUserCertAdded, make_scoped_refptr(cert)); +void CertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) { + observer_list_->Notify(&Observer::OnCertAdded, make_scoped_refptr(cert)); } -void CertDatabase::NotifyObserversOfUserCertRemoved( - const X509Certificate* cert) { - CertDatabaseNotifier::GetInstance()->observer_list_->Notify( - &CertDatabase::Observer::OnUserCertRemoved, make_scoped_refptr(cert)); +void CertDatabase::NotifyObserversOfCertRemoved(const X509Certificate* cert) { + observer_list_->Notify(&Observer::OnCertRemoved, make_scoped_refptr(cert)); } void CertDatabase::NotifyObserversOfCertTrustChanged( const X509Certificate* cert) { - CertDatabaseNotifier::GetInstance()->observer_list_->Notify( - &CertDatabase::Observer::OnCertTrustChanged, make_scoped_refptr(cert)); + observer_list_->Notify( + &Observer::OnCertTrustChanged, make_scoped_refptr(cert)); } } // namespace net diff --git a/net/base/cert_database.h b/net/base/cert_database.h index 6785316..8c7035e 100644 --- a/net/base/cert_database.h +++ b/net/base/cert_database.h @@ -5,23 +5,19 @@ #ifndef NET_BASE_CERT_DATABASE_H_ #define NET_BASE_CERT_DATABASE_H_ -#include <string> -#include <vector> - #include "base/basictypes.h" #include "base/memory/ref_counted.h" -#include "base/string16.h" -#include "net/base/cert_type.h" +#include "base/memory/scoped_ptr.h" #include "net/base/net_export.h" #include "net/base/x509_certificate.h" +template <typename T> struct DefaultSingletonTraits; +template <class ObserverType> class ObserverListThreadSafe; + namespace net { -class CryptoModule; -typedef std::vector<scoped_refptr<CryptoModule> > CryptoModuleList; - -// This class provides functions to manipulate the local -// certificate store. +// This class provides cross-platform functions to verify and add user +// certificates, and to observe changes to the underlying certificate stores. // TODO(gauravsh): This class could be augmented with methods // for all operations that manipulate the underlying system @@ -39,17 +35,13 @@ class NET_EXPORT CertDatabase { public: virtual ~Observer() {} - // Will be called when a new user certificate is added. - // Called with |cert| == NULL after importing a list of certificates - // in ImportFromPKCS12(). - virtual void OnUserCertAdded(const X509Certificate* cert) {} + // Will be called when a new certificate is added. + virtual void OnCertAdded(const X509Certificate* cert) {} - // Will be called when a user certificate is removed. - virtual void OnUserCertRemoved(const X509Certificate* cert) {} + // Will be called when a certificate is removed. + virtual void OnCertRemoved(const X509Certificate* cert) {} // Will be called when a certificate's trust is changed. - // Called with |cert| == NULL after importing a list of certificates - // in ImportCACerts(). virtual void OnCertTrustChanged(const X509Certificate* cert) {} protected: @@ -59,44 +51,8 @@ class NET_EXPORT CertDatabase { DISALLOW_COPY_AND_ASSIGN(Observer); }; - // Stores per-certificate error codes for import failures. - struct NET_EXPORT ImportCertFailure { - public: - ImportCertFailure(X509Certificate* cert, int err); - ~ImportCertFailure(); - - scoped_refptr<X509Certificate> certificate; - int net_error; - }; - typedef std::vector<ImportCertFailure> ImportCertFailureList; - - // Constants that define which usages a certificate is trusted for. - // They are used in combination with CertType to specify trust for each type - // of certificate. - // For a CA_CERT, they specify that the CA is trusted for issuing server and - // client certs of each type. - // For SERVER_CERT, only TRUSTED_SSL makes sense, and specifies the cert is - // trusted as a server. - // For EMAIL_CERT, only TRUSTED_EMAIL makes sense, and specifies the cert is - // trusted for email. - // DISTRUSTED_* specifies that the cert should not be trusted for the given - // usage, regardless of whether it would otherwise inherit trust from the - // issuer chain. - // Use TRUST_DEFAULT to inherit trust as normal. - // NOTE: The actual constants are defined using an enum instead of static - // consts due to compilation/linkage constraints with template functions. - typedef uint32 TrustBits; - enum { - TRUST_DEFAULT = 0, - TRUSTED_SSL = 1 << 0, - TRUSTED_EMAIL = 1 << 1, - TRUSTED_OBJ_SIGN = 1 << 2, - DISTRUSTED_SSL = 1 << 3, - DISTRUSTED_EMAIL = 1 << 4, - DISTRUSTED_OBJ_SIGN = 1 << 5, - }; - - CertDatabase(); + // Returns the CertDatabase singleton. + static CertDatabase* GetInstance(); // Check whether this is a valid user cert that we have the private key for. // Returns OK or a network error code such as ERR_CERT_CONTAINS_ERRORS. @@ -107,109 +63,33 @@ class NET_EXPORT CertDatabase { // the platform cert database, or possibly other network error codes. int AddUserCert(X509Certificate* cert); -#if defined(USE_NSS) - // Get a list of unique certificates in the certificate database (one - // instance of all certificates). - void ListCerts(CertificateList* certs); - - // Get the default module for public key data. - // The returned pointer must be stored in a scoped_refptr<CryptoModule>. - CryptoModule* GetPublicModule() const; - - // Get the default module for private key or mixed private/public key data. - // The returned pointer must be stored in a scoped_refptr<CryptoModule>. - CryptoModule* GetPrivateModule() const; - - // Get all modules. - // If |need_rw| is true, only writable modules will be returned. - void ListModules(CryptoModuleList* modules, bool need_rw) const; - - // Import certificates and private keys from PKCS #12 blob into the module. - // If |is_extractable| is false, mark the private key as being unextractable - // from the module. - // Returns OK or a network error code such as ERR_PKCS12_IMPORT_BAD_PASSWORD - // or ERR_PKCS12_IMPORT_ERROR. |imported_certs|, if non-NULL, returns a list - // of certs that were imported. - int ImportFromPKCS12(CryptoModule* module, - const std::string& data, - const string16& password, - bool is_extractable, - CertificateList* imported_certs); - - // Export the given certificates and private keys into a PKCS #12 blob, - // storing into |output|. - // Returns the number of certificates successfully exported. - int ExportToPKCS12(const CertificateList& certs, const string16& password, - std::string* output) const; - - // Uses similar logic to nsNSSCertificateDB::handleCACertDownload to find the - // root. Assumes the list is an ordered hierarchy with the root being either - // the first or last element. - // TODO(mattm): improve this to handle any order. - X509Certificate* FindRootInList(const CertificateList& certificates) const; - - // Import CA certificates. - // Tries to import all the certificates given. The root will be trusted - // according to |trust_bits|. Any certificates that could not be imported - // will be listed in |not_imported|. - // Returns false if there is an internal error, otherwise true is returned and - // |not_imported| should be checked for any certificates that were not - // imported. - bool ImportCACerts(const CertificateList& certificates, - TrustBits trust_bits, - ImportCertFailureList* not_imported); - - // Import server certificate. The first cert should be the server cert. Any - // additional certs should be intermediate/CA certs and will be imported but - // not given any trust. - // Any certificates that could not be imported will be listed in - // |not_imported|. - // |trust_bits| can be set to explicitly trust or distrust the certificate, or - // use TRUST_DEFAULT to inherit trust as normal. - // Returns false if there is an internal error, otherwise true is returned and - // |not_imported| should be checked for any certificates that were not - // imported. - bool ImportServerCert(const CertificateList& certificates, - TrustBits trust_bits, - ImportCertFailureList* not_imported); - - // Get trust bits for certificate. - TrustBits GetCertTrust(const X509Certificate* 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 X509Certificate* cert) const; - - // Set trust values for certificate. - // Returns true on success or false on failure. - bool SetCertTrust(const X509Certificate* cert, - CertType type, - TrustBits trust_bits); - - // Delete certificate and associated private key (if one exists). - // |cert| is still valid when this function returns. Returns true on - // success. - bool DeleteCertAndKey(const X509Certificate* cert); - - // Check whether cert is stored in a readonly slot. - bool IsReadOnly(const X509Certificate* cert) const; -#endif - // Registers |observer| to receive notifications of certificate changes. The // thread on which this is called is the thread on which |observer| will be // called back with notifications. - static void AddObserver(Observer* observer); + void AddObserver(Observer* observer); // Unregisters |observer| from receiving notifications. This must be called // on the same thread on which AddObserver() was called. - static void RemoveObserver(Observer* observer); + void RemoveObserver(Observer* observer); private: + friend struct DefaultSingletonTraits<CertDatabase>; + + CertDatabase(); + ~CertDatabase(); + // Broadcasts notifications to all registered observers. - static void NotifyObserversOfUserCertAdded(const X509Certificate* cert); - static void NotifyObserversOfUserCertRemoved(const X509Certificate* cert); - static void NotifyObserversOfCertTrustChanged(const X509Certificate* cert); + void NotifyObserversOfCertAdded(const X509Certificate* cert); + void NotifyObserversOfCertRemoved(const X509Certificate* cert); + void NotifyObserversOfCertTrustChanged(const X509Certificate* cert); + + const scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_; + +#if defined(USE_NSS) + class Notifier; + friend class Notifier; + scoped_ptr<Notifier> notifier_; +#endif DISALLOW_COPY_AND_ASSIGN(CertDatabase); }; diff --git a/net/base/cert_database_mac.cc b/net/base/cert_database_mac.cc index 5e97fae..8214cf7 100644 --- a/net/base/cert_database_mac.cc +++ b/net/base/cert_database_mac.cc @@ -15,9 +15,6 @@ namespace net { -CertDatabase::CertDatabase() { -} - int CertDatabase::CheckUserCert(X509Certificate* cert) { if (!cert) return ERR_CERT_INVALID; @@ -48,7 +45,7 @@ int CertDatabase::AddUserCert(X509Certificate* cert) { } switch (err) { case noErr: - CertDatabase::NotifyObserversOfUserCertAdded(cert); + CertDatabase::NotifyObserversOfCertAdded(cert); // Fall through. case errSecDuplicateItem: return OK; diff --git a/net/base/cert_database_nss.cc b/net/base/cert_database_nss.cc index be7ea74..161a31b 100644 --- a/net/base/cert_database_nss.cc +++ b/net/base/cert_database_nss.cc @@ -5,37 +5,16 @@ #include "net/base/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 "crypto/nss_util.h" -#include "crypto/nss_util_internal.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 { -CertDatabase::CertDatabase() { - crypto::EnsureNSSInit(); - psm::EnsurePKCS12Init(); -} - int CertDatabase::CheckUserCert(X509Certificate* cert_obj) { if (!cert_obj) return ERR_CERT_INVALID; @@ -76,270 +55,8 @@ int CertDatabase::AddUserCert(X509Certificate* cert_obj) { return ERR_ADD_USER_CERT_FAILED; } PK11_FreeSlot(slot); - CertDatabase::NotifyObserversOfUserCertAdded(cert_obj); + NotifyObserversOfCertAdded(cert_obj); return OK; } -void CertDatabase::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* CertDatabase::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* CertDatabase::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 CertDatabase::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 CertDatabase::ImportFromPKCS12( - CryptoModule* module, - const std::string& data, - const 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) - CertDatabase::NotifyObserversOfUserCertAdded(NULL); - - return result; -} - -int CertDatabase::ExportToPKCS12( - const CertificateList& certs, - const string16& password, - std::string* output) const { - return psm::nsPKCS12Blob_Export(output, certs, password); -} - -X509Certificate* CertDatabase::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 CertDatabase::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) - CertDatabase::NotifyObserversOfCertTrustChanged(NULL); - - return success; -} - -bool CertDatabase::ImportServerCert(const CertificateList& certificates, - TrustBits trust_bits, - ImportCertFailureList* not_imported) { - return psm::ImportServerCert(certificates, trust_bits, not_imported); -} - -CertDatabase::TrustBits CertDatabase::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 CertDatabase::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 CertDatabase::SetCertTrust(const X509Certificate* cert, - CertType type, - TrustBits trust_bits) { - bool success = psm::SetCertTrust(cert, type, trust_bits); - if (success) - CertDatabase::NotifyObserversOfCertTrustChanged(cert); - - return success; -} - -bool CertDatabase::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; - } - } - - CertDatabase::NotifyObserversOfUserCertRemoved(cert); - - return true; -} - -bool CertDatabase::IsReadOnly(const X509Certificate* cert) const { - PK11SlotInfo* slot = cert->os_cert_handle()->slot; - return slot && PK11_IsReadOnly(slot); -} - } // namespace net diff --git a/net/base/cert_database_openssl.cc b/net/base/cert_database_openssl.cc index c5f86d4..0ff899c 100644 --- a/net/base/cert_database_openssl.cc +++ b/net/base/cert_database_openssl.cc @@ -14,9 +14,6 @@ namespace net { -CertDatabase::CertDatabase() { -} - int CertDatabase::CheckUserCert(X509Certificate* cert) { if (!cert) return ERR_CERT_INVALID; diff --git a/net/base/cert_database_win.cc b/net/base/cert_database_win.cc index 038fc1c..2471850 100644 --- a/net/base/cert_database_win.cc +++ b/net/base/cert_database_win.cc @@ -13,9 +13,6 @@ namespace net { -CertDatabase::CertDatabase() { -} - int CertDatabase::CheckUserCert(X509Certificate* cert) { if (!cert) return ERR_CERT_INVALID; @@ -50,7 +47,7 @@ int CertDatabase::AddUserCert(X509Certificate* cert) { if (!added) return ERR_ADD_USER_CERT_FAILED; - CertDatabase::NotifyObserversOfUserCertAdded(cert); + NotifyObserversOfCertAdded(cert); return OK; } diff --git a/net/base/multi_threaded_cert_verifier.cc b/net/base/multi_threaded_cert_verifier.cc index 54e0324..3e8cf13 100644 --- a/net/base/multi_threaded_cert_verifier.cc +++ b/net/base/multi_threaded_cert_verifier.cc @@ -382,13 +382,12 @@ MultiThreadedCertVerifier::MultiThreadedCertVerifier() cache_hits_(0), inflight_joins_(0), verify_proc_(CertVerifyProc::CreateDefault()) { - CertDatabase::AddObserver(this); + CertDatabase::GetInstance()->AddObserver(this); } MultiThreadedCertVerifier::~MultiThreadedCertVerifier() { STLDeleteValues(&inflight_); - - CertDatabase::RemoveObserver(this); + CertDatabase::GetInstance()->RemoveObserver(this); } int MultiThreadedCertVerifier::Verify(X509Certificate* cert, diff --git a/net/base/nss_cert_database.cc b/net/base/nss_cert_database.cc new file mode 100644 index 0000000..4834af2 --- /dev/null +++ b/net/base/nss_cert_database.cc @@ -0,0 +1,344 @@ +// 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 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 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 diff --git a/net/base/nss_cert_database.h b/net/base/nss_cert_database.h new file mode 100644 index 0000000..9e0310d --- /dev/null +++ b/net/base/nss_cert_database.h @@ -0,0 +1,207 @@ +// 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. + +#ifndef NET_BASE_NSS_CERT_DATABASE_H_ +#define NET_BASE_NSS_CERT_DATABASE_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/string16.h" +#include "net/base/cert_type.h" +#include "net/base/net_export.h" +#include "net/base/x509_certificate.h" + +template <typename T> struct DefaultSingletonTraits; +template <class ObserverType> class ObserverListThreadSafe; + +namespace net { + +class CryptoModule; +typedef std::vector<scoped_refptr<CryptoModule> > CryptoModuleList; + +// Provides functions to manipulate the NSS certificate stores. +class NET_EXPORT NSSCertDatabase { + public: + + class NET_EXPORT Observer { + public: + virtual ~Observer() {} + + // Will be called when a new certificate is added. + // Called with |cert| == NULL after importing a list of certificates + // in ImportFromPKCS12(). + virtual void OnCertAdded(const X509Certificate* cert) {} + + // Will be called when a certificate is removed. + virtual void OnCertRemoved(const X509Certificate* cert) {} + + // Will be called when a certificate's trust is changed. + // Called with |cert| == NULL after importing a list of certificates + // in ImportCACerts(). + virtual void OnCertTrustChanged(const X509Certificate* cert) {} + + protected: + Observer() {} + + private: + DISALLOW_COPY_AND_ASSIGN(Observer); + }; + + // Stores per-certificate error codes for import failures. + struct NET_EXPORT ImportCertFailure { + public: + ImportCertFailure(X509Certificate* cert, int err); + ~ImportCertFailure(); + + scoped_refptr<X509Certificate> certificate; + int net_error; + }; + typedef std::vector<ImportCertFailure> ImportCertFailureList; + + // Constants that define which usages a certificate is trusted for. + // They are used in combination with CertType to specify trust for each type + // of certificate. + // For a CA_CERT, they specify that the CA is trusted for issuing server and + // client certs of each type. + // For SERVER_CERT, only TRUSTED_SSL makes sense, and specifies the cert is + // trusted as a server. + // For EMAIL_CERT, only TRUSTED_EMAIL makes sense, and specifies the cert is + // trusted for email. + // DISTRUSTED_* specifies that the cert should not be trusted for the given + // usage, regardless of whether it would otherwise inherit trust from the + // issuer chain. + // Use TRUST_DEFAULT to inherit trust as normal. + // NOTE: The actual constants are defined using an enum instead of static + // consts due to compilation/linkage constraints with template functions. + typedef uint32 TrustBits; + enum { + TRUST_DEFAULT = 0, + TRUSTED_SSL = 1 << 0, + TRUSTED_EMAIL = 1 << 1, + TRUSTED_OBJ_SIGN = 1 << 2, + DISTRUSTED_SSL = 1 << 3, + DISTRUSTED_EMAIL = 1 << 4, + DISTRUSTED_OBJ_SIGN = 1 << 5, + }; + + static NSSCertDatabase* GetInstance(); + + // Get a list of unique certificates in the certificate database (one + // instance of all certificates). + void ListCerts(CertificateList* certs); + + // Get the default module for public key data. + // The returned pointer must be stored in a scoped_refptr<CryptoModule>. + CryptoModule* GetPublicModule() const; + + // Get the default module for private key or mixed private/public key data. + // The returned pointer must be stored in a scoped_refptr<CryptoModule>. + CryptoModule* GetPrivateModule() const; + + // Get all modules. + // If |need_rw| is true, only writable modules will be returned. + void ListModules(CryptoModuleList* modules, bool need_rw) const; + + // Import certificates and private keys from PKCS #12 blob into the module. + // If |is_extractable| is false, mark the private key as being unextractable + // from the module. + // Returns OK or a network error code such as ERR_PKCS12_IMPORT_BAD_PASSWORD + // or ERR_PKCS12_IMPORT_ERROR. |imported_certs|, if non-NULL, returns a list + // of certs that were imported. + int ImportFromPKCS12(CryptoModule* module, + const std::string& data, + const string16& password, + bool is_extractable, + CertificateList* imported_certs); + + // Export the given certificates and private keys into a PKCS #12 blob, + // storing into |output|. + // Returns the number of certificates successfully exported. + int ExportToPKCS12(const CertificateList& certs, const string16& password, + std::string* output) const; + + // Uses similar logic to nsNSSCertificateDB::handleCACertDownload to find the + // root. Assumes the list is an ordered hierarchy with the root being either + // the first or last element. + // TODO(mattm): improve this to handle any order. + X509Certificate* FindRootInList(const CertificateList& certificates) const; + + // Import CA certificates. + // Tries to import all the certificates given. The root will be trusted + // according to |trust_bits|. Any certificates that could not be imported + // will be listed in |not_imported|. + // Returns false if there is an internal error, otherwise true is returned and + // |not_imported| should be checked for any certificates that were not + // imported. + bool ImportCACerts(const CertificateList& certificates, + TrustBits trust_bits, + ImportCertFailureList* not_imported); + + // Import server certificate. The first cert should be the server cert. Any + // additional certs should be intermediate/CA certs and will be imported but + // not given any trust. + // Any certificates that could not be imported will be listed in + // |not_imported|. + // |trust_bits| can be set to explicitly trust or distrust the certificate, or + // use TRUST_DEFAULT to inherit trust as normal. + // Returns false if there is an internal error, otherwise true is returned and + // |not_imported| should be checked for any certificates that were not + // imported. + bool ImportServerCert(const CertificateList& certificates, + TrustBits trust_bits, + ImportCertFailureList* not_imported); + + // Get trust bits for certificate. + TrustBits GetCertTrust(const X509Certificate* 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 X509Certificate* cert) const; + + // Set trust values for certificate. + // Returns true on success or false on failure. + bool SetCertTrust(const X509Certificate* cert, + CertType type, + TrustBits trust_bits); + + // Delete certificate and associated private key (if one exists). + // |cert| is still valid when this function returns. Returns true on + // success. + bool DeleteCertAndKey(const X509Certificate* cert); + + // Check whether cert is stored in a readonly slot. + bool IsReadOnly(const X509Certificate* cert) const; + + // Registers |observer| to receive notifications of certificate changes. The + // thread on which this is called is the thread on which |observer| will be + // called back with notifications. + void AddObserver(Observer* observer); + + // Unregisters |observer| from receiving notifications. This must be called + // on the same thread on which AddObserver() was called. + void RemoveObserver(Observer* observer); + + private: + friend struct DefaultSingletonTraits<NSSCertDatabase>; + + NSSCertDatabase(); + ~NSSCertDatabase(); + + // Broadcasts notifications to all registered observers. + void NotifyObserversOfCertAdded(const X509Certificate* cert); + void NotifyObserversOfCertRemoved(const X509Certificate* cert); + void NotifyObserversOfCertTrustChanged(const X509Certificate* cert); + + const scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_; + + DISALLOW_COPY_AND_ASSIGN(NSSCertDatabase); +}; + +} // namespace net + +#endif // NET_BASE_NSS_CERT_DATABASE_H_ diff --git a/net/base/cert_database_nss_unittest.cc b/net/base/nss_cert_database_unittest.cc index c4e3b9b..0b1d323 100644 --- a/net/base/cert_database_nss_unittest.cc +++ b/net/base/nss_cert_database_unittest.cc @@ -19,13 +19,13 @@ #include "crypto/nss_util.h" #include "crypto/nss_util_internal.h" #include "crypto/scoped_nss_types.h" -#include "net/base/cert_database.h" #include "net/base/cert_status_flags.h" #include "net/base/cert_test_util.h" #include "net/base/cert_verify_proc.h" #include "net/base/cert_verify_result.h" #include "net/base/crypto_module.h" #include "net/base/net_errors.h" +#include "net/base/nss_cert_database.h" #include "net/base/x509_certificate.h" #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h" #include "testing/gtest/include/gtest/gtest.h" @@ -52,7 +52,8 @@ class CertDatabaseNSSTest : public testing::Test { } virtual void SetUp() { - slot_ = cert_db_.GetPublicModule(); + cert_db_ = NSSCertDatabase::GetInstance(); + slot_ = cert_db_->GetPublicModule(); // Test db should be empty at start of test. EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); @@ -62,11 +63,11 @@ class CertDatabaseNSSTest : public testing::Test { // Don't try to cleanup if the setup failed. ASSERT_TRUE(slot_->os_module_handle()); - EXPECT_TRUE(CleanupSlotContents(slot_->os_module_handle())); + EXPECT_TRUE(CleanupSlotContents()); // Run the message loop to process any observer callbacks (e.g. for the // ClientSocketFactory singleton) so that the scoped ref ptrs created in - // CertDatabase::NotifyObservers* get released. + // NSSCertDatabase::NotifyObservers* get released. MessageLoop::current()->RunAllPending(); EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); @@ -108,13 +109,12 @@ class CertDatabaseNSSTest : public testing::Test { } scoped_refptr<CryptoModule> slot_; - CertDatabase cert_db_; + NSSCertDatabase* cert_db_; private: - static bool CleanupSlotContents(PK11SlotInfo* slot) { - CertDatabase cert_db; + bool CleanupSlotContents() { bool ok = true; - CertificateList certs = ListCertsInSlot(slot); + CertificateList certs = ListCertsInSlot(slot_->os_module_handle()); CERTCertTrust default_trust = {0}; for (size_t i = 0; i < certs.size(); ++i) { // Reset cert trust values to defaults before deleting. Otherwise NSS @@ -124,7 +124,7 @@ class CertDatabaseNSSTest : public testing::Test { if (srv != SECSuccess) ok = false; - if (!cert_db.DeleteCertAndKey(certs[i])) + if (!cert_db_->DeleteCertAndKey(certs[i])) ok = false; } return ok; @@ -135,7 +135,7 @@ TEST_F(CertDatabaseNSSTest, ListCerts) { // This test isn't terribly useful, though it will at least let valgrind test // for leaks. CertificateList certs; - cert_db_.ListCerts(&certs); + cert_db_->ListCerts(&certs); // The test DB is empty, but let's assume there will always be something in // the other slots. EXPECT_LT(0U, certs.size()); @@ -145,11 +145,11 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12WrongPassword) { std::string pkcs12_data = ReadTestFile("client.p12"); EXPECT_EQ(ERR_PKCS12_IMPORT_BAD_PASSWORD, - cert_db_.ImportFromPKCS12(slot_, - pkcs12_data, - string16(), - true, // is_extractable - NULL)); + cert_db_->ImportFromPKCS12(slot_, + pkcs12_data, + string16(), + true, // is_extractable + NULL)); // Test db should still be empty. EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); @@ -158,11 +158,11 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12WrongPassword) { TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsExtractableAndExportAgain) { std::string pkcs12_data = ReadTestFile("client.p12"); - EXPECT_EQ(OK, cert_db_.ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - true, // is_extractable - NULL)); + EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, + pkcs12_data, + ASCIIToUTF16("12345"), + true, // is_extractable + NULL)); CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); ASSERT_EQ(1U, cert_list.size()); @@ -173,8 +173,8 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsExtractableAndExportAgain) { // TODO(mattm): move export test to separate test case? std::string exported_data; - EXPECT_EQ(1, cert_db_.ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), - &exported_data)); + EXPECT_EQ(1, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), + &exported_data)); ASSERT_LT(0U, exported_data.size()); // TODO(mattm): further verification of exported data? } @@ -182,31 +182,31 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsExtractableAndExportAgain) { TEST_F(CertDatabaseNSSTest, ImportFromPKCS12Twice) { std::string pkcs12_data = ReadTestFile("client.p12"); - EXPECT_EQ(OK, cert_db_.ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - true, // is_extractable - NULL)); + EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, + pkcs12_data, + ASCIIToUTF16("12345"), + true, // is_extractable + NULL)); EXPECT_EQ(1U, ListCertsInSlot(slot_->os_module_handle()).size()); // NSS has a SEC_ERROR_PKCS12_DUPLICATE_DATA error, but it doesn't look like // it's ever used. This test verifies that. - EXPECT_EQ(OK, cert_db_.ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - true, // is_extractable - NULL)); + EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, + pkcs12_data, + ASCIIToUTF16("12345"), + true, // is_extractable + NULL)); EXPECT_EQ(1U, ListCertsInSlot(slot_->os_module_handle()).size()); } TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsUnextractableAndExportAgain) { std::string pkcs12_data = ReadTestFile("client.p12"); - EXPECT_EQ(OK, cert_db_.ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - false, // is_extractable - NULL)); + EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, + pkcs12_data, + ASCIIToUTF16("12345"), + false, // is_extractable + NULL)); CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); ASSERT_EQ(1U, cert_list.size()); @@ -216,38 +216,38 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsUnextractableAndExportAgain) { cert->subject().common_name); std::string exported_data; - EXPECT_EQ(0, cert_db_.ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), - &exported_data)); + EXPECT_EQ(0, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), + &exported_data)); } // Importing a PKCS#12 file with a certificate but no corresponding // private key should not mark an existing private key as unextractable. TEST_F(CertDatabaseNSSTest, ImportFromPKCS12OnlyMarkIncludedKey) { std::string pkcs12_data = ReadTestFile("client.p12"); - EXPECT_EQ(OK, cert_db_.ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - true, // is_extractable - NULL)); + EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, + pkcs12_data, + ASCIIToUTF16("12345"), + true, // is_extractable + NULL)); CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); ASSERT_EQ(1U, cert_list.size()); // Now import a PKCS#12 file with just a certificate but no private key. pkcs12_data = ReadTestFile("client-nokey.p12"); - EXPECT_EQ(OK, cert_db_.ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - false, // is_extractable - NULL)); + EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, + pkcs12_data, + ASCIIToUTF16("12345"), + false, // is_extractable + NULL)); cert_list = ListCertsInSlot(slot_->os_module_handle()); ASSERT_EQ(1U, cert_list.size()); // Make sure the imported private key is still extractable. std::string exported_data; - EXPECT_EQ(1, cert_db_.ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), - &exported_data)); + EXPECT_EQ(1, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), + &exported_data)); ASSERT_LT(0U, exported_data.size()); } @@ -255,11 +255,11 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12InvalidFile) { std::string pkcs12_data = "Foobarbaz"; EXPECT_EQ(ERR_PKCS12_IMPORT_INVALID_FILE, - cert_db_.ImportFromPKCS12(slot_, - pkcs12_data, - string16(), - true, // is_extractable - NULL)); + cert_db_->ImportFromPKCS12(slot_, + pkcs12_data, + string16(), + true, // is_extractable + NULL)); // Test db should still be empty. EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); @@ -273,9 +273,9 @@ TEST_F(CertDatabaseNSSTest, ImportCACert_SSLTrust) { EXPECT_FALSE(certs[0]->os_cert_handle()->isperm); // Import it. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts(certs, CertDatabase::TRUSTED_SSL, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_SSL, + &failed)); EXPECT_EQ(0U, failed.size()); @@ -284,8 +284,8 @@ TEST_F(CertDatabaseNSSTest, ImportCACert_SSLTrust) { scoped_refptr<X509Certificate> cert(cert_list[0]); EXPECT_EQ("Test CA", cert->subject().common_name); - EXPECT_EQ(CertDatabase::TRUSTED_SSL, - cert_db_.GetCertTrust(cert.get(), CA_CERT)); + EXPECT_EQ(NSSCertDatabase::TRUSTED_SSL, + cert_db_->GetCertTrust(cert.get(), CA_CERT)); EXPECT_EQ(unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA), @@ -304,9 +304,9 @@ TEST_F(CertDatabaseNSSTest, ImportCACert_EmailTrust) { EXPECT_FALSE(certs[0]->os_cert_handle()->isperm); // Import it. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts(certs, CertDatabase::TRUSTED_EMAIL, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_EMAIL, + &failed)); EXPECT_EQ(0U, failed.size()); @@ -315,8 +315,8 @@ TEST_F(CertDatabaseNSSTest, ImportCACert_EmailTrust) { scoped_refptr<X509Certificate> cert(cert_list[0]); EXPECT_EQ("Test CA", cert->subject().common_name); - EXPECT_EQ(CertDatabase::TRUSTED_EMAIL, - cert_db_.GetCertTrust(cert.get(), CA_CERT)); + EXPECT_EQ(NSSCertDatabase::TRUSTED_EMAIL, + cert_db_->GetCertTrust(cert.get(), CA_CERT)); EXPECT_EQ(unsigned(CERTDB_VALID_CA), cert->os_cert_handle()->trust->sslFlags); @@ -335,9 +335,9 @@ TEST_F(CertDatabaseNSSTest, ImportCACert_ObjSignTrust) { EXPECT_FALSE(certs[0]->os_cert_handle()->isperm); // Import it. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts(certs, CertDatabase::TRUSTED_OBJ_SIGN, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_OBJ_SIGN, + &failed)); EXPECT_EQ(0U, failed.size()); @@ -346,8 +346,8 @@ TEST_F(CertDatabaseNSSTest, ImportCACert_ObjSignTrust) { scoped_refptr<X509Certificate> cert(cert_list[0]); EXPECT_EQ("Test CA", cert->subject().common_name); - EXPECT_EQ(CertDatabase::TRUSTED_OBJ_SIGN, - cert_db_.GetCertTrust(cert.get(), CA_CERT)); + EXPECT_EQ(NSSCertDatabase::TRUSTED_OBJ_SIGN, + cert_db_->GetCertTrust(cert.get(), CA_CERT)); EXPECT_EQ(unsigned(CERTDB_VALID_CA), cert->os_cert_handle()->trust->sslFlags); @@ -366,9 +366,9 @@ TEST_F(CertDatabaseNSSTest, ImportCA_NotCACert) { EXPECT_FALSE(certs[0]->os_cert_handle()->isperm); // Import it. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts(certs, CertDatabase::TRUSTED_SSL, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_SSL, + &failed)); ASSERT_EQ(1U, failed.size()); // Note: this compares pointers directly. It's okay in this case because // ImportCACerts returns the same pointers that were passed in. In the @@ -386,13 +386,13 @@ TEST_F(CertDatabaseNSSTest, ImportCACertHierarchy) { ASSERT_TRUE(ReadCertIntoList("www_us_army_mil_cert.der", &certs)); // Import it. - CertDatabase::ImportCertFailureList failed; + NSSCertDatabase::ImportCertFailureList failed; // Have to specify email trust for the cert verification of the child cert to // work (see // http://mxr.mozilla.org/mozilla/source/security/nss/lib/certhigh/certvfy.c#752 // "XXX This choice of trustType seems arbitrary.") - EXPECT_TRUE(cert_db_.ImportCACerts( - certs, CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL, + EXPECT_TRUE(cert_db_->ImportCACerts( + certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL, &failed)); ASSERT_EQ(2U, failed.size()); @@ -411,9 +411,9 @@ TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyDupeRoot) { ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs)); // First import just the root. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts( - certs, CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL, + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts( + certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL, &failed)); EXPECT_EQ(0U, failed.size()); @@ -427,8 +427,8 @@ TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyDupeRoot) { // Now import with the other certs in the list too. Even though the root is // already present, we should still import the rest. failed.clear(); - EXPECT_TRUE(cert_db_.ImportCACerts( - certs, CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL, + EXPECT_TRUE(cert_db_->ImportCACerts( + certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL, &failed)); ASSERT_EQ(3U, failed.size()); @@ -450,9 +450,9 @@ TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyUntrusted) { ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs)); // Import it. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts(certs, CertDatabase::TRUST_DEFAULT, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUST_DEFAULT, + &failed)); ASSERT_EQ(1U, failed.size()); EXPECT_EQ("DOD CA-17", failed[0].certificate->subject().common_name); @@ -472,9 +472,9 @@ TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyTree) { ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs)); // Import it. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts( - certs, CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL, + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts( + certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL, &failed)); EXPECT_EQ(2U, failed.size()); @@ -497,10 +497,10 @@ TEST_F(CertDatabaseNSSTest, ImportCACertNotHierarchy) { ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs)); // Import it. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts( - certs, CertDatabase::TRUSTED_SSL | CertDatabase::TRUSTED_EMAIL | - CertDatabase::TRUSTED_OBJ_SIGN, &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts( + certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL | + NSSCertDatabase::TRUSTED_OBJ_SIGN, &failed)); ASSERT_EQ(2U, failed.size()); // TODO(mattm): should check for net error equivalent of @@ -526,9 +526,9 @@ TEST_F(CertDatabaseNSSTest, DISABLED_ImportServerCert) { X509Certificate::FORMAT_AUTO); ASSERT_EQ(2U, certs.size()); - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportServerCert(certs, CertDatabase::TRUST_DEFAULT, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT, + &failed)); EXPECT_EQ(0U, failed.size()); @@ -539,8 +539,8 @@ TEST_F(CertDatabaseNSSTest, DISABLED_ImportServerCert) { EXPECT_EQ("www.google.com", goog_cert->subject().common_name); EXPECT_EQ("Thawte SGC CA", thawte_cert->subject().common_name); - EXPECT_EQ(CertDatabase::TRUST_DEFAULT, - cert_db_.GetCertTrust(goog_cert.get(), SERVER_CERT)); + EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, + cert_db_->GetCertTrust(goog_cert.get(), SERVER_CERT)); EXPECT_EQ(0U, goog_cert->os_cert_handle()->trust->sslFlags); @@ -557,9 +557,9 @@ TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned) { CertificateList certs; ASSERT_TRUE(ReadCertIntoList("punycodetest.der", &certs)); - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportServerCert(certs, CertDatabase::TRUST_DEFAULT, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT, + &failed)); EXPECT_EQ(0U, failed.size()); @@ -567,8 +567,8 @@ TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned) { ASSERT_EQ(1U, cert_list.size()); scoped_refptr<X509Certificate> puny_cert(cert_list[0]); - EXPECT_EQ(CertDatabase::TRUST_DEFAULT, - cert_db_.GetCertTrust(puny_cert.get(), SERVER_CERT)); + EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, + cert_db_->GetCertTrust(puny_cert.get(), SERVER_CERT)); EXPECT_EQ(0U, puny_cert->os_cert_handle()->trust->sslFlags); scoped_refptr<CertVerifyProc> verify_proc(CertVerifyProc::CreateDefault()); @@ -591,9 +591,9 @@ TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned_Trusted) { CertificateList certs; ASSERT_TRUE(ReadCertIntoList("punycodetest.der", &certs)); - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportServerCert(certs, CertDatabase::TRUSTED_SSL, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUSTED_SSL, + &failed)); EXPECT_EQ(0U, failed.size()); @@ -601,8 +601,8 @@ TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned_Trusted) { ASSERT_EQ(1U, cert_list.size()); scoped_refptr<X509Certificate> puny_cert(cert_list[0]); - EXPECT_EQ(CertDatabase::TRUSTED_SSL, - cert_db_.GetCertTrust(puny_cert.get(), SERVER_CERT)); + EXPECT_EQ(NSSCertDatabase::TRUSTED_SSL, + cert_db_->GetCertTrust(puny_cert.get(), SERVER_CERT)); EXPECT_EQ(unsigned(CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD), puny_cert->os_cert_handle()->trust->sslFlags); @@ -622,9 +622,9 @@ TEST_F(CertDatabaseNSSTest, ImportCaAndServerCert) { ASSERT_EQ(1U, ca_certs.size()); // Import CA cert and trust it. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts(ca_certs, CertDatabase::TRUSTED_SSL, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL, + &failed)); EXPECT_EQ(0U, failed.size()); CertificateList certs = CreateCertificateListFromFile( @@ -633,8 +633,8 @@ TEST_F(CertDatabaseNSSTest, ImportCaAndServerCert) { ASSERT_EQ(1U, certs.size()); // Import server cert with default trust. - EXPECT_TRUE(cert_db_.ImportServerCert(certs, CertDatabase::TRUST_DEFAULT, - &failed)); + EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT, + &failed)); EXPECT_EQ(0U, failed.size()); // Server cert should verify. @@ -660,9 +660,9 @@ TEST_F(CertDatabaseNSSTest, ImportCaAndServerCert_DistrustServer) { ASSERT_EQ(1U, ca_certs.size()); // Import CA cert and trust it. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts(ca_certs, CertDatabase::TRUSTED_SSL, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL, + &failed)); EXPECT_EQ(0U, failed.size()); CertificateList certs = CreateCertificateListFromFile( @@ -672,11 +672,11 @@ TEST_F(CertDatabaseNSSTest, ImportCaAndServerCert_DistrustServer) { // Import server cert without inheriting trust from issuer (explicit // distrust). - EXPECT_TRUE(cert_db_.ImportServerCert( - certs, CertDatabase::DISTRUSTED_SSL, &failed)); + EXPECT_TRUE(cert_db_->ImportServerCert( + certs, NSSCertDatabase::DISTRUSTED_SSL, &failed)); EXPECT_EQ(0U, failed.size()); - EXPECT_EQ(CertDatabase::DISTRUSTED_SSL, - cert_db_.GetCertTrust(certs[0], SERVER_CERT)); + EXPECT_EQ(NSSCertDatabase::DISTRUSTED_SSL, + cert_db_->GetCertTrust(certs[0], SERVER_CERT)); EXPECT_EQ(unsigned(CERTDB_TERMINAL_RECORD), certs[0]->os_cert_handle()->trust->sslFlags); @@ -698,9 +698,9 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa) { ASSERT_EQ(1U, ca_certs.size()); // Import Root CA cert and distrust it. - CertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_.ImportCACerts(ca_certs, CertDatabase::DISTRUSTED_SSL, - &failed)); + NSSCertDatabase::ImportCertFailureList failed; + EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::DISTRUSTED_SSL, + &failed)); EXPECT_EQ(0U, failed.size()); CertificateList intermediate_certs = CreateCertificateListFromFile( @@ -709,8 +709,8 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa) { ASSERT_EQ(1U, intermediate_certs.size()); // Import Intermediate CA cert and trust it. - EXPECT_TRUE(cert_db_.ImportCACerts(intermediate_certs, - CertDatabase::TRUSTED_SSL, &failed)); + EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs, + NSSCertDatabase::TRUSTED_SSL, &failed)); EXPECT_EQ(0U, failed.size()); CertificateList certs = CreateCertificateListFromFile( @@ -719,11 +719,11 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa) { ASSERT_EQ(1U, certs.size()); // Import server cert with default trust. - EXPECT_TRUE(cert_db_.ImportServerCert( - certs, CertDatabase::TRUST_DEFAULT, &failed)); + EXPECT_TRUE(cert_db_->ImportServerCert( + certs, NSSCertDatabase::TRUST_DEFAULT, &failed)); EXPECT_EQ(0U, failed.size()); - EXPECT_EQ(CertDatabase::TRUST_DEFAULT, - cert_db_.GetCertTrust(certs[0], SERVER_CERT)); + EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, + cert_db_->GetCertTrust(certs[0], SERVER_CERT)); // Server cert should verify. scoped_refptr<CertVerifyProc> verify_proc(CertVerifyProc::CreateDefault()); @@ -741,10 +741,10 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa) { } // Trust the root cert and distrust the intermediate. - EXPECT_TRUE(cert_db_.SetCertTrust( - ca_certs[0], CA_CERT, CertDatabase::TRUSTED_SSL)); - EXPECT_TRUE(cert_db_.SetCertTrust( - intermediate_certs[0], CA_CERT, CertDatabase::DISTRUSTED_SSL)); + EXPECT_TRUE(cert_db_->SetCertTrust( + ca_certs[0], CA_CERT, NSSCertDatabase::TRUSTED_SSL)); + EXPECT_TRUE(cert_db_->SetCertTrust( + intermediate_certs[0], CA_CERT, NSSCertDatabase::DISTRUSTED_SSL)); EXPECT_EQ( unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA), ca_certs[0]->os_cert_handle()->trust->sslFlags); @@ -769,7 +769,7 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa) { } TEST_F(CertDatabaseNSSTest, TrustIntermediateCa2) { - CertDatabase::ImportCertFailureList failed; + NSSCertDatabase::ImportCertFailureList failed; CertificateList intermediate_certs = CreateCertificateListFromFile( GetTestCertsDirectory(), "2048-rsa-intermediate.pem", @@ -777,8 +777,8 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa2) { ASSERT_EQ(1U, intermediate_certs.size()); // Import Intermediate CA cert and trust it. - EXPECT_TRUE(cert_db_.ImportCACerts(intermediate_certs, - CertDatabase::TRUSTED_SSL, &failed)); + EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs, + NSSCertDatabase::TRUSTED_SSL, &failed)); EXPECT_EQ(0U, failed.size()); CertificateList certs = CreateCertificateListFromFile( @@ -787,11 +787,11 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa2) { ASSERT_EQ(1U, certs.size()); // Import server cert with default trust. - EXPECT_TRUE(cert_db_.ImportServerCert( - certs, CertDatabase::TRUST_DEFAULT, &failed)); + EXPECT_TRUE(cert_db_->ImportServerCert( + certs, NSSCertDatabase::TRUST_DEFAULT, &failed)); EXPECT_EQ(0U, failed.size()); - EXPECT_EQ(CertDatabase::TRUST_DEFAULT, - cert_db_.GetCertTrust(certs[0], SERVER_CERT)); + EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, + cert_db_->GetCertTrust(certs[0], SERVER_CERT)); // Server cert should verify. scoped_refptr<CertVerifyProc> verify_proc(CertVerifyProc::CreateDefault()); @@ -803,8 +803,8 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa2) { EXPECT_EQ(0U, verify_result.cert_status); // Without explicit trust of the intermediate, verification should fail. - EXPECT_TRUE(cert_db_.SetCertTrust( - intermediate_certs[0], CA_CERT, CertDatabase::TRUST_DEFAULT)); + EXPECT_TRUE(cert_db_->SetCertTrust( + intermediate_certs[0], CA_CERT, NSSCertDatabase::TRUST_DEFAULT)); // Server cert should fail to verify. CertVerifyResult verify_result2; @@ -815,7 +815,7 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa2) { } TEST_F(CertDatabaseNSSTest, TrustIntermediateCa3) { - CertDatabase::ImportCertFailureList failed; + NSSCertDatabase::ImportCertFailureList failed; CertificateList ca_certs = CreateCertificateListFromFile( GetTestCertsDirectory(), "2048-rsa-root.pem", @@ -823,8 +823,8 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa3) { ASSERT_EQ(1U, ca_certs.size()); // Import Root CA cert and default trust it. - EXPECT_TRUE(cert_db_.ImportCACerts(ca_certs, CertDatabase::TRUST_DEFAULT, - &failed)); + EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUST_DEFAULT, + &failed)); EXPECT_EQ(0U, failed.size()); CertificateList intermediate_certs = CreateCertificateListFromFile( @@ -833,8 +833,8 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa3) { ASSERT_EQ(1U, intermediate_certs.size()); // Import Intermediate CA cert and trust it. - EXPECT_TRUE(cert_db_.ImportCACerts(intermediate_certs, - CertDatabase::TRUSTED_SSL, &failed)); + EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs, + NSSCertDatabase::TRUSTED_SSL, &failed)); EXPECT_EQ(0U, failed.size()); CertificateList certs = CreateCertificateListFromFile( @@ -843,11 +843,11 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa3) { ASSERT_EQ(1U, certs.size()); // Import server cert with default trust. - EXPECT_TRUE(cert_db_.ImportServerCert( - certs, CertDatabase::TRUST_DEFAULT, &failed)); + EXPECT_TRUE(cert_db_->ImportServerCert( + certs, NSSCertDatabase::TRUST_DEFAULT, &failed)); EXPECT_EQ(0U, failed.size()); - EXPECT_EQ(CertDatabase::TRUST_DEFAULT, - cert_db_.GetCertTrust(certs[0], SERVER_CERT)); + EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, + cert_db_->GetCertTrust(certs[0], SERVER_CERT)); // Server cert should verify. scoped_refptr<CertVerifyProc> verify_proc(CertVerifyProc::CreateDefault()); @@ -859,8 +859,8 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa3) { EXPECT_EQ(0U, verify_result.cert_status); // Without explicit trust of the intermediate, verification should fail. - EXPECT_TRUE(cert_db_.SetCertTrust( - intermediate_certs[0], CA_CERT, CertDatabase::TRUST_DEFAULT)); + EXPECT_TRUE(cert_db_->SetCertTrust( + intermediate_certs[0], CA_CERT, NSSCertDatabase::TRUST_DEFAULT)); // Server cert should fail to verify. CertVerifyResult verify_result2; @@ -877,7 +877,7 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa4) { return; } - CertDatabase::ImportCertFailureList failed; + NSSCertDatabase::ImportCertFailureList failed; CertificateList ca_certs = CreateCertificateListFromFile( GetTestCertsDirectory(), "2048-rsa-root.pem", @@ -885,8 +885,8 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa4) { ASSERT_EQ(1U, ca_certs.size()); // Import Root CA cert and trust it. - EXPECT_TRUE(cert_db_.ImportCACerts(ca_certs, CertDatabase::TRUSTED_SSL, - &failed)); + EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL, + &failed)); EXPECT_EQ(0U, failed.size()); CertificateList intermediate_certs = CreateCertificateListFromFile( @@ -895,8 +895,8 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa4) { ASSERT_EQ(1U, intermediate_certs.size()); // Import Intermediate CA cert and distrust it. - EXPECT_TRUE(cert_db_.ImportCACerts(intermediate_certs, - CertDatabase::DISTRUSTED_SSL, &failed)); + EXPECT_TRUE(cert_db_->ImportCACerts( + intermediate_certs, NSSCertDatabase::DISTRUSTED_SSL, &failed)); EXPECT_EQ(0U, failed.size()); CertificateList certs = CreateCertificateListFromFile( @@ -905,11 +905,11 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa4) { ASSERT_EQ(1U, certs.size()); // Import server cert with default trust. - EXPECT_TRUE(cert_db_.ImportServerCert( - certs, CertDatabase::TRUST_DEFAULT, &failed)); + EXPECT_TRUE(cert_db_->ImportServerCert( + certs, NSSCertDatabase::TRUST_DEFAULT, &failed)); EXPECT_EQ(0U, failed.size()); - EXPECT_EQ(CertDatabase::TRUST_DEFAULT, - cert_db_.GetCertTrust(certs[0], SERVER_CERT)); + EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, + cert_db_->GetCertTrust(certs[0], SERVER_CERT)); // Server cert should not verify. scoped_refptr<CertVerifyProc> verify_proc(CertVerifyProc::CreateDefault()); @@ -921,8 +921,8 @@ TEST_F(CertDatabaseNSSTest, TrustIntermediateCa4) { EXPECT_EQ(CERT_STATUS_REVOKED, verify_result.cert_status); // Without explicit distrust of the intermediate, verification should succeed. - EXPECT_TRUE(cert_db_.SetCertTrust( - intermediate_certs[0], CA_CERT, CertDatabase::TRUST_DEFAULT)); + EXPECT_TRUE(cert_db_->SetCertTrust( + intermediate_certs[0], CA_CERT, NSSCertDatabase::TRUST_DEFAULT)); // Server cert should verify. CertVerifyResult verify_result2; diff --git a/net/base/ssl_client_auth_cache.cc b/net/base/ssl_client_auth_cache.cc index 7b0e158..f5e5e91 100644 --- a/net/base/ssl_client_auth_cache.cc +++ b/net/base/ssl_client_auth_cache.cc @@ -10,11 +10,11 @@ namespace net { SSLClientAuthCache::SSLClientAuthCache() { - CertDatabase::AddObserver(this); + CertDatabase::GetInstance()->AddObserver(this); } SSLClientAuthCache::~SSLClientAuthCache() { - CertDatabase::RemoveObserver(this); + CertDatabase::GetInstance()->RemoveObserver(this); } bool SSLClientAuthCache::Lookup( @@ -41,7 +41,7 @@ void SSLClientAuthCache::Remove(const std::string& server) { cache_.erase(server); } -void SSLClientAuthCache::OnUserCertAdded(const X509Certificate* cert) { +void SSLClientAuthCache::OnCertAdded(const X509Certificate* cert) { cache_.clear(); } diff --git a/net/base/ssl_client_auth_cache.h b/net/base/ssl_client_auth_cache.h index 6bfa8e6..f8175d2 100644 --- a/net/base/ssl_client_auth_cache.h +++ b/net/base/ssl_client_auth_cache.h @@ -47,7 +47,7 @@ class NET_EXPORT_PRIVATE SSLClientAuthCache : public CertDatabase::Observer { void Remove(const std::string& server); // CertDatabase::Observer methods: - virtual void OnUserCertAdded(const X509Certificate* cert) OVERRIDE; + virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE; private: typedef std::string AuthCacheKey; diff --git a/net/base/ssl_client_auth_cache_unittest.cc b/net/base/ssl_client_auth_cache_unittest.cc index 6408887..29ede5be 100644 --- a/net/base/ssl_client_auth_cache_unittest.cc +++ b/net/base/ssl_client_auth_cache_unittest.cc @@ -137,8 +137,8 @@ TEST(SSLClientAuthCacheTest, LookupNullPreference) { EXPECT_EQ(NULL, cached_cert.get()); } -// Check that the OnUserCertAdded() method removes all cache entries. -TEST(SSLClientAuthCacheTest, OnUserCertAdded) { +// Check that the OnCertAdded() method removes all cache entries. +TEST(SSLClientAuthCacheTest, OnCertAdded) { SSLClientAuthCache cache; base::Time start_date = base::Time::Now(); base::Time expiration_date = start_date + base::TimeDelta::FromDays(1); @@ -161,7 +161,7 @@ TEST(SSLClientAuthCacheTest, OnUserCertAdded) { EXPECT_TRUE(cache.Lookup(server2, &cached_cert)); EXPECT_EQ(NULL, cached_cert.get()); - cache.OnUserCertAdded(NULL); + cache.OnCertAdded(NULL); // Check that we no longer have entries for either server. EXPECT_FALSE(cache.Lookup(server1, &cached_cert)); diff --git a/net/net.gyp b/net/net.gyp index dc4f4c4..a5b1cba 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -210,6 +210,8 @@ 'base/network_config_watcher_mac.h', 'base/network_delegate.cc', 'base/network_delegate.h', + 'base/nss_cert_database.cc', + 'base/nss_cert_database.h', 'base/nss_memio.c', 'base/nss_memio.h', 'base/openssl_memory_private_key_store.cc', @@ -903,6 +905,8 @@ 'base/dnssec_keyset.cc', 'base/dnssec_keyset.h', 'base/keygen_handler_nss.cc', + 'base/nss_cert_database.cc', + 'base/nss_cert_database.h', 'base/nss_memio.c', 'base/nss_memio.h', 'base/test_root_certs_nss.cc', @@ -986,6 +990,8 @@ 'base/cert_database_nss.cc', 'base/crypto_module_nss.cc', 'base/keygen_handler_nss.cc', + 'base/nss_cert_database.cc', + 'base/nss_cert_database.h', 'base/test_root_certs_nss.cc', 'base/x509_certificate_nss.cc', 'ocsp/nss_ocsp.cc', @@ -1169,7 +1175,6 @@ 'base/address_tracker_linux_unittest.cc', 'base/backoff_entry_unittest.cc', 'base/big_endian_unittest.cc', - 'base/cert_database_nss_unittest.cc', 'base/cert_verify_proc_unittest.cc', 'base/crl_set_unittest.cc', 'base/data_url_unittest.cc', @@ -1200,6 +1205,7 @@ 'base/net_util_unittest.cc', 'base/network_change_notifier_linux_unittest.cc', 'base/network_change_notifier_win_unittest.cc', + 'base/nss_cert_database_unittest.cc', 'base/pem_tokenizer_unittest.cc', 'base/prioritized_dispatcher_unittest.cc', 'base/priority_queue_unittest.cc', @@ -1414,9 +1420,9 @@ 'dependencies': [ '../build/linux/system.gyp:ssl', ], - }, { # else: OS is not in the above list + }, { # else use_glib == 0: !posix || mac 'sources!': [ - 'base/cert_database_nss_unittest.cc', + 'base/nss_cert_database_unittest.cc', ], }, ], @@ -1453,8 +1459,8 @@ # functionality is ported to OpenSSL. 'sources!': [ 'base/x509_util_nss_unittest.cc', - 'base/cert_database_nss_unittest.cc', 'base/dnssec_unittest.cc', + 'base/nss_cert_database_unittest.cc', ], }, { # else !use_openssl: remove the unneeded files 'sources!': [ diff --git a/net/socket/client_socket_factory.cc b/net/socket/client_socket_factory.cc index f354317..531a9ca 100644 --- a/net/socket/client_socket_factory.cc +++ b/net/socket/client_socket_factory.cc @@ -55,16 +55,16 @@ class DefaultClientSocketFactory : public ClientSocketFactory, base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); } - CertDatabase::AddObserver(this); + CertDatabase::GetInstance()->AddObserver(this); } virtual ~DefaultClientSocketFactory() { // Note: This code never runs, as the factory is defined as a Leaky // singleton. - CertDatabase::RemoveObserver(this); + CertDatabase::GetInstance()->RemoveObserver(this); } - virtual void OnUserCertAdded(const X509Certificate* cert) OVERRIDE { + virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE { ClearSSLSessionCache(); } diff --git a/net/socket/client_socket_pool_manager_impl.cc b/net/socket/client_socket_pool_manager_impl.cc index b67ad0d..a91bca9 100644 --- a/net/socket/client_socket_pool_manager_impl.cc +++ b/net/socket/client_socket_pool_manager_impl.cc @@ -83,11 +83,11 @@ ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl( ssl_for_https_proxy_pool_histograms_("SSLforHTTPSProxy"), http_proxy_pool_histograms_("HTTPProxy"), ssl_socket_pool_for_proxies_histograms_("SSLForProxies") { - CertDatabase::AddObserver(this); + CertDatabase::GetInstance()->AddObserver(this); } ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() { - CertDatabase::RemoveObserver(this); + CertDatabase::GetInstance()->RemoveObserver(this); } void ClientSocketPoolManagerImpl::FlushSocketPools() { @@ -371,7 +371,7 @@ Value* ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const { return list; } -void ClientSocketPoolManagerImpl::OnUserCertAdded(const X509Certificate* cert) { +void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) { FlushSocketPools(); } diff --git a/net/socket/client_socket_pool_manager_impl.h b/net/socket/client_socket_pool_manager_impl.h index a3bb9a1..1b0de1d 100644 --- a/net/socket/client_socket_pool_manager_impl.h +++ b/net/socket/client_socket_pool_manager_impl.h @@ -89,7 +89,7 @@ class ClientSocketPoolManagerImpl : public base::NonThreadSafe, virtual base::Value* SocketPoolInfoToValue() const OVERRIDE; // CertDatabase::Observer methods: - virtual void OnUserCertAdded(const X509Certificate* cert) OVERRIDE; + virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE; virtual void OnCertTrustChanged(const X509Certificate* cert) OVERRIDE; private: diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc index 0a8eb7f..3c9db1d 100644 --- a/net/spdy/spdy_session_pool.cc +++ b/net/spdy/spdy_session_pool.cc @@ -55,7 +55,7 @@ SpdySessionPool::SpdySessionPool( NetworkChangeNotifier::AddIPAddressObserver(this); if (ssl_config_service_) ssl_config_service_->AddObserver(this); - CertDatabase::AddObserver(this); + CertDatabase::GetInstance()->AddObserver(this); } SpdySessionPool::~SpdySessionPool() { @@ -64,7 +64,7 @@ SpdySessionPool::~SpdySessionPool() { if (ssl_config_service_) ssl_config_service_->RemoveObserver(this); NetworkChangeNotifier::RemoveIPAddressObserver(this); - CertDatabase::RemoveObserver(this); + CertDatabase::GetInstance()->RemoveObserver(this); } scoped_refptr<SpdySession> SpdySessionPool::Get( @@ -309,7 +309,7 @@ scoped_refptr<SpdySession> SpdySessionPool::GetFromAlias( return NULL; } -void SpdySessionPool::OnUserCertAdded(const X509Certificate* cert) { +void SpdySessionPool::OnCertAdded(const X509Certificate* cert) { CloseCurrentSessions(); } diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h index ec9a74f..ebd9668 100644 --- a/net/spdy/spdy_session_pool.h +++ b/net/spdy/spdy_session_pool.h @@ -134,7 +134,7 @@ class NET_EXPORT SpdySessionPool static void enable_ip_pooling(bool value) { g_enable_ip_pooling = value; } // CertDatabase::Observer methods: - virtual void OnUserCertAdded(const X509Certificate* cert) OVERRIDE; + virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE; virtual void OnCertTrustChanged(const X509Certificate* cert) OVERRIDE; private: diff --git a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp index 234c065..89d0191 100644 --- a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp +++ b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp @@ -62,8 +62,8 @@ namespace mozilla_security_manager { // Based on nsNSSCertificateDB::handleCACertDownload, minus the UI bits. bool ImportCACerts(const net::CertificateList& certificates, net::X509Certificate* root, - net::CertDatabase::TrustBits trustBits, - net::CertDatabase::ImportCertFailureList* not_imported) { + net::NSSCertDatabase::TrustBits trustBits, + net::NSSCertDatabase::ImportCertFailureList* not_imported) { if (certificates.empty() || !root) return false; @@ -78,14 +78,14 @@ bool ImportCACerts(const net::CertificateList& certificates, // itself, so we skip it here. if (!CERT_IsCACert(root->os_cert_handle(), NULL)) { - not_imported->push_back(net::CertDatabase::ImportCertFailure( + not_imported->push_back(net::NSSCertDatabase::ImportCertFailure( root, net::ERR_IMPORT_CA_CERT_NOT_CA)); } else if (root->os_cert_handle()->isperm) { // Mozilla just returns here, but we continue in case there are other certs // in the list which aren't already imported. // TODO(mattm): should we set/add trust if it differs from the present // settings? - not_imported->push_back(net::CertDatabase::ImportCertFailure( + not_imported->push_back(net::NSSCertDatabase::ImportCertFailure( root, net::ERR_IMPORT_CERT_ALREADY_EXISTS)); } else { // Mozilla uses CERT_AddTempCertToPerm, however it is privately exported, @@ -122,14 +122,14 @@ bool ImportCACerts(const net::CertificateList& certificates, // Mozilla uses CERT_FilterCertListByUsage(certList, certUsageAnyCA, // PR_TRUE). Afaict, checking !CERT_IsCACert on each cert is equivalent. if (!CERT_IsCACert(cert->os_cert_handle(), NULL)) { - not_imported->push_back(net::CertDatabase::ImportCertFailure( + not_imported->push_back(net::NSSCertDatabase::ImportCertFailure( cert, net::ERR_IMPORT_CA_CERT_NOT_CA)); VLOG(1) << "skipping cert (non-ca)"; continue; } if (cert->os_cert_handle()->isperm) { - not_imported->push_back(net::CertDatabase::ImportCertFailure( + not_imported->push_back(net::NSSCertDatabase::ImportCertFailure( cert, net::ERR_IMPORT_CERT_ALREADY_EXISTS)); VLOG(1) << "skipping cert (perm)"; continue; @@ -140,7 +140,7 @@ bool ImportCACerts(const net::CertificateList& certificates, // TODO(mattm): use better error code (map PORT_GetError to an appropriate // error value). (maybe make MapSecurityError or MapCertErrorToCertStatus // public.) - not_imported->push_back(net::CertDatabase::ImportCertFailure( + not_imported->push_back(net::NSSCertDatabase::ImportCertFailure( cert, net::ERR_FAILED)); VLOG(1) << "skipping cert (verify) " << PORT_GetError(); continue; @@ -158,7 +158,7 @@ bool ImportCACerts(const net::CertificateList& certificates, LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError(); // TODO(mattm): Should we bail or continue on error here? Mozilla doesn't // check error code at all. - not_imported->push_back(net::CertDatabase::ImportCertFailure( + not_imported->push_back(net::NSSCertDatabase::ImportCertFailure( cert, net::ERR_IMPORT_CA_CERT_FAILED)); } } @@ -168,9 +168,10 @@ bool ImportCACerts(const net::CertificateList& certificates, } // Based on nsNSSCertificateDB::ImportServerCertificate. -bool ImportServerCert(const net::CertificateList& certificates, - net::CertDatabase::TrustBits trustBits, - net::CertDatabase::ImportCertFailureList* not_imported) { +bool ImportServerCert( + const net::CertificateList& certificates, + net::NSSCertDatabase::TrustBits trustBits, + net::NSSCertDatabase::ImportCertFailureList* not_imported) { if (certificates.empty()) return false; @@ -193,7 +194,7 @@ bool ImportServerCert(const net::CertificateList& certificates, PR_FALSE /* includeTrust (unused) */); if (srv != SECSuccess) { LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError(); - not_imported->push_back(net::CertDatabase::ImportCertFailure( + not_imported->push_back(net::NSSCertDatabase::ImportCertFailure( cert, net::ERR_IMPORT_SERVER_CERT_FAILED)); continue; } @@ -211,14 +212,14 @@ bool ImportServerCert(const net::CertificateList& certificates, bool SetCertTrust(const net::X509Certificate* cert, net::CertType type, - net::CertDatabase::TrustBits trustBits) + net::NSSCertDatabase::TrustBits trustBits) { - const unsigned kSSLTrustBits = net::CertDatabase::TRUSTED_SSL | - net::CertDatabase::DISTRUSTED_SSL; - const unsigned kEmailTrustBits = net::CertDatabase::TRUSTED_EMAIL | - net::CertDatabase::DISTRUSTED_EMAIL; - const unsigned kObjSignTrustBits = net::CertDatabase::TRUSTED_OBJ_SIGN | - net::CertDatabase::DISTRUSTED_OBJ_SIGN; + const unsigned kSSLTrustBits = net::NSSCertDatabase::TRUSTED_SSL | + net::NSSCertDatabase::DISTRUSTED_SSL; + const unsigned kEmailTrustBits = net::NSSCertDatabase::TRUSTED_EMAIL | + net::NSSCertDatabase::DISTRUSTED_EMAIL; + const unsigned kObjSignTrustBits = net::NSSCertDatabase::TRUSTED_OBJ_SIGN | + net::NSSCertDatabase::DISTRUSTED_OBJ_SIGN; if ((trustBits & kSSLTrustBits) == kSSLTrustBits || (trustBits & kEmailTrustBits) == kEmailTrustBits || (trustBits & kObjSignTrustBits) == kObjSignTrustBits) { @@ -236,19 +237,19 @@ SetCertTrust(const net::X509Certificate* cert, // CERTDB_TERMINAL_RECORD only. CERTCertTrust trust = {CERTDB_VALID_CA, CERTDB_VALID_CA, CERTDB_VALID_CA}; - if (trustBits & net::CertDatabase::DISTRUSTED_SSL) + if (trustBits & net::NSSCertDatabase::DISTRUSTED_SSL) trust.sslFlags = CERTDB_TERMINAL_RECORD; - else if (trustBits & net::CertDatabase::TRUSTED_SSL) + else if (trustBits & net::NSSCertDatabase::TRUSTED_SSL) trust.sslFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; - if (trustBits & net::CertDatabase::DISTRUSTED_EMAIL) + if (trustBits & net::NSSCertDatabase::DISTRUSTED_EMAIL) trust.emailFlags = CERTDB_TERMINAL_RECORD; - else if (trustBits & net::CertDatabase::TRUSTED_EMAIL) + else if (trustBits & net::NSSCertDatabase::TRUSTED_EMAIL) trust.emailFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; - if (trustBits & net::CertDatabase::DISTRUSTED_OBJ_SIGN) + if (trustBits & net::NSSCertDatabase::DISTRUSTED_OBJ_SIGN) trust.objectSigningFlags = CERTDB_TERMINAL_RECORD; - else if (trustBits & net::CertDatabase::TRUSTED_OBJ_SIGN) + else if (trustBits & net::NSSCertDatabase::TRUSTED_OBJ_SIGN) trust.objectSigningFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert, &trust); @@ -258,9 +259,9 @@ SetCertTrust(const net::X509Certificate* cert, CERT_GetCertTrust(nsscert, &trust); trust.sslFlags = 0; - if (trustBits & net::CertDatabase::DISTRUSTED_SSL) + if (trustBits & net::NSSCertDatabase::DISTRUSTED_SSL) trust.sslFlags |= CERTDB_TERMINAL_RECORD; - else if (trustBits & net::CertDatabase::TRUSTED_SSL) + else if (trustBits & net::NSSCertDatabase::TRUSTED_SSL) trust.sslFlags |= CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD; srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert, &trust); diff --git a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h index e7a5a103..0e5b33b 100644 --- a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h +++ b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h @@ -42,7 +42,7 @@ #include <vector> #include "base/memory/ref_counted.h" -#include "net/base/cert_database.h" +#include "net/base/nss_cert_database.h" typedef struct CERTCertificateStr CERTCertificate; namespace net { @@ -54,16 +54,17 @@ namespace mozilla_security_manager { bool ImportCACerts(const net::CertificateList& certificates, net::X509Certificate* root, - net::CertDatabase::TrustBits trustBits, - net::CertDatabase::ImportCertFailureList* not_imported); + net::NSSCertDatabase::TrustBits trustBits, + net::NSSCertDatabase::ImportCertFailureList* not_imported); -bool ImportServerCert(const net::CertificateList& certificates, - net::CertDatabase::TrustBits trustBits, - net::CertDatabase::ImportCertFailureList* not_imported); +bool ImportServerCert( + const net::CertificateList& certificates, + net::NSSCertDatabase::TrustBits trustBits, + net::NSSCertDatabase::ImportCertFailureList* not_imported); bool SetCertTrust(const net::X509Certificate* cert, net::CertType type, - net::CertDatabase::TrustBits trustBits); + net::NSSCertDatabase::TrustBits trustBits); } // namespace mozilla_security_manager |