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

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

Powered by Google App Engine
This is Rietveld 408576698