| 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/cert/nss_cert_database.h" | 5 #include "net/cert/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> |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 // the c'tor of NSSCertDatabase, see https://crbug.com/395983 . | 44 // the c'tor of NSSCertDatabase, see https://crbug.com/395983 . |
| 45 // Helper that observes events from the NSSCertDatabase and forwards them to | 45 // Helper that observes events from the NSSCertDatabase and forwards them to |
| 46 // the given CertDatabase. | 46 // the given CertDatabase. |
| 47 class CertNotificationForwarder : public NSSCertDatabase::Observer { | 47 class CertNotificationForwarder : public NSSCertDatabase::Observer { |
| 48 public: | 48 public: |
| 49 explicit CertNotificationForwarder(CertDatabase* cert_db) | 49 explicit CertNotificationForwarder(CertDatabase* cert_db) |
| 50 : cert_db_(cert_db) {} | 50 : cert_db_(cert_db) {} |
| 51 | 51 |
| 52 ~CertNotificationForwarder() override {} | 52 ~CertNotificationForwarder() override {} |
| 53 | 53 |
| 54 void OnCertDBChanged(const X509Certificate* cert) override { | 54 void OnCertDBChanged() override { cert_db_->NotifyObserversCertDBChanged(); } |
| 55 cert_db_->NotifyObserversCertDBChanged(cert); | |
| 56 } | |
| 57 | 55 |
| 58 private: | 56 private: |
| 59 CertDatabase* cert_db_; | 57 CertDatabase* cert_db_; |
| 60 | 58 |
| 61 DISALLOW_COPY_AND_ASSIGN(CertNotificationForwarder); | 59 DISALLOW_COPY_AND_ASSIGN(CertNotificationForwarder); |
| 62 }; | 60 }; |
| 63 | 61 |
| 64 } // namespace | 62 } // namespace |
| 65 | 63 |
| 66 NSSCertDatabase::ImportCertFailure::ImportCertFailure( | 64 NSSCertDatabase::ImportCertFailure::ImportCertFailure( |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 CertificateList* imported_certs) { | 175 CertificateList* imported_certs) { |
| 178 DVLOG(1) << __func__ << " " | 176 DVLOG(1) << __func__ << " " |
| 179 << PK11_GetModuleID(slot_info) << ":" | 177 << PK11_GetModuleID(slot_info) << ":" |
| 180 << PK11_GetSlotID(slot_info); | 178 << PK11_GetSlotID(slot_info); |
| 181 int result = psm::nsPKCS12Blob_Import(slot_info, | 179 int result = psm::nsPKCS12Blob_Import(slot_info, |
| 182 data.data(), data.size(), | 180 data.data(), data.size(), |
| 183 password, | 181 password, |
| 184 is_extractable, | 182 is_extractable, |
| 185 imported_certs); | 183 imported_certs); |
| 186 if (result == OK) | 184 if (result == OK) |
| 187 NotifyObserversCertDBChanged(NULL); | 185 NotifyObserversCertDBChanged(); |
| 188 | 186 |
| 189 return result; | 187 return result; |
| 190 } | 188 } |
| 191 | 189 |
| 192 int NSSCertDatabase::ExportToPKCS12( | 190 int NSSCertDatabase::ExportToPKCS12( |
| 193 const CertificateList& certs, | 191 const CertificateList& certs, |
| 194 const base::string16& password, | 192 const base::string16& password, |
| 195 std::string* output) const { | 193 std::string* output) const { |
| 196 return psm::nsPKCS12Blob_Export(output, certs, password); | 194 return psm::nsPKCS12Blob_Export(output, certs, password); |
| 197 } | 195 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 219 return cert0; | 217 return cert0; |
| 220 } | 218 } |
| 221 | 219 |
| 222 int NSSCertDatabase::ImportUserCert(const std::string& data) { | 220 int NSSCertDatabase::ImportUserCert(const std::string& data) { |
| 223 CertificateList certificates = | 221 CertificateList certificates = |
| 224 X509Certificate::CreateCertificateListFromBytes( | 222 X509Certificate::CreateCertificateListFromBytes( |
| 225 data.c_str(), data.size(), net::X509Certificate::FORMAT_AUTO); | 223 data.c_str(), data.size(), net::X509Certificate::FORMAT_AUTO); |
| 226 int result = psm::ImportUserCert(certificates); | 224 int result = psm::ImportUserCert(certificates); |
| 227 | 225 |
| 228 if (result == OK) | 226 if (result == OK) |
| 229 NotifyObserversCertDBChanged(NULL); | 227 NotifyObserversCertDBChanged(); |
| 230 | 228 |
| 231 return result; | 229 return result; |
| 232 } | 230 } |
| 233 | 231 |
| 234 int NSSCertDatabase::ImportUserCert(X509Certificate* certificate) { | 232 int NSSCertDatabase::ImportUserCert(X509Certificate* certificate) { |
| 235 CertificateList certificates; | 233 CertificateList certificates; |
| 236 certificates.emplace_back(certificate); | 234 certificates.emplace_back(certificate); |
| 237 int result = psm::ImportUserCert(certificates); | 235 int result = psm::ImportUserCert(certificates); |
| 238 | 236 |
| 239 if (result == OK) | 237 if (result == OK) |
| 240 NotifyObserversCertDBChanged(NULL); | 238 NotifyObserversCertDBChanged(); |
| 241 | 239 |
| 242 return result; | 240 return result; |
| 243 } | 241 } |
| 244 | 242 |
| 245 bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates, | 243 bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates, |
| 246 TrustBits trust_bits, | 244 TrustBits trust_bits, |
| 247 ImportCertFailureList* not_imported) { | 245 ImportCertFailureList* not_imported) { |
| 248 crypto::ScopedPK11Slot slot(GetPublicSlot()); | 246 crypto::ScopedPK11Slot slot(GetPublicSlot()); |
| 249 X509Certificate* root = FindRootInList(certificates); | 247 X509Certificate* root = FindRootInList(certificates); |
| 250 bool success = psm::ImportCACerts( | 248 bool success = psm::ImportCACerts( |
| 251 slot.get(), certificates, root, trust_bits, not_imported); | 249 slot.get(), certificates, root, trust_bits, not_imported); |
| 252 if (success) | 250 if (success) |
| 253 NotifyObserversCertDBChanged(NULL); | 251 NotifyObserversCertDBChanged(); |
| 254 | 252 |
| 255 return success; | 253 return success; |
| 256 } | 254 } |
| 257 | 255 |
| 258 bool NSSCertDatabase::ImportServerCert(const CertificateList& certificates, | 256 bool NSSCertDatabase::ImportServerCert(const CertificateList& certificates, |
| 259 TrustBits trust_bits, | 257 TrustBits trust_bits, |
| 260 ImportCertFailureList* not_imported) { | 258 ImportCertFailureList* not_imported) { |
| 261 crypto::ScopedPK11Slot slot(GetPublicSlot()); | 259 crypto::ScopedPK11Slot slot(GetPublicSlot()); |
| 262 return psm::ImportServerCert( | 260 return psm::ImportServerCert( |
| 263 slot.get(), certificates, trust_bits, not_imported); | 261 slot.get(), certificates, trust_bits, not_imported); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 } | 359 } |
| 362 | 360 |
| 363 return false; | 361 return false; |
| 364 } | 362 } |
| 365 | 363 |
| 366 bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert, | 364 bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert, |
| 367 CertType type, | 365 CertType type, |
| 368 TrustBits trust_bits) { | 366 TrustBits trust_bits) { |
| 369 bool success = psm::SetCertTrust(cert, type, trust_bits); | 367 bool success = psm::SetCertTrust(cert, type, trust_bits); |
| 370 if (success) | 368 if (success) |
| 371 NotifyObserversCertDBChanged(cert); | 369 NotifyObserversCertDBChanged(); |
| 372 | 370 |
| 373 return success; | 371 return success; |
| 374 } | 372 } |
| 375 | 373 |
| 376 bool NSSCertDatabase::DeleteCertAndKey(X509Certificate* cert) { | 374 bool NSSCertDatabase::DeleteCertAndKey(X509Certificate* cert) { |
| 377 if (!DeleteCertAndKeyImpl(cert)) | 375 if (!DeleteCertAndKeyImpl(cert)) |
| 378 return false; | 376 return false; |
| 379 NotifyObserversCertDBChanged(cert); | 377 NotifyObserversCertDBChanged(); |
| 380 return true; | 378 return true; |
| 381 } | 379 } |
| 382 | 380 |
| 383 void NSSCertDatabase::DeleteCertAndKeyAsync( | 381 void NSSCertDatabase::DeleteCertAndKeyAsync( |
| 384 const scoped_refptr<X509Certificate>& cert, | 382 const scoped_refptr<X509Certificate>& cert, |
| 385 const DeleteCertCallback& callback) { | 383 const DeleteCertCallback& callback) { |
| 386 base::PostTaskWithTraitsAndReplyWithResult( | 384 base::PostTaskWithTraitsAndReplyWithResult( |
| 387 FROM_HERE, base::TaskTraits() | 385 FROM_HERE, base::TaskTraits() |
| 388 .WithShutdownBehavior( | 386 .WithShutdownBehavior( |
| 389 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) | 387 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) |
| 390 .MayBlock(), | 388 .MayBlock(), |
| 391 base::Bind(&NSSCertDatabase::DeleteCertAndKeyImpl, cert), | 389 base::Bind(&NSSCertDatabase::DeleteCertAndKeyImpl, cert), |
| 392 base::Bind(&NSSCertDatabase::NotifyCertRemovalAndCallBack, | 390 base::Bind(&NSSCertDatabase::NotifyCertRemovalAndCallBack, |
| 393 weak_factory_.GetWeakPtr(), cert, callback)); | 391 weak_factory_.GetWeakPtr(), callback)); |
| 394 } | 392 } |
| 395 | 393 |
| 396 bool NSSCertDatabase::IsReadOnly(const X509Certificate* cert) const { | 394 bool NSSCertDatabase::IsReadOnly(const X509Certificate* cert) const { |
| 397 PK11SlotInfo* slot = cert->os_cert_handle()->slot; | 395 PK11SlotInfo* slot = cert->os_cert_handle()->slot; |
| 398 return slot && PK11_IsReadOnly(slot); | 396 return slot && PK11_IsReadOnly(slot); |
| 399 } | 397 } |
| 400 | 398 |
| 401 bool NSSCertDatabase::IsHardwareBacked(const X509Certificate* cert) const { | 399 bool NSSCertDatabase::IsHardwareBacked(const X509Certificate* cert) const { |
| 402 PK11SlotInfo* slot = cert->os_cert_handle()->slot; | 400 PK11SlotInfo* slot = cert->os_cert_handle()->slot; |
| 403 return slot && PK11_IsHW(slot); | 401 return slot && PK11_IsHW(slot); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 425 CERTCertListNode* node; | 423 CERTCertListNode* node; |
| 426 for (node = CERT_LIST_HEAD(cert_list); !CERT_LIST_END(node, cert_list); | 424 for (node = CERT_LIST_HEAD(cert_list); !CERT_LIST_END(node, cert_list); |
| 427 node = CERT_LIST_NEXT(node)) { | 425 node = CERT_LIST_NEXT(node)) { |
| 428 certs->push_back(X509Certificate::CreateFromHandle( | 426 certs->push_back(X509Certificate::CreateFromHandle( |
| 429 node->cert, X509Certificate::OSCertHandles())); | 427 node->cert, X509Certificate::OSCertHandles())); |
| 430 } | 428 } |
| 431 CERT_DestroyCertList(cert_list); | 429 CERT_DestroyCertList(cert_list); |
| 432 } | 430 } |
| 433 | 431 |
| 434 void NSSCertDatabase::NotifyCertRemovalAndCallBack( | 432 void NSSCertDatabase::NotifyCertRemovalAndCallBack( |
| 435 scoped_refptr<X509Certificate> cert, | |
| 436 const DeleteCertCallback& callback, | 433 const DeleteCertCallback& callback, |
| 437 bool success) { | 434 bool success) { |
| 438 if (success) | 435 if (success) |
| 439 NotifyObserversCertDBChanged(cert.get()); | 436 NotifyObserversCertDBChanged(); |
| 440 callback.Run(success); | 437 callback.Run(success); |
| 441 } | 438 } |
| 442 | 439 |
| 443 void NSSCertDatabase::NotifyObserversCertDBChanged( | 440 void NSSCertDatabase::NotifyObserversCertDBChanged() { |
| 444 const X509Certificate* cert) { | 441 observer_list_->Notify(FROM_HERE, &Observer::OnCertDBChanged); |
| 445 observer_list_->Notify(FROM_HERE, &Observer::OnCertDBChanged, | |
| 446 base::RetainedRef(cert)); | |
| 447 } | 442 } |
| 448 | 443 |
| 449 // static | 444 // static |
| 450 bool NSSCertDatabase::DeleteCertAndKeyImpl( | 445 bool NSSCertDatabase::DeleteCertAndKeyImpl( |
| 451 scoped_refptr<X509Certificate> cert) { | 446 scoped_refptr<X509Certificate> cert) { |
| 452 // For some reason, PK11_DeleteTokenCertAndKey only calls | 447 // For some reason, PK11_DeleteTokenCertAndKey only calls |
| 453 // SEC_DeletePermCertificate if the private key is found. So, we check | 448 // SEC_DeletePermCertificate if the private key is found. So, we check |
| 454 // whether a private key exists before deciding which function to call to | 449 // whether a private key exists before deciding which function to call to |
| 455 // delete the cert. | 450 // delete the cert. |
| 456 SECKEYPrivateKey* privKey = | 451 SECKEYPrivateKey* privKey = |
| 457 PK11_FindKeyByAnyCert(cert->os_cert_handle(), NULL); | 452 PK11_FindKeyByAnyCert(cert->os_cert_handle(), NULL); |
| 458 if (privKey) { | 453 if (privKey) { |
| 459 SECKEY_DestroyPrivateKey(privKey); | 454 SECKEY_DestroyPrivateKey(privKey); |
| 460 if (PK11_DeleteTokenCertAndKey(cert->os_cert_handle(), NULL)) { | 455 if (PK11_DeleteTokenCertAndKey(cert->os_cert_handle(), NULL)) { |
| 461 LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError(); | 456 LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError(); |
| 462 return false; | 457 return false; |
| 463 } | 458 } |
| 464 } else { | 459 } else { |
| 465 if (SEC_DeletePermCertificate(cert->os_cert_handle())) { | 460 if (SEC_DeletePermCertificate(cert->os_cert_handle())) { |
| 466 LOG(ERROR) << "SEC_DeletePermCertificate failed: " << PORT_GetError(); | 461 LOG(ERROR) << "SEC_DeletePermCertificate failed: " << PORT_GetError(); |
| 467 return false; | 462 return false; |
| 468 } | 463 } |
| 469 } | 464 } |
| 470 return true; | 465 return true; |
| 471 } | 466 } |
| 472 | 467 |
| 473 } // namespace net | 468 } // namespace net |
| OLD | NEW |