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:
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user