Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Side by Side Diff: crypto/nss_util.cc

Issue 36593002: crypto/nss_util: Get TPM slot id, do lookup by id instead of by name. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sandbox debugging crap Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "crypto/nss_util.h" 5 #include "crypto/nss_util.h"
6 #include "crypto/nss_util_internal.h" 6 #include "crypto/nss_util_internal.h"
7 7
8 #include <nss.h> 8 #include <nss.h>
9 #include <pk11pub.h> 9 #include <pk11pub.h>
10 #include <plarena.h> 10 #include <plarena.h>
11 #include <prerror.h> 11 #include <prerror.h>
12 #include <prinit.h> 12 #include <prinit.h>
13 #include <prtime.h> 13 #include <prtime.h>
14 #include <secmod.h> 14 #include <secmod.h>
15 15
16 #if defined(OS_LINUX) 16 #if defined(OS_LINUX)
17 #include <linux/nfs_fs.h> 17 #include <linux/nfs_fs.h>
18 #include <sys/vfs.h> 18 #include <sys/vfs.h>
19 #elif defined(OS_OPENBSD) 19 #elif defined(OS_OPENBSD)
20 #include <sys/mount.h> 20 #include <sys/mount.h>
21 #include <sys/param.h> 21 #include <sys/param.h>
22 #endif 22 #endif
23 23
24 #include <vector> 24 #include <vector>
25 25
26 #include "base/debug/alias.h" 26 #include "base/debug/alias.h"
27 #include "base/debug/stack_trace.h"
27 #include "base/environment.h" 28 #include "base/environment.h"
28 #include "base/file_util.h" 29 #include "base/file_util.h"
29 #include "base/files/file_path.h" 30 #include "base/files/file_path.h"
30 #include "base/files/scoped_temp_dir.h" 31 #include "base/files/scoped_temp_dir.h"
31 #include "base/lazy_instance.h" 32 #include "base/lazy_instance.h"
32 #include "base/logging.h" 33 #include "base/logging.h"
33 #include "base/memory/scoped_ptr.h" 34 #include "base/memory/scoped_ptr.h"
34 #include "base/metrics/histogram.h" 35 #include "base/metrics/histogram.h"
35 #include "base/native_library.h" 36 #include "base/native_library.h"
36 #include "base/strings/stringprintf.h" 37 #include "base/strings/stringprintf.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 #endif 162 #endif
162 scoped_ptr<base::Environment> env(base::Environment::Create()); 163 scoped_ptr<base::Environment> env(base::Environment::Create());
163 const char* use_cache_env_var = "NSS_SDB_USE_CACHE"; 164 const char* use_cache_env_var = "NSS_SDB_USE_CACHE";
164 if (!env->HasVar(use_cache_env_var)) 165 if (!env->HasVar(use_cache_env_var))
165 env->SetVar(use_cache_env_var, "yes"); 166 env->SetVar(use_cache_env_var, "yes");
166 } 167 }
167 } 168 }
168 #endif // defined(OS_LINUX) || defined(OS_OPENBSD) 169 #endif // defined(OS_LINUX) || defined(OS_OPENBSD)
169 } 170 }
170 171
171 PK11SlotInfo* FindSlotWithTokenName(const std::string& token_name) {
172 AutoSECMODListReadLock auto_lock;
173 SECMODModuleList* head = SECMOD_GetDefaultModuleList();
174 for (SECMODModuleList* item = head; item != NULL; item = item->next) {
175 int slot_count = item->module->loaded ? item->module->slotCount : 0;
176 for (int i = 0; i < slot_count; i++) {
177 PK11SlotInfo* slot = item->module->slots[i];
178 if (PK11_GetTokenName(slot) == token_name)
179 return PK11_ReferenceSlot(slot);
180 }
181 }
182 return NULL;
183 }
184
185 #endif // defined(USE_NSS) 172 #endif // defined(USE_NSS)
186 173
187 // A singleton to initialize/deinitialize NSPR. 174 // A singleton to initialize/deinitialize NSPR.
188 // Separate from the NSS singleton because we initialize NSPR on the UI thread. 175 // Separate from the NSS singleton because we initialize NSPR on the UI thread.
189 // Now that we're leaking the singleton, we could merge back with the NSS 176 // Now that we're leaking the singleton, we could merge back with the NSS
190 // singleton. 177 // singleton.
191 class NSPRInitSingleton { 178 class NSPRInitSingleton {
192 private: 179 private:
193 friend struct base::DefaultLazyInstanceTraits<NSPRInitSingleton>; 180 friend struct base::DefaultLazyInstanceTraits<NSPRInitSingleton>;
194 181
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 // This creates another DB slot in NSS that is read/write, unlike 227 // This creates another DB slot in NSS that is read/write, unlike
241 // the fake root CA cert DB and the "default" crypto key 228 // the fake root CA cert DB and the "default" crypto key
242 // provider, which are still read-only (because we initialized 229 // provider, which are still read-only (because we initialized
243 // NSS before we had a cryptohome mounted). 230 // NSS before we had a cryptohome mounted).
244 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), 231 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(),
245 kNSSDatabaseName); 232 kNSSDatabaseName);
246 } 233 }
247 } 234 }
248 235
249 void EnableTPMTokenForNSS() { 236 void EnableTPMTokenForNSS() {
237 // If this gets set, then we'll use the TPM for certs with
238 // private keys, otherwise we'll fall back to the software
239 // implementation.
250 tpm_token_enabled_for_nss_ = true; 240 tpm_token_enabled_for_nss_ = true;
251 } 241 }
252 242
253 bool InitializeTPMToken(const std::string& token_name, 243 bool InitializeTPMToken(const std::string& token_name,
254 const std::string& user_pin) { 244 const std::string& user_pin,
245 int token_slot_id) {
255 // If EnableTPMTokenForNSS hasn't been called, return false. 246 // If EnableTPMTokenForNSS hasn't been called, return false.
256 if (!tpm_token_enabled_for_nss_) 247 if (!tpm_token_enabled_for_nss_)
257 return false; 248 return false;
258 249
259 // If everything is already initialized, then return true. 250 // If everything is already initialized, then return true.
260 if (chaps_module_ && tpm_slot_) 251 if (chaps_module_ && tpm_slot_)
261 return true; 252 return true;
262 253
263 tpm_token_name_ = token_name; 254 tpm_token_name_ = token_name;
264 tpm_user_pin_ = user_pin; 255 tpm_user_pin_ = user_pin;
265 256
266 // This tries to load the Chaps module so NSS can talk to the hardware 257 // This tries to load the Chaps module so NSS can talk to the hardware
267 // TPM. 258 // TPM.
268 if (!chaps_module_) { 259 if (!chaps_module_) {
269 chaps_module_ = LoadModule( 260 chaps_module_ = LoadModule(
270 kChapsModuleName, 261 kChapsModuleName,
271 kChapsPath, 262 kChapsPath,
272 // For more details on these parameters, see: 263 // For more details on these parameters, see:
273 // https://developer.mozilla.org/en/PKCS11_Module_Specs 264 // https://developer.mozilla.org/en/PKCS11_Module_Specs
274 // slotFlags=[PublicCerts] -- Certificates and public keys can be 265 // slotFlags=[PublicCerts] -- Certificates and public keys can be
275 // read from this slot without requiring a call to C_Login. 266 // read from this slot without requiring a call to C_Login.
276 // askpw=only -- Only authenticate to the token when necessary. 267 // askpw=only -- Only authenticate to the token when necessary.
277 "NSS=\"slotParams=(0={slotFlags=[PublicCerts] askpw=only})\""); 268 "NSS=\"slotParams=(0={slotFlags=[PublicCerts] askpw=only})\"");
269 if (!chaps_module_ && test_slot_) {
270 // chromeos_unittests try to test the TPM initialization process. If we
271 // have a test DB open, pretend that it is the TPM slot.
272 tpm_slot_ = PK11_ReferenceSlot(test_slot_);
273 return true;
274 }
278 } 275 }
279 if (chaps_module_){ 276 if (chaps_module_){
280 // If this gets set, then we'll use the TPM for certs with 277 tpm_slot_ = GetTPMSlotForId(token_slot_id);
Ryan Sleevi 2013/10/24 01:26:21 CASTING DANGER: CK_SLOT_ID is a CK_ULONG - which i
mattm 2013/10/24 01:59:07 Done.
281 // private keys, otherwise we'll fall back to the software
282 // implementation.
283 tpm_slot_ = GetTPMSlot();
284 278
285 return tpm_slot_ != NULL; 279 return tpm_slot_ != NULL;
286 } 280 }
287 return false; 281 return false;
288 } 282 }
289 283
290 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { 284 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) {
291 if (!tpm_token_enabled_for_nss_) { 285 if (!tpm_token_enabled_for_nss_) {
292 LOG(ERROR) << "GetTPMTokenInfo called before TPM Token is ready."; 286 LOG(ERROR) << "GetTPMTokenInfo called before TPM Token is ready.";
293 return; 287 return;
294 } 288 }
295 if (token_name) 289 if (token_name)
296 *token_name = tpm_token_name_; 290 *token_name = tpm_token_name_;
297 if (user_pin) 291 if (user_pin)
298 *user_pin = tpm_user_pin_; 292 *user_pin = tpm_user_pin_;
299 } 293 }
300 294
301 bool IsTPMTokenReady() { 295 bool IsTPMTokenReady() {
302 return tpm_slot_ != NULL; 296 return tpm_slot_ != NULL;
303 } 297 }
304 298
305 PK11SlotInfo* GetTPMSlot() { 299 PK11SlotInfo* GetTPMSlotForId(CK_SLOT_ID slot_id) {
306 std::string token_name; 300 if (!chaps_module_)
307 GetTPMTokenInfo(&token_name, NULL); 301 return NULL;
308 return FindSlotWithTokenName(token_name); 302
303 VLOG(1) << "Poking chaps module.";
304 SECStatus rv = SECMOD_UpdateSlotList(chaps_module_);
305 if (rv != SECSuccess)
306 PLOG(ERROR) << "SECMOD_UpdateSlotList failed: " << PORT_GetError();
307
308 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module_->moduleID, slot_id);
309 if (!slot)
310 LOG(ERROR) << "TPM slot " << slot_id << " not found.";
311 return slot;
309 } 312 }
310 #endif // defined(OS_CHROMEOS) 313 #endif // defined(OS_CHROMEOS)
311 314
312 315
313 bool OpenTestNSSDB() { 316 bool OpenTestNSSDB() {
314 if (test_slot_) 317 if (test_slot_)
315 return true; 318 return true;
316 if (!g_test_nss_db_dir.Get().CreateUniqueTempDir()) 319 if (!g_test_nss_db_dir.Get().CreateUniqueTempDir())
317 return false; 320 return false;
318 test_slot_ = OpenUserDB(g_test_nss_db_dir.Get().path(), kTestTPMTokenName); 321 test_slot_ = OpenUserDB(g_test_nss_db_dir.Get().path(), kTestTPMTokenName);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; 379 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>;
377 380
378 NSSInitSingleton() 381 NSSInitSingleton()
379 : tpm_token_enabled_for_nss_(false), 382 : tpm_token_enabled_for_nss_(false),
380 chaps_module_(NULL), 383 chaps_module_(NULL),
381 software_slot_(NULL), 384 software_slot_(NULL),
382 test_slot_(NULL), 385 test_slot_(NULL),
383 tpm_slot_(NULL), 386 tpm_slot_(NULL),
384 root_(NULL), 387 root_(NULL),
385 chromeos_user_logged_in_(false) { 388 chromeos_user_logged_in_(false) {
389 LOG(ERROR) << __func__;
390 base::debug::StackTrace().Print();
386 base::TimeTicks start_time = base::TimeTicks::Now(); 391 base::TimeTicks start_time = base::TimeTicks::Now();
387 EnsureNSPRInit(); 392 EnsureNSPRInit();
388 393
389 // We *must* have NSS >= 3.14.3. 394 // We *must* have NSS >= 3.14.3.
390 COMPILE_ASSERT( 395 COMPILE_ASSERT(
391 (NSS_VMAJOR == 3 && NSS_VMINOR == 14 && NSS_VPATCH >= 3) || 396 (NSS_VMAJOR == 3 && NSS_VMINOR == 14 && NSS_VPATCH >= 3) ||
392 (NSS_VMAJOR == 3 && NSS_VMINOR > 14) || 397 (NSS_VMAJOR == 3 && NSS_VMINOR > 14) ||
393 (NSS_VMAJOR > 3), 398 (NSS_VMAJOR > 3),
394 nss_version_check_failed); 399 nss_version_check_failed);
395 // Also check the run-time NSS version. 400 // Also check the run-time NSS version.
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 // declare input string arguments as const. Bug 547 // declare input string arguments as const. Bug
543 // https://bugzilla.mozilla.org/show_bug.cgi?id=642546 was filed 548 // https://bugzilla.mozilla.org/show_bug.cgi?id=642546 was filed
544 // on NSS codebase to address this. 549 // on NSS codebase to address this.
545 SECMODModule* module = SECMOD_LoadUserModule( 550 SECMODModule* module = SECMOD_LoadUserModule(
546 const_cast<char*>(modparams.c_str()), NULL, PR_FALSE); 551 const_cast<char*>(modparams.c_str()), NULL, PR_FALSE);
547 if (!module) { 552 if (!module) {
548 LOG(ERROR) << "Error loading " << name << " module into NSS: " 553 LOG(ERROR) << "Error loading " << name << " module into NSS: "
549 << GetNSSErrorMessage(); 554 << GetNSSErrorMessage();
550 return NULL; 555 return NULL;
551 } 556 }
557 if (!module->loaded) {
558 LOG(ERROR) << "After loading " << name << ", loaded==false: "
559 << GetNSSErrorMessage();
560 SECMOD_DestroyModule(module);
561 return NULL;
562 }
552 return module; 563 return module;
553 } 564 }
554 #endif 565 #endif
555 566
556 static PK11SlotInfo* OpenUserDB(const base::FilePath& path, 567 static PK11SlotInfo* OpenUserDB(const base::FilePath& path,
557 const char* description) { 568 const char* description) {
558 const std::string modspec = 569 const std::string modspec =
559 base::StringPrintf("configDir='sql:%s' tokenDescription='%s'", 570 base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
560 path.value().c_str(), description); 571 path.value().c_str(), description);
561 PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str()); 572 PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 634
624 void EnsureNSSInit() { 635 void EnsureNSSInit() {
625 // Initializing SSL causes us to do blocking IO. 636 // Initializing SSL causes us to do blocking IO.
626 // Temporarily allow it until we fix 637 // Temporarily allow it until we fix
627 // http://code.google.com/p/chromium/issues/detail?id=59847 638 // http://code.google.com/p/chromium/issues/detail?id=59847
628 base::ThreadRestrictions::ScopedAllowIO allow_io; 639 base::ThreadRestrictions::ScopedAllowIO allow_io;
629 g_nss_singleton.Get(); 640 g_nss_singleton.Get();
630 } 641 }
631 642
632 void ForceNSSNoDBInit() { 643 void ForceNSSNoDBInit() {
644 LOG(ERROR) << "OKAAAAAAAAAAAAAAAAY";
633 NSSInitSingleton::ForceNoDBInit(); 645 NSSInitSingleton::ForceNoDBInit();
634 } 646 }
635 647
636 void DisableNSSForkCheck() { 648 void DisableNSSForkCheck() {
637 scoped_ptr<base::Environment> env(base::Environment::Create()); 649 scoped_ptr<base::Environment> env(base::Environment::Create());
638 env->SetVar("NSS_STRICT_NOFORK", "DISABLED"); 650 env->SetVar("NSS_STRICT_NOFORK", "DISABLED");
639 } 651 }
640 652
641 void LoadNSSLibraries() { 653 void LoadNSSLibraries() {
642 // Some NSS libraries are linked dynamically so load them here. 654 // Some NSS libraries are linked dynamically so load them here.
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 757
746 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { 758 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) {
747 g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin); 759 g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin);
748 } 760 }
749 761
750 bool IsTPMTokenReady() { 762 bool IsTPMTokenReady() {
751 return g_nss_singleton.Get().IsTPMTokenReady(); 763 return g_nss_singleton.Get().IsTPMTokenReady();
752 } 764 }
753 765
754 bool InitializeTPMToken(const std::string& token_name, 766 bool InitializeTPMToken(const std::string& token_name,
755 const std::string& user_pin) { 767 const std::string& user_pin,
756 return g_nss_singleton.Get().InitializeTPMToken(token_name, user_pin); 768 int token_slot_id) {
769 return g_nss_singleton.Get().InitializeTPMToken(
770 token_name, user_pin, token_slot_id);
771 }
772
773 PK11SlotInfo* GetTPMSlotForId(CK_SLOT_ID slot_id) {
774 return g_nss_singleton.Get().GetTPMSlotForId(slot_id);
757 } 775 }
758 #endif // defined(OS_CHROMEOS) 776 #endif // defined(OS_CHROMEOS)
759 777
760 base::Time PRTimeToBaseTime(PRTime prtime) { 778 base::Time PRTimeToBaseTime(PRTime prtime) {
761 return base::Time::FromInternalValue( 779 return base::Time::FromInternalValue(
762 prtime + base::Time::UnixEpoch().ToInternalValue()); 780 prtime + base::Time::UnixEpoch().ToInternalValue());
763 } 781 }
764 782
765 PRTime BaseTimeToPRTime(base::Time time) { 783 PRTime BaseTimeToPRTime(base::Time time) {
766 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); 784 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue();
767 } 785 }
768 786
769 PK11SlotInfo* GetPublicNSSKeySlot() { 787 PK11SlotInfo* GetPublicNSSKeySlot() {
770 return g_nss_singleton.Get().GetPublicNSSKeySlot(); 788 return g_nss_singleton.Get().GetPublicNSSKeySlot();
771 } 789 }
772 790
773 PK11SlotInfo* GetPrivateNSSKeySlot() { 791 PK11SlotInfo* GetPrivateNSSKeySlot() {
774 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); 792 return g_nss_singleton.Get().GetPrivateNSSKeySlot();
775 } 793 }
776 794
777 } // namespace crypto 795 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/nss_util.h ('k') | crypto/nss_util_internal.h » ('j') | crypto/nss_util_internal.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698