| 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 |