0

crypto/nss_util: Get TPM slot id, do lookup by id instead of by name.

chromeos/cert_loader: store slot id as int.

BUG=302124

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231126 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
mattm@chromium.org
2013-10-25 22:03:26 +00:00
parent e5d506af10
commit 3f3b9b1815
6 changed files with 62 additions and 41 deletions

@ -94,6 +94,7 @@ CertLoader::CertLoader()
tpm_token_state_(TPM_STATE_UNKNOWN),
tpm_request_delay_(
base::TimeDelta::FromMilliseconds(kInitialRequestDelayMs)),
tpm_token_slot_id_(-1),
initialize_token_factory_(this),
update_certificates_factory_(this) {
if (LoginState::IsInitialized())
@ -211,8 +212,10 @@ void CertLoader::InitializeTokenAndLoadCertificates() {
base::PostTaskAndReplyWithResult(
crypto_task_runner_.get(),
FROM_HERE,
base::Bind(
&crypto::InitializeTPMToken, tpm_token_name_, tpm_user_pin_),
base::Bind(&crypto::InitializeTPMToken,
tpm_token_name_,
tpm_token_slot_id_,
tpm_user_pin_),
base::Bind(&CertLoader::OnTPMTokenInitialized,
initialize_token_factory_.GetWeakPtr()));
return;
@ -298,7 +301,7 @@ void CertLoader::OnPkcs11IsTpmTokenReady(DBusMethodCallStatus call_status,
void CertLoader::OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status,
const std::string& token_name,
const std::string& user_pin,
int token_slot) {
int token_slot_id) {
VLOG(1) << "OnPkcs11GetTpmTokenInfo: " << token_name;
if (call_status == DBUS_METHOD_CALL_FAILURE) {
@ -307,7 +310,7 @@ void CertLoader::OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status,
}
tpm_token_name_ = token_name;
tpm_token_slot_ = base::IntToString(token_slot);
tpm_token_slot_id_ = token_slot_id;
tpm_user_pin_ = user_pin;
tpm_token_state_ = TPM_TOKEN_INFO_RECEIVED;

@ -100,7 +100,7 @@ class CHROMEOS_EXPORT CertLoader : public net::CertDatabase::Observer,
// TPM info is only valid once the TPM is available (IsHardwareBacked is
// true). Otherwise empty strings will be returned.
const std::string& tpm_token_name() const { return tpm_token_name_; }
const std::string& tpm_token_slot() const { return tpm_token_slot_; }
int tpm_token_slot_id() const { return tpm_token_slot_id_; }
const std::string& tpm_user_pin() const { return tpm_user_pin_; }
// This will be empty until certificates_loaded() is true.
@ -124,7 +124,7 @@ class CHROMEOS_EXPORT CertLoader : public net::CertDatabase::Observer,
void OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status,
const std::string& token_name,
const std::string& user_pin,
int token_slot);
int token_slot_id);
void OnTPMTokenInitialized(bool success);
// These calls handle the updating of the certificate list after the TPM token
@ -178,7 +178,7 @@ class CHROMEOS_EXPORT CertLoader : public net::CertDatabase::Observer,
// Cached TPM token info.
std::string tpm_token_name_;
std::string tpm_token_slot_;
int tpm_token_slot_id_;
std::string tpm_user_pin_;
// Cached Certificates.

@ -12,6 +12,7 @@
#include <string>
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/task_runner.h"
#include "base/threading/worker_pool.h"
#include "base/time/time.h"
@ -431,11 +432,12 @@ void ClientCertResolver::ConfigureCertificates(NetworkCertMatches* matches) {
VLOG(1) << "Configuring certificate of network " << it->service_path;
CertLoader* cert_loader = CertLoader::Get();
base::DictionaryValue shill_properties;
client_cert::SetShillProperties(it->cert_config_type,
cert_loader->tpm_token_slot(),
cert_loader->tpm_user_pin(),
&it->pkcs11_id,
&shill_properties);
client_cert::SetShillProperties(
it->cert_config_type,
base::IntToString(cert_loader->tpm_token_slot_id()),
cert_loader->tpm_user_pin(),
&it->pkcs11_id,
&shill_properties);
DBusThreadManager::Get()->GetShillServiceClient()->
SetProperties(dbus::ObjectPath(it->service_path),
shill_properties,

@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/strings/string_number_conversions.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_manager_client.h"
@ -441,11 +442,12 @@ void NetworkConnectionHandler::VerifyConfiguredAndConnect(
if (cert_loader_ && cert_loader_->IsHardwareBacked()) {
// Pass NULL if pkcs11_id is empty, so that it doesn't clear any
// previously configured client cert.
client_cert::SetShillProperties(client_cert_type,
cert_loader_->tpm_token_slot(),
cert_loader_->tpm_user_pin(),
pkcs11_id.empty() ? NULL : &pkcs11_id,
&config_properties);
client_cert::SetShillProperties(
client_cert_type,
base::IntToString(cert_loader_->tpm_token_slot_id()),
cert_loader_->tpm_user_pin(),
pkcs11_id.empty() ? NULL : &pkcs11_id,
&config_properties);
}
}

@ -168,20 +168,6 @@ void UseLocalCacheOfNSSDatabaseIfNFS(const base::FilePath& database_dir) {
#endif // defined(OS_LINUX) || defined(OS_OPENBSD)
}
PK11SlotInfo* FindSlotWithTokenName(const std::string& token_name) {
AutoSECMODListReadLock auto_lock;
SECMODModuleList* head = SECMOD_GetDefaultModuleList();
for (SECMODModuleList* item = head; item != NULL; item = item->next) {
int slot_count = item->module->loaded ? item->module->slotCount : 0;
for (int i = 0; i < slot_count; i++) {
PK11SlotInfo* slot = item->module->slots[i];
if (PK11_GetTokenName(slot) == token_name)
return PK11_ReferenceSlot(slot);
}
}
return NULL;
}
#endif // defined(USE_NSS)
// A singleton to initialize/deinitialize NSPR.
@ -247,10 +233,14 @@ class NSSInitSingleton {
}
void EnableTPMTokenForNSS() {
// 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_token_enabled_for_nss_ = true;
}
bool InitializeTPMToken(const std::string& token_name,
int token_slot_id,
const std::string& user_pin) {
// If EnableTPMTokenForNSS hasn't been called, return false.
if (!tpm_token_enabled_for_nss_)
@ -275,12 +265,15 @@ class NSSInitSingleton {
// read from this slot without requiring a call to C_Login.
// askpw=only -- Only authenticate to the token when necessary.
"NSS=\"slotParams=(0={slotFlags=[PublicCerts] askpw=only})\"");
if (!chaps_module_ && test_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_);
return true;
}
}
if (chaps_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();
tpm_slot_ = GetTPMSlotForId(token_slot_id);
return tpm_slot_ != NULL;
}
@ -302,10 +295,22 @@ class NSSInitSingleton {
return tpm_slot_ != NULL;
}
PK11SlotInfo* GetTPMSlot() {
std::string token_name;
GetTPMTokenInfo(&token_name, NULL);
return FindSlotWithTokenName(token_name);
// Note that CK_SLOT_ID is an unsigned long, but cryptohome gives us the slot
// id as an int. This should be safe since this is only used with chaps, which
// we also control.
PK11SlotInfo* GetTPMSlotForId(CK_SLOT_ID slot_id) {
if (!chaps_module_)
return NULL;
VLOG(1) << "Poking chaps module.";
SECStatus rv = SECMOD_UpdateSlotList(chaps_module_);
if (rv != SECSuccess)
PLOG(ERROR) << "SECMOD_UpdateSlotList failed: " << PORT_GetError();
PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module_->moduleID, slot_id);
if (!slot)
LOG(ERROR) << "TPM slot " << slot_id << " not found.";
return slot;
}
#endif // defined(OS_CHROMEOS)
@ -526,7 +531,7 @@ class NSSInitSingleton {
// Aw, snap. Can't find/load root cert shared library.
// This will make it hard to talk to anybody via https.
NOTREACHED();
// TODO(mattm): Re-add the NOTREACHED here when crbug.com/310972 is fixed.
return NULL;
}
@ -549,6 +554,12 @@ class NSSInitSingleton {
<< GetNSSErrorMessage();
return NULL;
}
if (!module->loaded) {
LOG(ERROR) << "After loading " << name << ", loaded==false: "
<< GetNSSErrorMessage();
SECMOD_DestroyModule(module);
return NULL;
}
return module;
}
#endif
@ -752,8 +763,10 @@ bool IsTPMTokenReady() {
}
bool InitializeTPMToken(const std::string& token_name,
int token_slot_id,
const std::string& user_pin) {
return g_nss_singleton.Get().InitializeTPMToken(token_name, user_pin);
return g_nss_singleton.Get().InitializeTPMToken(
token_name, token_slot_id, user_pin);
}
#endif // defined(OS_CHROMEOS)

@ -116,6 +116,7 @@ CRYPTO_EXPORT bool IsTPMTokenReady();
// Initialize the TPM token. Does nothing if it is already initialized.
CRYPTO_EXPORT bool InitializeTPMToken(const std::string& token_name,
int token_slot_id,
const std::string& user_pin);
#endif