From 0c0c09bad1d7f32eb223ed50f84aa4aba5688adb Mon Sep 17 00:00:00 2001 From: "dkrahn@chromium.org" Date: Thu, 10 Oct 2013 22:41:53 +0000 Subject: [PATCH] Add support for the Pkcs11GetTpmTokenInfoForUser cryptohome call. This call already existed but had not been added to CryptohomeClient. BUG=chromium:205206 TEST=unit, manual Review URL: https://codereview.chromium.org/26407002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@228033 0039d316-1c4b-4281-b951-d872f2087c98 --- chromeos/cert_loader.cc | 8 ++-- chromeos/cert_loader.h | 3 +- chromeos/dbus/cryptohome_client.cc | 49 +++++++++++++++++++++++-- chromeos/dbus/cryptohome_client.h | 25 +++++++++++-- chromeos/dbus/fake_cryptohome_client.cc | 10 ++++- chromeos/dbus/fake_cryptohome_client.h | 3 ++ chromeos/dbus/mock_cryptohome_client.h | 3 ++ 7 files changed, 87 insertions(+), 14 deletions(-) diff --git a/chromeos/cert_loader.cc b/chromeos/cert_loader.cc index ecae58ae826477..567411732a0e85 100644 --- a/chromeos/cert_loader.cc +++ b/chromeos/cert_loader.cc @@ -297,7 +297,8 @@ void CertLoader::OnPkcs11IsTpmTokenReady(DBusMethodCallStatus call_status, void CertLoader::OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status, const std::string& token_name, - const std::string& user_pin) { + const std::string& user_pin, + int token_slot) { VLOG(1) << "OnPkcs11GetTpmTokenInfo: " << token_name; if (call_status == DBUS_METHOD_CALL_FAILURE) { @@ -306,10 +307,7 @@ void CertLoader::OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status, } tpm_token_name_ = token_name; - // TODO(stevenjb): The network code expects a slot ID, not a label. See - // crbug.com/201101. For now, use a hard coded, well known slot instead. - const char kHardcodedTpmSlot[] = "0"; - tpm_token_slot_ = kHardcodedTpmSlot; + tpm_token_slot_ = base::IntToString(token_slot); tpm_user_pin_ = user_pin; tpm_token_state_ = TPM_TOKEN_INFO_RECEIVED; diff --git a/chromeos/cert_loader.h b/chromeos/cert_loader.h index 9c5ace491c981d..f9c2de07a5c3d5 100644 --- a/chromeos/cert_loader.h +++ b/chromeos/cert_loader.h @@ -123,7 +123,8 @@ class CHROMEOS_EXPORT CertLoader : public net::CertDatabase::Observer, bool is_tpm_token_ready); void OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status, const std::string& token_name, - const std::string& user_pin); + const std::string& user_pin, + int token_slot); void OnTPMTokenInitialized(bool success); // These calls handle the updating of the certificate list after the TPM token diff --git a/chromeos/dbus/cryptohome_client.cc b/chromeos/dbus/cryptohome_client.cc index cd027e3e6249f3..86133aea627567 100644 --- a/chromeos/dbus/cryptohome_client.cc +++ b/chromeos/dbus/cryptohome_client.cc @@ -329,6 +329,23 @@ class CryptohomeClientImpl : public CryptohomeClient { callback)); } + // CryptohomeClient override. + virtual void Pkcs11GetTpmTokenInfoForUser( + const std::string& user_email, + const Pkcs11GetTpmTokenInfoCallback& callback) OVERRIDE { + dbus::MethodCall method_call( + cryptohome::kCryptohomeInterface, + cryptohome::kCryptohomePkcs11GetTpmTokenInfoForUser); + dbus::MessageWriter writer(&method_call); + writer.AppendString(user_email); + proxy_->CallMethod( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind( + &CryptohomeClientImpl::OnPkcs11GetTpmTokenInfoForUser, + weak_ptr_factory_.GetWeakPtr(), + callback)); + } + // CryptohomeClient override. virtual bool InstallAttributesGet(const std::string& name, std::vector* value, @@ -729,6 +746,7 @@ class CryptohomeClientImpl : public CryptohomeClient { bool result = false; if (!reader.PopBool(&result)) { callback.Run(DBUS_METHOD_CALL_FAILURE, false); + LOG(ERROR) << "Invalid response: " << response->ToString(); return; } callback.Run(DBUS_METHOD_CALL_SUCCESS, result); @@ -770,21 +788,44 @@ class CryptohomeClientImpl : public CryptohomeClient { callback.Run(DBUS_METHOD_CALL_SUCCESS, result, data); } - // Handles responses for Pkcs11GetTpmtTokenInfo. + // Handles responses for Pkcs11GetTpmTokenInfo. void OnPkcs11GetTpmTokenInfo(const Pkcs11GetTpmTokenInfoCallback& callback, dbus::Response* response) { if (!response) { - callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string()); + callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1); return; } dbus::MessageReader reader(response); std::string label; std::string user_pin; if (!reader.PopString(&label) || !reader.PopString(&user_pin)) { - callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string()); + callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1); + LOG(ERROR) << "Invalid response: " << response->ToString(); + return; + } + const int kDefaultSlot = 0; + callback.Run(DBUS_METHOD_CALL_SUCCESS, label, user_pin, kDefaultSlot); + } + + // Handles responses for Pkcs11GetTpmTokenInfoForUser. + void OnPkcs11GetTpmTokenInfoForUser( + const Pkcs11GetTpmTokenInfoCallback& callback, + dbus::Response* response) { + if (!response) { + callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1); + return; + } + dbus::MessageReader reader(response); + std::string label; + std::string user_pin; + int slot = 0; + if (!reader.PopString(&label) || !reader.PopString(&user_pin) || + !reader.PopInt32(&slot)) { + callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1); + LOG(ERROR) << "Invalid response: " << response->ToString(); return; } - callback.Run(DBUS_METHOD_CALL_SUCCESS, label, user_pin); + callback.Run(DBUS_METHOD_CALL_SUCCESS, label, user_pin, slot); } // Handles AsyncCallStatus signal. diff --git a/chromeos/dbus/cryptohome_client.h b/chromeos/dbus/cryptohome_client.h index b1019c5b7b1f6c..f230d03470148a 100644 --- a/chromeos/dbus/cryptohome_client.h +++ b/chromeos/dbus/cryptohome_client.h @@ -35,11 +35,19 @@ class CHROMEOS_EXPORT CryptohomeClient : public DBusClient { AsyncCallStatusWithDataHandler; // A callback to handle responses of AsyncXXX methods. typedef base::Callback AsyncMethodCallback; - // A callback to handle responses of Pkcs11GetTpmTokenInfo method. + // A callback to handle responses of Pkcs11GetTpmTokenInfo method. The result + // of the D-Bus call is in |call_status|. On success, |label| holds the + // PKCS #11 token label. This is not useful in practice to identify a token + // but may be meaningful to a user. The |user_pin| can be used with the + // C_Login PKCS #11 function but is not necessary because tokens are logged in + // for the duration of a signed-in session. The |slot| corresponds to a + // CK_SLOT_ID for the PKCS #11 API and reliably identifies the token for the + // duration of the signed-in session. typedef base::Callback Pkcs11GetTpmTokenInfoCallback; + const std::string& user_pin, + int slot)> Pkcs11GetTpmTokenInfoCallback; // A callback for methods which return both a bool result and data. typedef base::CallbackPostTask( FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, std::string(crypto::kTestTPMTokenName), - std::string(kStubUserPin))); + std::string(kStubUserPin), + kStubSlot)); +} + +void FakeCryptohomeClient::Pkcs11GetTpmTokenInfoForUser( + const std::string& username, + const Pkcs11GetTpmTokenInfoCallback& callback) { + Pkcs11GetTpmTokenInfo(callback); } bool FakeCryptohomeClient::InstallAttributesGet(const std::string& name, diff --git a/chromeos/dbus/fake_cryptohome_client.h b/chromeos/dbus/fake_cryptohome_client.h index 26e2cc8c11b7a7..35de2c461e8b93 100644 --- a/chromeos/dbus/fake_cryptohome_client.h +++ b/chromeos/dbus/fake_cryptohome_client.h @@ -70,6 +70,9 @@ class CHROMEOS_EXPORT FakeCryptohomeClient : public CryptohomeClient { const BoolDBusMethodCallback& callback) OVERRIDE; virtual void Pkcs11GetTpmTokenInfo( const Pkcs11GetTpmTokenInfoCallback& callback) OVERRIDE; + virtual void Pkcs11GetTpmTokenInfoForUser( + const std::string& username, + const Pkcs11GetTpmTokenInfoCallback& callback) OVERRIDE; virtual bool InstallAttributesGet(const std::string& name, std::vector* value, bool* successful) OVERRIDE; diff --git a/chromeos/dbus/mock_cryptohome_client.h b/chromeos/dbus/mock_cryptohome_client.h index f057709dc1b4fc..76f3069ba0f5a6 100644 --- a/chromeos/dbus/mock_cryptohome_client.h +++ b/chromeos/dbus/mock_cryptohome_client.h @@ -71,6 +71,9 @@ class MockCryptohomeClient : public CryptohomeClient { void(const BoolDBusMethodCallback& callback)); MOCK_METHOD1(Pkcs11GetTpmTokenInfo, void(const Pkcs11GetTpmTokenInfoCallback& callback)); + MOCK_METHOD2(Pkcs11GetTpmTokenInfoForUser, + void(const std::string& username, + const Pkcs11GetTpmTokenInfoCallback& callback)); MOCK_METHOD3(InstallAttributesGet, bool(const std::string& name, std::vector* value,