Chromium Code Reviews| 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 "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 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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_.reset(tpm_args->tpm_slot); |
|
Ryan Sleevi
2014/07/29 23:43:40
Would be great to either make this a scoped_ptr<>
pneubeck (no reviews)
2014/07/30 08:28:49
Done.
| |
| 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 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 589 << base::debug::StackTrace().ToString(); | 589 << base::debug::StackTrace().ToString(); |
| 590 } | 590 } |
| 591 | 591 |
| 592 return PK11_GetInternalKeySlot(); | 592 return PK11_GetInternalKeySlot(); |
| 593 } | 593 } |
| 594 #endif | 594 #endif |
| 595 | 595 |
| 596 #if defined(OS_CHROMEOS) | 596 #if defined(OS_CHROMEOS) |
| 597 void GetSystemNSSKeySlotCallback( | 597 void GetSystemNSSKeySlotCallback( |
| 598 const base::Callback<void(ScopedPK11Slot)>& callback) { | 598 const base::Callback<void(ScopedPK11Slot)>& callback) { |
| 599 callback.Run(ScopedPK11Slot(PK11_ReferenceSlot(tpm_slot_))); | 599 callback.Run(ScopedPK11Slot(PK11_ReferenceSlot(tpm_slot_.get()))); |
| 600 } | 600 } |
| 601 | 601 |
| 602 ScopedPK11Slot GetSystemNSSKeySlot( | 602 ScopedPK11Slot GetSystemNSSKeySlot( |
| 603 const base::Callback<void(ScopedPK11Slot)>& callback) { | 603 const base::Callback<void(ScopedPK11Slot)>& callback) { |
| 604 DCHECK(thread_checker_.CalledOnValidThread()); | 604 DCHECK(thread_checker_.CalledOnValidThread()); |
| 605 // TODO(mattm): chromeos::TPMTokenloader always calls | 605 // TODO(mattm): chromeos::TPMTokenloader always calls |
| 606 // InitializeTPMTokenAndSystemSlot with slot 0. If the system slot is | 606 // InitializeTPMTokenAndSystemSlot with slot 0. If the system slot is |
| 607 // disabled, tpm_slot_ will be the first user's slot instead. Can that be | 607 // disabled, tpm_slot_ will be the first user's slot instead. Can that be |
| 608 // detected and return NULL instead? | 608 // detected and return NULL instead? |
| 609 | 609 |
| 610 base::Closure wrapped_callback; | 610 base::Closure wrapped_callback; |
| 611 if (!callback.is_null()) { | 611 if (!callback.is_null()) { |
| 612 wrapped_callback = | 612 wrapped_callback = |
| 613 base::Bind(&NSSInitSingleton::GetSystemNSSKeySlotCallback, | 613 base::Bind(&NSSInitSingleton::GetSystemNSSKeySlotCallback, |
| 614 base::Unretained(this) /* singleton is leaky */, | 614 base::Unretained(this) /* singleton is leaky */, |
| 615 callback); | 615 callback); |
| 616 } | 616 } |
| 617 if (IsTPMTokenReady(wrapped_callback)) | 617 if (IsTPMTokenReady(wrapped_callback)) |
| 618 return ScopedPK11Slot(PK11_ReferenceSlot(tpm_slot_)); | 618 return ScopedPK11Slot(PK11_ReferenceSlot(tpm_slot_.get())); |
| 619 return ScopedPK11Slot(); | 619 return ScopedPK11Slot(); |
| 620 } | 620 } |
| 621 #endif | 621 #endif |
| 622 | 622 |
| 623 #if defined(USE_NSS) | 623 #if defined(USE_NSS) |
| 624 base::Lock* write_lock() { | 624 base::Lock* write_lock() { |
| 625 return &write_lock_; | 625 return &write_lock_; |
| 626 } | 626 } |
| 627 #endif // defined(USE_NSS) | 627 #endif // defined(USE_NSS) |
| 628 | 628 |
| 629 // This method is used to force NSS to be initialized without a DB. | 629 // This method is used to force NSS to be initialized without a DB. |
| 630 // Call this method before NSSInitSingleton() is constructed. | 630 // Call this method before NSSInitSingleton() is constructed. |
| 631 static void ForceNoDBInit() { | 631 static void ForceNoDBInit() { |
| 632 force_nodb_init_ = true; | 632 force_nodb_init_ = true; |
| 633 } | 633 } |
| 634 | 634 |
| 635 private: | 635 private: |
| 636 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; | 636 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; |
| 637 | 637 |
| 638 NSSInitSingleton() | 638 NSSInitSingleton() |
| 639 : tpm_token_enabled_for_nss_(false), | 639 : tpm_token_enabled_for_nss_(false), |
| 640 initializing_tpm_token_(false), | 640 initializing_tpm_token_(false), |
| 641 chaps_module_(NULL), | 641 chaps_module_(NULL), |
| 642 tpm_slot_(NULL), | |
| 643 root_(NULL) { | 642 root_(NULL) { |
| 644 base::TimeTicks start_time = base::TimeTicks::Now(); | 643 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 645 | 644 |
| 646 // It's safe to construct on any thread, since LazyInstance will prevent any | 645 // It's safe to construct on any thread, since LazyInstance will prevent any |
| 647 // other threads from accessing until the constructor is done. | 646 // other threads from accessing until the constructor is done. |
| 648 thread_checker_.DetachFromThread(); | 647 thread_checker_.DetachFromThread(); |
| 649 | 648 |
| 650 DisableAESNIIfNeeded(); | 649 DisableAESNIIfNeeded(); |
| 651 | 650 |
| 652 EnsureNSPRInit(); | 651 EnsureNSPRInit(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 749 50); | 748 50); |
| 750 } | 749 } |
| 751 | 750 |
| 752 // NOTE(willchan): We don't actually execute this code since we leak NSS to | 751 // 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 | 752 // prevent non-joinable threads from using NSS after it's already been shut |
| 754 // down. | 753 // down. |
| 755 ~NSSInitSingleton() { | 754 ~NSSInitSingleton() { |
| 756 #if defined(OS_CHROMEOS) | 755 #if defined(OS_CHROMEOS) |
| 757 STLDeleteValues(&chromeos_user_map_); | 756 STLDeleteValues(&chromeos_user_map_); |
| 758 #endif | 757 #endif |
| 759 if (tpm_slot_) { | 758 tpm_slot_.reset(); |
| 760 PK11_FreeSlot(tpm_slot_); | |
| 761 tpm_slot_ = NULL; | |
| 762 } | |
| 763 if (root_) { | 759 if (root_) { |
| 764 SECMOD_UnloadUserModule(root_); | 760 SECMOD_UnloadUserModule(root_); |
| 765 SECMOD_DestroyModule(root_); | 761 SECMOD_DestroyModule(root_); |
| 766 root_ = NULL; | 762 root_ = NULL; |
| 767 } | 763 } |
| 768 if (chaps_module_) { | 764 if (chaps_module_) { |
| 769 SECMOD_UnloadUserModule(chaps_module_); | 765 SECMOD_UnloadUserModule(chaps_module_); |
| 770 SECMOD_DestroyModule(chaps_module_); | 766 SECMOD_DestroyModule(chaps_module_); |
| 771 chaps_module_ = NULL; | 767 chaps_module_ = NULL; |
| 772 } | 768 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 837 } | 833 } |
| 838 | 834 |
| 839 // If this is set to true NSS is forced to be initialized without a DB. | 835 // If this is set to true NSS is forced to be initialized without a DB. |
| 840 static bool force_nodb_init_; | 836 static bool force_nodb_init_; |
| 841 | 837 |
| 842 bool tpm_token_enabled_for_nss_; | 838 bool tpm_token_enabled_for_nss_; |
| 843 bool initializing_tpm_token_; | 839 bool initializing_tpm_token_; |
| 844 typedef std::vector<base::Closure> TPMReadyCallbackList; | 840 typedef std::vector<base::Closure> TPMReadyCallbackList; |
| 845 TPMReadyCallbackList tpm_ready_callback_list_; | 841 TPMReadyCallbackList tpm_ready_callback_list_; |
| 846 SECMODModule* chaps_module_; | 842 SECMODModule* chaps_module_; |
| 847 PK11SlotInfo* tpm_slot_; | 843 crypto::ScopedPK11Slot tpm_slot_; |
| 848 SECMODModule* root_; | 844 SECMODModule* root_; |
| 849 #if defined(OS_CHROMEOS) | 845 #if defined(OS_CHROMEOS) |
| 850 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap; | 846 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap; |
| 851 ChromeOSUserMap chromeos_user_map_; | 847 ChromeOSUserMap chromeos_user_map_; |
| 852 ScopedPK11Slot test_system_slot_; | 848 ScopedPK11Slot test_system_slot_; |
| 853 #endif | 849 #endif |
| 854 #if defined(USE_NSS) | 850 #if defined(USE_NSS) |
| 855 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 | 851 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 |
| 856 // is fixed, we will no longer need the lock. | 852 // is fixed, we will no longer need the lock. |
| 857 base::Lock write_lock_; | 853 base::Lock write_lock_; |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1093 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); | 1089 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); |
| 1094 } | 1090 } |
| 1095 | 1091 |
| 1096 #if !defined(OS_CHROMEOS) | 1092 #if !defined(OS_CHROMEOS) |
| 1097 PK11SlotInfo* GetPersistentNSSKeySlot() { | 1093 PK11SlotInfo* GetPersistentNSSKeySlot() { |
| 1098 return g_nss_singleton.Get().GetPersistentNSSKeySlot(); | 1094 return g_nss_singleton.Get().GetPersistentNSSKeySlot(); |
| 1099 } | 1095 } |
| 1100 #endif | 1096 #endif |
| 1101 | 1097 |
| 1102 } // namespace crypto | 1098 } // namespace crypto |
| OLD | NEW |