1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/cert_database.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <cert.h> 83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <certdb.h> 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <keyhi.h> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <pk11pub.h> 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <secmod.h> 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/nss_util.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/nss_util_internal.h" 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/base/crypto_module.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/x509_certificate.h" 203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h" 21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/third_party/mozilla_security_manager/nsNSSCertTrust.h" 223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h" 233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// PSM = Mozilla's Personal Security Manager. 253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace psm = mozilla_security_manager; 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCertDatabase::CertDatabase() { 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::EnsureNSSInit(); 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick psm::EnsurePKCS12Init(); 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint CertDatabase::CheckUserCert(X509Certificate* cert_obj) { 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!cert_obj) 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ERR_CERT_INVALID; 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cert_obj->HasExpired()) 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ERR_CERT_DATE_INVALID; 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Check if the private key corresponding to the certificate exist 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We shouldn't accept any random client certificate sent by a CA. 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note: The NSS source documentation wrongly suggests that this 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // also imports the certificate if the private key exists. This 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // doesn't seem to be the case. 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CERTCertificate* cert = cert_obj->os_cert_handle(); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PK11SlotInfo* slot = PK11_KeyForCertExists(cert, NULL, NULL); 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!slot) { 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "No corresponding private key in store"; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ERR_NO_PRIVATE_KEY_FOR_CERT; 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PK11_FreeSlot(slot); 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return OK; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint CertDatabase::AddUserCert(X509Certificate* cert_obj) { 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CERTCertificate* cert = cert_obj->os_cert_handle(); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PK11SlotInfo* slot = NULL; 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string nickname; 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Create a nickname for this certificate. 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We use the scheme used by Firefox: 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // --> <subject's common name>'s <issuer's common name> ID. 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string username, ca_name; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char* temp_username = CERT_GetCommonName(&cert->subject); 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char* temp_ca_name = CERT_GetCommonName(&cert->issuer); 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (temp_username) { 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott username = temp_username; 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PORT_Free(temp_username); 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (temp_ca_name) { 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ca_name = temp_ca_name; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PORT_Free(temp_ca_name); 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott nickname = username + "'s " + ca_name + " ID"; 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::AutoNSSWriteLock lock; 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch slot = PK11_ImportCertForKey(cert, 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>(nickname.c_str()), 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!slot) { 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Couldn't import user certificate."; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ERR_ADD_USER_CERT_FAILED; 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PK11_FreeSlot(slot); 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CertDatabase::NotifyObserversOfUserCertAdded(cert_obj); 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return OK; 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid CertDatabase::ListCerts(CertificateList* certs) { 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick certs->clear(); 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CERTCertList* cert_list = PK11_ListCerts(PK11CertListUnique, NULL); 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CERTCertListNode* node; 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (node = CERT_LIST_HEAD(cert_list); 1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick !CERT_LIST_END(node, cert_list); 1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick node = CERT_LIST_NEXT(node)) { 1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick certs->push_back(X509Certificate::CreateFromHandle( 1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick node->cert, 1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick X509Certificate::SOURCE_LONE_CERT_IMPORT, 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick X509Certificate::OSCertHandles())); 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CERT_DestroyCertList(cert_list); 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenCryptoModule* CertDatabase::GetPublicModule() const { 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CryptoModule* module = 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CryptoModule::CreateFromHandle(crypto::GetPublicNSSKeySlot()); 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The module is already referenced when returned from 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // GetPublicNSSKeySlot, so we need to deref it once. 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PK11_FreeSlot(module->os_module_handle()); 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return module; 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenCryptoModule* CertDatabase::GetPrivateModule() const { 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CryptoModule* module = 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CryptoModule::CreateFromHandle(crypto::GetPrivateNSSKeySlot()); 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The module is already referenced when returned from 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // GetPrivateNSSKeySlot, so we need to deref it once. 12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PK11_FreeSlot(module->os_module_handle()); 12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return module; 13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CertDatabase::ListModules(CryptoModuleList* modules, bool need_rw) const { 133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen modules->clear(); 134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PK11SlotList* slot_list = NULL; 136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc. 137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen slot_list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, 138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen need_rw ? PR_TRUE : PR_FALSE, // needRW 139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PR_TRUE, // loadCerts (unused) 140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NULL); // wincx 141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!slot_list) { 142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(ERROR) << "PK11_GetAllTokens failed: " << PORT_GetError(); 143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PK11SlotListElement* slot_element = PK11_GetFirstSafe(slot_list); 147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen while (slot_element) { 148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen modules->push_back(CryptoModule::CreateFromHandle(slot_element->slot)); 149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen slot_element = PK11_GetNextSafe(slot_list, slot_element, 150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PR_FALSE); // restart 151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PK11_FreeSlotList(slot_list); 154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint CertDatabase::ImportFromPKCS12( 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CryptoModule* module, 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& data, 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& password) { 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int result = psm::nsPKCS12Blob_Import(module->os_module_handle(), 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen data.data(), data.size(), 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen password); 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (result == net::OK) 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CertDatabase::NotifyObserversOfUserCertAdded(NULL); 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint CertDatabase::ExportToPKCS12( 1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const CertificateList& certs, 1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& password, 172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string* output) const { 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return psm::nsPKCS12Blob_Export(output, certs, password); 1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickX509Certificate* CertDatabase::FindRootInList( 177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const CertificateList& certificates) const { 1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_GT(certificates.size(), 0U); 1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (certificates.size() == 1) 1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return certificates[0].get(); 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick X509Certificate* cert0 = certificates[0]; 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick X509Certificate* cert1 = certificates[1]; 1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick X509Certificate* certn_2 = certificates[certificates.size() - 2]; 1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick X509Certificate* certn_1 = certificates[certificates.size() - 1]; 1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (CERT_CompareName(&cert1->os_cert_handle()->issuer, 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick &cert0->os_cert_handle()->subject) == SECEqual) 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return cert0; 1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (CERT_CompareName(&certn_2->os_cert_handle()->issuer, 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick &certn_1->os_cert_handle()->subject) == SECEqual) 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return certn_1; 1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "certificate list is not a hierarchy"; 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return cert0; 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool CertDatabase::ImportCACerts(const CertificateList& certificates, 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick unsigned int trust_bits, 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ImportCertFailureList* not_imported) { 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick X509Certificate* root = FindRootInList(certificates); 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool success = psm::ImportCACerts(certificates, root, trust_bits, 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen not_imported); 205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (success) 206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CertDatabase::NotifyObserversOfCertTrustChanged(NULL); 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return success; 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 211731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool CertDatabase::ImportServerCert(const CertificateList& certificates, 212731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ImportCertFailureList* not_imported) { 213731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return psm::ImportServerCert(certificates, not_imported); 214731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickunsigned int CertDatabase::GetCertTrust( 217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const X509Certificate* cert, CertType type) const { 218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CERTCertTrust nsstrust; 219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SECStatus srv = CERT_GetCertTrust(cert->os_cert_handle(), &nsstrust); 220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (srv != SECSuccess) { 221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError(); 222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return UNTRUSTED; 223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick psm::nsNSSCertTrust trust(&nsstrust); 225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick switch (type) { 226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case CA_CERT: 227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return trust.HasTrustedCA(PR_TRUE, PR_FALSE, PR_FALSE) * TRUSTED_SSL + 228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick trust.HasTrustedCA(PR_FALSE, PR_TRUE, PR_FALSE) * TRUSTED_EMAIL + 229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick trust.HasTrustedCA(PR_FALSE, PR_FALSE, PR_TRUE) * TRUSTED_OBJ_SIGN; 230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case SERVER_CERT: 231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return trust.HasTrustedPeer(PR_TRUE, PR_FALSE, PR_FALSE) * TRUSTED_SSL + 232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick trust.HasTrustedPeer(PR_FALSE, PR_TRUE, PR_FALSE) * TRUSTED_EMAIL + 233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick trust.HasTrustedPeer(PR_FALSE, PR_FALSE, PR_TRUE) * TRUSTED_OBJ_SIGN; 234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default: 235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return UNTRUSTED; 236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool CertDatabase::SetCertTrust(const X509Certificate* cert, 2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CertType type, 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick unsigned int trusted) { 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool success = psm::SetCertTrust(cert, type, trusted); 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (success) 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CertDatabase::NotifyObserversOfCertTrustChanged(cert); 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return success; 2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(xiyuan): Add an Observer method for this event. 2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool CertDatabase::DeleteCertAndKey(const X509Certificate* cert) { 2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // For some reason, PK11_DeleteTokenCertAndKey only calls 2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // SEC_DeletePermCertificate if the private key is found. So, we check 2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // whether a private key exists before deciding which function to call to 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // delete the cert. 2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert->os_cert_handle(), 2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL); 2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (privKey) { 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SECKEY_DestroyPrivateKey(privKey); 2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (PK11_DeleteTokenCertAndKey(cert->os_cert_handle(), NULL)) { 2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError(); 2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (SEC_DeletePermCertificate(cert->os_cert_handle())) { 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "SEC_DeletePermCertificate failed: " << PORT_GetError(); 2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 2703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 272513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool CertDatabase::IsReadOnly(const X509Certificate* cert) const { 273513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PK11SlotInfo* slot = cert->os_cert_handle()->slot; 274513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return slot && PK11_IsReadOnly(slot); 275513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 278