Remove TPMTokenInfoDelegate to make TPM initialization code path simple

Move Cryptohome D-Bus method calls to chromeos::CertLibrary

BUG=125848
TEST=can login

Review URL: https://chromiumcodereview.appspot.com/10332191

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137646 0039d316-1c4b-4281-b951-d872f2087c98
parent 4ded2f91
...@@ -23,20 +23,17 @@ ...@@ -23,20 +23,17 @@
#include <vector> #include <vector>
#include "base/bind.h"
#include "base/environment.h" #include "base/environment.h"
#include "base/file_path.h" #include "base/file_path.h"
#include "base/file_util.h" #include "base/file_util.h"
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/native_library.h" #include "base/native_library.h"
#include "base/scoped_temp_dir.h" #include "base/scoped_temp_dir.h"
#include "base/stringprintf.h" #include "base/stringprintf.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "crypto/scoped_nss_types.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "crypto/symmetric_key.h" #include "crypto/symmetric_key.h"
...@@ -214,9 +211,8 @@ class NSPRInitSingleton { ...@@ -214,9 +211,8 @@ class NSPRInitSingleton {
~NSPRInitSingleton() { ~NSPRInitSingleton() {
PL_ArenaFinish(); PL_ArenaFinish();
PRStatus prstatus = PR_Cleanup(); PRStatus prstatus = PR_Cleanup();
if (prstatus != PR_SUCCESS) { if (prstatus != PR_SUCCESS)
LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?"; LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?";
}
} }
}; };
...@@ -247,35 +243,56 @@ class NSSInitSingleton { ...@@ -247,35 +243,56 @@ class NSSInitSingleton {
} }
} }
void EnableTPMTokenForNSS(TPMTokenInfoDelegate* info_delegate) { void EnableTPMTokenForNSS() {
CHECK(info_delegate); tpm_token_enabled_for_nss_ = true;
tpm_token_info_delegate_.reset(info_delegate);
} }
void InitializeTPMToken(InitializeTPMTokenCallback callback) { bool InitializeTPMToken(const std::string& token_name,
// If EnableTPMTokenForNSS hasn't been called, run |callback| with false. const std::string& user_pin) {
if (tpm_token_info_delegate_.get() == NULL) { // If EnableTPMTokenForNSS hasn't been called, return false.
MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, false)); if (!tpm_token_enabled_for_nss_)
return; return false;
// If everything is already initialized, then return true.
if (chaps_module_ && tpm_slot_)
return true;
tpm_token_name_ = token_name;
tpm_user_pin_ = user_pin;
// This tries to load the Chaps module so NSS can talk to the hardware
// TPM.
if (!chaps_module_) {
chaps_module_ = LoadModule(
kChapsModuleName,
kChapsPath,
// For more details on these parameters, see:
// https://developer.mozilla.org/en/PKCS11_Module_Specs
// slotFlags=[PublicCerts] -- Certificates and public keys can be
// 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_){
// 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();
// If everything is already initialized, then run |callback| with true. return tpm_slot_ != NULL;
if (chaps_module_ && tpm_slot_) {
MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true));
return;
} }
tpm_token_info_delegate_->RequestIsTokenReady( return false;
base::Bind(&NSSInitSingleton::InitializeTPMTokenInternal,
weak_ptr_factory_.GetWeakPtr(),
callback));
} }
void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) {
if (tpm_token_info_delegate_.get() == NULL) { if (!tpm_token_enabled_for_nss_) {
LOG(ERROR) << "GetTPMTokenInfo called before TPM Token is ready."; LOG(ERROR) << "GetTPMTokenInfo called before TPM Token is ready.";
return; return;
} }
tpm_token_info_delegate_->GetTokenInfo(token_name, user_pin); if (token_name)
*token_name = tpm_token_name_;
if (user_pin)
*user_pin = tpm_user_pin_;
} }
bool IsTPMTokenReady() { bool IsTPMTokenReady() {
...@@ -358,7 +375,7 @@ class NSSInitSingleton { ...@@ -358,7 +375,7 @@ class NSSInitSingleton {
return PK11_ReferenceSlot(test_slot_); return PK11_ReferenceSlot(test_slot_);
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
if (tpm_token_info_delegate_.get() != NULL) { if (tpm_token_enabled_for_nss_) {
if (IsTPMTokenReady()) { if (IsTPMTokenReady()) {
return PK11_ReferenceSlot(tpm_slot_); return PK11_ReferenceSlot(tpm_slot_);
} else { } else {
...@@ -391,13 +408,13 @@ class NSSInitSingleton { ...@@ -391,13 +408,13 @@ class NSSInitSingleton {
friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>;
NSSInitSingleton() NSSInitSingleton()
: chaps_module_(NULL), : tpm_token_enabled_for_nss_(false),
chaps_module_(NULL),
software_slot_(NULL), software_slot_(NULL),
test_slot_(NULL), test_slot_(NULL),
tpm_slot_(NULL), tpm_slot_(NULL),
root_(NULL), root_(NULL),
chromeos_user_logged_in_(false), chromeos_user_logged_in_(false) {
ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
EnsureNSPRInit(); EnsureNSPRInit();
// We *must* have NSS >= 3.12.3. See bug 26448. // We *must* have NSS >= 3.12.3. See bug 26448.
...@@ -521,38 +538,6 @@ class NSSInitSingleton { ...@@ -521,38 +538,6 @@ class NSSInitSingleton {
} }
} }
#if defined(OS_CHROMEOS)
// This method is used to implement InitializeTPMToken.
void InitializeTPMTokenInternal(InitializeTPMTokenCallback callback,
bool is_token_ready) {
if (is_token_ready) {
// This tries to load the Chaps module so NSS can talk to the hardware
// TPM.
if (!chaps_module_) {
chaps_module_ = LoadModule(
kChapsModuleName,
kChapsPath,
// For more details on these parameters, see:
// https://developer.mozilla.org/en/PKCS11_Module_Specs
// slotFlags=[PublicCerts] -- Certificates and public keys can be
// 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_) {
// 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();
callback.Run(tpm_slot_ != NULL);
return;
}
}
callback.Run(false);
}
#endif // defined(OS_CHROMEOS)
#if defined(USE_NSS) #if defined(USE_NSS)
// Load nss's built-in root certs. // Load nss's built-in root certs.
SECMODModule* InitDefaultRootCerts() { SECMODModule* InitDefaultRootCerts() {
...@@ -609,17 +594,15 @@ class NSSInitSingleton { ...@@ -609,17 +594,15 @@ class NSSInitSingleton {
// If this is set to true NSS is forced to be initialized without a DB. // If this is set to true NSS is forced to be initialized without a DB.
static bool force_nodb_init_; static bool force_nodb_init_;
#if defined(OS_CHROMEOS) bool tpm_token_enabled_for_nss_;
scoped_ptr<TPMTokenInfoDelegate> tpm_token_info_delegate_; std::string tpm_token_name_;
#endif std::string tpm_user_pin_;
SECMODModule* chaps_module_; SECMODModule* chaps_module_;
PK11SlotInfo* software_slot_; PK11SlotInfo* software_slot_;
PK11SlotInfo* test_slot_; PK11SlotInfo* test_slot_;
PK11SlotInfo* tpm_slot_; PK11SlotInfo* tpm_slot_;
SECMODModule* root_; SECMODModule* root_;
bool chromeos_user_logged_in_; bool chromeos_user_logged_in_;
base::WeakPtrFactory<NSSInitSingleton> weak_ptr_factory_;
#if defined(USE_NSS) #if defined(USE_NSS)
// TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011
// is fixed, we will no longer need the lock. // is fixed, we will no longer need the lock.
...@@ -753,11 +736,8 @@ void OpenPersistentNSSDB() { ...@@ -753,11 +736,8 @@ void OpenPersistentNSSDB() {
g_nss_singleton.Get().OpenPersistentNSSDB(); g_nss_singleton.Get().OpenPersistentNSSDB();
} }
TPMTokenInfoDelegate::TPMTokenInfoDelegate() {} void EnableTPMTokenForNSS() {
TPMTokenInfoDelegate::~TPMTokenInfoDelegate() {} g_nss_singleton.Get().EnableTPMTokenForNSS();
void EnableTPMTokenForNSS(TPMTokenInfoDelegate* info_delegate) {
g_nss_singleton.Get().EnableTPMTokenForNSS(info_delegate);
} }
void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) {
...@@ -768,8 +748,9 @@ bool IsTPMTokenReady() { ...@@ -768,8 +748,9 @@ bool IsTPMTokenReady() {
return g_nss_singleton.Get().IsTPMTokenReady(); return g_nss_singleton.Get().IsTPMTokenReady();
} }
void InitializeTPMToken(InitializeTPMTokenCallback callback) { bool InitializeTPMToken(const std::string& token_name,
g_nss_singleton.Get().InitializeTPMToken(callback); const std::string& user_pin) {
return g_nss_singleton.Get().InitializeTPMToken(token_name, user_pin);
} }
SymmetricKey* GetSupplementalUserKey() { SymmetricKey* GetSupplementalUserKey() {
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <string> #include <string>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/callback.h"
#include "crypto/crypto_export.h" #include "crypto/crypto_export.h"
#if defined(USE_NSS) #if defined(USE_NSS)
...@@ -27,9 +26,6 @@ namespace crypto { ...@@ -27,9 +26,6 @@ namespace crypto {
class SymmetricKey; class SymmetricKey;
// A callback to handle the result of InitializeTPMToken.
typedef base::Callback<void(bool result)> InitializeTPMTokenCallback;
#if defined(USE_NSS) #if defined(USE_NSS)
// EarlySetupForNSSInit performs lightweight setup which must occur before the // EarlySetupForNSSInit performs lightweight setup which must occur before the
// process goes multithreaded. This does not initialise NSS. For test, see // process goes multithreaded. This does not initialise NSS. For test, see
...@@ -93,36 +89,10 @@ bool CheckNSSVersion(const char* version); ...@@ -93,36 +89,10 @@ bool CheckNSSVersion(const char* version);
// GetPublicNSSKeySlot(). // GetPublicNSSKeySlot().
CRYPTO_EXPORT void OpenPersistentNSSDB(); CRYPTO_EXPORT void OpenPersistentNSSDB();
// A delegate class that we can use to access the cros API for
// communication with cryptohomed and the TPM.
class CRYPTO_EXPORT TPMTokenInfoDelegate {
public:
// A callback to handle the result of RequestIsTokenReady.
typedef base::Callback<void(bool result)> RequestIsTokenReadyCallback;
TPMTokenInfoDelegate();
virtual ~TPMTokenInfoDelegate();
// Runs |callback| with true if the TPM and PKCS#11 token slot is ready to be
// used.
// If IsTokenAvailable() is false this should run |callback| with false.
// If IsTokenAvailable() is true, this should eventually run |callback| with
// true.
virtual void RequestIsTokenReady(RequestIsTokenReadyCallback callback) const
= 0;
// Fetches token properties. TODO(stevenjb): make this interface asynchronous
// so that the implementation does not have to be blocking.
virtual void GetTokenInfo(std::string* token_name,
std::string* user_pin) const = 0;
};
// Indicates that NSS should load the Chaps library so that we // Indicates that NSS should load the Chaps library so that we
// can access the TPM through NSS. Once this is called, // can access the TPM through NSS. Once this is called,
// GetPrivateNSSKeySlot() will return the TPM slot if one was found. // GetPrivateNSSKeySlot() will return the TPM slot if one was found.
// Takes ownership of the passed-in delegate object so it can access CRYPTO_EXPORT void EnableTPMTokenForNSS();
// the cros library to talk to cryptohomed.
CRYPTO_EXPORT void EnableTPMTokenForNSS(TPMTokenInfoDelegate* delegate);
// Get name and user PIN for the built-in TPM token on ChromeOS. // Get name and user PIN for the built-in TPM token on ChromeOS.
// Either one can safely be NULL. Should only be called after // Either one can safely be NULL. Should only be called after
...@@ -137,7 +107,8 @@ CRYPTO_EXPORT void GetTPMTokenInfo(std::string* token_name, ...@@ -137,7 +107,8 @@ CRYPTO_EXPORT void GetTPMTokenInfo(std::string* token_name,
CRYPTO_EXPORT bool IsTPMTokenReady(); CRYPTO_EXPORT bool IsTPMTokenReady();
// Initialize the TPM token. Does nothing if it is already initialized. // Initialize the TPM token. Does nothing if it is already initialized.
CRYPTO_EXPORT void InitializeTPMToken(InitializeTPMTokenCallback callback); CRYPTO_EXPORT bool InitializeTPMToken(const std::string& token_name,
const std::string& user_pin);
// Gets supplemental user key. Creates one in NSS database if it does not exist. // Gets supplemental user key. Creates one in NSS database if it does not exist.
// The supplemental user key is used for AES encryption of user data that is // The supplemental user key is used for AES encryption of user data that is
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment