| Index: crypto/nss_util.cc
|
| diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc
|
| index f6b61330e91979e52d1ef9edaa9f7deac280a2a3..10501e0777800ec4d6f2031028e8830324852a37 100644
|
| --- a/crypto/nss_util.cc
|
| +++ b/crypto/nss_util.cc
|
| @@ -50,6 +50,7 @@
|
| #if defined(USE_NSS)
|
| #include "base/synchronization/lock.h"
|
| #include "crypto/nss_crypto_module_delegate.h"
|
| +#include "crypto/scoped_test_nss_db.h"
|
| #endif // defined(USE_NSS)
|
|
|
| namespace crypto {
|
| @@ -198,12 +199,6 @@ class NSPRInitSingleton {
|
| base::LazyInstance<NSPRInitSingleton>::Leaky
|
| g_nspr_singleton = LAZY_INSTANCE_INITIALIZER;
|
|
|
| -// This is a LazyInstance so that it will be deleted automatically when the
|
| -// unittest exits. NSSInitSingleton is a LeakySingleton, so it would not be
|
| -// deleted if it were a regular member.
|
| -base::LazyInstance<base::ScopedTempDir> g_test_nss_db_dir =
|
| - LAZY_INSTANCE_INITIALIZER;
|
| -
|
| // Force a crash with error info on NSS_NoDB_Init failure.
|
| void CrashOnNSSInitFailure() {
|
| int nss_error = PR_GetError();
|
| @@ -287,8 +282,8 @@ class NSSInitSingleton {
|
| PK11SlotInfo* tpm_slot;
|
| };
|
|
|
| - PK11SlotInfo* OpenPersistentNSSDBForPath(const std::string& db_name,
|
| - const base::FilePath& path) {
|
| + ScopedPK11Slot OpenPersistentNSSDBForPath(const std::string& db_name,
|
| + const base::FilePath& path) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| // NSS is allowed to do IO on the current thread since dispatching
|
| // to a dedicated thread would still have the affect of blocking
|
| @@ -298,7 +293,7 @@ class NSSInitSingleton {
|
| base::FilePath nssdb_path = path.AppendASCII(".pki").AppendASCII("nssdb");
|
| if (!base::CreateDirectory(nssdb_path)) {
|
| LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory.";
|
| - return NULL;
|
| + return ScopedPK11Slot();
|
| }
|
| return OpenUserDB(nssdb_path, db_name);
|
| }
|
| @@ -393,10 +388,10 @@ class NSSInitSingleton {
|
|
|
| chaps_module_ = tpm_args->chaps_module;
|
| tpm_slot_ = tpm_args->tpm_slot;
|
| - if (!chaps_module_ && test_slot_) {
|
| + if (!chaps_module_ && test_system_slot_) {
|
| // chromeos_unittests try to test the TPM initialization process. If we
|
| // have a test DB open, pretend that it is the TPM slot.
|
| - tpm_slot_ = PK11_ReferenceSlot(test_slot_);
|
| + tpm_slot_ = PK11_ReferenceSlot(test_system_slot_.get());
|
| }
|
| initializing_tpm_token_ = false;
|
|
|
| @@ -463,12 +458,6 @@ class NSSInitSingleton {
|
| return false;
|
| }
|
|
|
| - // If test slot is set, slot getter methods will short circuit
|
| - // checking |chromeos_user_map_|, so there is nothing left to be
|
| - // initialized.
|
| - if (test_slot_)
|
| - return false;
|
| -
|
| DVLOG(2) << "Opening NSS DB " << path.value();
|
| std::string db_name = base::StringPrintf(
|
| "%s %s", kUserNSSDatabaseName, username_hash.c_str());
|
| @@ -551,11 +540,6 @@ class NSSInitSingleton {
|
| return ScopedPK11Slot();
|
| }
|
|
|
| - if (test_slot_) {
|
| - DVLOG(2) << "returning test_slot_ for " << username_hash;
|
| - return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_));
|
| - }
|
| -
|
| if (chromeos_user_map_.find(username_hash) == chromeos_user_map_.end()) {
|
| LOG(ERROR) << username_hash << " not initialized.";
|
| return ScopedPK11Slot();
|
| @@ -579,11 +563,6 @@ class NSSInitSingleton {
|
|
|
| DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());
|
|
|
| - if (test_slot_) {
|
| - DVLOG(2) << "returning test_slot_ for " << username_hash;
|
| - return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_));
|
| - }
|
| -
|
| return chromeos_user_map_[username_hash]->GetPrivateSlot(callback);
|
| }
|
|
|
| @@ -594,41 +573,13 @@ class NSSInitSingleton {
|
| delete i->second;
|
| chromeos_user_map_.erase(i);
|
| }
|
| -#endif // defined(OS_CHROMEOS)
|
|
|
| -
|
| - bool OpenTestNSSDB() {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - // NSS is allowed to do IO on the current thread since dispatching
|
| - // to a dedicated thread would still have the affect of blocking
|
| - // the current thread, due to NSS's internal locking requirements
|
| - base::ThreadRestrictions::ScopedAllowIO allow_io;
|
| -
|
| - if (test_slot_)
|
| - return true;
|
| - if (!g_test_nss_db_dir.Get().CreateUniqueTempDir())
|
| - return false;
|
| - test_slot_ = OpenUserDB(g_test_nss_db_dir.Get().path(), kTestTPMTokenName);
|
| - return !!test_slot_;
|
| - }
|
| -
|
| - void CloseTestNSSDB() {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - // NSS is allowed to do IO on the current thread since dispatching
|
| - // to a dedicated thread would still have the affect of blocking
|
| - // the current thread, due to NSS's internal locking requirements
|
| - base::ThreadRestrictions::ScopedAllowIO allow_io;
|
| -
|
| - if (!test_slot_)
|
| - return;
|
| - SECStatus status = SECMOD_CloseUserDB(test_slot_);
|
| - if (status != SECSuccess)
|
| - PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError();
|
| - PK11_FreeSlot(test_slot_);
|
| - test_slot_ = NULL;
|
| - ignore_result(g_test_nss_db_dir.Get().Delete());
|
| + void SetTestSystemKeySlot(ScopedPK11Slot slot) {
|
| + test_system_slot_ = slot.Pass();
|
| }
|
| +#endif // defined(OS_CHROMEOS)
|
|
|
| +#if !defined(OS_CHROMEOS)
|
| PK11SlotInfo* GetPersistentNSSKeySlot() {
|
| // TODO(mattm): Change to DCHECK when callers have been fixed.
|
| if (!thread_checker_.CalledOnValidThread()) {
|
| @@ -636,17 +587,16 @@ class NSSInitSingleton {
|
| << base::debug::StackTrace().ToString();
|
| }
|
|
|
| - if (test_slot_)
|
| - return PK11_ReferenceSlot(test_slot_);
|
| return PK11_GetInternalKeySlot();
|
| }
|
| +#endif
|
|
|
| #if defined(OS_CHROMEOS)
|
| PK11SlotInfo* GetSystemNSSKeySlot() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - if (test_slot_)
|
| - return PK11_ReferenceSlot(test_slot_);
|
| + if (test_system_slot_)
|
| + return PK11_ReferenceSlot(test_system_slot_.get());
|
|
|
| // TODO(mattm): chromeos::TPMTokenloader always calls
|
| // InitializeTPMTokenAndSystemSlot with slot 0. If the system slot is
|
| @@ -679,7 +629,6 @@ class NSSInitSingleton {
|
| : tpm_token_enabled_for_nss_(false),
|
| initializing_tpm_token_(false),
|
| chaps_module_(NULL),
|
| - test_slot_(NULL),
|
| tpm_slot_(NULL),
|
| root_(NULL) {
|
| base::TimeTicks start_time = base::TimeTicks::Now();
|
| @@ -801,7 +750,6 @@ class NSSInitSingleton {
|
| PK11_FreeSlot(tpm_slot_);
|
| tpm_slot_ = NULL;
|
| }
|
| - CloseTestNSSDB();
|
| if (root_) {
|
| SECMOD_UnloadUserModule(root_);
|
| SECMOD_DestroyModule(root_);
|
| @@ -863,24 +811,6 @@ class NSSInitSingleton {
|
| }
|
| #endif
|
|
|
| - static PK11SlotInfo* OpenUserDB(const base::FilePath& path,
|
| - const std::string& description) {
|
| - const std::string modspec =
|
| - base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
|
| - path.value().c_str(),
|
| - description.c_str());
|
| - PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str());
|
| - if (db_slot) {
|
| - if (PK11_NeedUserInit(db_slot))
|
| - PK11_InitPin(db_slot, NULL, NULL);
|
| - }
|
| - else {
|
| - LOG(ERROR) << "Error opening persistent database (" << modspec
|
| - << "): " << GetNSSErrorMessage();
|
| - }
|
| - return db_slot;
|
| - }
|
| -
|
| static void DisableAESNIIfNeeded() {
|
| if (NSS_VersionCheck("3.15") && !NSS_VersionCheck("3.15.4")) {
|
| // Some versions of NSS have a bug that causes AVX instructions to be
|
| @@ -904,12 +834,12 @@ class NSSInitSingleton {
|
| typedef std::vector<base::Closure> TPMReadyCallbackList;
|
| TPMReadyCallbackList tpm_ready_callback_list_;
|
| SECMODModule* chaps_module_;
|
| - PK11SlotInfo* test_slot_;
|
| PK11SlotInfo* tpm_slot_;
|
| SECMODModule* root_;
|
| #if defined(OS_CHROMEOS)
|
| typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap;
|
| ChromeOSUserMap chromeos_user_map_;
|
| + ScopedPK11Slot test_system_slot_;
|
| #endif
|
| #if defined(USE_NSS)
|
| // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011
|
| @@ -927,9 +857,24 @@ base::LazyInstance<NSSInitSingleton>::Leaky
|
| g_nss_singleton = LAZY_INSTANCE_INITIALIZER;
|
| } // namespace
|
|
|
| -const char kTestTPMTokenName[] = "Test DB";
|
| -
|
| #if defined(USE_NSS)
|
| +ScopedPK11Slot OpenUserDB(const base::FilePath& path,
|
| + const std::string& description) {
|
| + const std::string modspec =
|
| + base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
|
| + path.value().c_str(),
|
| + description.c_str());
|
| + PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str());
|
| + if (db_slot) {
|
| + if (PK11_NeedUserInit(db_slot))
|
| + PK11_InitPin(db_slot, NULL, NULL);
|
| + } else {
|
| + LOG(ERROR) << "Error opening persistent database (" << modspec
|
| + << "): " << GetNSSErrorMessage();
|
| + }
|
| + return ScopedPK11Slot(db_slot);
|
| +}
|
| +
|
| void EarlySetupForNSSInit() {
|
| base::FilePath database_dir = GetInitialConfigDirectory();
|
| if (!database_dir.empty())
|
| @@ -1028,19 +973,24 @@ bool CheckNSSVersion(const char* version) {
|
| }
|
|
|
| #if defined(USE_NSS)
|
| -ScopedTestNSSDB::ScopedTestNSSDB()
|
| - : is_open_(g_nss_singleton.Get().OpenTestNSSDB()) {
|
| +#if defined(OS_CHROMEOS)
|
| +ScopedTestSystemNSSKeySlot::ScopedTestSystemNSSKeySlot()
|
| + : test_db_(new ScopedTestNSSDB) {
|
| + if (!test_db_->is_open())
|
| + return;
|
| + g_nss_singleton.Get().SetTestSystemKeySlot(
|
| + ScopedPK11Slot(PK11_ReferenceSlot(test_db_->slot())));
|
| }
|
|
|
| -ScopedTestNSSDB::~ScopedTestNSSDB() {
|
| - // Don't close when NSS is < 3.15.1, because it would require an additional
|
| - // sleep for 1 second after closing the database, due to
|
| - // http://bugzil.la/875601.
|
| - if (NSS_VersionCheck("3.15.1")) {
|
| - g_nss_singleton.Get().CloseTestNSSDB();
|
| - }
|
| +ScopedTestSystemNSSKeySlot::~ScopedTestSystemNSSKeySlot() {
|
| + g_nss_singleton.Get().SetTestSystemKeySlot(ScopedPK11Slot());
|
| }
|
|
|
| +bool ScopedTestSystemNSSKeySlot::ConstructedSuccessfully() const {
|
| + return test_db_->is_open();
|
| +}
|
| +#endif // defined(OS_CHROMEOS)
|
| +
|
| base::Lock* GetNSSWriteLock() {
|
| return g_nss_singleton.Get().write_lock();
|
| }
|
| @@ -1066,7 +1016,6 @@ AutoSECMODListReadLock::AutoSECMODListReadLock()
|
| AutoSECMODListReadLock::~AutoSECMODListReadLock() {
|
| SECMOD_ReleaseReadLock(lock_);
|
| }
|
| -
|
| #endif // defined(USE_NSS)
|
|
|
| #if defined(OS_CHROMEOS)
|
| @@ -1164,8 +1113,10 @@ PRTime BaseTimeToPRTime(base::Time time) {
|
| return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue();
|
| }
|
|
|
| +#if !defined(OS_CHROMEOS)
|
| PK11SlotInfo* GetPersistentNSSKeySlot() {
|
| return g_nss_singleton.Get().GetPersistentNSSKeySlot();
|
| }
|
| +#endif
|
|
|
| } // namespace crypto
|
|
|