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

Side by Side Diff: crypto/nss_util.cc

Issue 10332191: Remove TPMTokenInfoDelegate (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix logic error Created 8 years, 7 months 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
« no previous file with comments | « crypto/nss_util.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <plarena.h> 9 #include <plarena.h>
10 #include <prerror.h> 10 #include <prerror.h>
11 #include <prinit.h> 11 #include <prinit.h>
12 #include <prtime.h> 12 #include <prtime.h>
13 #include <pk11pub.h> 13 #include <pk11pub.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/bind.h"
27 #include "base/environment.h" 26 #include "base/environment.h"
28 #include "base/file_path.h" 27 #include "base/file_path.h"
29 #include "base/file_util.h" 28 #include "base/file_util.h"
30 #include "base/lazy_instance.h" 29 #include "base/lazy_instance.h"
31 #include "base/logging.h" 30 #include "base/logging.h"
32 #include "base/memory/scoped_ptr.h" 31 #include "base/memory/scoped_ptr.h"
33 #include "base/message_loop.h"
34 #include "base/native_library.h" 32 #include "base/native_library.h"
35 #include "base/scoped_temp_dir.h" 33 #include "base/scoped_temp_dir.h"
36 #include "base/stringprintf.h" 34 #include "base/stringprintf.h"
37 #include "base/threading/thread_restrictions.h" 35 #include "base/threading/thread_restrictions.h"
38 #include "build/build_config.h" 36 #include "build/build_config.h"
39 #include "crypto/scoped_nss_types.h"
40 37
41 #if defined(OS_CHROMEOS) 38 #if defined(OS_CHROMEOS)
42 #include "crypto/symmetric_key.h" 39 #include "crypto/symmetric_key.h"
43 #endif 40 #endif
44 41
45 // USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not 42 // USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not
46 // defined, such as on Mac and Windows, we use NSS for SSL only -- we don't 43 // defined, such as on Mac and Windows, we use NSS for SSL only -- we don't
47 // use NSS for crypto or certificate verification, and we don't use the NSS 44 // use NSS for crypto or certificate verification, and we don't use the NSS
48 // certificate and key databases. 45 // certificate and key databases.
49 #if defined(USE_NSS) 46 #if defined(USE_NSS)
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 NSPRInitSingleton() { 204 NSPRInitSingleton() {
208 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); 205 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
209 } 206 }
210 207
211 // NOTE(willchan): We don't actually execute this code since we leak NSS to 208 // NOTE(willchan): We don't actually execute this code since we leak NSS to
212 // prevent non-joinable threads from using NSS after it's already been shut 209 // prevent non-joinable threads from using NSS after it's already been shut
213 // down. 210 // down.
214 ~NSPRInitSingleton() { 211 ~NSPRInitSingleton() {
215 PL_ArenaFinish(); 212 PL_ArenaFinish();
216 PRStatus prstatus = PR_Cleanup(); 213 PRStatus prstatus = PR_Cleanup();
217 if (prstatus != PR_SUCCESS) { 214 if (prstatus != PR_SUCCESS)
218 LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?"; 215 LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?";
219 }
220 } 216 }
221 }; 217 };
222 218
223 base::LazyInstance<NSPRInitSingleton>::Leaky 219 base::LazyInstance<NSPRInitSingleton>::Leaky
224 g_nspr_singleton = LAZY_INSTANCE_INITIALIZER; 220 g_nspr_singleton = LAZY_INSTANCE_INITIALIZER;
225 221
226 // This is a LazyInstance so that it will be deleted automatically when the 222 // This is a LazyInstance so that it will be deleted automatically when the
227 // unittest exits. NSSInitSingleton is a LeakySingleton, so it would not be 223 // unittest exits. NSSInitSingleton is a LeakySingleton, so it would not be
228 // deleted if it were a regular member. 224 // deleted if it were a regular member.
229 base::LazyInstance<ScopedTempDir> g_test_nss_db_dir = LAZY_INSTANCE_INITIALIZER; 225 base::LazyInstance<ScopedTempDir> g_test_nss_db_dir = LAZY_INSTANCE_INITIALIZER;
(...skipping 10 matching lines...) Expand all
240 236
241 // This creates another DB slot in NSS that is read/write, unlike 237 // This creates another DB slot in NSS that is read/write, unlike
242 // the fake root CA cert DB and the "default" crypto key 238 // the fake root CA cert DB and the "default" crypto key
243 // provider, which are still read-only (because we initialized 239 // provider, which are still read-only (because we initialized
244 // NSS before we had a cryptohome mounted). 240 // NSS before we had a cryptohome mounted).
245 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), 241 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(),
246 kNSSDatabaseName); 242 kNSSDatabaseName);
247 } 243 }
248 } 244 }
249 245
250 void EnableTPMTokenForNSS(TPMTokenInfoDelegate* info_delegate) { 246 void EnableTPMTokenForNSS() {
251 CHECK(info_delegate); 247 tpm_token_enabled_for_nss_ = true;
252 tpm_token_info_delegate_.reset(info_delegate);
253 } 248 }
254 249
255 void InitializeTPMToken(InitializeTPMTokenCallback callback) { 250 bool InitializeTPMToken(const std::string& token_name,
256 // If EnableTPMTokenForNSS hasn't been called, run |callback| with false. 251 const std::string& user_pin) {
257 if (tpm_token_info_delegate_.get() == NULL) { 252 // If EnableTPMTokenForNSS hasn't been called, return false.
258 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, false)); 253 if (!tpm_token_enabled_for_nss_)
259 return; 254 return false;
255
256 // If everything is already initialized, then return true.
257 if (chaps_module_ && tpm_slot_)
258 return true;
259
260 tpm_token_name_ = token_name;
261 tpm_user_pin_ = user_pin;
262
263 // This tries to load the Chaps module so NSS can talk to the hardware
264 // TPM.
265 if (!chaps_module_) {
266 chaps_module_ = LoadModule(
267 kChapsModuleName,
268 kChapsPath,
269 // For more details on these parameters, see:
270 // https://developer.mozilla.org/en/PKCS11_Module_Specs
271 // slotFlags=[PublicCerts] -- Certificates and public keys can be
272 // read from this slot without requiring a call to C_Login.
273 // askpw=only -- Only authenticate to the token when necessary.
274 "NSS=\"slotParams=(0={slotFlags=[PublicCerts] askpw=only})\"");
260 } 275 }
276 if (chaps_module_){
277 // If this gets set, then we'll use the TPM for certs with
278 // private keys, otherwise we'll fall back to the software
279 // implementation.
280 tpm_slot_ = GetTPMSlot();
261 281
262 // If everything is already initialized, then run |callback| with true. 282 return tpm_slot_ != NULL;
263 if (chaps_module_ && tpm_slot_) {
264 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true));
265 return;
266 } 283 }
267 tpm_token_info_delegate_->RequestIsTokenReady( 284 return false;
268 base::Bind(&NSSInitSingleton::InitializeTPMTokenInternal,
269 weak_ptr_factory_.GetWeakPtr(),
270 callback));
271 } 285 }
272 286
273 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { 287 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) {
274 if (tpm_token_info_delegate_.get() == NULL) { 288 if (!tpm_token_enabled_for_nss_) {
275 LOG(ERROR) << "GetTPMTokenInfo called before TPM Token is ready."; 289 LOG(ERROR) << "GetTPMTokenInfo called before TPM Token is ready.";
276 return; 290 return;
277 } 291 }
278 tpm_token_info_delegate_->GetTokenInfo(token_name, user_pin); 292 if (token_name)
293 *token_name = tpm_token_name_;
294 if (user_pin)
295 *user_pin = tpm_user_pin_;
279 } 296 }
280 297
281 bool IsTPMTokenReady() { 298 bool IsTPMTokenReady() {
282 return tpm_slot_ != NULL; 299 return tpm_slot_ != NULL;
283 } 300 }
284 301
285 PK11SlotInfo* GetTPMSlot() { 302 PK11SlotInfo* GetTPMSlot() {
286 std::string token_name; 303 std::string token_name;
287 GetTPMTokenInfo(&token_name, NULL); 304 GetTPMTokenInfo(&token_name, NULL);
288 return FindSlotWithTokenName(token_name); 305 return FindSlotWithTokenName(token_name);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 if (software_slot_) 368 if (software_slot_)
352 return PK11_ReferenceSlot(software_slot_); 369 return PK11_ReferenceSlot(software_slot_);
353 return PK11_GetInternalKeySlot(); 370 return PK11_GetInternalKeySlot();
354 } 371 }
355 372
356 PK11SlotInfo* GetPrivateNSSKeySlot() { 373 PK11SlotInfo* GetPrivateNSSKeySlot() {
357 if (test_slot_) 374 if (test_slot_)
358 return PK11_ReferenceSlot(test_slot_); 375 return PK11_ReferenceSlot(test_slot_);
359 376
360 #if defined(OS_CHROMEOS) 377 #if defined(OS_CHROMEOS)
361 if (tpm_token_info_delegate_.get() != NULL) { 378 if (tpm_token_enabled_for_nss_) {
362 if (IsTPMTokenReady()) { 379 if (IsTPMTokenReady()) {
363 return PK11_ReferenceSlot(tpm_slot_); 380 return PK11_ReferenceSlot(tpm_slot_);
364 } else { 381 } else {
365 // If we were supposed to get the hardware token, but were 382 // If we were supposed to get the hardware token, but were
366 // unable to, return NULL rather than fall back to sofware. 383 // unable to, return NULL rather than fall back to sofware.
367 return NULL; 384 return NULL;
368 } 385 }
369 } 386 }
370 #endif 387 #endif
371 // If we weren't supposed to enable the TPM for NSS, then return 388 // If we weren't supposed to enable the TPM for NSS, then return
(...skipping 12 matching lines...) Expand all
384 // This method is used to force NSS to be initialized without a DB. 401 // This method is used to force NSS to be initialized without a DB.
385 // Call this method before NSSInitSingleton() is constructed. 402 // Call this method before NSSInitSingleton() is constructed.
386 static void ForceNoDBInit() { 403 static void ForceNoDBInit() {
387 force_nodb_init_ = true; 404 force_nodb_init_ = true;
388 } 405 }
389 406
390 private: 407 private:
391 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; 408 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>;
392 409
393 NSSInitSingleton() 410 NSSInitSingleton()
394 : chaps_module_(NULL), 411 : tpm_token_enabled_for_nss_(false),
412 chaps_module_(NULL),
395 software_slot_(NULL), 413 software_slot_(NULL),
396 test_slot_(NULL), 414 test_slot_(NULL),
397 tpm_slot_(NULL), 415 tpm_slot_(NULL),
398 root_(NULL), 416 root_(NULL),
399 chromeos_user_logged_in_(false), 417 chromeos_user_logged_in_(false) {
400 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
401 EnsureNSPRInit(); 418 EnsureNSPRInit();
402 419
403 // We *must* have NSS >= 3.12.3. See bug 26448. 420 // We *must* have NSS >= 3.12.3. See bug 26448.
404 COMPILE_ASSERT( 421 COMPILE_ASSERT(
405 (NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH >= 3) || 422 (NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH >= 3) ||
406 (NSS_VMAJOR == 3 && NSS_VMINOR > 12) || 423 (NSS_VMAJOR == 3 && NSS_VMINOR > 12) ||
407 (NSS_VMAJOR > 3), 424 (NSS_VMAJOR > 3),
408 nss_version_check_failed); 425 nss_version_check_failed);
409 // Also check the run-time NSS version. 426 // Also check the run-time NSS version.
410 // NSS_VersionCheck is a >= check, not strict equality. 427 // NSS_VersionCheck is a >= check, not strict equality.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 } 531 }
515 532
516 SECStatus status = NSS_Shutdown(); 533 SECStatus status = NSS_Shutdown();
517 if (status != SECSuccess) { 534 if (status != SECSuccess) {
518 // We VLOG(1) because this failure is relatively harmless (leaking, but 535 // We VLOG(1) because this failure is relatively harmless (leaking, but
519 // we're shutting down anyway). 536 // we're shutting down anyway).
520 VLOG(1) << "NSS_Shutdown failed; see http://crbug.com/4609"; 537 VLOG(1) << "NSS_Shutdown failed; see http://crbug.com/4609";
521 } 538 }
522 } 539 }
523 540
524 #if defined(OS_CHROMEOS)
525 // This method is used to implement InitializeTPMToken.
526 void InitializeTPMTokenInternal(InitializeTPMTokenCallback callback,
527 bool is_token_ready) {
528 if (is_token_ready) {
529 // This tries to load the Chaps module so NSS can talk to the hardware
530 // TPM.
531 if (!chaps_module_) {
532 chaps_module_ = LoadModule(
533 kChapsModuleName,
534 kChapsPath,
535 // For more details on these parameters, see:
536 // https://developer.mozilla.org/en/PKCS11_Module_Specs
537 // slotFlags=[PublicCerts] -- Certificates and public keys can be
538 // read from this slot without requiring a call to C_Login.
539 // askpw=only -- Only authenticate to the token when necessary.
540 "NSS=\"slotParams=(0={slotFlags=[PublicCerts] askpw=only})\"");
541 }
542 if (chaps_module_) {
543 // If this gets set, then we'll use the TPM for certs with
544 // private keys, otherwise we'll fall back to the software
545 // implementation.
546 tpm_slot_ = GetTPMSlot();
547
548 callback.Run(tpm_slot_ != NULL);
549 return;
550 }
551 }
552 callback.Run(false);
553 }
554 #endif // defined(OS_CHROMEOS)
555
556 #if defined(USE_NSS) 541 #if defined(USE_NSS)
557 // Load nss's built-in root certs. 542 // Load nss's built-in root certs.
558 SECMODModule* InitDefaultRootCerts() { 543 SECMODModule* InitDefaultRootCerts() {
559 SECMODModule* root = LoadModule("Root Certs", "libnssckbi.so", NULL); 544 SECMODModule* root = LoadModule("Root Certs", "libnssckbi.so", NULL);
560 if (root) 545 if (root)
561 return root; 546 return root;
562 547
563 // Aw, snap. Can't find/load root cert shared library. 548 // Aw, snap. Can't find/load root cert shared library.
564 // This will make it hard to talk to anybody via https. 549 // This will make it hard to talk to anybody via https.
565 NOTREACHED(); 550 NOTREACHED();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 else { 587 else {
603 LOG(ERROR) << "Error opening persistent database (" << modspec 588 LOG(ERROR) << "Error opening persistent database (" << modspec
604 << "): " << GetNSSErrorMessage(); 589 << "): " << GetNSSErrorMessage();
605 } 590 }
606 return db_slot; 591 return db_slot;
607 } 592 }
608 593
609 // If this is set to true NSS is forced to be initialized without a DB. 594 // If this is set to true NSS is forced to be initialized without a DB.
610 static bool force_nodb_init_; 595 static bool force_nodb_init_;
611 596
612 #if defined(OS_CHROMEOS) 597 bool tpm_token_enabled_for_nss_;
613 scoped_ptr<TPMTokenInfoDelegate> tpm_token_info_delegate_; 598 std::string tpm_token_name_;
614 #endif 599 std::string tpm_user_pin_;
615
616 SECMODModule* chaps_module_; 600 SECMODModule* chaps_module_;
617 PK11SlotInfo* software_slot_; 601 PK11SlotInfo* software_slot_;
618 PK11SlotInfo* test_slot_; 602 PK11SlotInfo* test_slot_;
619 PK11SlotInfo* tpm_slot_; 603 PK11SlotInfo* tpm_slot_;
620 SECMODModule* root_; 604 SECMODModule* root_;
621 bool chromeos_user_logged_in_; 605 bool chromeos_user_logged_in_;
622 base::WeakPtrFactory<NSSInitSingleton> weak_ptr_factory_;
623 #if defined(USE_NSS) 606 #if defined(USE_NSS)
624 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 607 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011
625 // is fixed, we will no longer need the lock. 608 // is fixed, we will no longer need the lock.
626 base::Lock write_lock_; 609 base::Lock write_lock_;
627 #endif // defined(USE_NSS) 610 #endif // defined(USE_NSS)
628 }; 611 };
629 612
630 // static 613 // static
631 bool NSSInitSingleton::force_nodb_init_ = false; 614 bool NSSInitSingleton::force_nodb_init_ = false;
632 615
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 SECMOD_ReleaseReadLock(lock_); 729 SECMOD_ReleaseReadLock(lock_);
747 } 730 }
748 731
749 #endif // defined(USE_NSS) 732 #endif // defined(USE_NSS)
750 733
751 #if defined(OS_CHROMEOS) 734 #if defined(OS_CHROMEOS)
752 void OpenPersistentNSSDB() { 735 void OpenPersistentNSSDB() {
753 g_nss_singleton.Get().OpenPersistentNSSDB(); 736 g_nss_singleton.Get().OpenPersistentNSSDB();
754 } 737 }
755 738
756 TPMTokenInfoDelegate::TPMTokenInfoDelegate() {} 739 void EnableTPMTokenForNSS() {
757 TPMTokenInfoDelegate::~TPMTokenInfoDelegate() {} 740 g_nss_singleton.Get().EnableTPMTokenForNSS();
758
759 void EnableTPMTokenForNSS(TPMTokenInfoDelegate* info_delegate) {
760 g_nss_singleton.Get().EnableTPMTokenForNSS(info_delegate);
761 } 741 }
762 742
763 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { 743 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) {
764 g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin); 744 g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin);
765 } 745 }
766 746
767 bool IsTPMTokenReady() { 747 bool IsTPMTokenReady() {
768 return g_nss_singleton.Get().IsTPMTokenReady(); 748 return g_nss_singleton.Get().IsTPMTokenReady();
769 } 749 }
770 750
771 void InitializeTPMToken(InitializeTPMTokenCallback callback) { 751 bool InitializeTPMToken(const std::string& token_name,
772 g_nss_singleton.Get().InitializeTPMToken(callback); 752 const std::string& user_pin) {
753 return g_nss_singleton.Get().InitializeTPMToken(token_name, user_pin);
773 } 754 }
774 755
775 SymmetricKey* GetSupplementalUserKey() { 756 SymmetricKey* GetSupplementalUserKey() {
776 return g_nss_singleton.Get().GetSupplementalUserKey(); 757 return g_nss_singleton.Get().GetSupplementalUserKey();
777 } 758 }
778 #endif // defined(OS_CHROMEOS) 759 #endif // defined(OS_CHROMEOS)
779 760
780 base::Time PRTimeToBaseTime(PRTime prtime) { 761 base::Time PRTimeToBaseTime(PRTime prtime) {
781 return base::Time::FromInternalValue( 762 return base::Time::FromInternalValue(
782 prtime + base::Time::UnixEpoch().ToInternalValue()); 763 prtime + base::Time::UnixEpoch().ToInternalValue());
783 } 764 }
784 765
785 PRTime BaseTimeToPRTime(base::Time time) { 766 PRTime BaseTimeToPRTime(base::Time time) {
786 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); 767 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue();
787 } 768 }
788 769
789 PK11SlotInfo* GetPublicNSSKeySlot() { 770 PK11SlotInfo* GetPublicNSSKeySlot() {
790 return g_nss_singleton.Get().GetPublicNSSKeySlot(); 771 return g_nss_singleton.Get().GetPublicNSSKeySlot();
791 } 772 }
792 773
793 PK11SlotInfo* GetPrivateNSSKeySlot() { 774 PK11SlotInfo* GetPrivateNSSKeySlot() {
794 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); 775 return g_nss_singleton.Get().GetPrivateNSSKeySlot();
795 } 776 }
796 777
797 } // namespace crypto 778 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/nss_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698