Index: crypto/nss_util.cc |
diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc |
index 5958ad972daf74db958b9c50b88badfef4169b5b..1598ba907bff34cfa389bc228afb31e67c1297ce 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) { |