| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/cert_database.h" | 5 #include "net/base/nss_cert_database.h" |
| 6 | 6 |
| 7 #include <cert.h> | 7 #include <cert.h> |
| 8 #include <certdb.h> | 8 #include <certdb.h> |
| 9 #include <keyhi.h> | 9 #include <keyhi.h> |
| 10 #include <pk11pub.h> | 10 #include <pk11pub.h> |
| 11 #include <secmod.h> | 11 #include <secmod.h> |
| 12 | 12 |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/memory/singleton.h" |
| 16 #include "base/observer_list_threadsafe.h" |
| 15 #include "crypto/nss_util.h" | 17 #include "crypto/nss_util.h" |
| 16 #include "crypto/nss_util_internal.h" | 18 #include "crypto/nss_util_internal.h" |
| 19 #include "net/base/cert_database.h" |
| 17 #include "net/base/crypto_module.h" | 20 #include "net/base/crypto_module.h" |
| 18 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 19 #include "net/base/x509_certificate.h" | 22 #include "net/base/x509_certificate.h" |
| 20 #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h" | 23 #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h" |
| 21 #include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h" | 24 #include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h" |
| 22 | 25 |
| 23 // In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use | 26 // In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use |
| 24 // the new name of the macro. | 27 // the new name of the macro. |
| 25 #if !defined(CERTDB_TERMINAL_RECORD) | 28 #if !defined(CERTDB_TERMINAL_RECORD) |
| 26 #define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER | 29 #define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER |
| 27 #endif | 30 #endif |
| 28 | 31 |
| 29 // PSM = Mozilla's Personal Security Manager. | 32 // PSM = Mozilla's Personal Security Manager. |
| 30 namespace psm = mozilla_security_manager; | 33 namespace psm = mozilla_security_manager; |
| 31 | 34 |
| 32 namespace net { | 35 namespace net { |
| 33 | 36 |
| 34 CertDatabase::CertDatabase() { | 37 namespace { |
| 35 crypto::EnsureNSSInit(); | 38 |
| 36 psm::EnsurePKCS12Init(); | 39 // Notifies registered observers when new user certificates are added to the |
| 37 } | 40 // database. |
| 41 class NSSCertDatabaseNotifier { |
| 42 public: |
| 43 NSSCertDatabaseNotifier() |
| 44 : observer_list_(new ObserverListThreadSafe<NSSCertDatabase::Observer>) {} |
| 45 |
| 46 static NSSCertDatabaseNotifier* GetInstance() { |
| 47 return Singleton<NSSCertDatabaseNotifier>::get(); |
| 48 } |
| 49 |
| 50 private: |
| 51 friend struct DefaultSingletonTraits<NSSCertDatabaseNotifier>; |
| 52 friend class net::NSSCertDatabase; |
| 53 |
| 54 const scoped_refptr<ObserverListThreadSafe<NSSCertDatabase::Observer> > |
| 55 observer_list_; |
| 56 }; |
| 57 |
| 58 } // namespace |
| 59 |
| 60 // CertDatabase ---------------------------------------------------------------- |
| 38 | 61 |
| 39 int CertDatabase::CheckUserCert(X509Certificate* cert_obj) { | 62 int CertDatabase::CheckUserCert(X509Certificate* cert_obj) { |
| 40 if (!cert_obj) | 63 if (!cert_obj) |
| 41 return ERR_CERT_INVALID; | 64 return ERR_CERT_INVALID; |
| 42 if (cert_obj->HasExpired()) | 65 if (cert_obj->HasExpired()) |
| 43 return ERR_CERT_DATE_INVALID; | 66 return ERR_CERT_DATE_INVALID; |
| 44 | 67 |
| 45 // Check if the private key corresponding to the certificate exist | 68 // Check if the private key corresponding to the certificate exist |
| 46 // We shouldn't accept any random client certificate sent by a CA. | 69 // We shouldn't accept any random client certificate sent by a CA. |
| 47 | 70 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 69 cert, | 92 cert, |
| 70 cert_obj->GetDefaultNickname(net::USER_CERT).c_str(), | 93 cert_obj->GetDefaultNickname(net::USER_CERT).c_str(), |
| 71 NULL); | 94 NULL); |
| 72 } | 95 } |
| 73 | 96 |
| 74 if (!slot) { | 97 if (!slot) { |
| 75 LOG(ERROR) << "Couldn't import user certificate."; | 98 LOG(ERROR) << "Couldn't import user certificate."; |
| 76 return ERR_ADD_USER_CERT_FAILED; | 99 return ERR_ADD_USER_CERT_FAILED; |
| 77 } | 100 } |
| 78 PK11_FreeSlot(slot); | 101 PK11_FreeSlot(slot); |
| 79 CertDatabase::NotifyObserversOfUserCertAdded(cert_obj); | 102 NotifyObserversOfCertAdded(cert_obj); |
| 80 return OK; | 103 return OK; |
| 81 } | 104 } |
| 82 | 105 |
| 83 void CertDatabase::ListCerts(CertificateList* certs) { | 106 // NSSCertDatabase::ImportCertFailure ------------------------------------------ |
| 107 |
| 108 NSSCertDatabase::ImportCertFailure::ImportCertFailure( |
| 109 X509Certificate* cert, int err) |
| 110 : certificate(cert), |
| 111 net_error(err) {} |
| 112 |
| 113 NSSCertDatabase::ImportCertFailure::~ImportCertFailure() {} |
| 114 |
| 115 // NSSCertDatabase ------------------------------------------------------------- |
| 116 |
| 117 NSSCertDatabase::NSSCertDatabase() { |
| 118 EnsureInit(); |
| 119 } |
| 120 |
| 121 // static |
| 122 void NSSCertDatabase::EnsureInit() { |
| 123 crypto::EnsureNSSInit(); |
| 124 psm::EnsurePKCS12Init(); |
| 125 } |
| 126 |
| 127 void NSSCertDatabase::ListCerts(CertificateList* certs) { |
| 84 certs->clear(); | 128 certs->clear(); |
| 85 | 129 |
| 86 CERTCertList* cert_list = PK11_ListCerts(PK11CertListUnique, NULL); | 130 CERTCertList* cert_list = PK11_ListCerts(PK11CertListUnique, NULL); |
| 87 CERTCertListNode* node; | 131 CERTCertListNode* node; |
| 88 for (node = CERT_LIST_HEAD(cert_list); | 132 for (node = CERT_LIST_HEAD(cert_list); |
| 89 !CERT_LIST_END(node, cert_list); | 133 !CERT_LIST_END(node, cert_list); |
| 90 node = CERT_LIST_NEXT(node)) { | 134 node = CERT_LIST_NEXT(node)) { |
| 91 certs->push_back(X509Certificate::CreateFromHandle( | 135 certs->push_back(X509Certificate::CreateFromHandle( |
| 92 node->cert, X509Certificate::OSCertHandles())); | 136 node->cert, X509Certificate::OSCertHandles())); |
| 93 } | 137 } |
| 94 CERT_DestroyCertList(cert_list); | 138 CERT_DestroyCertList(cert_list); |
| 95 } | 139 } |
| 96 | 140 |
| 97 CryptoModule* CertDatabase::GetPublicModule() const { | 141 CryptoModule* NSSCertDatabase::GetPublicModule() const { |
| 98 CryptoModule* module = | 142 CryptoModule* module = |
| 99 CryptoModule::CreateFromHandle(crypto::GetPublicNSSKeySlot()); | 143 CryptoModule::CreateFromHandle(crypto::GetPublicNSSKeySlot()); |
| 100 // The module is already referenced when returned from | 144 // The module is already referenced when returned from |
| 101 // GetPublicNSSKeySlot, so we need to deref it once. | 145 // GetPublicNSSKeySlot, so we need to deref it once. |
| 102 PK11_FreeSlot(module->os_module_handle()); | 146 PK11_FreeSlot(module->os_module_handle()); |
| 103 | 147 |
| 104 return module; | 148 return module; |
| 105 } | 149 } |
| 106 | 150 |
| 107 CryptoModule* CertDatabase::GetPrivateModule() const { | 151 CryptoModule* NSSCertDatabase::GetPrivateModule() const { |
| 108 CryptoModule* module = | 152 CryptoModule* module = |
| 109 CryptoModule::CreateFromHandle(crypto::GetPrivateNSSKeySlot()); | 153 CryptoModule::CreateFromHandle(crypto::GetPrivateNSSKeySlot()); |
| 110 // The module is already referenced when returned from | 154 // The module is already referenced when returned from |
| 111 // GetPrivateNSSKeySlot, so we need to deref it once. | 155 // GetPrivateNSSKeySlot, so we need to deref it once. |
| 112 PK11_FreeSlot(module->os_module_handle()); | 156 PK11_FreeSlot(module->os_module_handle()); |
| 113 | 157 |
| 114 return module; | 158 return module; |
| 115 } | 159 } |
| 116 | 160 |
| 117 void CertDatabase::ListModules(CryptoModuleList* modules, bool need_rw) const { | 161 void NSSCertDatabase::ListModules(CryptoModuleList* modules, |
| 162 bool need_rw) const { |
| 118 modules->clear(); | 163 modules->clear(); |
| 119 | 164 |
| 120 PK11SlotList* slot_list = NULL; | 165 PK11SlotList* slot_list = NULL; |
| 121 // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc. | 166 // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc. |
| 122 slot_list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, | 167 slot_list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, |
| 123 need_rw ? PR_TRUE : PR_FALSE, // needRW | 168 need_rw ? PR_TRUE : PR_FALSE, // needRW |
| 124 PR_TRUE, // loadCerts (unused) | 169 PR_TRUE, // loadCerts (unused) |
| 125 NULL); // wincx | 170 NULL); // wincx |
| 126 if (!slot_list) { | 171 if (!slot_list) { |
| 127 LOG(ERROR) << "PK11_GetAllTokens failed: " << PORT_GetError(); | 172 LOG(ERROR) << "PK11_GetAllTokens failed: " << PORT_GetError(); |
| 128 return; | 173 return; |
| 129 } | 174 } |
| 130 | 175 |
| 131 PK11SlotListElement* slot_element = PK11_GetFirstSafe(slot_list); | 176 PK11SlotListElement* slot_element = PK11_GetFirstSafe(slot_list); |
| 132 while (slot_element) { | 177 while (slot_element) { |
| 133 modules->push_back(CryptoModule::CreateFromHandle(slot_element->slot)); | 178 modules->push_back(CryptoModule::CreateFromHandle(slot_element->slot)); |
| 134 slot_element = PK11_GetNextSafe(slot_list, slot_element, | 179 slot_element = PK11_GetNextSafe(slot_list, slot_element, |
| 135 PR_FALSE); // restart | 180 PR_FALSE); // restart |
| 136 } | 181 } |
| 137 | 182 |
| 138 PK11_FreeSlotList(slot_list); | 183 PK11_FreeSlotList(slot_list); |
| 139 } | 184 } |
| 140 | 185 |
| 141 int CertDatabase::ImportFromPKCS12( | 186 int NSSCertDatabase::ImportFromPKCS12( |
| 142 CryptoModule* module, | 187 CryptoModule* module, |
| 143 const std::string& data, | 188 const std::string& data, |
| 144 const string16& password, | 189 const string16& password, |
| 145 bool is_extractable, | 190 bool is_extractable, |
| 146 net::CertificateList* imported_certs) { | 191 net::CertificateList* imported_certs) { |
| 147 int result = psm::nsPKCS12Blob_Import(module->os_module_handle(), | 192 int result = psm::nsPKCS12Blob_Import(module->os_module_handle(), |
| 148 data.data(), data.size(), | 193 data.data(), data.size(), |
| 149 password, | 194 password, |
| 150 is_extractable, | 195 is_extractable, |
| 151 imported_certs); | 196 imported_certs); |
| 152 if (result == net::OK) | 197 if (result == net::OK) |
| 153 CertDatabase::NotifyObserversOfUserCertAdded(NULL); | 198 NotifyObserversOfCertAdded(NULL); |
| 154 | 199 |
| 155 return result; | 200 return result; |
| 156 } | 201 } |
| 157 | 202 |
| 158 int CertDatabase::ExportToPKCS12( | 203 int NSSCertDatabase::ExportToPKCS12( |
| 159 const CertificateList& certs, | 204 const CertificateList& certs, |
| 160 const string16& password, | 205 const string16& password, |
| 161 std::string* output) const { | 206 std::string* output) const { |
| 162 return psm::nsPKCS12Blob_Export(output, certs, password); | 207 return psm::nsPKCS12Blob_Export(output, certs, password); |
| 163 } | 208 } |
| 164 | 209 |
| 165 X509Certificate* CertDatabase::FindRootInList( | 210 X509Certificate* NSSCertDatabase::FindRootInList( |
| 166 const CertificateList& certificates) const { | 211 const CertificateList& certificates) const { |
| 167 DCHECK_GT(certificates.size(), 0U); | 212 DCHECK_GT(certificates.size(), 0U); |
| 168 | 213 |
| 169 if (certificates.size() == 1) | 214 if (certificates.size() == 1) |
| 170 return certificates[0].get(); | 215 return certificates[0].get(); |
| 171 | 216 |
| 172 X509Certificate* cert0 = certificates[0]; | 217 X509Certificate* cert0 = certificates[0]; |
| 173 X509Certificate* cert1 = certificates[1]; | 218 X509Certificate* cert1 = certificates[1]; |
| 174 X509Certificate* certn_2 = certificates[certificates.size() - 2]; | 219 X509Certificate* certn_2 = certificates[certificates.size() - 2]; |
| 175 X509Certificate* certn_1 = certificates[certificates.size() - 1]; | 220 X509Certificate* certn_1 = certificates[certificates.size() - 1]; |
| 176 | 221 |
| 177 if (CERT_CompareName(&cert1->os_cert_handle()->issuer, | 222 if (CERT_CompareName(&cert1->os_cert_handle()->issuer, |
| 178 &cert0->os_cert_handle()->subject) == SECEqual) | 223 &cert0->os_cert_handle()->subject) == SECEqual) |
| 179 return cert0; | 224 return cert0; |
| 180 if (CERT_CompareName(&certn_2->os_cert_handle()->issuer, | 225 if (CERT_CompareName(&certn_2->os_cert_handle()->issuer, |
| 181 &certn_1->os_cert_handle()->subject) == SECEqual) | 226 &certn_1->os_cert_handle()->subject) == SECEqual) |
| 182 return certn_1; | 227 return certn_1; |
| 183 | 228 |
| 184 VLOG(1) << "certificate list is not a hierarchy"; | 229 VLOG(1) << "certificate list is not a hierarchy"; |
| 185 return cert0; | 230 return cert0; |
| 186 } | 231 } |
| 187 | 232 |
| 188 bool CertDatabase::ImportCACerts(const CertificateList& certificates, | 233 bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates, |
| 189 TrustBits trust_bits, | 234 TrustBits trust_bits, |
| 190 ImportCertFailureList* not_imported) { | 235 ImportCertFailureList* not_imported) { |
| 191 X509Certificate* root = FindRootInList(certificates); | 236 X509Certificate* root = FindRootInList(certificates); |
| 192 bool success = psm::ImportCACerts(certificates, root, trust_bits, | 237 bool success = psm::ImportCACerts(certificates, root, trust_bits, |
| 193 not_imported); | 238 not_imported); |
| 194 if (success) | 239 if (success) |
| 195 CertDatabase::NotifyObserversOfCertTrustChanged(NULL); | 240 NotifyObserversOfCertTrustChanged(NULL); |
| 196 | 241 |
| 197 return success; | 242 return success; |
| 198 } | 243 } |
| 199 | 244 |
| 200 bool CertDatabase::ImportServerCert(const CertificateList& certificates, | 245 bool NSSCertDatabase::ImportServerCert(const CertificateList& certificates, |
| 201 TrustBits trust_bits, | 246 TrustBits trust_bits, |
| 202 ImportCertFailureList* not_imported) { | 247 ImportCertFailureList* not_imported) { |
| 203 return psm::ImportServerCert(certificates, trust_bits, not_imported); | 248 return psm::ImportServerCert(certificates, trust_bits, not_imported); |
| 204 } | 249 } |
| 205 | 250 |
| 206 CertDatabase::TrustBits CertDatabase::GetCertTrust(const X509Certificate* cert, | 251 NSSCertDatabase::TrustBits NSSCertDatabase::GetCertTrust( |
| 207 CertType type) const { | 252 const X509Certificate* cert, |
| 253 CertType type) const { |
| 208 CERTCertTrust trust; | 254 CERTCertTrust trust; |
| 209 SECStatus srv = CERT_GetCertTrust(cert->os_cert_handle(), &trust); | 255 SECStatus srv = CERT_GetCertTrust(cert->os_cert_handle(), &trust); |
| 210 if (srv != SECSuccess) { | 256 if (srv != SECSuccess) { |
| 211 LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError(); | 257 LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError(); |
| 212 return TRUST_DEFAULT; | 258 return TRUST_DEFAULT; |
| 213 } | 259 } |
| 214 // We define our own more "friendly" TrustBits, which means we aren't able to | 260 // We define our own more "friendly" TrustBits, which means we aren't able to |
| 215 // round-trip all possible NSS trust flag combinations. We try to map them in | 261 // round-trip all possible NSS trust flag combinations. We try to map them in |
| 216 // a sensible way. | 262 // a sensible way. |
| 217 switch (type) { | 263 switch (type) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 242 if (trust.sslFlags & CERTDB_TRUSTED) | 288 if (trust.sslFlags & CERTDB_TRUSTED) |
| 243 return TRUSTED_SSL; | 289 return TRUSTED_SSL; |
| 244 return DISTRUSTED_SSL; | 290 return DISTRUSTED_SSL; |
| 245 } | 291 } |
| 246 return TRUST_DEFAULT; | 292 return TRUST_DEFAULT; |
| 247 default: | 293 default: |
| 248 return TRUST_DEFAULT; | 294 return TRUST_DEFAULT; |
| 249 } | 295 } |
| 250 } | 296 } |
| 251 | 297 |
| 252 bool CertDatabase::IsUntrusted(const X509Certificate* cert) const { | 298 bool NSSCertDatabase::IsUntrusted(const X509Certificate* cert) const { |
| 253 CERTCertTrust nsstrust; | 299 CERTCertTrust nsstrust; |
| 254 SECStatus rv = CERT_GetCertTrust(cert->os_cert_handle(), &nsstrust); | 300 SECStatus rv = CERT_GetCertTrust(cert->os_cert_handle(), &nsstrust); |
| 255 if (rv != SECSuccess) { | 301 if (rv != SECSuccess) { |
| 256 LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError(); | 302 LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError(); |
| 257 return false; | 303 return false; |
| 258 } | 304 } |
| 259 | 305 |
| 260 // The CERTCertTrust structure contains three trust records: | 306 // The CERTCertTrust structure contains three trust records: |
| 261 // sslFlags, emailFlags, and objectSigningFlags. The three | 307 // sslFlags, emailFlags, and objectSigningFlags. The three |
| 262 // trust records are independent of each other. | 308 // trust records are independent of each other. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 if (CERT_CompareName(&cert->os_cert_handle()->issuer, | 341 if (CERT_CompareName(&cert->os_cert_handle()->issuer, |
| 296 &cert->os_cert_handle()->subject) == SECEqual) { | 342 &cert->os_cert_handle()->subject) == SECEqual) { |
| 297 return (nsstrust.sslFlags & kTrusted) == 0 && | 343 return (nsstrust.sslFlags & kTrusted) == 0 && |
| 298 (nsstrust.emailFlags & kTrusted) == 0 && | 344 (nsstrust.emailFlags & kTrusted) == 0 && |
| 299 (nsstrust.objectSigningFlags & kTrusted) == 0; | 345 (nsstrust.objectSigningFlags & kTrusted) == 0; |
| 300 } | 346 } |
| 301 | 347 |
| 302 return false; | 348 return false; |
| 303 } | 349 } |
| 304 | 350 |
| 305 bool CertDatabase::SetCertTrust(const X509Certificate* cert, | 351 bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert, |
| 306 CertType type, | 352 CertType type, |
| 307 TrustBits trust_bits) { | 353 TrustBits trust_bits) { |
| 308 bool success = psm::SetCertTrust(cert, type, trust_bits); | 354 bool success = psm::SetCertTrust(cert, type, trust_bits); |
| 309 if (success) | 355 if (success) |
| 310 CertDatabase::NotifyObserversOfCertTrustChanged(cert); | 356 NotifyObserversOfCertTrustChanged(cert); |
| 311 | 357 |
| 312 return success; | 358 return success; |
| 313 } | 359 } |
| 314 | 360 |
| 315 bool CertDatabase::DeleteCertAndKey(const X509Certificate* cert) { | 361 bool NSSCertDatabase::DeleteCertAndKey(const X509Certificate* cert) { |
| 316 // For some reason, PK11_DeleteTokenCertAndKey only calls | 362 // For some reason, PK11_DeleteTokenCertAndKey only calls |
| 317 // SEC_DeletePermCertificate if the private key is found. So, we check | 363 // SEC_DeletePermCertificate if the private key is found. So, we check |
| 318 // whether a private key exists before deciding which function to call to | 364 // whether a private key exists before deciding which function to call to |
| 319 // delete the cert. | 365 // delete the cert. |
| 320 SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert->os_cert_handle(), | 366 SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert->os_cert_handle(), |
| 321 NULL); | 367 NULL); |
| 322 if (privKey) { | 368 if (privKey) { |
| 323 SECKEY_DestroyPrivateKey(privKey); | 369 SECKEY_DestroyPrivateKey(privKey); |
| 324 if (PK11_DeleteTokenCertAndKey(cert->os_cert_handle(), NULL)) { | 370 if (PK11_DeleteTokenCertAndKey(cert->os_cert_handle(), NULL)) { |
| 325 LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError(); | 371 LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError(); |
| 326 return false; | 372 return false; |
| 327 } | 373 } |
| 328 } else { | 374 } else { |
| 329 if (SEC_DeletePermCertificate(cert->os_cert_handle())) { | 375 if (SEC_DeletePermCertificate(cert->os_cert_handle())) { |
| 330 LOG(ERROR) << "SEC_DeletePermCertificate failed: " << PORT_GetError(); | 376 LOG(ERROR) << "SEC_DeletePermCertificate failed: " << PORT_GetError(); |
| 331 return false; | 377 return false; |
| 332 } | 378 } |
| 333 } | 379 } |
| 334 | 380 |
| 335 CertDatabase::NotifyObserversOfUserCertRemoved(cert); | 381 NotifyObserversOfCertRemoved(cert); |
| 336 | 382 |
| 337 return true; | 383 return true; |
| 338 } | 384 } |
| 339 | 385 |
| 340 bool CertDatabase::IsReadOnly(const X509Certificate* cert) const { | 386 bool NSSCertDatabase::IsReadOnly(const X509Certificate* cert) const { |
| 341 PK11SlotInfo* slot = cert->os_cert_handle()->slot; | 387 PK11SlotInfo* slot = cert->os_cert_handle()->slot; |
| 342 return slot && PK11_IsReadOnly(slot); | 388 return slot && PK11_IsReadOnly(slot); |
| 343 } | 389 } |
| 344 | 390 |
| 391 void NSSCertDatabase::AddObserver(Observer* observer) { |
| 392 NSSCertDatabaseNotifier::GetInstance()->observer_list_->AddObserver(observer); |
| 393 } |
| 394 |
| 395 void NSSCertDatabase::RemoveObserver(Observer* observer) { |
| 396 NSSCertDatabaseNotifier::GetInstance()->observer_list_->RemoveObserver( |
| 397 observer); |
| 398 } |
| 399 |
| 400 void NSSCertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) { |
| 401 NSSCertDatabaseNotifier::GetInstance()->observer_list_->Notify( |
| 402 &Observer::OnCertAdded, make_scoped_refptr(cert)); |
| 403 } |
| 404 |
| 405 void NSSCertDatabase::NotifyObserversOfCertRemoved( |
| 406 const X509Certificate* cert) { |
| 407 NSSCertDatabaseNotifier::GetInstance()->observer_list_->Notify( |
| 408 &Observer::OnCertRemoved, make_scoped_refptr(cert)); |
| 409 } |
| 410 |
| 411 void NSSCertDatabase::NotifyObserversOfCertTrustChanged( |
| 412 const X509Certificate* cert) { |
| 413 NSSCertDatabaseNotifier::GetInstance()->observer_list_->Notify( |
| 414 &Observer::OnCertTrustChanged, make_scoped_refptr(cert)); |
| 415 } |
| 416 |
| 345 } // namespace net | 417 } // namespace net |
| OLD | NEW |