diff options
author | tbarzic@chromium.org <tbarzic@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-12 12:46:17 +0000 |
---|---|---|
committer | tbarzic@chromium.org <tbarzic@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-12 12:46:17 +0000 |
commit | 4071e6ac6d212ca5cc90cef59ed9f4852cfed50c (patch) | |
tree | 405b9842525c655d478f55c689fd6c7a36aeceee /crypto | |
parent | 1f48bda5498e693e5de11b9c9bb5899f83fa1882 (diff) | |
download | chromium_src-4071e6ac6d212ca5cc90cef59ed9f4852cfed50c.zip chromium_src-4071e6ac6d212ca5cc90cef59ed9f4852cfed50c.tar.gz chromium_src-4071e6ac6d212ca5cc90cef59ed9f4852cfed50c.tar.bz2 |
Remove usage of singleton software_slot_ in nss on ChromeOS
Instead of opening primary user's public slot separately, do it like it's done
for other users: when InitializeNSSForChromeOSUser is called.
This makes primary user's public slot state not dependent on chromeos::TPMTokenLoader.
Also, with this, opening primary users public slot is not bound with enabling
TPM anymore, so the slot may get open for guest user and on Linux ChromeOS.
BUG=383663, 302062
Review URL: https://codereview.chromium.org/317613004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282817 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/nss_util.cc | 117 | ||||
-rw-r--r-- | crypto/nss_util.h | 5 | ||||
-rw-r--r-- | crypto/nss_util_internal.h | 16 | ||||
-rw-r--r-- | crypto/rsa_private_key_nss_unittest.cc | 6 |
4 files changed, 76 insertions, 68 deletions
diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc index 5958ad9..1598ba9 100644 --- a/crypto/nss_util.cc +++ b/crypto/nss_util.cc @@ -81,6 +81,7 @@ std::string GetNSSErrorMessage() { } #if defined(USE_NSS) +#if !defined(OS_CHROMEOS) base::FilePath GetDefaultConfigDirectory() { base::FilePath dir; PathService::Get(base::DIR_HOME, &dir); @@ -96,6 +97,7 @@ base::FilePath GetDefaultConfigDirectory() { DVLOG(2) << "DefaultConfigDirectory: " << dir.value(); return dir; } +#endif // !defined(IS_CHROMEOS) // On non-Chrome OS platforms, return the default config directory. On Chrome OS // test images, return a read-only directory with fake root CA certs (which are @@ -216,11 +218,11 @@ void CrashOnNSSInitFailure() { #if defined(OS_CHROMEOS) class ChromeOSUserData { public: - ChromeOSUserData(ScopedPK11Slot public_slot, bool is_primary_user) + explicit ChromeOSUserData(ScopedPK11Slot public_slot) : public_slot_(public_slot.Pass()), - is_primary_user_(is_primary_user) {} + private_slot_initialization_started_(false) {} ~ChromeOSUserData() { - if (public_slot_ && !is_primary_user_) { + if (public_slot_) { SECStatus status = SECMOD_CloseUserDB(public_slot_.get()); if (status != SECSuccess) PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError(); @@ -254,10 +256,19 @@ class ChromeOSUserData { } } + bool private_slot_initialization_started() const { + return private_slot_initialization_started_; + } + + void set_private_slot_initialization_started() { + private_slot_initialization_started_ = true; + } + private: ScopedPK11Slot public_slot_; ScopedPK11Slot private_slot_; - bool is_primary_user_; + + bool private_slot_initialization_started_; typedef std::vector<base::Callback<void(ScopedPK11Slot)> > SlotReadyCallbackList; @@ -276,24 +287,6 @@ class NSSInitSingleton { PK11SlotInfo* tpm_slot; }; - void OpenPersistentNSSDB() { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (!chromeos_user_logged_in_) { - // GetDefaultConfigDirectory causes us to do blocking IO on UI thread. - // Temporarily allow it until we fix http://crbug.com/70119 - base::ThreadRestrictions::ScopedAllowIO allow_io; - chromeos_user_logged_in_ = true; - - // This creates another DB slot in NSS that is read/write, unlike - // the fake root CA cert DB and the "default" crypto key - // provider, which are still read-only (because we initialized - // NSS before we had a cryptohome mounted). - software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), - kNSSDatabaseName); - } - } - PK11SlotInfo* OpenPersistentNSSDBForPath(const base::FilePath& path) { DCHECK(thread_checker_.CalledOnValidThread()); // NSS is allowed to do IO on the current thread since dispatching @@ -459,7 +452,6 @@ class NSSInitSingleton { bool InitializeNSSForChromeOSUser( const std::string& email, const std::string& username_hash, - bool is_primary_user, const base::FilePath& path) { DCHECK(thread_checker_.CalledOnValidThread()); if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) { @@ -467,23 +459,42 @@ class NSSInitSingleton { DVLOG(2) << username_hash << " already initialized."; return false; } - ScopedPK11Slot public_slot; - if (is_primary_user) { - DVLOG(2) << "Primary user, using GetPublicNSSKeySlot()"; - public_slot.reset(GetPublicNSSKeySlot()); - } else { - DVLOG(2) << "Opening NSS DB " << path.value(); - public_slot.reset(OpenPersistentNSSDBForPath(path)); - } + + // 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(); + ScopedPK11Slot public_slot(OpenPersistentNSSDBForPath(path)); chromeos_user_map_[username_hash] = - new ChromeOSUserData(public_slot.Pass(), is_primary_user); + new ChromeOSUserData(public_slot.Pass()); return true; } + bool ShouldInitializeTPMForChromeOSUser(const std::string& username_hash) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); + + return !chromeos_user_map_[username_hash] + ->private_slot_initialization_started(); + } + + void WillInitializeTPMForChromeOSUser(const std::string& username_hash) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); + + chromeos_user_map_[username_hash] + ->set_private_slot_initialization_started(); + } + void InitializeTPMForChromeOSUser(const std::string& username_hash, CK_SLOT_ID slot_id) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); + DCHECK(chromeos_user_map_[username_hash]-> + private_slot_initialization_started()); if (!chaps_module_) return; @@ -519,6 +530,9 @@ class NSSInitSingleton { DCHECK(thread_checker_.CalledOnValidThread()); VLOG(1) << "using software private slot for " << username_hash; DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); + DCHECK(chromeos_user_map_[username_hash]-> + private_slot_initialization_started()); + chromeos_user_map_[username_hash]->SetPrivateSlot( chromeos_user_map_[username_hash]->GetPublicSlot()); } @@ -619,8 +633,6 @@ class NSSInitSingleton { if (test_slot_) return PK11_ReferenceSlot(test_slot_); - if (software_slot_) - return PK11_ReferenceSlot(software_slot_); return PK11_GetInternalKeySlot(); } @@ -645,10 +657,6 @@ class NSSInitSingleton { } } #endif - // If we weren't supposed to enable the TPM for NSS, then return - // the software slot. - if (software_slot_) - return PK11_ReferenceSlot(software_slot_); return PK11_GetInternalKeySlot(); } @@ -671,11 +679,9 @@ class NSSInitSingleton { : tpm_token_enabled_for_nss_(false), initializing_tpm_token_(false), chaps_module_(NULL), - software_slot_(NULL), test_slot_(NULL), tpm_slot_(NULL), - root_(NULL), - chromeos_user_logged_in_(false) { + root_(NULL) { base::TimeTicks start_time = base::TimeTicks::Now(); // It's safe to construct on any thread, since LazyInstance will prevent any @@ -795,11 +801,6 @@ class NSSInitSingleton { PK11_FreeSlot(tpm_slot_); tpm_slot_ = NULL; } - if (software_slot_) { - SECMOD_CloseUserDB(software_slot_); - PK11_FreeSlot(software_slot_); - software_slot_ = NULL; - } CloseTestNSSDB(); if (root_) { SECMOD_UnloadUserModule(root_); @@ -902,11 +903,9 @@ class NSSInitSingleton { typedef std::vector<base::Closure> TPMReadyCallbackList; TPMReadyCallbackList tpm_ready_callback_list_; SECMODModule* chaps_module_; - PK11SlotInfo* software_slot_; PK11SlotInfo* test_slot_; PK11SlotInfo* tpm_slot_; SECMODModule* root_; - bool chromeos_user_logged_in_; #if defined(OS_CHROMEOS) typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap; ChromeOSUserMap chromeos_user_map_; @@ -1070,10 +1069,6 @@ AutoSECMODListReadLock::~AutoSECMODListReadLock() { #endif // defined(USE_NSS) #if defined(OS_CHROMEOS) -void OpenPersistentNSSDB() { - g_nss_singleton.Get().OpenPersistentNSSDB(); -} - void EnableTPMTokenForNSS() { g_nss_singleton.Get().EnableTPMTokenForNSS(); } @@ -1099,7 +1094,6 @@ ScopedTestNSSChromeOSUser::ScopedTestNSSChromeOSUser( constructed_successfully_ = InitializeNSSForChromeOSUser(username_hash, username_hash, - false /* is_primary_user */, temp_dir_.path()); } @@ -1109,17 +1103,30 @@ ScopedTestNSSChromeOSUser::~ScopedTestNSSChromeOSUser() { } void ScopedTestNSSChromeOSUser::FinishInit() { + DCHECK(constructed_successfully_); + if (!ShouldInitializeTPMForChromeOSUser(username_hash_)) + return; + WillInitializeTPMForChromeOSUser(username_hash_); InitializePrivateSoftwareSlotForChromeOSUser(username_hash_); } bool InitializeNSSForChromeOSUser( const std::string& email, const std::string& username_hash, - bool is_primary_user, const base::FilePath& path) { return g_nss_singleton.Get().InitializeNSSForChromeOSUser( - email, username_hash, is_primary_user, path); + email, username_hash, path); } + +bool ShouldInitializeTPMForChromeOSUser(const std::string& username_hash) { + return g_nss_singleton.Get().ShouldInitializeTPMForChromeOSUser( + username_hash); +} + +void WillInitializeTPMForChromeOSUser(const std::string& username_hash) { + g_nss_singleton.Get().WillInitializeTPMForChromeOSUser(username_hash); +} + void InitializeTPMForChromeOSUser( const std::string& username_hash, CK_SLOT_ID slot_id) { diff --git a/crypto/nss_util.h b/crypto/nss_util.h index e94c4f6..4f8a1d6 100644 --- a/crypto/nss_util.h +++ b/crypto/nss_util.h @@ -95,11 +95,6 @@ CRYPTO_EXPORT void LoadNSSLibraries(); bool CheckNSSVersion(const char* version); #if defined(OS_CHROMEOS) -// Open the r/w nssdb that's stored inside the user's encrypted home -// directory. This is the default slot returned by -// GetPublicNSSKeySlot(). -CRYPTO_EXPORT void OpenPersistentNSSDB(); - // Indicates that NSS should load the Chaps library so that we // can access the TPM through NSS. Once this is called, // GetPrivateNSSKeySlot() will return the TPM slot if one was found. diff --git a/crypto/nss_util_internal.h b/crypto/nss_util_internal.h index 262a59a..8175604 100644 --- a/crypto/nss_util_internal.h +++ b/crypto/nss_util_internal.h @@ -51,8 +51,20 @@ class CRYPTO_EXPORT AutoSECMODListReadLock { CRYPTO_EXPORT bool InitializeNSSForChromeOSUser( const std::string& email, const std::string& username_hash, - bool is_primary_user, - const base::FilePath& path) WARN_UNUSED_RESULT; + const base::FilePath& path); + +// Returns whether TPM for ChromeOS user still needs initialization. If +// true is returned, the caller can proceed to initialize TPM slot for the +// user, but should call |WillInitializeTPMForChromeOSUser| first. +// |InitializeNSSForChromeOSUser| must have been called first. +CRYPTO_EXPORT bool ShouldInitializeTPMForChromeOSUser( + const std::string& username_hash) WARN_UNUSED_RESULT; + +// Makes |ShouldInitializeTPMForChromeOSUser| start returning false. +// Should be called before starting TPM initialization for the user. +// Assumes |InitializeNSSForChromeOSUser| had already been called. +CRYPTO_EXPORT void WillInitializeTPMForChromeOSUser( + const std::string& username_hash); // Use TPM slot |slot_id| for user. InitializeNSSForChromeOSUser must have been // called first. diff --git a/crypto/rsa_private_key_nss_unittest.cc b/crypto/rsa_private_key_nss_unittest.cc index 66d352a..f376f15 100644 --- a/crypto/rsa_private_key_nss_unittest.cc +++ b/crypto/rsa_private_key_nss_unittest.cc @@ -18,12 +18,6 @@ class RSAPrivateKeyNSSTest : public testing::Test { RSAPrivateKeyNSSTest() {} virtual ~RSAPrivateKeyNSSTest() {} - virtual void SetUp() { -#if defined(OS_CHROMEOS) - OpenPersistentNSSDB(); -#endif - } - private: ScopedTestNSSDB test_nssdb_; |