Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(748)

Side by Side Diff: net/cert/nss_cert_database.cc

Issue 214863002: Extension API enterprise.platformKeys. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Asynchronous calls revisited. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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>
11 #include <secmod.h> 11 #include <secmod.h>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_ptr.h"
18 #include "base/observer_list_threadsafe.h" 18 #include "base/observer_list_threadsafe.h"
19 #include "base/task_runner.h" 19 #include "base/task_runner.h"
20 #include "base/task_runner_util.h"
20 #include "base/threading/worker_pool.h" 21 #include "base/threading/worker_pool.h"
21 #include "crypto/nss_util.h" 22 #include "crypto/nss_util.h"
22 #include "crypto/nss_util_internal.h" 23 #include "crypto/nss_util_internal.h"
23 #include "crypto/scoped_nss_types.h" 24 #include "crypto/scoped_nss_types.h"
24 #include "net/base/crypto_module.h" 25 #include "net/base/crypto_module.h"
25 #include "net/base/net_errors.h" 26 #include "net/base/net_errors.h"
26 #include "net/cert/cert_database.h" 27 #include "net/cert/cert_database.h"
27 #include "net/cert/x509_certificate.h" 28 #include "net/cert/x509_certificate.h"
28 #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h" 29 #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h"
29 #include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h" 30 #include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h"
(...skipping 28 matching lines...) Expand all
58 // TODO(mattm): Remove this ifdef guard once the linux impl of 59 // TODO(mattm): Remove this ifdef guard once the linux impl of
59 // GetNSSCertDatabaseForResourceContext does not call GetInstance. 60 // GetNSSCertDatabaseForResourceContext does not call GetInstance.
60 #if defined(OS_CHROMEOS) 61 #if defined(OS_CHROMEOS)
61 LOG(ERROR) << "NSSCertDatabase::GetInstance() is deprecated." 62 LOG(ERROR) << "NSSCertDatabase::GetInstance() is deprecated."
62 << "See http://crbug.com/329735."; 63 << "See http://crbug.com/329735.";
63 #endif 64 #endif
64 return &g_nss_cert_database.Get(); 65 return &g_nss_cert_database.Get();
65 } 66 }
66 67
67 NSSCertDatabase::NSSCertDatabase() 68 NSSCertDatabase::NSSCertDatabase()
68 : observer_list_(new ObserverListThreadSafe<Observer>) { 69 : observer_list_(new ObserverListThreadSafe<Observer>),
70 weak_factory_(this) {
69 // This also makes sure that NSS has been initialized. 71 // This also makes sure that NSS has been initialized.
70 CertDatabase::GetInstance()->ObserveNSSCertDatabase(this); 72 CertDatabase::GetInstance()->ObserveNSSCertDatabase(this);
71 73
72 psm::EnsurePKCS12Init(); 74 psm::EnsurePKCS12Init();
73 } 75 }
74 76
75 NSSCertDatabase::~NSSCertDatabase() {} 77 NSSCertDatabase::~NSSCertDatabase() {}
76 78
77 void NSSCertDatabase::ListCertsSync(CertificateList* certs) { 79 void NSSCertDatabase::ListCertsSync(CertificateList* certs) {
78 ListCertsImpl(certs); 80 ListCertsImpl(crypto::ScopedPK11Slot(), certs);
79 } 81 }
80 82
81 void NSSCertDatabase::ListCerts( 83 void NSSCertDatabase::ListCerts(
82 const base::Callback<void(scoped_ptr<CertificateList> certs)>& callback) { 84 const base::Callback<void(scoped_ptr<CertificateList> certs)>& callback) {
83 scoped_ptr<CertificateList> certs(new CertificateList()); 85 scoped_ptr<CertificateList> certs(new CertificateList());
84 86
85 // base::Pased will NULL out |certs|, so cache the underlying pointer here. 87 // base::Passed will NULL out |certs|, so cache the underlying pointer here.
86 CertificateList* raw_certs = certs.get(); 88 CertificateList* raw_certs = certs.get();
87 GetSlowTaskRunner()->PostTaskAndReply( 89 GetSlowTaskRunner()->PostTaskAndReply(
88 FROM_HERE, 90 FROM_HERE,
89 base::Bind(&NSSCertDatabase::ListCertsImpl, 91 base::Bind(&NSSCertDatabase::ListCertsImpl,
92 base::Passed(crypto::ScopedPK11Slot()),
90 base::Unretained(raw_certs)), 93 base::Unretained(raw_certs)),
91 base::Bind(callback, base::Passed(&certs))); 94 base::Bind(callback, base::Passed(&certs)));
92 } 95 }
96
97 void NSSCertDatabase::ListCertsInSlot(const ListCertsCallback& callback,
98 PK11SlotInfo* slot) {
99 DCHECK(slot);
100 scoped_ptr<CertificateList> certs(new CertificateList());
101
102 // base::Passed will NULL out |certs|, so cache the underlying pointer here.
103 CertificateList* raw_certs = certs.get();
104 GetSlowTaskRunner()->PostTaskAndReply(
105 FROM_HERE,
106 base::Bind(&NSSCertDatabase::ListCertsImpl,
107 base::Passed(crypto::ScopedPK11Slot(PK11_ReferenceSlot(slot))),
108 base::Unretained(raw_certs)),
109 base::Bind(callback, base::Passed(&certs)));
110 }
93 111
94 crypto::ScopedPK11Slot NSSCertDatabase::GetPublicSlot() const { 112 crypto::ScopedPK11Slot NSSCertDatabase::GetPublicSlot() const {
95 return crypto::ScopedPK11Slot(crypto::GetPublicNSSKeySlot()); 113 return crypto::ScopedPK11Slot(crypto::GetPublicNSSKeySlot());
96 } 114 }
97 115
98 crypto::ScopedPK11Slot NSSCertDatabase::GetPrivateSlot() const { 116 crypto::ScopedPK11Slot NSSCertDatabase::GetPrivateSlot() const {
99 return crypto::ScopedPK11Slot(crypto::GetPrivateNSSKeySlot()); 117 return crypto::ScopedPK11Slot(crypto::GetPrivateNSSKeySlot());
100 } 118 }
101 119
102 CryptoModule* NSSCertDatabase::GetPublicModule() const { 120 CryptoModule* NSSCertDatabase::GetPublicModule() const {
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert, 324 bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert,
307 CertType type, 325 CertType type,
308 TrustBits trust_bits) { 326 TrustBits trust_bits) {
309 bool success = psm::SetCertTrust(cert, type, trust_bits); 327 bool success = psm::SetCertTrust(cert, type, trust_bits);
310 if (success) 328 if (success)
311 NotifyObserversOfCACertChanged(cert); 329 NotifyObserversOfCACertChanged(cert);
312 330
313 return success; 331 return success;
314 } 332 }
315 333
316 bool NSSCertDatabase::DeleteCertAndKey(const X509Certificate* cert) { 334 bool NSSCertDatabase::DeleteCertAndKey(X509Certificate* cert) {
317 // For some reason, PK11_DeleteTokenCertAndKey only calls 335 if (!DeleteCertAndKeyImpl(cert))
318 // SEC_DeletePermCertificate if the private key is found. So, we check 336 return false;
319 // whether a private key exists before deciding which function to call to 337 NotifyObserversOfCertRemoved(cert);
320 // delete the cert. 338 return true;
321 SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert->os_cert_handle(), 339 }
322 NULL);
323 if (privKey) {
324 SECKEY_DestroyPrivateKey(privKey);
325 if (PK11_DeleteTokenCertAndKey(cert->os_cert_handle(), NULL)) {
326 LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError();
327 return false;
328 }
329 } else {
330 if (SEC_DeletePermCertificate(cert->os_cert_handle())) {
331 LOG(ERROR) << "SEC_DeletePermCertificate failed: " << PORT_GetError();
332 return false;
333 }
334 }
335 340
336 NotifyObserversOfCertRemoved(cert); 341 void NSSCertDatabase::DeleteCertAndKeyAsync(
337 342 const scoped_refptr<X509Certificate>& cert,
338 return true; 343 const DeleteCertCallback& callback) {
344 base::PostTaskAndReplyWithResult(
345 GetSlowTaskRunner().get(),
346 FROM_HERE,
347 base::Bind(&NSSCertDatabase::DeleteCertAndKeyImpl, cert),
348 base::Bind(&NSSCertDatabase::NotifyCertRemovalAndCallBack,
349 weak_factory_.GetWeakPtr(),
350 cert,
351 callback));
339 } 352 }
340 353
341 bool NSSCertDatabase::IsReadOnly(const X509Certificate* cert) const { 354 bool NSSCertDatabase::IsReadOnly(const X509Certificate* cert) const {
342 PK11SlotInfo* slot = cert->os_cert_handle()->slot; 355 PK11SlotInfo* slot = cert->os_cert_handle()->slot;
343 return slot && PK11_IsReadOnly(slot); 356 return slot && PK11_IsReadOnly(slot);
344 } 357 }
345 358
346 bool NSSCertDatabase::IsHardwareBacked(const X509Certificate* cert) const { 359 bool NSSCertDatabase::IsHardwareBacked(const X509Certificate* cert) const {
347 PK11SlotInfo* slot = cert->os_cert_handle()->slot; 360 PK11SlotInfo* slot = cert->os_cert_handle()->slot;
348 return slot && PK11_IsHW(slot); 361 return slot && PK11_IsHW(slot);
349 } 362 }
350 363
351 void NSSCertDatabase::AddObserver(Observer* observer) { 364 void NSSCertDatabase::AddObserver(Observer* observer) {
352 observer_list_->AddObserver(observer); 365 observer_list_->AddObserver(observer);
353 } 366 }
354 367
355 void NSSCertDatabase::RemoveObserver(Observer* observer) { 368 void NSSCertDatabase::RemoveObserver(Observer* observer) {
356 observer_list_->RemoveObserver(observer); 369 observer_list_->RemoveObserver(observer);
357 } 370 }
358 371
359 void NSSCertDatabase::SetSlowTaskRunnerForTest( 372 void NSSCertDatabase::SetSlowTaskRunnerForTest(
360 const scoped_refptr<base::TaskRunner>& task_runner) { 373 const scoped_refptr<base::TaskRunner>& task_runner) {
361 slow_task_runner_for_test_ = task_runner; 374 slow_task_runner_for_test_ = task_runner;
362 } 375 }
363 376
364 // static 377 // static
365 void NSSCertDatabase::ListCertsImpl(CertificateList* certs) { 378 void NSSCertDatabase::ListCertsImpl(crypto::ScopedPK11Slot slot,
379 CertificateList* certs) {
366 certs->clear(); 380 certs->clear();
367 381
368 CERTCertList* cert_list = PK11_ListCerts(PK11CertListUnique, NULL); 382 CERTCertList* cert_list = NULL;
383 if (slot)
384 cert_list = PK11_ListCertsInSlot(slot.get());
385 else
386 cert_list = PK11_ListCerts(PK11CertListUnique, NULL);
387
369 CERTCertListNode* node; 388 CERTCertListNode* node;
370 for (node = CERT_LIST_HEAD(cert_list); 389 for (node = CERT_LIST_HEAD(cert_list); !CERT_LIST_END(node, cert_list);
371 !CERT_LIST_END(node, cert_list);
372 node = CERT_LIST_NEXT(node)) { 390 node = CERT_LIST_NEXT(node)) {
373 certs->push_back(X509Certificate::CreateFromHandle( 391 certs->push_back(X509Certificate::CreateFromHandle(
374 node->cert, X509Certificate::OSCertHandles())); 392 node->cert, X509Certificate::OSCertHandles()));
375 } 393 }
376 CERT_DestroyCertList(cert_list); 394 CERT_DestroyCertList(cert_list);
377 } 395 }
378 396
379 scoped_refptr<base::TaskRunner> NSSCertDatabase::GetSlowTaskRunner() const { 397 scoped_refptr<base::TaskRunner> NSSCertDatabase::GetSlowTaskRunner() const {
380 if (slow_task_runner_for_test_) 398 if (slow_task_runner_for_test_)
381 return slow_task_runner_for_test_; 399 return slow_task_runner_for_test_;
382 return base::WorkerPool::GetTaskRunner(true /*task is slow*/); 400 return base::WorkerPool::GetTaskRunner(true /*task is slow*/);
383 } 401 }
384 402
403 void NSSCertDatabase::NotifyCertRemovalAndCallBack(
404 scoped_refptr<X509Certificate> cert,
405 const DeleteCertCallback& callback,
406 bool success) {
407 if (success)
408 NotifyObserversOfCertRemoved(cert);
409 callback.Run(success);
410 }
411
385 void NSSCertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) { 412 void NSSCertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) {
386 observer_list_->Notify(&Observer::OnCertAdded, make_scoped_refptr(cert)); 413 observer_list_->Notify(&Observer::OnCertAdded, make_scoped_refptr(cert));
387 } 414 }
388 415
389 void NSSCertDatabase::NotifyObserversOfCertRemoved( 416 void NSSCertDatabase::NotifyObserversOfCertRemoved(
390 const X509Certificate* cert) { 417 const X509Certificate* cert) {
391 observer_list_->Notify(&Observer::OnCertRemoved, make_scoped_refptr(cert)); 418 observer_list_->Notify(&Observer::OnCertRemoved, make_scoped_refptr(cert));
392 } 419 }
393 420
394 void NSSCertDatabase::NotifyObserversOfCACertChanged( 421 void NSSCertDatabase::NotifyObserversOfCACertChanged(
395 const X509Certificate* cert) { 422 const X509Certificate* cert) {
396 observer_list_->Notify( 423 observer_list_->Notify(
397 &Observer::OnCACertChanged, make_scoped_refptr(cert)); 424 &Observer::OnCACertChanged, make_scoped_refptr(cert));
398 } 425 }
399 426
427 // static
428 bool NSSCertDatabase::DeleteCertAndKeyImpl(
429 scoped_refptr<X509Certificate> cert) {
430 // For some reason, PK11_DeleteTokenCertAndKey only calls
431 // SEC_DeletePermCertificate if the private key is found. So, we check
432 // whether a private key exists before deciding which function to call to
433 // delete the cert.
434 SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert->os_cert_handle(),
435 NULL);
436 if (privKey) {
437 SECKEY_DestroyPrivateKey(privKey);
438 if (PK11_DeleteTokenCertAndKey(cert->os_cert_handle(), NULL)) {
439 LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError();
440 return false;
441 }
442 } else {
443 if (SEC_DeletePermCertificate(cert->os_cert_handle())) {
444 LOG(ERROR) << "SEC_DeletePermCertificate failed: " << PORT_GetError();
445 return false;
446 }
447 }
448 return true;
449 }
450
400 } // namespace net 451 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698