Index: crypto/nss_util.cc |
diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc |
index 80191b3366f4b4c29eb478560c759cdda3d92669..b4f537d5a28ee04a7fe3454d40eb29b1fb956388 100644 |
--- a/crypto/nss_util.cc |
+++ b/crypto/nss_util.cc |
@@ -23,6 +23,7 @@ |
#include <vector> |
+#include "base/callback.h" |
#include "base/debug/alias.h" |
#include "base/environment.h" |
#include "base/file_util.h" |
@@ -86,6 +87,7 @@ base::FilePath GetDefaultConfigDirectory() { |
LOG(ERROR) << "Failed to create " << dir.value() << " directory."; |
dir.clear(); |
} |
+ LOG(WARNING) << "GetDefaultConfigDirectory: " << dir.value(); |
return dir; |
} |
@@ -246,12 +248,39 @@ class NSSInitSingleton { |
} |
} |
+ PK11SlotInfo* OpenPersistentNSSDBForPath(const base::FilePath& path) { |
+ LOG(WARNING) << __func__ << " " << path.AsUTF8Unsafe(); |
+ // We do NSS file io on the IO thread. |
+ base::ThreadRestrictions::ScopedAllowIO allow_io; |
+ |
+ if (force_nodb_init_) { |
+ // XXX probably unneccessary |
+ LOG(WARNING) << "force_nodb_init_, returning NULL"; |
+ return NULL; |
+ } |
+ base::FilePath nssdb_path = path.AppendASCII(".pki").AppendASCII("nssdb"); |
+ // XXX shoud we be doing this? |
+ if (!file_util::CreateDirectory(nssdb_path)) { |
+ LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory."; |
+ return NULL; |
+ } |
+ return OpenUserDB(nssdb_path, kNSSDatabaseName); |
+ } |
+ |
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 IsTPMTokenEnabledForNSS() { |
+ return tpm_token_enabled_for_nss_; |
+ } |
+ |
bool InitializeTPMToken(const std::string& token_name, |
- const std::string& user_pin) { |
+ const std::string& user_pin, |
+ int token_slot_id) { |
// If EnableTPMTokenForNSS hasn't been called, return false. |
if (!tpm_token_enabled_for_nss_) |
return false; |
@@ -277,10 +306,17 @@ class NSSInitSingleton { |
"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(); |
+ tpm_slot_ = GetTPMSlotForId(token_slot_id); |
+ |
+ if (tpm_slot_) { |
+ for (std::vector<base::Closure>::iterator i = |
+ tpm_ready_callback_list_.begin(); |
+ i != tpm_ready_callback_list_.end(); |
+ ++i) { |
+ (*i).Run(); |
+ } |
+ tpm_ready_callback_list_.clear(); |
+ } |
return tpm_slot_ != NULL; |
} |
@@ -302,10 +338,26 @@ class NSSInitSingleton { |
return tpm_slot_ != NULL; |
} |
- PK11SlotInfo* GetTPMSlot() { |
- std::string token_name; |
- GetTPMTokenInfo(&token_name, NULL); |
- return FindSlotWithTokenName(token_name); |
+ void OnTPMReady(const base::Closure& callback) { |
+ if (IsTPMTokenReady()) |
+ callback.Run(); |
+ else |
+ tpm_ready_callback_list_.push_back(callback); |
+ } |
+ |
+ 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) |
@@ -576,6 +628,7 @@ class NSSInitSingleton { |
bool tpm_token_enabled_for_nss_; |
std::string tpm_token_name_; |
std::string tpm_user_pin_; |
+ std::vector<base::Closure> tpm_ready_callback_list_; |
SECMODModule* chaps_module_; |
PK11SlotInfo* software_slot_; |
PK11SlotInfo* test_slot_; |
@@ -743,6 +796,10 @@ void EnableTPMTokenForNSS() { |
g_nss_singleton.Get().EnableTPMTokenForNSS(); |
} |
+bool IsTPMTokenEnabledForNSS() { |
+ return g_nss_singleton.Get().IsTPMTokenEnabledForNSS(); |
+} |
+ |
void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { |
g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin); |
} |
@@ -751,9 +808,23 @@ bool IsTPMTokenReady() { |
return g_nss_singleton.Get().IsTPMTokenReady(); |
} |
+void OnTPMReady(const base::Closure& callback) { |
+ g_nss_singleton.Get().OnTPMReady(callback); |
+} |
+ |
bool InitializeTPMToken(const std::string& token_name, |
- const std::string& user_pin) { |
- return g_nss_singleton.Get().InitializeTPMToken(token_name, user_pin); |
+ const std::string& user_pin, |
+ int token_slot_id) { |
+ return g_nss_singleton.Get().InitializeTPMToken( |
+ token_name, user_pin, token_slot_id); |
+} |
+ |
+PK11SlotInfo* OpenPersistentNSSDBForPath(const base::FilePath& path) { |
+ return g_nss_singleton.Get().OpenPersistentNSSDBForPath(path); |
+} |
+ |
+PK11SlotInfo* GetTPMSlotForId(CK_SLOT_ID slot_id) { |
+ return g_nss_singleton.Get().GetTPMSlotForId(slot_id); |
} |
#endif // defined(OS_CHROMEOS) |
@@ -774,4 +845,26 @@ PK11SlotInfo* GetPrivateNSSKeySlot() { |
return g_nss_singleton.Get().GetPrivateNSSKeySlot(); |
} |
+void DumpNSSSlotInfos() { |
+ AutoSECMODListReadLock auto_lock; |
+ SECMODModuleList* head = SECMOD_GetDefaultModuleList(); |
+ LOG(WARNING) << "DumpNSSSlotInfos:"; |
+ for (SECMODModuleList* item = head; item != NULL; item = item->next) { |
+ int slot_count = item->module->loaded ? item->module->slotCount : 0; |
+ LOG(WARNING) << item->module->moduleID |
+ << " module " << item->module->commonName |
+ << " loaded:" << item->module->loaded; |
+ for (int i = 0; i < slot_count; i++) { |
+ PK11SlotInfo* slot = item->module->slots[i]; |
+ LOG(WARNING) << " " << PK11_GetSlotID(slot) |
+ << " tok:" << PK11_GetTokenName(slot) |
+ << " slot:" << PK11_GetSlotName(slot) |
+ << (PK11_IsInternal(slot) ? " internal" : "") |
+ << (PK11_IsInternalKeySlot(slot) ? " internalkeyslot" : "") |
+ << (PK11_IsReadOnly(slot) ? " readonly" : ""); |
+ } |
+ } |
+ LOG(WARNING) << ""; |
+} |
+ |
} // namespace crypto |