OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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> |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #include "crypto/crypto_module_blocking_password_delegate.h" | 48 #include "crypto/crypto_module_blocking_password_delegate.h" |
49 #endif // defined(USE_NSS) | 49 #endif // defined(USE_NSS) |
50 | 50 |
51 namespace crypto { | 51 namespace crypto { |
52 | 52 |
53 namespace { | 53 namespace { |
54 | 54 |
55 #if defined(OS_CHROMEOS) | 55 #if defined(OS_CHROMEOS) |
56 const char kNSSDatabaseName[] = "Real NSS database"; | 56 const char kNSSDatabaseName[] = "Real NSS database"; |
57 | 57 |
58 // Constants for loading opencryptoki. | 58 // Constants for loading the Chrome OS TPM-backed PKCS #11 library. |
59 const char kOpencryptokiModuleName[] = "opencryptoki"; | 59 const char kChapsModuleName[] = "Chaps"; |
60 const char kOpencryptokiPath[] = "/usr/lib/opencryptoki/libopencryptoki.so"; | 60 const char kChapsPath[] = "libchaps.so"; |
61 | 61 |
62 // Fake certificate authority database used for testing. | 62 // Fake certificate authority database used for testing. |
63 static const FilePath::CharType kReadOnlyCertDB[] = | 63 static const FilePath::CharType kReadOnlyCertDB[] = |
64 FILE_PATH_LITERAL("/etc/fake_root_ca/nssdb"); | 64 FILE_PATH_LITERAL("/etc/fake_root_ca/nssdb"); |
65 #endif // defined(OS_CHROMEOS) | 65 #endif // defined(OS_CHROMEOS) |
66 | 66 |
67 std::string GetNSSErrorMessage() { | 67 std::string GetNSSErrorMessage() { |
68 std::string result; | 68 std::string result; |
69 if (PR_GetErrorTextLength()) { | 69 if (PR_GetErrorTextLength()) { |
70 scoped_array<char> error_text(new char[PR_GetErrorTextLength() + 1]); | 70 scoped_array<char> error_text(new char[PR_GetErrorTextLength() + 1]); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), | 238 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), |
239 kNSSDatabaseName); | 239 kNSSDatabaseName); |
240 } | 240 } |
241 } | 241 } |
242 | 242 |
243 void EnableTPMTokenForNSS(TPMTokenInfoDelegate* info_delegate) { | 243 void EnableTPMTokenForNSS(TPMTokenInfoDelegate* info_delegate) { |
244 CHECK(info_delegate); | 244 CHECK(info_delegate); |
245 tpm_token_info_delegate_.reset(info_delegate); | 245 tpm_token_info_delegate_.reset(info_delegate); |
246 } | 246 } |
247 | 247 |
248 // This is called whenever we want to make sure opencryptoki is | 248 // This is called whenever we want to make sure Chaps is |
249 // properly loaded, because it can fail shortly after the initial | 249 // properly loaded, because it can fail shortly after the initial |
250 // login while the PINs are being initialized, and we want to retry | 250 // login while the PINs are being initialized, and we want to retry |
251 // if this happens. | 251 // if this happens. |
252 bool EnsureTPMTokenReady() { | 252 bool EnsureTPMTokenReady() { |
253 // If EnableTPMTokenForNSS hasn't been called, return false. | 253 // If EnableTPMTokenForNSS hasn't been called, return false. |
254 if (tpm_token_info_delegate_.get() == NULL) | 254 if (tpm_token_info_delegate_.get() == NULL) |
255 return false; | 255 return false; |
256 | 256 |
257 // If everything is already initialized, then return true. | 257 // If everything is already initialized, then return true. |
258 if (opencryptoki_module_ && tpm_slot_) | 258 if (chaps_module_ && tpm_slot_) |
259 return true; | 259 return true; |
260 | 260 |
261 if (tpm_token_info_delegate_->IsTokenReady()) { | 261 if (tpm_token_info_delegate_->IsTokenReady()) { |
262 // This tries to load the opencryptoki module so NSS can talk to | 262 // This tries to load the Chaps module so NSS can talk to the hardware |
263 // the hardware TPM. | 263 // TPM. |
264 if (!opencryptoki_module_) { | 264 if (!chaps_module_) { |
265 opencryptoki_module_ = LoadModule( | 265 chaps_module_ = LoadModule( |
266 kOpencryptokiModuleName, | 266 kChapsModuleName, |
267 kOpencryptokiPath, | 267 kChapsPath, |
268 // trustOrder=100 -- means it'll select this as the most | 268 // trustOrder=100 -- means it'll select this as the most |
269 // trusted slot for the mechanisms it provides. | 269 // trusted slot for the mechanisms it provides. |
270 // slotParams=... -- selects RSA as the only mechanism, and only | 270 // slotParams=... -- selects RSA as the only mechanism, and only |
271 // asks for the password when necessary (instead of every | 271 // asks for the password when necessary (instead of every |
272 // time, or after a timeout). | 272 // time, or after a timeout). |
273 "trustOrder=100 slotParams=(1={slotFlags=[RSA] askpw=only})"); | 273 "trustOrder=100 slotParams=(1={slotFlags=[RSA] askpw=only})"); |
274 } | 274 } |
275 if (opencryptoki_module_) { | 275 if (chaps_module_) { |
276 // If this gets set, then we'll use the TPM for certs with | 276 // If this gets set, then we'll use the TPM for certs with |
277 // private keys, otherwise we'll fall back to the software | 277 // private keys, otherwise we'll fall back to the software |
278 // implementation. | 278 // implementation. |
279 tpm_slot_ = GetTPMSlot(); | 279 tpm_slot_ = GetTPMSlot(); |
280 return tpm_slot_ != NULL; | 280 return tpm_slot_ != NULL; |
281 } | 281 } |
282 } | 282 } |
283 return false; | 283 return false; |
284 } | 284 } |
285 | 285 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 return PK11_ReferenceSlot(software_slot_); | 366 return PK11_ReferenceSlot(software_slot_); |
367 return PK11_GetInternalKeySlot(); | 367 return PK11_GetInternalKeySlot(); |
368 } | 368 } |
369 | 369 |
370 PK11SlotInfo* GetPrivateNSSKeySlot() { | 370 PK11SlotInfo* GetPrivateNSSKeySlot() { |
371 if (test_slot_) | 371 if (test_slot_) |
372 return PK11_ReferenceSlot(test_slot_); | 372 return PK11_ReferenceSlot(test_slot_); |
373 | 373 |
374 #if defined(OS_CHROMEOS) | 374 #if defined(OS_CHROMEOS) |
375 // Make sure that if EnableTPMTokenForNSS has been called that we | 375 // Make sure that if EnableTPMTokenForNSS has been called that we |
376 // have successfully loaded opencryptoki. | 376 // have successfully loaded Chaps. |
377 if (tpm_token_info_delegate_.get() != NULL) { | 377 if (tpm_token_info_delegate_.get() != NULL) { |
378 if (EnsureTPMTokenReady()) { | 378 if (EnsureTPMTokenReady()) { |
379 return PK11_ReferenceSlot(tpm_slot_); | 379 return PK11_ReferenceSlot(tpm_slot_); |
380 } else { | 380 } else { |
381 // If we were supposed to get the hardware token, but were | 381 // If we were supposed to get the hardware token, but were |
382 // unable to, return NULL rather than fall back to sofware. | 382 // unable to, return NULL rather than fall back to sofware. |
383 return NULL; | 383 return NULL; |
384 } | 384 } |
385 } | 385 } |
386 #endif | 386 #endif |
(...skipping 13 matching lines...) Expand all Loading... |
400 // This method is used to force NSS to be initialized without a DB. | 400 // This method is used to force NSS to be initialized without a DB. |
401 // Call this method before NSSInitSingleton() is constructed. | 401 // Call this method before NSSInitSingleton() is constructed. |
402 static void ForceNoDBInit() { | 402 static void ForceNoDBInit() { |
403 force_nodb_init_ = true; | 403 force_nodb_init_ = true; |
404 } | 404 } |
405 | 405 |
406 private: | 406 private: |
407 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; | 407 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; |
408 | 408 |
409 NSSInitSingleton() | 409 NSSInitSingleton() |
410 : opencryptoki_module_(NULL), | 410 : chaps_module_(NULL), |
411 software_slot_(NULL), | 411 software_slot_(NULL), |
412 test_slot_(NULL), | 412 test_slot_(NULL), |
413 tpm_slot_(NULL), | 413 tpm_slot_(NULL), |
414 root_(NULL), | 414 root_(NULL), |
415 chromeos_user_logged_in_(false) { | 415 chromeos_user_logged_in_(false) { |
416 EnsureNSPRInit(); | 416 EnsureNSPRInit(); |
417 | 417 |
418 // We *must* have NSS >= 3.12.3. See bug 26448. | 418 // We *must* have NSS >= 3.12.3. See bug 26448. |
419 COMPILE_ASSERT( | 419 COMPILE_ASSERT( |
420 (NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH >= 3) || | 420 (NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH >= 3) || |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 SECMOD_CloseUserDB(software_slot_); | 515 SECMOD_CloseUserDB(software_slot_); |
516 PK11_FreeSlot(software_slot_); | 516 PK11_FreeSlot(software_slot_); |
517 software_slot_ = NULL; | 517 software_slot_ = NULL; |
518 } | 518 } |
519 CloseTestNSSDB(); | 519 CloseTestNSSDB(); |
520 if (root_) { | 520 if (root_) { |
521 SECMOD_UnloadUserModule(root_); | 521 SECMOD_UnloadUserModule(root_); |
522 SECMOD_DestroyModule(root_); | 522 SECMOD_DestroyModule(root_); |
523 root_ = NULL; | 523 root_ = NULL; |
524 } | 524 } |
525 if (opencryptoki_module_) { | 525 if (chaps_module_) { |
526 SECMOD_UnloadUserModule(opencryptoki_module_); | 526 SECMOD_UnloadUserModule(chaps_module_); |
527 SECMOD_DestroyModule(opencryptoki_module_); | 527 SECMOD_DestroyModule(chaps_module_); |
528 opencryptoki_module_ = NULL; | 528 chaps_module_ = NULL; |
529 } | 529 } |
530 | 530 |
531 SECStatus status = NSS_Shutdown(); | 531 SECStatus status = NSS_Shutdown(); |
532 if (status != SECSuccess) { | 532 if (status != SECSuccess) { |
533 // We VLOG(1) because this failure is relatively harmless (leaking, but | 533 // We VLOG(1) because this failure is relatively harmless (leaking, but |
534 // we're shutting down anyway). | 534 // we're shutting down anyway). |
535 VLOG(1) << "NSS_Shutdown failed; see http://crbug.com/4609"; | 535 VLOG(1) << "NSS_Shutdown failed; see http://crbug.com/4609"; |
536 } | 536 } |
537 } | 537 } |
538 | 538 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 return db_slot; | 589 return db_slot; |
590 } | 590 } |
591 | 591 |
592 // If this is set to true NSS is forced to be initialized without a DB. | 592 // If this is set to true NSS is forced to be initialized without a DB. |
593 static bool force_nodb_init_; | 593 static bool force_nodb_init_; |
594 | 594 |
595 #if defined(OS_CHROMEOS) | 595 #if defined(OS_CHROMEOS) |
596 scoped_ptr<TPMTokenInfoDelegate> tpm_token_info_delegate_; | 596 scoped_ptr<TPMTokenInfoDelegate> tpm_token_info_delegate_; |
597 #endif | 597 #endif |
598 | 598 |
599 SECMODModule* opencryptoki_module_; | 599 SECMODModule* chaps_module_; |
600 PK11SlotInfo* software_slot_; | 600 PK11SlotInfo* software_slot_; |
601 PK11SlotInfo* test_slot_; | 601 PK11SlotInfo* test_slot_; |
602 PK11SlotInfo* tpm_slot_; | 602 PK11SlotInfo* tpm_slot_; |
603 SECMODModule* root_; | 603 SECMODModule* root_; |
604 bool chromeos_user_logged_in_; | 604 bool chromeos_user_logged_in_; |
605 #if defined(USE_NSS) | 605 #if defined(USE_NSS) |
606 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 | 606 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 |
607 // is fixed, we will no longer need the lock. | 607 // is fixed, we will no longer need the lock. |
608 base::Lock write_lock_; | 608 base::Lock write_lock_; |
609 #endif // defined(USE_NSS) | 609 #endif // defined(USE_NSS) |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 | 790 |
791 PK11SlotInfo* GetPublicNSSKeySlot() { | 791 PK11SlotInfo* GetPublicNSSKeySlot() { |
792 return g_nss_singleton.Get().GetPublicNSSKeySlot(); | 792 return g_nss_singleton.Get().GetPublicNSSKeySlot(); |
793 } | 793 } |
794 | 794 |
795 PK11SlotInfo* GetPrivateNSSKeySlot() { | 795 PK11SlotInfo* GetPrivateNSSKeySlot() { |
796 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); | 796 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); |
797 } | 797 } |
798 | 798 |
799 } // namespace crypto | 799 } // namespace crypto |
OLD | NEW |