Commit 190933f2 authored by pneubeck@chromium.org's avatar pneubeck@chromium.org

Extract ScopedTestNSSDB from nss_util.

Before ScopedTestNSSDB affected several slot getters from nss_util.h .
This change reduces ScopedTestNSSDB to solely setup a temporary test DB and not influencing the global state in nss_util anymore.

As a replacement for some of its old behavior, a new ScopedTestSystemNSSKeySlot is added, which allows to override the slot returned by GetSystemNSSKeySlot().

With this change it's now possible to write tests that need both a user and system NSS DB by using ScopedTestSystemNSSKeySlot.

As a side-effect, GetPersistentNSSKeySlot() is now compiled on !OS_CHROMEOS only.

BUG=210525
(For include changes:)

R=rsleevi@chromium.org
TBR=nkostylev@chromium.org, stevenjb@chromium.org

Review URL: https://codereview.chromium.org/401623006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285881 0039d316-1c4b-4281-b951-d872f2087c98
parent a017c660
......@@ -37,8 +37,8 @@
#include "chromeos/login/auth/user_context.h"
#include "components/user_manager/user.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_test_nss_chromeos_user.h"
#include "google_apis/gaia/mock_url_fetcher_factory.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request_status.h"
......
......@@ -4,8 +4,8 @@
#include "chrome/browser/chromeos/net/cert_verify_proc_chromeos.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_test_nss_chromeos_user.h"
#include "net/base/net_errors.h"
#include "net/base/test_data_directory.h"
#include "net/cert/cert_verify_proc.h"
......
......@@ -13,8 +13,8 @@
#include "chrome/browser/chromeos/net/cert_verify_proc_chromeos.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_test_nss_chromeos_user.h"
#include "net/base/net_log.h"
#include "net/base/test_completion_callback.h"
#include "net/base/test_data_directory.h"
......
......@@ -1835,8 +1835,8 @@
'browser/certificate_manager_model.cc',
'browser/certificate_manager_model.h',
'browser/net/nss_context.cc',
'browser/net/nss_context_chromeos.cc',
'browser/net/nss_context.h',
'browser/net/nss_context_chromeos.cc',
'browser/net/nss_context_linux.cc',
'third_party/mozilla_security_manager/nsNSSCertHelper.cpp',
'third_party/mozilla_security_manager/nsNSSCertHelper.h',
......@@ -3234,6 +3234,13 @@
}],
['use_nss==1', {
'sources': [ '<@(chrome_browser_nss_sources)' ],
'conditions': [
['chromeos==1', {
'sources!': [ 'browser/net/nss_context_linux.cc' ],
}, { # chromeos==0
'sources!': [ 'browser/net/nss_context_chromeos.cc' ],
}],
],
}],
['notifications==1', {
'sources': [ '<@(chrome_browser_notifications_sources)' ],
......
......@@ -796,6 +796,7 @@
'../components/components.gyp:translate_core_common',
'../components/components_resources.gyp:components_resources',
'../components/components_strings.gyp:components_strings',
'../crypto/crypto.gyp:crypto_test_support',
'../device/bluetooth/bluetooth.gyp:device_bluetooth_mocks',
'../device/serial/serial.gyp:device_serial_test_util',
'../extensions/common/api/api.gyp:extensions_api',
......
......@@ -490,6 +490,7 @@
'../components/components_resources.gyp:components_resources',
'../content/content_shell_and_tests.gyp:test_support_content',
'../content/content.gyp:content_app_both',
'../crypto/crypto.gyp:crypto_test_support',
'../net/net.gyp:net',
'../net/net.gyp:net_test_support',
'../sync/sync.gyp:test_support_sync_api',
......
......@@ -11,7 +11,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#if defined(USE_NSS)
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_test_nss_db.h"
#include "net/cert/nss_cert_database.h"
#endif
......@@ -224,12 +224,11 @@ TEST(X509CertificateModelTest, GetTypeCA) {
EXPECT_EQ(net::CA_CERT,
x509_certificate_model::GetType(cert->os_cert_handle()));
// Additional parantheses required to disambiguate from function declaration.
net::NSSCertDatabase db(
(crypto::ScopedPK11Slot(
crypto::GetPersistentNSSKeySlot())) /* public slot */,
crypto::ScopedPK11Slot(
crypto::GetPersistentNSSKeySlot()) /* private lot */);
crypto::ScopedTestNSSDB test_nssdb;
net::NSSCertDatabase db(crypto::ScopedPK11Slot(PK11_ReferenceSlot(
test_nssdb.slot())) /* public slot */,
crypto::ScopedPK11Slot(PK11_ReferenceSlot(
test_nssdb.slot())) /* private slot */);
// Test that explicitly distrusted CA certs are still returned as CA_CERT
// type. See http://crbug.com/96654.
......@@ -259,12 +258,11 @@ TEST(X509CertificateModelTest, GetTypeServer) {
EXPECT_EQ(net::OTHER_CERT,
x509_certificate_model::GetType(cert->os_cert_handle()));
// Additional parantheses required to disambiguate from function declaration.
net::NSSCertDatabase db(
(crypto::ScopedPK11Slot(
crypto::GetPersistentNSSKeySlot())) /* public slot */,
crypto::ScopedPK11Slot(
crypto::GetPersistentNSSKeySlot()) /* private lot */);
crypto::ScopedTestNSSDB test_nssdb;
net::NSSCertDatabase db(crypto::ScopedPK11Slot(PK11_ReferenceSlot(
test_nssdb.slot())) /* public slot */,
crypto::ScopedPK11Slot(PK11_ReferenceSlot(
test_nssdb.slot())) /* private slot */);
// Test GetCertType with server certs and explicit trust.
EXPECT_TRUE(db.SetCertTrust(
......
......@@ -9,9 +9,9 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_nss_types.h"
#include "crypto/scoped_test_nss_chromeos_user.h"
#include "net/base/net_errors.h"
#include "net/base/test_data_directory.h"
#include "net/cert/nss_cert_database_chromeos.h"
......
......@@ -511,6 +511,7 @@
'../build/linux/system.gyp:ssl',
'../components/components.gyp:onc_component',
'../crypto/crypto.gyp:crypto',
'../crypto/crypto.gyp:crypto_test_support',
'../dbus/dbus.gyp:dbus_test_support',
'../net/net.gyp:net',
'../net/net.gyp:net_test_support',
......
......@@ -23,8 +23,8 @@
#include "chromeos/network/network_state_handler.h"
#include "chromeos/tpm_token_loader.h"
#include "components/onc/onc_constants.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_test_nss_chromeos_user.h"
#include "net/base/crypto_module.h"
#include "net/base/net_errors.h"
#include "net/base/test_data_directory.h"
......
......@@ -14,8 +14,8 @@
#include "chromeos/dbus/shill_service_client.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/tpm_token_loader.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_test_nss_chromeos_user.h"
#include "net/base/crypto_module.h"
#include "net/base/net_errors.h"
#include "net/base/test_data_directory.h"
......
......@@ -25,8 +25,8 @@
#include "chromeos/network/onc/onc_utils.h"
#include "chromeos/tpm_token_loader.h"
#include "components/onc/onc_constants.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_test_nss_chromeos_user.h"
#include "net/base/net_errors.h"
#include "net/base/test_data_directory.h"
#include "net/cert/nss_cert_database_chromeos.h"
......
......@@ -16,8 +16,8 @@
#include "base/values.h"
#include "chromeos/network/onc/onc_test_utils.h"
#include "components/onc/onc_constants.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_test_nss_chromeos_user.h"
#include "net/base/crypto_module.h"
#include "net/cert/cert_type.h"
#include "net/cert/nss_cert_database_chromeos.h"
......
......@@ -131,6 +131,7 @@ component("crypto") {
"hmac_nss.cc",
"nss_util.cc",
"nss_util.h",
"nss_util_internal.h",
"rsa_private_key_nss.cc",
"secure_hash_default.cc",
"signature_creator_nss.cc",
......@@ -229,6 +230,7 @@ test("crypto_unittests") {
deps = [
":crypto",
":platform",
":test_support",
"//base",
"//base/test:run_all_unittests",
"//base/test:test_support",
......@@ -237,6 +239,38 @@ test("crypto_unittests") {
]
}
source_set("test_support") {
sources = [
"scoped_test_nss_db.cc",
"scoped_test_nss_db.h",
"scoped_test_nss_chromeos_user.cc",
"scoped_test_nss_chromeos_user.h",
"scoped_test_system_nss_key_slot.cc",
"scoped_test_system_nss_key_slot.h",
]
deps = [
":crypto",
":platform",
"//base",
]
if (!use_nss_certs) {
sources -= [
"scoped_test_nss_db.cc",
"scoped_test_nss_db.h",
]
}
if (!is_chromeos) {
sources -= [
"scoped_test_nss_chromeos_user.cc",
"scoped_test_nss_chromeos_user.h",
"scoped_test_system_nss_key_slot.cc",
"scoped_test_system_nss_key_slot.h",
]
}
}
# This is a meta-target that forwards to NSS's SSL library or OpenSSL,
# according to the state of the crypto flags. A target just wanting to depend
# on the current SSL library should just depend on this.
......
......@@ -111,6 +111,7 @@
'hmac_nss.cc',
'nss_util.cc',
'nss_util.h',
'nss_util_internal.h',
'rsa_private_key_nss.cc',
'secure_hash_default.cc',
'signature_creator_nss.cc',
......@@ -174,6 +175,7 @@
],
'dependencies': [
'crypto',
'crypto_test_support',
'../base/base.gyp:base',
'../base/base.gyp:run_all_unittests',
'../base/base.gyp:test_support_base',
......@@ -254,5 +256,47 @@
},
],
}],
['use_nss==1', {
'targets': [
{
'target_name': 'crypto_test_support',
'type': 'static_library',
'dependencies': [
'../base/base.gyp:base',
'crypto',
],
'sources': [
'scoped_test_nss_db.cc',
'scoped_test_nss_db.h',
'scoped_test_nss_chromeos_user.cc',
'scoped_test_nss_chromeos_user.h',
'scoped_test_system_nss_key_slot.cc',
'scoped_test_system_nss_key_slot.h',
],
'conditions': [
['use_nss==0', {
'sources!': [
'scoped_test_nss_db.cc',
'scoped_test_nss_db.h',
],
}],
[ 'chromeos==0', {
'sources!': [
'scoped_test_nss_chromeos_user.cc',
'scoped_test_nss_chromeos_user.h',
'scoped_test_system_nss_key_slot.cc',
'scoped_test_system_nss_key_slot.h',
],
}],
],
}
]}, { # use_nss==0
'targets': [
{
'target_name': 'crypto_test_support',
'type': 'none',
'sources': [],
}
]}],
],
}
......@@ -198,12 +198,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 +281,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,9 +292,9 @@ 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);
return OpenSoftwareNSSDB(nssdb_path, db_name);
}
void EnableTPMTokenForNSS() {
......@@ -393,10 +387,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 +457,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 +539,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,56 +562,26 @@ 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);
}
void CloseTestChromeOSUser(const std::string& username_hash) {
void CloseChromeOSUserForTesting(const std::string& username_hash) {
DCHECK(thread_checker_.CalledOnValidThread());
ChromeOSUserMap::iterator i = chromeos_user_map_.find(username_hash);
DCHECK(i != chromeos_user_map_.end());
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 SetSystemKeySlotForTesting(ScopedPK11Slot slot) {
// Ensure that a previous value of test_system_slot_ is not overwritten.
// Unsetting, i.e. setting a NULL, however is allowed.
DCHECK(!slot || !test_system_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,18 +589,14 @@ 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_);
// TODO(mattm): chromeos::TPMTokenloader always calls
// InitializeTPMTokenAndSystemSlot with slot 0. If the system slot is
// disabled, tpm_slot_ will be the first user's slot instead. Can that be
......@@ -679,7 +628,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 +749,6 @@ class NSSInitSingleton {
PK11_FreeSlot(tpm_slot_);
tpm_slot_ = NULL;
}
CloseTestNSSDB();
if (root_) {
SECMOD_UnloadUserModule(root_);
SECMOD_DestroyModule(root_);
......@@ -863,23 +810,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
......@@ -903,12 +833,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
......@@ -926,9 +856,24 @@ base::LazyInstance<NSSInitSingleton>::Leaky
g_nss_singleton = LAZY_INSTANCE_INITIALIZER;
} // namespace
const char kTestTPMTokenName[] = "Test DB";
#if defined(USE_NSS)
ScopedPK11Slot OpenSoftwareNSSDB(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())
......@@ -1027,19 +972,6 @@ bool CheckNSSVersion(const char* version) {
}
#if defined(USE_NSS)
ScopedTestNSSDB::ScopedTestNSSDB()
: is_open_(g_nss_singleton.Get().OpenTestNSSDB()) {
}
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();
}
}
base::Lock* GetNSSWriteLock() {
return g_nss_singleton.Get().write_lock();
}
......@@ -1065,7 +997,6 @@ AutoSECMODListReadLock::AutoSECMODListReadLock()
AutoSECMODListReadLock::~AutoSECMODListReadLock() {
SECMOD_ReleaseReadLock(lock_);
}
#endif // defined(USE_NSS)
#if defined(OS_CHROMEOS)
......@@ -1073,6 +1004,10 @@ PK11SlotInfo* GetSystemNSSKeySlot() {
return g_nss_singleton.Get().GetSystemNSSKeySlot();
}
void SetSystemKeySlotForTesting(ScopedPK11Slot slot) {
g_nss_singleton.Get().SetSystemKeySlotForTesting(ScopedPK11Slot());
}
void EnableTPMTokenForNSS() {
g_nss_singleton.Get().EnableTPMTokenForNSS();
}
......@@ -1092,30 +1027,6 @@ void InitializeTPMTokenAndSystemSlot(
callback);
}
ScopedTestNSSChromeOSUser::ScopedTestNSSChromeOSUser(
const std::string& username_hash)
: username_hash_(username_hash), constructed_successfully_(false) {
if (!temp_dir_.CreateUniqueTempDir())
return;
constructed_successfully_ =
InitializeNSSForChromeOSUser(username_hash,
username_hash,
temp_dir_.path());
}
ScopedTestNSSChromeOSUser::~ScopedTestNSSChromeOSUser() {
if (constructed_successfully_)
g_nss_singleton.Get().CloseTestChromeOSUser(username_hash_);
}
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,
......@@ -1138,20 +1049,27 @@ void InitializeTPMForChromeOSUser(
CK_SLOT_ID slot_id) {
g_nss_singleton.Get().InitializeTPMForChromeOSUser(username_hash, slot_id);
}
void InitializePrivateSoftwareSlotForChromeOSUser(
const std::string& username_hash) {
g_nss_singleton.Get().InitializePrivateSoftwareSlotForChromeOSUser(
username_hash);
}
ScopedPK11Slot GetPublicSlotForChromeOSUser(const std::string& username_hash) {
return g_nss_singleton.Get().GetPublicSlotForChromeOSUser(username_hash);
}
ScopedPK11Slot GetPrivateSlotForChromeOSUser(
const std::string& username_hash,
const base::Callback<void(ScopedPK11Slot)>& callback) {
return g_nss_singleton.Get().GetPrivateSlotForChromeOSUser(username_hash,
callback);
}
void CloseChromeOSUserForTesting(const std::string& username_hash) {
g_nss_singleton.Get().CloseChromeOSUserForTesting(username_hash);