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

Side by Side Diff: crypto/nss_util.cc

Issue 428933002: Make NSSInitSingleton::tpm_slot_ a ScopedPK11Slot. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use scoped ptr in TPMModuleAndSlot. Created 6 years, 4 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "crypto/nss_util.h" 5 #include "crypto/nss_util.h"
6 #include "crypto/nss_util_internal.h" 6 #include "crypto/nss_util_internal.h"
7 7
8 #include <nss.h> 8 #include <nss.h>
9 #include <pk11pub.h> 9 #include <pk11pub.h>
10 #include <plarena.h> 10 #include <plarena.h>
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 SlotReadyCallbackList tpm_ready_callback_list_; 269 SlotReadyCallbackList tpm_ready_callback_list_;
270 }; 270 };
271 #endif // defined(OS_CHROMEOS) 271 #endif // defined(OS_CHROMEOS)
272 272
273 class NSSInitSingleton { 273 class NSSInitSingleton {
274 public: 274 public:
275 #if defined(OS_CHROMEOS) 275 #if defined(OS_CHROMEOS)
276 // Used with PostTaskAndReply to pass handles to worker thread and back. 276 // Used with PostTaskAndReply to pass handles to worker thread and back.
277 struct TPMModuleAndSlot { 277 struct TPMModuleAndSlot {
278 explicit TPMModuleAndSlot(SECMODModule* init_chaps_module) 278 explicit TPMModuleAndSlot(SECMODModule* init_chaps_module)
279 : chaps_module(init_chaps_module), tpm_slot(NULL) {} 279 : chaps_module(init_chaps_module) {}
280 SECMODModule* chaps_module; 280 SECMODModule* chaps_module;
281 PK11SlotInfo* tpm_slot; 281 crypto::ScopedPK11Slot tpm_slot;
282 }; 282 };
283 283
284 ScopedPK11Slot OpenPersistentNSSDBForPath(const std::string& db_name, 284 ScopedPK11Slot OpenPersistentNSSDBForPath(const std::string& db_name,
285 const base::FilePath& path) { 285 const base::FilePath& path) {
286 DCHECK(thread_checker_.CalledOnValidThread()); 286 DCHECK(thread_checker_.CalledOnValidThread());
287 // NSS is allowed to do IO on the current thread since dispatching 287 // NSS is allowed to do IO on the current thread since dispatching
288 // to a dedicated thread would still have the affect of blocking 288 // to a dedicated thread would still have the affect of blocking
289 // the current thread, due to NSS's internal locking requirements 289 // the current thread, due to NSS's internal locking requirements
290 base::ThreadRestrictions::ScopedAllowIO allow_io; 290 base::ThreadRestrictions::ScopedAllowIO allow_io;
291 291
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 } 379 }
380 380
381 void OnInitializedTPMTokenAndSystemSlot( 381 void OnInitializedTPMTokenAndSystemSlot(
382 const base::Callback<void(bool)>& callback, 382 const base::Callback<void(bool)>& callback,
383 scoped_ptr<TPMModuleAndSlot> tpm_args) { 383 scoped_ptr<TPMModuleAndSlot> tpm_args) {
384 DCHECK(thread_checker_.CalledOnValidThread()); 384 DCHECK(thread_checker_.CalledOnValidThread());
385 DVLOG(2) << "Loaded chaps: " << !!tpm_args->chaps_module 385 DVLOG(2) << "Loaded chaps: " << !!tpm_args->chaps_module
386 << ", got tpm slot: " << !!tpm_args->tpm_slot; 386 << ", got tpm slot: " << !!tpm_args->tpm_slot;
387 387
388 chaps_module_ = tpm_args->chaps_module; 388 chaps_module_ = tpm_args->chaps_module;
389 tpm_slot_ = tpm_args->tpm_slot; 389 tpm_slot_ = tpm_args->tpm_slot.Pass();
390 if (!chaps_module_ && test_system_slot_) { 390 if (!chaps_module_ && test_system_slot_) {
391 // chromeos_unittests try to test the TPM initialization process. If we 391 // chromeos_unittests try to test the TPM initialization process. If we
392 // have a test DB open, pretend that it is the TPM slot. 392 // have a test DB open, pretend that it is the TPM slot.
393 tpm_slot_ = PK11_ReferenceSlot(test_system_slot_.get()); 393 tpm_slot_.reset(PK11_ReferenceSlot(test_system_slot_.get()));
394 } 394 }
395 initializing_tpm_token_ = false; 395 initializing_tpm_token_ = false;
396 396
397 if (tpm_slot_) { 397 if (tpm_slot_) {
398 TPMReadyCallbackList callback_list; 398 TPMReadyCallbackList callback_list;
399 callback_list.swap(tpm_ready_callback_list_); 399 callback_list.swap(tpm_ready_callback_list_);
400 for (TPMReadyCallbackList::iterator i = callback_list.begin(); 400 for (TPMReadyCallbackList::iterator i = callback_list.begin();
401 i != callback_list.end(); 401 i != callback_list.end();
402 ++i) { 402 ++i) {
403 (*i).Run(); 403 (*i).Run();
404 } 404 }
405 } 405 }
406 406
407 callback.Run(!!tpm_slot_); 407 callback.Run(!!tpm_slot_);
408 } 408 }
409 409
410 bool IsTPMTokenReady(const base::Closure& callback) { 410 bool IsTPMTokenReady(const base::Closure& callback) {
411 if (!callback.is_null()) { 411 if (!callback.is_null()) {
412 // Cannot DCHECK in the general case yet, but since the callback is 412 // Cannot DCHECK in the general case yet, but since the callback is
413 // a new addition to the API, DCHECK to make sure at least the new uses 413 // a new addition to the API, DCHECK to make sure at least the new uses
414 // don't regress. 414 // don't regress.
415 DCHECK(thread_checker_.CalledOnValidThread()); 415 DCHECK(thread_checker_.CalledOnValidThread());
416 } else if (!thread_checker_.CalledOnValidThread()) { 416 } else if (!thread_checker_.CalledOnValidThread()) {
417 // TODO(mattm): Change to DCHECK when callers have been fixed. 417 // TODO(mattm): Change to DCHECK when callers have been fixed.
418 DVLOG(1) << "Called on wrong thread.\n" 418 DVLOG(1) << "Called on wrong thread.\n"
419 << base::debug::StackTrace().ToString(); 419 << base::debug::StackTrace().ToString();
420 } 420 }
421 421
422 if (tpm_slot_ != NULL) 422 if (tpm_slot_)
423 return true; 423 return true;
424 424
425 if (!callback.is_null()) 425 if (!callback.is_null())
426 tpm_ready_callback_list_.push_back(callback); 426 tpm_ready_callback_list_.push_back(callback);
427 427
428 return false; 428 return false;
429 } 429 }
430 430
431 // Note that CK_SLOT_ID is an unsigned long, but cryptohome gives us the slot 431 // Note that CK_SLOT_ID is an unsigned long, but cryptohome gives us the slot
432 // id as an int. This should be safe since this is only used with chaps, which 432 // id as an int. This should be safe since this is only used with chaps, which
433 // we also control. 433 // we also control.
434 static PK11SlotInfo* GetTPMSlotForIdOnWorkerThread(SECMODModule* chaps_module, 434 static crypto::ScopedPK11Slot GetTPMSlotForIdOnWorkerThread(
435 CK_SLOT_ID slot_id) { 435 SECMODModule* chaps_module,
436 CK_SLOT_ID slot_id) {
436 DCHECK(chaps_module); 437 DCHECK(chaps_module);
437 438
438 DVLOG(3) << "Poking chaps module."; 439 DVLOG(3) << "Poking chaps module.";
439 SECStatus rv = SECMOD_UpdateSlotList(chaps_module); 440 SECStatus rv = SECMOD_UpdateSlotList(chaps_module);
440 if (rv != SECSuccess) 441 if (rv != SECSuccess)
441 PLOG(ERROR) << "SECMOD_UpdateSlotList failed: " << PORT_GetError(); 442 PLOG(ERROR) << "SECMOD_UpdateSlotList failed: " << PORT_GetError();
442 443
443 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module->moduleID, slot_id); 444 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module->moduleID, slot_id);
444 if (!slot) 445 if (!slot)
445 LOG(ERROR) << "TPM slot " << slot_id << " not found."; 446 LOG(ERROR) << "TPM slot " << slot_id << " not found.";
446 return slot; 447 return crypto::ScopedPK11Slot(slot);
447 } 448 }
448 449
449 bool InitializeNSSForChromeOSUser( 450 bool InitializeNSSForChromeOSUser(
450 const std::string& email, 451 const std::string& email,
451 const std::string& username_hash, 452 const std::string& username_hash,
452 const base::FilePath& path) { 453 const base::FilePath& path) {
453 DCHECK(thread_checker_.CalledOnValidThread()); 454 DCHECK(thread_checker_.CalledOnValidThread());
454 if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) { 455 if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) {
455 // This user already exists in our mapping. 456 // This user already exists in our mapping.
456 DVLOG(2) << username_hash << " already initialized."; 457 DVLOG(2) << username_hash << " already initialized.";
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 true /* task_is_slow */ 509 true /* task_is_slow */
509 ); 510 );
510 } 511 }
511 512
512 void OnInitializedTPMForChromeOSUser(const std::string& username_hash, 513 void OnInitializedTPMForChromeOSUser(const std::string& username_hash,
513 scoped_ptr<TPMModuleAndSlot> tpm_args) { 514 scoped_ptr<TPMModuleAndSlot> tpm_args) {
514 DCHECK(thread_checker_.CalledOnValidThread()); 515 DCHECK(thread_checker_.CalledOnValidThread());
515 DVLOG(2) << "Got tpm slot for " << username_hash << " " 516 DVLOG(2) << "Got tpm slot for " << username_hash << " "
516 << !!tpm_args->tpm_slot; 517 << !!tpm_args->tpm_slot;
517 chromeos_user_map_[username_hash]->SetPrivateSlot( 518 chromeos_user_map_[username_hash]->SetPrivateSlot(
518 ScopedPK11Slot(tpm_args->tpm_slot)); 519 tpm_args->tpm_slot.Pass());
519 } 520 }
520 521
521 void InitializePrivateSoftwareSlotForChromeOSUser( 522 void InitializePrivateSoftwareSlotForChromeOSUser(
522 const std::string& username_hash) { 523 const std::string& username_hash) {
523 DCHECK(thread_checker_.CalledOnValidThread()); 524 DCHECK(thread_checker_.CalledOnValidThread());
524 VLOG(1) << "using software private slot for " << username_hash; 525 VLOG(1) << "using software private slot for " << username_hash;
525 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); 526 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());
526 DCHECK(chromeos_user_map_[username_hash]-> 527 DCHECK(chromeos_user_map_[username_hash]->
527 private_slot_initialization_started()); 528 private_slot_initialization_started());
528 529
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 << base::debug::StackTrace().ToString(); 590 << base::debug::StackTrace().ToString();
590 } 591 }
591 592
592 return PK11_GetInternalKeySlot(); 593 return PK11_GetInternalKeySlot();
593 } 594 }
594 #endif 595 #endif
595 596
596 #if defined(OS_CHROMEOS) 597 #if defined(OS_CHROMEOS)
597 void GetSystemNSSKeySlotCallback( 598 void GetSystemNSSKeySlotCallback(
598 const base::Callback<void(ScopedPK11Slot)>& callback) { 599 const base::Callback<void(ScopedPK11Slot)>& callback) {
599 callback.Run(ScopedPK11Slot(PK11_ReferenceSlot(tpm_slot_))); 600 callback.Run(ScopedPK11Slot(PK11_ReferenceSlot(tpm_slot_.get())));
600 } 601 }
601 602
602 ScopedPK11Slot GetSystemNSSKeySlot( 603 ScopedPK11Slot GetSystemNSSKeySlot(
603 const base::Callback<void(ScopedPK11Slot)>& callback) { 604 const base::Callback<void(ScopedPK11Slot)>& callback) {
604 DCHECK(thread_checker_.CalledOnValidThread()); 605 DCHECK(thread_checker_.CalledOnValidThread());
605 // TODO(mattm): chromeos::TPMTokenloader always calls 606 // TODO(mattm): chromeos::TPMTokenloader always calls
606 // InitializeTPMTokenAndSystemSlot with slot 0. If the system slot is 607 // InitializeTPMTokenAndSystemSlot with slot 0. If the system slot is
607 // disabled, tpm_slot_ will be the first user's slot instead. Can that be 608 // disabled, tpm_slot_ will be the first user's slot instead. Can that be
608 // detected and return NULL instead? 609 // detected and return NULL instead?
609 610
610 base::Closure wrapped_callback; 611 base::Closure wrapped_callback;
611 if (!callback.is_null()) { 612 if (!callback.is_null()) {
612 wrapped_callback = 613 wrapped_callback =
613 base::Bind(&NSSInitSingleton::GetSystemNSSKeySlotCallback, 614 base::Bind(&NSSInitSingleton::GetSystemNSSKeySlotCallback,
614 base::Unretained(this) /* singleton is leaky */, 615 base::Unretained(this) /* singleton is leaky */,
615 callback); 616 callback);
616 } 617 }
617 if (IsTPMTokenReady(wrapped_callback)) 618 if (IsTPMTokenReady(wrapped_callback))
618 return ScopedPK11Slot(PK11_ReferenceSlot(tpm_slot_)); 619 return ScopedPK11Slot(PK11_ReferenceSlot(tpm_slot_.get()));
619 return ScopedPK11Slot(); 620 return ScopedPK11Slot();
620 } 621 }
621 #endif 622 #endif
622 623
623 #if defined(USE_NSS) 624 #if defined(USE_NSS)
624 base::Lock* write_lock() { 625 base::Lock* write_lock() {
625 return &write_lock_; 626 return &write_lock_;
626 } 627 }
627 #endif // defined(USE_NSS) 628 #endif // defined(USE_NSS)
628 629
629 // This method is used to force NSS to be initialized without a DB. 630 // This method is used to force NSS to be initialized without a DB.
630 // Call this method before NSSInitSingleton() is constructed. 631 // Call this method before NSSInitSingleton() is constructed.
631 static void ForceNoDBInit() { 632 static void ForceNoDBInit() {
632 force_nodb_init_ = true; 633 force_nodb_init_ = true;
633 } 634 }
634 635
635 private: 636 private:
636 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; 637 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>;
637 638
638 NSSInitSingleton() 639 NSSInitSingleton()
639 : tpm_token_enabled_for_nss_(false), 640 : tpm_token_enabled_for_nss_(false),
640 initializing_tpm_token_(false), 641 initializing_tpm_token_(false),
641 chaps_module_(NULL), 642 chaps_module_(NULL),
642 tpm_slot_(NULL),
643 root_(NULL) { 643 root_(NULL) {
644 base::TimeTicks start_time = base::TimeTicks::Now(); 644 base::TimeTicks start_time = base::TimeTicks::Now();
645 645
646 // It's safe to construct on any thread, since LazyInstance will prevent any 646 // It's safe to construct on any thread, since LazyInstance will prevent any
647 // other threads from accessing until the constructor is done. 647 // other threads from accessing until the constructor is done.
648 thread_checker_.DetachFromThread(); 648 thread_checker_.DetachFromThread();
649 649
650 DisableAESNIIfNeeded(); 650 DisableAESNIIfNeeded();
651 651
652 EnsureNSPRInit(); 652 EnsureNSPRInit();
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 50); 749 50);
750 } 750 }
751 751
752 // NOTE(willchan): We don't actually execute this code since we leak NSS to 752 // NOTE(willchan): We don't actually execute this code since we leak NSS to
753 // prevent non-joinable threads from using NSS after it's already been shut 753 // prevent non-joinable threads from using NSS after it's already been shut
754 // down. 754 // down.
755 ~NSSInitSingleton() { 755 ~NSSInitSingleton() {
756 #if defined(OS_CHROMEOS) 756 #if defined(OS_CHROMEOS)
757 STLDeleteValues(&chromeos_user_map_); 757 STLDeleteValues(&chromeos_user_map_);
758 #endif 758 #endif
759 if (tpm_slot_) { 759 tpm_slot_.reset();
760 PK11_FreeSlot(tpm_slot_);
761 tpm_slot_ = NULL;
762 }
763 if (root_) { 760 if (root_) {
764 SECMOD_UnloadUserModule(root_); 761 SECMOD_UnloadUserModule(root_);
765 SECMOD_DestroyModule(root_); 762 SECMOD_DestroyModule(root_);
766 root_ = NULL; 763 root_ = NULL;
767 } 764 }
768 if (chaps_module_) { 765 if (chaps_module_) {
769 SECMOD_UnloadUserModule(chaps_module_); 766 SECMOD_UnloadUserModule(chaps_module_);
770 SECMOD_DestroyModule(chaps_module_); 767 SECMOD_DestroyModule(chaps_module_);
771 chaps_module_ = NULL; 768 chaps_module_ = NULL;
772 } 769 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 } 834 }
838 835
839 // If this is set to true NSS is forced to be initialized without a DB. 836 // If this is set to true NSS is forced to be initialized without a DB.
840 static bool force_nodb_init_; 837 static bool force_nodb_init_;
841 838
842 bool tpm_token_enabled_for_nss_; 839 bool tpm_token_enabled_for_nss_;
843 bool initializing_tpm_token_; 840 bool initializing_tpm_token_;
844 typedef std::vector<base::Closure> TPMReadyCallbackList; 841 typedef std::vector<base::Closure> TPMReadyCallbackList;
845 TPMReadyCallbackList tpm_ready_callback_list_; 842 TPMReadyCallbackList tpm_ready_callback_list_;
846 SECMODModule* chaps_module_; 843 SECMODModule* chaps_module_;
847 PK11SlotInfo* tpm_slot_; 844 crypto::ScopedPK11Slot tpm_slot_;
848 SECMODModule* root_; 845 SECMODModule* root_;
849 #if defined(OS_CHROMEOS) 846 #if defined(OS_CHROMEOS)
850 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap; 847 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap;
851 ChromeOSUserMap chromeos_user_map_; 848 ChromeOSUserMap chromeos_user_map_;
852 ScopedPK11Slot test_system_slot_; 849 ScopedPK11Slot test_system_slot_;
853 #endif 850 #endif
854 #if defined(USE_NSS) 851 #if defined(USE_NSS)
855 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 852 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011
856 // is fixed, we will no longer need the lock. 853 // is fixed, we will no longer need the lock.
857 base::Lock write_lock_; 854 base::Lock write_lock_;
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); 1090 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue();
1094 } 1091 }
1095 1092
1096 #if !defined(OS_CHROMEOS) 1093 #if !defined(OS_CHROMEOS)
1097 PK11SlotInfo* GetPersistentNSSKeySlot() { 1094 PK11SlotInfo* GetPersistentNSSKeySlot() {
1098 return g_nss_singleton.Get().GetPersistentNSSKeySlot(); 1095 return g_nss_singleton.Get().GetPersistentNSSKeySlot();
1099 } 1096 }
1100 #endif 1097 #endif
1101 1098
1102 } // namespace crypto 1099 } // namespace crypto
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698