Commit 4071e6ac authored by tbarzic@chromium.org's avatar tbarzic@chromium.org

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
parent 1f48bda5
......@@ -508,14 +508,16 @@ bool ParallelAuthenticator::VerifyOwner() {
const std::string& user_id = current_state_->user_context.GetUserID();
OwnerSettingsServiceFactory::GetInstance()->SetUsername(user_id);
// This should trigger certificate loading, which is needed in order to
// correctly determine if the current user is the owner.
// |IsOwnerForSafeModeAsync| expects logged in state to be
// LOGGED_IN_SAFE_MODE.
if (LoginState::IsInitialized()) {
LoginState::Get()->SetLoggedInState(LoginState::LOGGED_IN_SAFE_MODE,
LoginState::LOGGED_IN_USER_NONE);
}
OwnerSettingsService::IsPrivateKeyExistAsync(
OwnerSettingsService::IsOwnerForSafeModeAsync(
user_id,
current_state_->user_context.GetUserIDHash(),
base::Bind(&ParallelAuthenticator::OnOwnershipChecked, this));
return false;
}
......
......@@ -24,8 +24,11 @@
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
#include "chrome/browser/chromeos/settings/mock_owner_key_util.h"
#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/cryptohome/mock_async_method_caller.h"
#include "chromeos/cryptohome/system_salt_getter.h"
......@@ -34,6 +37,7 @@
#include "chromeos/login/auth/key.h"
#include "chromeos/login/auth/user_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "crypto/nss_util.h"
#include "google_apis/gaia/mock_url_fetcher_factory.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request_status.h"
......@@ -54,8 +58,10 @@ class ParallelAuthenticatorTest : public testing::Test {
: user_context_("me@nowhere.org"),
user_manager_(new FakeUserManager()),
user_manager_enabler_(user_manager_),
mock_caller_(NULL) {
mock_caller_(NULL),
owner_key_util_(new MockOwnerKeyUtil) {
user_context_.SetKey(Key("fakepass"));
user_context_.SetUserIDHash("me_nowhere_com_hash");
const User* user = user_manager_->AddUser(user_context_.GetUserID());
profile_.set_profile_name(user_context_.GetUserID());
......@@ -67,9 +73,7 @@ class ParallelAuthenticatorTest : public testing::Test {
FakeCryptohomeClient::GetStubSystemSalt()));
}
virtual ~ParallelAuthenticatorTest() {
DCHECK(!mock_caller_);
}
virtual ~ParallelAuthenticatorTest() {}
virtual void SetUp() {
CommandLine::ForCurrentProcess()->AppendSwitch(switches::kLoginManager);
......@@ -85,12 +89,15 @@ class ParallelAuthenticatorTest : public testing::Test {
SystemSaltGetter::Initialize();
OwnerSettingsService::SetOwnerKeyUtilForTesting(owner_key_util_);
auth_ = new ParallelAuthenticator(&consumer_);
state_.reset(new TestAttemptState(user_context_, false));
}
// Tears down the test fixture.
virtual void TearDown() {
OwnerSettingsService::SetOwnerKeyUtilForTesting(NULL);
SystemSaltGetter::Shutdown();
DBusThreadManager::Shutdown();
......@@ -193,15 +200,20 @@ class ParallelAuthenticatorTest : public testing::Test {
ScopedTestCrosSettings test_cros_settings_;
TestingProfile profile_;
scoped_ptr<TestingProfileManager> profile_manager_;
FakeUserManager* user_manager_;
ScopedUserManagerEnabler user_manager_enabler_;
cryptohome::MockAsyncMethodCaller* mock_caller_;
crypto::ScopedTestNSSDB test_nssdb_;
MockConsumer consumer_;
scoped_refptr<ParallelAuthenticator> auth_;
scoped_ptr<TestAttemptState> state_;
FakeCryptohomeClient* fake_cryptohome_client_;
scoped_refptr<MockOwnerKeyUtil> owner_key_util_;
};
TEST_F(ParallelAuthenticatorTest, OnLoginSuccess) {
......@@ -276,6 +288,10 @@ TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededMount) {
}
TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) {
profile_manager_.reset(
new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
ASSERT_TRUE(profile_manager_->SetUp());
FailOnLoginSuccess(); // Set failing on success as the default...
LoginFailure failure = LoginFailure(LoginFailure::OWNER_REQUIRED);
ExpectLoginFailure(failure);
......@@ -305,20 +321,18 @@ TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) {
SetAndResolveState(auth_.get(), state_.release()));
EXPECT_TRUE(LoginState::Get()->IsInSafeMode());
// Simulate TPM token ready event.
OwnerSettingsService* service =
OwnerSettingsServiceFactory::GetForProfile(&profile_);
ASSERT_TRUE(service);
service->OnTPMTokenReady();
// Flush all the pending operations. The operations should induce an owner
// verification.
device_settings_test_helper_.Flush();
// Test that the mount has succeeded.
state_.reset(new TestAttemptState(user_context_, false));
state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
// The owner key util should not have found the owner key, so login should
// not be allowed.
EXPECT_EQ(ParallelAuthenticator::OWNER_REQUIRED,
SetAndResolveState(auth_.get(), state_.release()));
EXPECT_TRUE(LoginState::Get()->IsInSafeMode());
// Unset global objects used by this test.
LoginState::Shutdown();
......
......@@ -7,6 +7,7 @@
#include <string>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/login/users/user.h"
#include "chrome/browser/chromeos/login/users/user_manager.h"
......@@ -102,7 +103,7 @@ void LoadPrivateKey(
}
}
bool IsPrivateKeyExistAsyncHelper(
bool DoesPrivateKeyExistAsyncHelper(
const scoped_refptr<OwnerKeyUtil>& owner_key_util) {
std::vector<uint8> public_key;
if (!owner_key_util->ImportPublicKey(&public_key))
......@@ -113,6 +114,26 @@ bool IsPrivateKeyExistAsyncHelper(
return is_owner;
}
// Checks whether NSS slots with private key are mounted or
// not. Responds via |callback|.
void DoesPrivateKeyExistAsync(
const OwnerSettingsService::IsOwnerCallback& callback) {
scoped_refptr<OwnerKeyUtil> owner_key_util;
if (g_owner_key_util_for_testing)
owner_key_util = *g_owner_key_util_for_testing;
else
owner_key_util = OwnerKeyUtil::Create();
scoped_refptr<base::TaskRunner> task_runner =
content::BrowserThread::GetBlockingPool()
->GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
base::PostTaskAndReplyWithResult(
task_runner.get(),
FROM_HERE,
base::Bind(&DoesPrivateKeyExistAsyncHelper, owner_key_util),
callback);
}
} // namespace
OwnerSettingsService::OwnerSettingsService(Profile* profile)
......@@ -197,22 +218,22 @@ void OwnerSettingsService::OnTPMTokenReady() {
}
// static
void OwnerSettingsService::IsPrivateKeyExistAsync(
void OwnerSettingsService::IsOwnerForSafeModeAsync(
const std::string& user_id,
const std::string& user_hash,
const IsOwnerCallback& callback) {
scoped_refptr<OwnerKeyUtil> owner_key_util;
if (g_owner_key_util_for_testing)
owner_key_util = *g_owner_key_util_for_testing;
else
owner_key_util = OwnerKeyUtil::Create();
scoped_refptr<base::TaskRunner> task_runner =
content::BrowserThread::GetBlockingPool()
->GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
base::PostTaskAndReplyWithResult(
task_runner.get(),
CHECK(chromeos::LoginState::Get()->IsInSafeMode());
// Make sure NSS is initialized and NSS DB is loaded for the user before
// searching for the owner key.
BrowserThread::PostTaskAndReply(
BrowserThread::IO,
FROM_HERE,
base::Bind(&IsPrivateKeyExistAsyncHelper, owner_key_util),
callback);
base::Bind(base::IgnoreResult(&crypto::InitializeNSSForChromeOSUser),
user_id,
user_hash,
ProfileHelper::GetProfilePathByUserIdHash(user_hash)),
base::Bind(&DoesPrivateKeyExistAsync, callback));
}
// static
......
......@@ -52,9 +52,11 @@ class OwnerSettingsService : public DeviceSettingsService::PrivateKeyDelegate,
// TPMTokenLoader::Observer:
virtual void OnTPMTokenReady() OVERRIDE;
// Checks whether NSS slots with private key are mounted or
// not. Responds via |callback|.
static void IsPrivateKeyExistAsync(const IsOwnerCallback& callback);
// Checks if the user is the device owner, without the user profile having to
// been initialized. Should be used only if login state is in safe mode.
static void IsOwnerForSafeModeAsync(const std::string& user_id,
const std::string& user_hash,
const IsOwnerCallback& callback);
static void SetOwnerKeyUtilForTesting(
const scoped_refptr<OwnerKeyUtil>& owner_key_util);
......
......@@ -288,20 +288,21 @@ void StartTPMSlotInitializationOnIOThread(const std::string& username,
void StartNSSInitOnIOThread(const std::string& username,
const std::string& username_hash,
const base::FilePath& path,
bool is_primary_user) {
const base::FilePath& path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DVLOG(1) << "Starting NSS init for " << username
<< " hash:" << username_hash
<< " is_primary_user:" << is_primary_user;
if (!crypto::InitializeNSSForChromeOSUser(
username, username_hash, is_primary_user, path)) {
// If the user already exists in nss_util's map, it is already initialized
// or in the process of being initialized. In either case, there's no need
// to do anything.
<< " hash:" << username_hash;
// Make sure NSS is initialized for the user.
crypto::InitializeNSSForChromeOSUser(username, username_hash, path);
// Check if it's OK to initialize TPM for the user before continuing. This
// may not be the case if the TPM slot initialization was previously
// requested for the same user.
if (!crypto::ShouldInitializeTPMForChromeOSUser(username_hash))
return;
}
crypto::WillInitializeTPMForChromeOSUser(username_hash);
if (crypto::IsTPMTokenEnabledForNSS()) {
if (crypto::IsTPMTokenReady(base::Bind(
......@@ -360,20 +361,22 @@ void ProfileIOData::InitializeOnUIThread(Profile* profile) {
if (user_manager) {
chromeos::User* user =
chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
if (user) {
// No need to initialize NSS for users with empty username hash:
// Getters for a user's NSS slots always return NULL slot if the user's
// username hash is empty, even when the NSS is not initialized for the
// user.
if (user && !user->username_hash().empty()) {
params->username_hash = user->username_hash();
bool is_primary_user = (user_manager->GetPrimaryUser() == user);
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&StartNSSInitOnIOThread,
user->email(),
user->username_hash(),
profile->GetPath(),
is_primary_user));
profile->GetPath()));
}
}
if (params->username_hash.empty())
LOG(WARNING) << "no username_hash";
LOG(WARNING) << "No username_hash; skipped NSS initialization.";
#endif
params->profile = profile;
......
......@@ -38,16 +38,6 @@ base::TimeDelta GetNextRequestDelayMs(base::TimeDelta last_delay) {
return next_delay;
}
void CallOpenPersistentNSSDB() {
// Called from crypto_task_runner_.
VLOG(1) << "CallOpenPersistentNSSDB";
// Ensure we've opened the user's key/certificate database.
if (base::SysInfo::IsRunningOnChromeOS())
crypto::OpenPersistentNSSDB();
crypto::EnableTPMTokenForNSS();
}
void PostResultToTaskRunner(scoped_refptr<base::SequencedTaskRunner> runner,
const base::Callback<void(bool)>& callback,
bool success) {
......@@ -140,8 +130,7 @@ void TPMTokenLoader::MaybeStartTokenInitialization() {
if (!LoginState::IsInitialized())
return;
bool start_initialization = LoginState::Get()->IsUserLoggedIn() ||
LoginState::Get()->IsInSafeMode();
bool start_initialization = LoginState::Get()->IsUserLoggedIn();
VLOG(1) << "StartTokenInitialization: " << start_initialization;
if (!start_initialization)
......@@ -167,8 +156,8 @@ void TPMTokenLoader::ContinueTokenInitialization() {
case TPM_STATE_UNKNOWN: {
crypto_task_runner_->PostTaskAndReply(
FROM_HERE,
base::Bind(&CallOpenPersistentNSSDB),
base::Bind(&TPMTokenLoader::OnPersistentNSSDBOpened,
base::Bind(&crypto::EnableTPMTokenForNSS),
base::Bind(&TPMTokenLoader::OnTPMTokenEnabledForNSS,
weak_factory_.GetWeakPtr()));
tpm_token_state_ = TPM_INITIALIZATION_STARTED;
return;
......@@ -177,7 +166,7 @@ void TPMTokenLoader::ContinueTokenInitialization() {
NOTREACHED();
return;
}
case TPM_DB_OPENED: {
case TPM_TOKEN_ENABLED_FOR_NSS: {
DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled(
base::Bind(&TPMTokenLoader::OnTpmIsEnabled,
weak_factory_.GetWeakPtr()));
......@@ -232,9 +221,9 @@ void TPMTokenLoader::RetryTokenInitializationLater() {
tpm_request_delay_ = GetNextRequestDelayMs(tpm_request_delay_);
}
void TPMTokenLoader::OnPersistentNSSDBOpened() {
VLOG(1) << "PersistentNSSDBOpened";
tpm_token_state_ = TPM_DB_OPENED;
void TPMTokenLoader::OnTPMTokenEnabledForNSS() {
VLOG(1) << "TPMTokenEnabledForNSS";
tpm_token_state_ = TPM_TOKEN_ENABLED_FOR_NSS;
ContinueTokenInitialization();
}
......
......@@ -81,7 +81,7 @@ class CHROMEOS_EXPORT TPMTokenLoader : public LoginState::Observer {
// This is the cyclic chain of callbacks to initialize the TPM token.
void ContinueTokenInitialization();
void OnPersistentNSSDBOpened();
void OnTPMTokenEnabledForNSS();
void OnTpmIsEnabled(DBusMethodCallStatus call_status,
bool tpm_is_enabled);
void OnPkcs11IsTpmTokenReady(DBusMethodCallStatus call_status,
......@@ -111,7 +111,7 @@ class CHROMEOS_EXPORT TPMTokenLoader : public LoginState::Observer {
enum TPMTokenState {
TPM_STATE_UNKNOWN,
TPM_INITIALIZATION_STARTED,
TPM_DB_OPENED,
TPM_TOKEN_ENABLED_FOR_NSS,
TPM_DISABLED,
TPM_ENABLED,
TPM_TOKEN_READY,
......
......@@ -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) {
......
......@@ -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.
......
......@@ -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.
......
......@@ -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_;
......
......@@ -30,11 +30,10 @@ class KeygenHandlerTest : public ::testing::Test {
KeygenHandlerTest() {}
virtual ~KeygenHandlerTest() {}
virtual void SetUp() {
private:
#if defined(OS_CHROMEOS) && defined(USE_NSS)
crypto::OpenPersistentNSSDB();
crypto::ScopedTestNSSDB test_nss_db_;
#endif
}
};
// Assert that |result| is a valid output for KeygenHandler given challenge
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment