diff options
author | gspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-19 18:49:54 +0000 |
---|---|---|
committer | gspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-19 18:49:54 +0000 |
commit | c64b9143b18ce8ec3746c1288c7c1204e8ce6612 (patch) | |
tree | ffb0482fb7be708006274e1a3e3d0a29e7030b13 /crypto/nss_util.cc | |
parent | 18a8ff16490804f05c5f3d939e863c3b09749ede (diff) | |
download | chromium_src-c64b9143b18ce8ec3746c1288c7c1204e8ce6612.zip chromium_src-c64b9143b18ce8ec3746c1288c7c1204e8ce6612.tar.gz chromium_src-c64b9143b18ce8ec3746c1288c7c1204e8ce6612.tar.bz2 |
This adds calls to new API for cryptohomed that gives status
of the PKCS#11 initialization of the TPM.
Also, add cros_library wrapper calls for new libcros API.
BUG=chromium-os:12303
TEST=Ran on device, checked to make sure TPM certs showed up,
indicating that status and user PIN were successfully retrieved.
Review URL: http://codereview.chromium.org/6838032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@82134 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'crypto/nss_util.cc')
-rw-r--r-- | crypto/nss_util.cc | 164 |
1 files changed, 91 insertions, 73 deletions
diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc index 198a692..d4f0855 100644 --- a/crypto/nss_util.cc +++ b/crypto/nss_util.cc @@ -51,13 +51,6 @@ const char kNSSDatabaseName[] = "Real NSS database"; const char kOpencryptokiModuleName[] = "opencryptoki"; const char kOpencryptokiPath[] = "/usr/lib/opencryptoki/libopencryptoki.so"; -// TODO(gspencer): Get these values from cryptohomed's dbus API when -// we ask if it has initialized the TPM yet. These should not be -// hard-coded here. -const char kTPMTokenName[] = "Initialized by CrOS"; -const char kTPMUserPIN[] = "111111"; -const char kTPMSecurityOfficerPIN[] = "000000"; - // Fake certificate authority database used for testing. static const FilePath::CharType kReadOnlyCertDB[] = FILE_PATH_LITERAL("/etc/fake_root_ca/nssdb"); @@ -109,9 +102,15 @@ FilePath GetInitialConfigDirectory() { char* PKCS11PasswordFunc(PK11SlotInfo* slot, PRBool retry, void* arg) { #if defined(OS_CHROMEOS) // If we get asked for a password for the TPM, then return the - // static password we use. - if (PK11_GetTokenName(slot) == crypto::GetTPMTokenName()) - return PORT_Strdup(GetTPMUserPIN().c_str()); + // well known password we use, as long as the TPM slot has been + // initialized. + if (crypto::IsTPMTokenReady()) { + std::string token_name; + std::string user_pin; + crypto::GetTPMTokenInfo(&token_name, &user_pin); + if (PK11_GetTokenName(slot) == token_name) + return PORT_Strdup(user_pin.c_str()); + } #endif crypto::CryptoModuleBlockingPasswordDelegate* delegate = reinterpret_cast<crypto::CryptoModuleBlockingPasswordDelegate*>(arg); @@ -237,51 +236,26 @@ class NSSInitSingleton { } } - bool EnableTPMForNSS() { - if (!opencryptoki_module_) { - // This loads the opencryptoki module so we can talk to the - // hardware TPM. - opencryptoki_module_ = LoadModule( - kOpencryptokiModuleName, - kOpencryptokiPath, - // trustOrder=100 -- means it'll select this as the most - // trusted slot for the mechanisms it provides. - // slotParams=... -- selects RSA as the only mechanism, and only - // asks for the password when necessary (instead of every - // time, or after a timeout). - "trustOrder=100 slotParams=(1={slotFlags=[RSA] askpw=only})"); - if (opencryptoki_module_) { - // We shouldn't need to initialize the TPM PIN here because - // it'll be taken care of by cryptohomed, but we have to make - // sure that it is initialized. - - // TODO(gspencer): replace this with a dbus call that will - // check to see that cryptohomed has initialized the PINs, and - // will fetch the token name and PINs for accessing the TPM. - EnsureTPMInit(); - - // If this is set, then we'll use the TPM by default. - tpm_slot_ = GetTPMSlot(); - return true; - } - } - return false; + void EnableTPMTokenForNSS(TPMTokenInfoDelegate* info_delegate) { + CHECK(info_delegate); + tpm_token_info_delegate_.reset(info_delegate); + // Try to load once to avoid jank later. Ignore the return value, + // because if it fails we will try again later. + EnsureTPMTokenReady(); } - std::string GetTPMTokenName() { - // TODO(gspencer): This should come from the dbus interchange with - // cryptohomed instead of being hard-coded. - return std::string(kTPMTokenName); + void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { + tpm_token_info_delegate_->GetTokenInfo(token_name, user_pin); } - std::string GetTPMUserPIN() { - // TODO(gspencer): This should come from the dbus interchange with - // cryptohomed instead of being hard-coded. - return std::string(kTPMUserPIN); + bool IsTPMTokenReady() { + return tpm_slot_ != NULL; } PK11SlotInfo* GetTPMSlot() { - return FindSlotWithTokenName(GetTPMTokenName()); + std::string token_name; + GetTPMTokenInfo(&token_name, NULL); + return FindSlotWithTokenName(token_name); } #endif // defined(OS_CHROMEOS) @@ -312,10 +286,22 @@ class NSSInitSingleton { PK11SlotInfo* GetPrivateNSSKeySlot() { if (test_slot_) return PK11_ReferenceSlot(test_slot_); - // If the TPM slot has been opened, then return that one. - if (tpm_slot_) - return PK11_ReferenceSlot(tpm_slot_); - // If it hasn't, then return the software slot. + +#if defined(OS_CHROMEOS) + // Make sure that if EnableTPMTokenForNSS has been called that we + // have successfully loaded opencryptoki. + if (tpm_token_info_delegate_.get() != NULL) { + if (EnsureTPMTokenReady()) { + return PK11_ReferenceSlot(tpm_slot_); + } else { + // If we were supposed to get the hardware token, but were + // unable to, return NULL rather than fall back to sofware. + return NULL; + } + } +#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(); @@ -502,21 +488,6 @@ class NSSInitSingleton { } #endif -#if defined(OS_CHROMEOS) - void EnsureTPMInit() { - crypto::ScopedPK11Slot tpm_slot(GetTPMSlot()); - if (tpm_slot.get()) { - // TODO(gspencer): Remove this in favor of the dbus API for - // cryptohomed when that is available. - if (PK11_NeedUserInit(tpm_slot.get())) { - PK11_InitPin(tpm_slot.get(), - kTPMSecurityOfficerPIN, - kTPMUserPIN); - } - } - } -#endif - static PK11SlotInfo* OpenUserDB(const FilePath& path, const char* description) { const std::string modspec = @@ -534,9 +505,52 @@ class NSSInitSingleton { return db_slot; } +#if defined(OS_CHROMEOS) + // This is called whenever we want to make sure opencryptoki is + // properly loaded, because it can fail shortly after the initial + // login while the PINs are being initialized, and we want to retry + // if this happens. + bool EnsureTPMTokenReady() { + // If EnableTPMTokenForNSS hasn't been called, or if everything is + // already initialized, then this call succeeds. + if (tpm_token_info_delegate_.get() == NULL || + (opencryptoki_module_ && tpm_slot_)) { + return true; + } + + if (tpm_token_info_delegate_->IsTokenReady()) { + // This tries to load the opencryptoki module so NSS can talk to + // the hardware TPM. + if (!opencryptoki_module_) { + opencryptoki_module_ = LoadModule( + kOpencryptokiModuleName, + kOpencryptokiPath, + // trustOrder=100 -- means it'll select this as the most + // trusted slot for the mechanisms it provides. + // slotParams=... -- selects RSA as the only mechanism, and only + // asks for the password when necessary (instead of every + // time, or after a timeout). + "trustOrder=100 slotParams=(1={slotFlags=[RSA] askpw=only})"); + } + if (opencryptoki_module_) { + // If this gets set, then we'll use the TPM for certs with + // private keys, otherwise we'll fall back to the software + // implementation. + tpm_slot_ = GetTPMSlot(); + return tpm_slot_ != NULL; + } + } + return false; + } +#endif + // If this is set to true NSS is forced to be initialized without a DB. static bool force_nodb_init_; +#if defined(OS_CHROMEOS) + scoped_ptr<TPMTokenInfoDelegate> tpm_token_info_delegate_; +#endif + SECMODModule* opencryptoki_module_; PK11SlotInfo* software_slot_; PK11SlotInfo* test_slot_; @@ -663,17 +677,21 @@ void OpenPersistentNSSDB() { g_nss_singleton.Get().OpenPersistentNSSDB(); } -bool EnableTPMForNSS() { - return g_nss_singleton.Get().EnableTPMForNSS(); +TPMTokenInfoDelegate::TPMTokenInfoDelegate() {} +TPMTokenInfoDelegate::~TPMTokenInfoDelegate() {} + +void EnableTPMTokenForNSS(TPMTokenInfoDelegate* info_delegate) { + g_nss_singleton.Get().EnableTPMTokenForNSS(info_delegate); } -std::string GetTPMTokenName() { - return g_nss_singleton.Get().GetTPMTokenName(); +void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { + g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin); } -std::string GetTPMUserPIN() { - return g_nss_singleton.Get().GetTPMUserPIN(); +bool IsTPMTokenReady() { + return g_nss_singleton.Get().IsTPMTokenReady(); } + #endif // defined(OS_CHROMEOS) // TODO(port): Implement this more simply. We can convert by subtracting an |