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

Side by Side Diff: crypto/nss_util.cc

Issue 401623006: Extract ScopedTestNSSDB from nss_util. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased. 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 | « crypto/nss_util.h ('k') | crypto/nss_util_internal.h » ('j') | 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 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 PL_ArenaFinish(); 191 PL_ArenaFinish();
192 PRStatus prstatus = PR_Cleanup(); 192 PRStatus prstatus = PR_Cleanup();
193 if (prstatus != PR_SUCCESS) 193 if (prstatus != PR_SUCCESS)
194 LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?"; 194 LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?";
195 } 195 }
196 }; 196 };
197 197
198 base::LazyInstance<NSPRInitSingleton>::Leaky 198 base::LazyInstance<NSPRInitSingleton>::Leaky
199 g_nspr_singleton = LAZY_INSTANCE_INITIALIZER; 199 g_nspr_singleton = LAZY_INSTANCE_INITIALIZER;
200 200
201 // This is a LazyInstance so that it will be deleted automatically when the
202 // unittest exits. NSSInitSingleton is a LeakySingleton, so it would not be
203 // deleted if it were a regular member.
204 base::LazyInstance<base::ScopedTempDir> g_test_nss_db_dir =
205 LAZY_INSTANCE_INITIALIZER;
206
207 // Force a crash with error info on NSS_NoDB_Init failure. 201 // Force a crash with error info on NSS_NoDB_Init failure.
208 void CrashOnNSSInitFailure() { 202 void CrashOnNSSInitFailure() {
209 int nss_error = PR_GetError(); 203 int nss_error = PR_GetError();
210 int os_error = PR_GetOSError(); 204 int os_error = PR_GetOSError();
211 base::debug::Alias(&nss_error); 205 base::debug::Alias(&nss_error);
212 base::debug::Alias(&os_error); 206 base::debug::Alias(&os_error);
213 LOG(ERROR) << "Error initializing NSS without a persistent database: " 207 LOG(ERROR) << "Error initializing NSS without a persistent database: "
214 << GetNSSErrorMessage(); 208 << GetNSSErrorMessage();
215 LOG(FATAL) << "nss_error=" << nss_error << ", os_error=" << os_error; 209 LOG(FATAL) << "nss_error=" << nss_error << ", os_error=" << os_error;
216 } 210 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 public: 274 public:
281 #if defined(OS_CHROMEOS) 275 #if defined(OS_CHROMEOS)
282 // Used with PostTaskAndReply to pass handles to worker thread and back. 276 // Used with PostTaskAndReply to pass handles to worker thread and back.
283 struct TPMModuleAndSlot { 277 struct TPMModuleAndSlot {
284 explicit TPMModuleAndSlot(SECMODModule* init_chaps_module) 278 explicit TPMModuleAndSlot(SECMODModule* init_chaps_module)
285 : chaps_module(init_chaps_module), tpm_slot(NULL) {} 279 : chaps_module(init_chaps_module), tpm_slot(NULL) {}
286 SECMODModule* chaps_module; 280 SECMODModule* chaps_module;
287 PK11SlotInfo* tpm_slot; 281 PK11SlotInfo* tpm_slot;
288 }; 282 };
289 283
290 PK11SlotInfo* OpenPersistentNSSDBForPath(const std::string& db_name, 284 ScopedPK11Slot OpenPersistentNSSDBForPath(const std::string& db_name,
291 const base::FilePath& path) { 285 const base::FilePath& path) {
292 DCHECK(thread_checker_.CalledOnValidThread()); 286 DCHECK(thread_checker_.CalledOnValidThread());
293 // 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
294 // to a dedicated thread would still have the affect of blocking 288 // to a dedicated thread would still have the affect of blocking
295 // the current thread, due to NSS's internal locking requirements 289 // the current thread, due to NSS's internal locking requirements
296 base::ThreadRestrictions::ScopedAllowIO allow_io; 290 base::ThreadRestrictions::ScopedAllowIO allow_io;
297 291
298 base::FilePath nssdb_path = path.AppendASCII(".pki").AppendASCII("nssdb"); 292 base::FilePath nssdb_path = path.AppendASCII(".pki").AppendASCII("nssdb");
299 if (!base::CreateDirectory(nssdb_path)) { 293 if (!base::CreateDirectory(nssdb_path)) {
300 LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory."; 294 LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory.";
301 return NULL; 295 return ScopedPK11Slot();
302 } 296 }
303 return OpenUserDB(nssdb_path, db_name); 297 return OpenSoftwareNSSDB(nssdb_path, db_name);
304 } 298 }
305 299
306 void EnableTPMTokenForNSS() { 300 void EnableTPMTokenForNSS() {
307 DCHECK(thread_checker_.CalledOnValidThread()); 301 DCHECK(thread_checker_.CalledOnValidThread());
308 302
309 // If this gets set, then we'll use the TPM for certs with 303 // If this gets set, then we'll use the TPM for certs with
310 // private keys, otherwise we'll fall back to the software 304 // private keys, otherwise we'll fall back to the software
311 // implementation. 305 // implementation.
312 tpm_token_enabled_for_nss_ = true; 306 tpm_token_enabled_for_nss_ = true;
313 } 307 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 380
387 void OnInitializedTPMTokenAndSystemSlot( 381 void OnInitializedTPMTokenAndSystemSlot(
388 const base::Callback<void(bool)>& callback, 382 const base::Callback<void(bool)>& callback,
389 scoped_ptr<TPMModuleAndSlot> tpm_args) { 383 scoped_ptr<TPMModuleAndSlot> tpm_args) {
390 DCHECK(thread_checker_.CalledOnValidThread()); 384 DCHECK(thread_checker_.CalledOnValidThread());
391 DVLOG(2) << "Loaded chaps: " << !!tpm_args->chaps_module 385 DVLOG(2) << "Loaded chaps: " << !!tpm_args->chaps_module
392 << ", got tpm slot: " << !!tpm_args->tpm_slot; 386 << ", got tpm slot: " << !!tpm_args->tpm_slot;
393 387
394 chaps_module_ = tpm_args->chaps_module; 388 chaps_module_ = tpm_args->chaps_module;
395 tpm_slot_ = tpm_args->tpm_slot; 389 tpm_slot_ = tpm_args->tpm_slot;
396 if (!chaps_module_ && test_slot_) { 390 if (!chaps_module_ && test_system_slot_) {
397 // chromeos_unittests try to test the TPM initialization process. If we 391 // chromeos_unittests try to test the TPM initialization process. If we
398 // 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.
399 tpm_slot_ = PK11_ReferenceSlot(test_slot_); 393 tpm_slot_ = PK11_ReferenceSlot(test_system_slot_.get());
400 } 394 }
401 initializing_tpm_token_ = false; 395 initializing_tpm_token_ = false;
402 396
403 if (tpm_slot_) { 397 if (tpm_slot_) {
404 TPMReadyCallbackList callback_list; 398 TPMReadyCallbackList callback_list;
405 callback_list.swap(tpm_ready_callback_list_); 399 callback_list.swap(tpm_ready_callback_list_);
406 for (TPMReadyCallbackList::iterator i = callback_list.begin(); 400 for (TPMReadyCallbackList::iterator i = callback_list.begin();
407 i != callback_list.end(); 401 i != callback_list.end();
408 ++i) { 402 ++i) {
409 (*i).Run(); 403 (*i).Run();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 const std::string& email, 450 const std::string& email,
457 const std::string& username_hash, 451 const std::string& username_hash,
458 const base::FilePath& path) { 452 const base::FilePath& path) {
459 DCHECK(thread_checker_.CalledOnValidThread()); 453 DCHECK(thread_checker_.CalledOnValidThread());
460 if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) { 454 if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) {
461 // This user already exists in our mapping. 455 // This user already exists in our mapping.
462 DVLOG(2) << username_hash << " already initialized."; 456 DVLOG(2) << username_hash << " already initialized.";
463 return false; 457 return false;
464 } 458 }
465 459
466 // If test slot is set, slot getter methods will short circuit
467 // checking |chromeos_user_map_|, so there is nothing left to be
468 // initialized.
469 if (test_slot_)
470 return false;
471
472 DVLOG(2) << "Opening NSS DB " << path.value(); 460 DVLOG(2) << "Opening NSS DB " << path.value();
473 std::string db_name = base::StringPrintf( 461 std::string db_name = base::StringPrintf(
474 "%s %s", kUserNSSDatabaseName, username_hash.c_str()); 462 "%s %s", kUserNSSDatabaseName, username_hash.c_str());
475 ScopedPK11Slot public_slot(OpenPersistentNSSDBForPath(db_name, path)); 463 ScopedPK11Slot public_slot(OpenPersistentNSSDBForPath(db_name, path));
476 chromeos_user_map_[username_hash] = 464 chromeos_user_map_[username_hash] =
477 new ChromeOSUserData(public_slot.Pass()); 465 new ChromeOSUserData(public_slot.Pass());
478 return true; 466 return true;
479 } 467 }
480 468
481 bool ShouldInitializeTPMForChromeOSUser(const std::string& username_hash) { 469 bool ShouldInitializeTPMForChromeOSUser(const std::string& username_hash) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 532
545 ScopedPK11Slot GetPublicSlotForChromeOSUser( 533 ScopedPK11Slot GetPublicSlotForChromeOSUser(
546 const std::string& username_hash) { 534 const std::string& username_hash) {
547 DCHECK(thread_checker_.CalledOnValidThread()); 535 DCHECK(thread_checker_.CalledOnValidThread());
548 536
549 if (username_hash.empty()) { 537 if (username_hash.empty()) {
550 DVLOG(2) << "empty username_hash"; 538 DVLOG(2) << "empty username_hash";
551 return ScopedPK11Slot(); 539 return ScopedPK11Slot();
552 } 540 }
553 541
554 if (test_slot_) {
555 DVLOG(2) << "returning test_slot_ for " << username_hash;
556 return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_));
557 }
558
559 if (chromeos_user_map_.find(username_hash) == chromeos_user_map_.end()) { 542 if (chromeos_user_map_.find(username_hash) == chromeos_user_map_.end()) {
560 LOG(ERROR) << username_hash << " not initialized."; 543 LOG(ERROR) << username_hash << " not initialized.";
561 return ScopedPK11Slot(); 544 return ScopedPK11Slot();
562 } 545 }
563 return chromeos_user_map_[username_hash]->GetPublicSlot(); 546 return chromeos_user_map_[username_hash]->GetPublicSlot();
564 } 547 }
565 548
566 ScopedPK11Slot GetPrivateSlotForChromeOSUser( 549 ScopedPK11Slot GetPrivateSlotForChromeOSUser(
567 const std::string& username_hash, 550 const std::string& username_hash,
568 const base::Callback<void(ScopedPK11Slot)>& callback) { 551 const base::Callback<void(ScopedPK11Slot)>& callback) {
569 DCHECK(thread_checker_.CalledOnValidThread()); 552 DCHECK(thread_checker_.CalledOnValidThread());
570 553
571 if (username_hash.empty()) { 554 if (username_hash.empty()) {
572 DVLOG(2) << "empty username_hash"; 555 DVLOG(2) << "empty username_hash";
573 if (!callback.is_null()) { 556 if (!callback.is_null()) {
574 base::MessageLoop::current()->PostTask( 557 base::MessageLoop::current()->PostTask(
575 FROM_HERE, base::Bind(callback, base::Passed(ScopedPK11Slot()))); 558 FROM_HERE, base::Bind(callback, base::Passed(ScopedPK11Slot())));
576 } 559 }
577 return ScopedPK11Slot(); 560 return ScopedPK11Slot();
578 } 561 }
579 562
580 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); 563 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());
581 564
582 if (test_slot_) {
583 DVLOG(2) << "returning test_slot_ for " << username_hash;
584 return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_));
585 }
586
587 return chromeos_user_map_[username_hash]->GetPrivateSlot(callback); 565 return chromeos_user_map_[username_hash]->GetPrivateSlot(callback);
588 } 566 }
589 567
590 void CloseTestChromeOSUser(const std::string& username_hash) { 568 void CloseChromeOSUserForTesting(const std::string& username_hash) {
591 DCHECK(thread_checker_.CalledOnValidThread()); 569 DCHECK(thread_checker_.CalledOnValidThread());
592 ChromeOSUserMap::iterator i = chromeos_user_map_.find(username_hash); 570 ChromeOSUserMap::iterator i = chromeos_user_map_.find(username_hash);
593 DCHECK(i != chromeos_user_map_.end()); 571 DCHECK(i != chromeos_user_map_.end());
594 delete i->second; 572 delete i->second;
595 chromeos_user_map_.erase(i); 573 chromeos_user_map_.erase(i);
596 } 574 }
575
576 void SetSystemKeySlotForTesting(ScopedPK11Slot slot) {
577 // Ensure that a previous value of test_system_slot_ is not overwritten.
578 // Unsetting, i.e. setting a NULL, however is allowed.
579 DCHECK(!slot || !test_system_slot_);
580 test_system_slot_ = slot.Pass();
mattm 2014/07/29 23:12:54 since the value may have already been referenced b
pneubeck (no reviews) 2014/07/30 07:51:26 Yeah, I realized this finally too. (it wasn't used
581 }
597 #endif // defined(OS_CHROMEOS) 582 #endif // defined(OS_CHROMEOS)
598 583
599 584 #if !defined(OS_CHROMEOS)
600 bool OpenTestNSSDB() {
601 DCHECK(thread_checker_.CalledOnValidThread());
602 // NSS is allowed to do IO on the current thread since dispatching
603 // to a dedicated thread would still have the affect of blocking
604 // the current thread, due to NSS's internal locking requirements
605 base::ThreadRestrictions::ScopedAllowIO allow_io;
606
607 if (test_slot_)
608 return true;
609 if (!g_test_nss_db_dir.Get().CreateUniqueTempDir())
610 return false;
611 test_slot_ = OpenUserDB(g_test_nss_db_dir.Get().path(), kTestTPMTokenName);
612 return !!test_slot_;
613 }
614
615 void CloseTestNSSDB() {
616 DCHECK(thread_checker_.CalledOnValidThread());
617 // NSS is allowed to do IO on the current thread since dispatching
618 // to a dedicated thread would still have the affect of blocking
619 // the current thread, due to NSS's internal locking requirements
620 base::ThreadRestrictions::ScopedAllowIO allow_io;
621
622 if (!test_slot_)
623 return;
624 SECStatus status = SECMOD_CloseUserDB(test_slot_);
625 if (status != SECSuccess)
626 PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError();
627 PK11_FreeSlot(test_slot_);
628 test_slot_ = NULL;
629 ignore_result(g_test_nss_db_dir.Get().Delete());
630 }
631
632 PK11SlotInfo* GetPersistentNSSKeySlot() { 585 PK11SlotInfo* GetPersistentNSSKeySlot() {
633 // TODO(mattm): Change to DCHECK when callers have been fixed. 586 // TODO(mattm): Change to DCHECK when callers have been fixed.
634 if (!thread_checker_.CalledOnValidThread()) { 587 if (!thread_checker_.CalledOnValidThread()) {
635 DVLOG(1) << "Called on wrong thread.\n" 588 DVLOG(1) << "Called on wrong thread.\n"
636 << base::debug::StackTrace().ToString(); 589 << base::debug::StackTrace().ToString();
637 } 590 }
638 591
639 if (test_slot_)
640 return PK11_ReferenceSlot(test_slot_);
641 return PK11_GetInternalKeySlot(); 592 return PK11_GetInternalKeySlot();
642 } 593 }
594 #endif
643 595
644 #if defined(OS_CHROMEOS) 596 #if defined(OS_CHROMEOS)
645 PK11SlotInfo* GetSystemNSSKeySlot() { 597 PK11SlotInfo* GetSystemNSSKeySlot() {
646 DCHECK(thread_checker_.CalledOnValidThread()); 598 DCHECK(thread_checker_.CalledOnValidThread());
647 599
648 if (test_slot_)
649 return PK11_ReferenceSlot(test_slot_);
650
651 // TODO(mattm): chromeos::TPMTokenloader always calls 600 // TODO(mattm): chromeos::TPMTokenloader always calls
652 // InitializeTPMTokenAndSystemSlot with slot 0. If the system slot is 601 // InitializeTPMTokenAndSystemSlot with slot 0. If the system slot is
653 // disabled, tpm_slot_ will be the first user's slot instead. Can that be 602 // disabled, tpm_slot_ will be the first user's slot instead. Can that be
654 // detected and return NULL instead? 603 // detected and return NULL instead?
655 if (tpm_token_enabled_for_nss_ && IsTPMTokenReady(base::Closure())) 604 if (tpm_token_enabled_for_nss_ && IsTPMTokenReady(base::Closure()))
656 return PK11_ReferenceSlot(tpm_slot_); 605 return PK11_ReferenceSlot(tpm_slot_);
657 // If we were supposed to get the hardware token, but were 606 // If we were supposed to get the hardware token, but were
658 // unable to, return NULL rather than fall back to sofware. 607 // unable to, return NULL rather than fall back to sofware.
659 return NULL; 608 return NULL;
660 } 609 }
(...skipping 11 matching lines...) Expand all
672 force_nodb_init_ = true; 621 force_nodb_init_ = true;
673 } 622 }
674 623
675 private: 624 private:
676 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; 625 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>;
677 626
678 NSSInitSingleton() 627 NSSInitSingleton()
679 : tpm_token_enabled_for_nss_(false), 628 : tpm_token_enabled_for_nss_(false),
680 initializing_tpm_token_(false), 629 initializing_tpm_token_(false),
681 chaps_module_(NULL), 630 chaps_module_(NULL),
682 test_slot_(NULL),
683 tpm_slot_(NULL), 631 tpm_slot_(NULL),
684 root_(NULL) { 632 root_(NULL) {
685 base::TimeTicks start_time = base::TimeTicks::Now(); 633 base::TimeTicks start_time = base::TimeTicks::Now();
686 634
687 // It's safe to construct on any thread, since LazyInstance will prevent any 635 // It's safe to construct on any thread, since LazyInstance will prevent any
688 // other threads from accessing until the constructor is done. 636 // other threads from accessing until the constructor is done.
689 thread_checker_.DetachFromThread(); 637 thread_checker_.DetachFromThread();
690 638
691 DisableAESNIIfNeeded(); 639 DisableAESNIIfNeeded();
692 640
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 // prevent non-joinable threads from using NSS after it's already been shut 742 // prevent non-joinable threads from using NSS after it's already been shut
795 // down. 743 // down.
796 ~NSSInitSingleton() { 744 ~NSSInitSingleton() {
797 #if defined(OS_CHROMEOS) 745 #if defined(OS_CHROMEOS)
798 STLDeleteValues(&chromeos_user_map_); 746 STLDeleteValues(&chromeos_user_map_);
799 #endif 747 #endif
800 if (tpm_slot_) { 748 if (tpm_slot_) {
801 PK11_FreeSlot(tpm_slot_); 749 PK11_FreeSlot(tpm_slot_);
802 tpm_slot_ = NULL; 750 tpm_slot_ = NULL;
803 } 751 }
804 CloseTestNSSDB();
805 if (root_) { 752 if (root_) {
806 SECMOD_UnloadUserModule(root_); 753 SECMOD_UnloadUserModule(root_);
807 SECMOD_DestroyModule(root_); 754 SECMOD_DestroyModule(root_);
808 root_ = NULL; 755 root_ = NULL;
809 } 756 }
810 if (chaps_module_) { 757 if (chaps_module_) {
811 SECMOD_UnloadUserModule(chaps_module_); 758 SECMOD_UnloadUserModule(chaps_module_);
812 SECMOD_DestroyModule(chaps_module_); 759 SECMOD_DestroyModule(chaps_module_);
813 chaps_module_ = NULL; 760 chaps_module_ = NULL;
814 } 761 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 if (!module->loaded) { 803 if (!module->loaded) {
857 LOG(ERROR) << "After loading " << name << ", loaded==false: " 804 LOG(ERROR) << "After loading " << name << ", loaded==false: "
858 << GetNSSErrorMessage(); 805 << GetNSSErrorMessage();
859 SECMOD_DestroyModule(module); 806 SECMOD_DestroyModule(module);
860 return NULL; 807 return NULL;
861 } 808 }
862 return module; 809 return module;
863 } 810 }
864 #endif 811 #endif
865 812
866 static PK11SlotInfo* OpenUserDB(const base::FilePath& path,
867 const std::string& description) {
868 const std::string modspec =
869 base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
870 path.value().c_str(),
871 description.c_str());
872 PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str());
873 if (db_slot) {
874 if (PK11_NeedUserInit(db_slot))
875 PK11_InitPin(db_slot, NULL, NULL);
876 } else {
877 LOG(ERROR) << "Error opening persistent database (" << modspec
878 << "): " << GetNSSErrorMessage();
879 }
880 return db_slot;
881 }
882
883 static void DisableAESNIIfNeeded() { 813 static void DisableAESNIIfNeeded() {
884 if (NSS_VersionCheck("3.15") && !NSS_VersionCheck("3.15.4")) { 814 if (NSS_VersionCheck("3.15") && !NSS_VersionCheck("3.15.4")) {
885 // Some versions of NSS have a bug that causes AVX instructions to be 815 // Some versions of NSS have a bug that causes AVX instructions to be
886 // used without testing whether XSAVE is enabled by the operating system. 816 // used without testing whether XSAVE is enabled by the operating system.
887 // In order to work around this, we disable AES-NI in NSS when we find 817 // In order to work around this, we disable AES-NI in NSS when we find
888 // that |has_avx()| is false (which includes the XSAVE test). See 818 // that |has_avx()| is false (which includes the XSAVE test). See
889 // https://bugzilla.mozilla.org/show_bug.cgi?id=940794 819 // https://bugzilla.mozilla.org/show_bug.cgi?id=940794
890 base::CPU cpu; 820 base::CPU cpu;
891 821
892 if (cpu.has_avx_hardware() && !cpu.has_avx()) { 822 if (cpu.has_avx_hardware() && !cpu.has_avx()) {
893 base::Environment::Create()->SetVar("NSS_DISABLE_HW_AES", "1"); 823 base::Environment::Create()->SetVar("NSS_DISABLE_HW_AES", "1");
894 } 824 }
895 } 825 }
896 } 826 }
897 827
898 // If this is set to true NSS is forced to be initialized without a DB. 828 // If this is set to true NSS is forced to be initialized without a DB.
899 static bool force_nodb_init_; 829 static bool force_nodb_init_;
900 830
901 bool tpm_token_enabled_for_nss_; 831 bool tpm_token_enabled_for_nss_;
902 bool initializing_tpm_token_; 832 bool initializing_tpm_token_;
903 typedef std::vector<base::Closure> TPMReadyCallbackList; 833 typedef std::vector<base::Closure> TPMReadyCallbackList;
904 TPMReadyCallbackList tpm_ready_callback_list_; 834 TPMReadyCallbackList tpm_ready_callback_list_;
905 SECMODModule* chaps_module_; 835 SECMODModule* chaps_module_;
906 PK11SlotInfo* test_slot_;
907 PK11SlotInfo* tpm_slot_; 836 PK11SlotInfo* tpm_slot_;
908 SECMODModule* root_; 837 SECMODModule* root_;
909 #if defined(OS_CHROMEOS) 838 #if defined(OS_CHROMEOS)
910 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap; 839 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap;
911 ChromeOSUserMap chromeos_user_map_; 840 ChromeOSUserMap chromeos_user_map_;
841 ScopedPK11Slot test_system_slot_;
912 #endif 842 #endif
913 #if defined(USE_NSS) 843 #if defined(USE_NSS)
914 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 844 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011
915 // is fixed, we will no longer need the lock. 845 // is fixed, we will no longer need the lock.
916 base::Lock write_lock_; 846 base::Lock write_lock_;
917 #endif // defined(USE_NSS) 847 #endif // defined(USE_NSS)
918 848
919 base::ThreadChecker thread_checker_; 849 base::ThreadChecker thread_checker_;
920 }; 850 };
921 851
922 // static 852 // static
923 bool NSSInitSingleton::force_nodb_init_ = false; 853 bool NSSInitSingleton::force_nodb_init_ = false;
924 854
925 base::LazyInstance<NSSInitSingleton>::Leaky 855 base::LazyInstance<NSSInitSingleton>::Leaky
926 g_nss_singleton = LAZY_INSTANCE_INITIALIZER; 856 g_nss_singleton = LAZY_INSTANCE_INITIALIZER;
927 } // namespace 857 } // namespace
928 858
929 const char kTestTPMTokenName[] = "Test DB"; 859 #if defined(USE_NSS)
860 ScopedPK11Slot OpenSoftwareNSSDB(const base::FilePath& path,
861 const std::string& description) {
862 const std::string modspec =
863 base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
864 path.value().c_str(),
865 description.c_str());
866 PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str());
867 if (db_slot) {
868 if (PK11_NeedUserInit(db_slot))
869 PK11_InitPin(db_slot, NULL, NULL);
870 } else {
871 LOG(ERROR) << "Error opening persistent database (" << modspec
872 << "): " << GetNSSErrorMessage();
873 }
874 return ScopedPK11Slot(db_slot);
875 }
930 876
931 #if defined(USE_NSS)
932 void EarlySetupForNSSInit() { 877 void EarlySetupForNSSInit() {
933 base::FilePath database_dir = GetInitialConfigDirectory(); 878 base::FilePath database_dir = GetInitialConfigDirectory();
934 if (!database_dir.empty()) 879 if (!database_dir.empty())
935 UseLocalCacheOfNSSDatabaseIfNFS(database_dir); 880 UseLocalCacheOfNSSDatabaseIfNFS(database_dir);
936 } 881 }
937 #endif 882 #endif
938 883
939 void EnsureNSPRInit() { 884 void EnsureNSPRInit() {
940 g_nspr_singleton.Get(); 885 g_nspr_singleton.Get();
941 } 886 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 LOG(ERROR) << "Failed to load NSS libraries."; 965 LOG(ERROR) << "Failed to load NSS libraries.";
1021 } 966 }
1022 #endif // defined(USE_NSS) 967 #endif // defined(USE_NSS)
1023 } 968 }
1024 969
1025 bool CheckNSSVersion(const char* version) { 970 bool CheckNSSVersion(const char* version) {
1026 return !!NSS_VersionCheck(version); 971 return !!NSS_VersionCheck(version);
1027 } 972 }
1028 973
1029 #if defined(USE_NSS) 974 #if defined(USE_NSS)
1030 ScopedTestNSSDB::ScopedTestNSSDB()
1031 : is_open_(g_nss_singleton.Get().OpenTestNSSDB()) {
1032 }
1033
1034 ScopedTestNSSDB::~ScopedTestNSSDB() {
1035 // Don't close when NSS is < 3.15.1, because it would require an additional
1036 // sleep for 1 second after closing the database, due to
1037 // http://bugzil.la/875601.
1038 if (NSS_VersionCheck("3.15.1")) {
1039 g_nss_singleton.Get().CloseTestNSSDB();
1040 }
1041 }
1042
1043 base::Lock* GetNSSWriteLock() { 975 base::Lock* GetNSSWriteLock() {
1044 return g_nss_singleton.Get().write_lock(); 976 return g_nss_singleton.Get().write_lock();
1045 } 977 }
1046 978
1047 AutoNSSWriteLock::AutoNSSWriteLock() : lock_(GetNSSWriteLock()) { 979 AutoNSSWriteLock::AutoNSSWriteLock() : lock_(GetNSSWriteLock()) {
1048 // May be NULL if the lock is not needed in our version of NSS. 980 // May be NULL if the lock is not needed in our version of NSS.
1049 if (lock_) 981 if (lock_)
1050 lock_->Acquire(); 982 lock_->Acquire();
1051 } 983 }
1052 984
1053 AutoNSSWriteLock::~AutoNSSWriteLock() { 985 AutoNSSWriteLock::~AutoNSSWriteLock() {
1054 if (lock_) { 986 if (lock_) {
1055 lock_->AssertAcquired(); 987 lock_->AssertAcquired();
1056 lock_->Release(); 988 lock_->Release();
1057 } 989 }
1058 } 990 }
1059 991
1060 AutoSECMODListReadLock::AutoSECMODListReadLock() 992 AutoSECMODListReadLock::AutoSECMODListReadLock()
1061 : lock_(SECMOD_GetDefaultModuleListLock()) { 993 : lock_(SECMOD_GetDefaultModuleListLock()) {
1062 SECMOD_GetReadLock(lock_); 994 SECMOD_GetReadLock(lock_);
1063 } 995 }
1064 996
1065 AutoSECMODListReadLock::~AutoSECMODListReadLock() { 997 AutoSECMODListReadLock::~AutoSECMODListReadLock() {
1066 SECMOD_ReleaseReadLock(lock_); 998 SECMOD_ReleaseReadLock(lock_);
1067 } 999 }
1068
1069 #endif // defined(USE_NSS) 1000 #endif // defined(USE_NSS)
1070 1001
1071 #if defined(OS_CHROMEOS) 1002 #if defined(OS_CHROMEOS)
1072 PK11SlotInfo* GetSystemNSSKeySlot() { 1003 PK11SlotInfo* GetSystemNSSKeySlot() {
1073 return g_nss_singleton.Get().GetSystemNSSKeySlot(); 1004 return g_nss_singleton.Get().GetSystemNSSKeySlot();
1074 } 1005 }
1075 1006
1007 void SetSystemKeySlotForTesting(ScopedPK11Slot slot) {
1008 g_nss_singleton.Get().SetSystemKeySlotForTesting(ScopedPK11Slot());
1009 }
1010
1076 void EnableTPMTokenForNSS() { 1011 void EnableTPMTokenForNSS() {
1077 g_nss_singleton.Get().EnableTPMTokenForNSS(); 1012 g_nss_singleton.Get().EnableTPMTokenForNSS();
1078 } 1013 }
1079 1014
1080 bool IsTPMTokenEnabledForNSS() { 1015 bool IsTPMTokenEnabledForNSS() {
1081 return g_nss_singleton.Get().IsTPMTokenEnabledForNSS(); 1016 return g_nss_singleton.Get().IsTPMTokenEnabledForNSS();
1082 } 1017 }
1083 1018
1084 bool IsTPMTokenReady(const base::Closure& callback) { 1019 bool IsTPMTokenReady(const base::Closure& callback) {
1085 return g_nss_singleton.Get().IsTPMTokenReady(callback); 1020 return g_nss_singleton.Get().IsTPMTokenReady(callback);
1086 } 1021 }
1087 1022
1088 void InitializeTPMTokenAndSystemSlot( 1023 void InitializeTPMTokenAndSystemSlot(
1089 int token_slot_id, 1024 int token_slot_id,
1090 const base::Callback<void(bool)>& callback) { 1025 const base::Callback<void(bool)>& callback) {
1091 g_nss_singleton.Get().InitializeTPMTokenAndSystemSlot(token_slot_id, 1026 g_nss_singleton.Get().InitializeTPMTokenAndSystemSlot(token_slot_id,
1092 callback); 1027 callback);
1093 } 1028 }
1094 1029
1095 ScopedTestNSSChromeOSUser::ScopedTestNSSChromeOSUser(
1096 const std::string& username_hash)
1097 : username_hash_(username_hash), constructed_successfully_(false) {
1098 if (!temp_dir_.CreateUniqueTempDir())
1099 return;
1100 constructed_successfully_ =
1101 InitializeNSSForChromeOSUser(username_hash,
1102 username_hash,
1103 temp_dir_.path());
1104 }
1105
1106 ScopedTestNSSChromeOSUser::~ScopedTestNSSChromeOSUser() {
1107 if (constructed_successfully_)
1108 g_nss_singleton.Get().CloseTestChromeOSUser(username_hash_);
1109 }
1110
1111 void ScopedTestNSSChromeOSUser::FinishInit() {
1112 DCHECK(constructed_successfully_);
1113 if (!ShouldInitializeTPMForChromeOSUser(username_hash_))
1114 return;
1115 WillInitializeTPMForChromeOSUser(username_hash_);
1116 InitializePrivateSoftwareSlotForChromeOSUser(username_hash_);
1117 }
1118
1119 bool InitializeNSSForChromeOSUser( 1030 bool InitializeNSSForChromeOSUser(
1120 const std::string& email, 1031 const std::string& email,
1121 const std::string& username_hash, 1032 const std::string& username_hash,
1122 const base::FilePath& path) { 1033 const base::FilePath& path) {
1123 return g_nss_singleton.Get().InitializeNSSForChromeOSUser( 1034 return g_nss_singleton.Get().InitializeNSSForChromeOSUser(
1124 email, username_hash, path); 1035 email, username_hash, path);
1125 } 1036 }
1126 1037
1127 bool ShouldInitializeTPMForChromeOSUser(const std::string& username_hash) { 1038 bool ShouldInitializeTPMForChromeOSUser(const std::string& username_hash) {
1128 return g_nss_singleton.Get().ShouldInitializeTPMForChromeOSUser( 1039 return g_nss_singleton.Get().ShouldInitializeTPMForChromeOSUser(
1129 username_hash); 1040 username_hash);
1130 } 1041 }
1131 1042
1132 void WillInitializeTPMForChromeOSUser(const std::string& username_hash) { 1043 void WillInitializeTPMForChromeOSUser(const std::string& username_hash) {
1133 g_nss_singleton.Get().WillInitializeTPMForChromeOSUser(username_hash); 1044 g_nss_singleton.Get().WillInitializeTPMForChromeOSUser(username_hash);
1134 } 1045 }
1135 1046
1136 void InitializeTPMForChromeOSUser( 1047 void InitializeTPMForChromeOSUser(
1137 const std::string& username_hash, 1048 const std::string& username_hash,
1138 CK_SLOT_ID slot_id) { 1049 CK_SLOT_ID slot_id) {
1139 g_nss_singleton.Get().InitializeTPMForChromeOSUser(username_hash, slot_id); 1050 g_nss_singleton.Get().InitializeTPMForChromeOSUser(username_hash, slot_id);
1140 } 1051 }
1052
1141 void InitializePrivateSoftwareSlotForChromeOSUser( 1053 void InitializePrivateSoftwareSlotForChromeOSUser(
1142 const std::string& username_hash) { 1054 const std::string& username_hash) {
1143 g_nss_singleton.Get().InitializePrivateSoftwareSlotForChromeOSUser( 1055 g_nss_singleton.Get().InitializePrivateSoftwareSlotForChromeOSUser(
1144 username_hash); 1056 username_hash);
1145 } 1057 }
1058
1146 ScopedPK11Slot GetPublicSlotForChromeOSUser(const std::string& username_hash) { 1059 ScopedPK11Slot GetPublicSlotForChromeOSUser(const std::string& username_hash) {
1147 return g_nss_singleton.Get().GetPublicSlotForChromeOSUser(username_hash); 1060 return g_nss_singleton.Get().GetPublicSlotForChromeOSUser(username_hash);
1148 } 1061 }
1062
1149 ScopedPK11Slot GetPrivateSlotForChromeOSUser( 1063 ScopedPK11Slot GetPrivateSlotForChromeOSUser(
1150 const std::string& username_hash, 1064 const std::string& username_hash,
1151 const base::Callback<void(ScopedPK11Slot)>& callback) { 1065 const base::Callback<void(ScopedPK11Slot)>& callback) {
1152 return g_nss_singleton.Get().GetPrivateSlotForChromeOSUser(username_hash, 1066 return g_nss_singleton.Get().GetPrivateSlotForChromeOSUser(username_hash,
1153 callback); 1067 callback);
1154 } 1068 }
1069
1070 void CloseChromeOSUserForTesting(const std::string& username_hash) {
1071 g_nss_singleton.Get().CloseChromeOSUserForTesting(username_hash);
1072 }
1155 #endif // defined(OS_CHROMEOS) 1073 #endif // defined(OS_CHROMEOS)
1156 1074
1157 base::Time PRTimeToBaseTime(PRTime prtime) { 1075 base::Time PRTimeToBaseTime(PRTime prtime) {
1158 return base::Time::FromInternalValue( 1076 return base::Time::FromInternalValue(
1159 prtime + base::Time::UnixEpoch().ToInternalValue()); 1077 prtime + base::Time::UnixEpoch().ToInternalValue());
1160 } 1078 }
1161 1079
1162 PRTime BaseTimeToPRTime(base::Time time) { 1080 PRTime BaseTimeToPRTime(base::Time time) {
1163 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); 1081 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue();
1164 } 1082 }
1165 1083
1084 #if !defined(OS_CHROMEOS)
1166 PK11SlotInfo* GetPersistentNSSKeySlot() { 1085 PK11SlotInfo* GetPersistentNSSKeySlot() {
1167 return g_nss_singleton.Get().GetPersistentNSSKeySlot(); 1086 return g_nss_singleton.Get().GetPersistentNSSKeySlot();
1168 } 1087 }
1088 #endif
1169 1089
1170 } // namespace crypto 1090 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/nss_util.h ('k') | crypto/nss_util_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698