Chromium Code Reviews| OLD | NEW |
|---|---|
| 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> |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 scoped_ptr<char[]> error_text(new char[PR_GetErrorTextLength() + 1]); | 74 scoped_ptr<char[]> error_text(new char[PR_GetErrorTextLength() + 1]); |
| 75 PRInt32 copied = PR_GetErrorText(error_text.get()); | 75 PRInt32 copied = PR_GetErrorText(error_text.get()); |
| 76 result = std::string(error_text.get(), copied); | 76 result = std::string(error_text.get(), copied); |
| 77 } else { | 77 } else { |
| 78 result = base::StringPrintf("NSS error code: %d", PR_GetError()); | 78 result = base::StringPrintf("NSS error code: %d", PR_GetError()); |
| 79 } | 79 } |
| 80 return result; | 80 return result; |
| 81 } | 81 } |
| 82 | 82 |
| 83 #if defined(USE_NSS) | 83 #if defined(USE_NSS) |
| 84 #if !defined(OS_CHROMEOS) | |
| 84 base::FilePath GetDefaultConfigDirectory() { | 85 base::FilePath GetDefaultConfigDirectory() { |
| 85 base::FilePath dir; | 86 base::FilePath dir; |
| 86 PathService::Get(base::DIR_HOME, &dir); | 87 PathService::Get(base::DIR_HOME, &dir); |
| 87 if (dir.empty()) { | 88 if (dir.empty()) { |
| 88 LOG(ERROR) << "Failed to get home directory."; | 89 LOG(ERROR) << "Failed to get home directory."; |
| 89 return dir; | 90 return dir; |
| 90 } | 91 } |
| 91 dir = dir.AppendASCII(".pki").AppendASCII("nssdb"); | 92 dir = dir.AppendASCII(".pki").AppendASCII("nssdb"); |
| 92 if (!base::CreateDirectory(dir)) { | 93 if (!base::CreateDirectory(dir)) { |
| 93 LOG(ERROR) << "Failed to create " << dir.value() << " directory."; | 94 LOG(ERROR) << "Failed to create " << dir.value() << " directory."; |
| 94 dir.clear(); | 95 dir.clear(); |
| 95 } | 96 } |
| 96 DVLOG(2) << "DefaultConfigDirectory: " << dir.value(); | 97 DVLOG(2) << "DefaultConfigDirectory: " << dir.value(); |
| 97 return dir; | 98 return dir; |
| 98 } | 99 } |
| 100 #endif // !defined(IS_CHROMEOS) | |
| 99 | 101 |
| 100 // On non-Chrome OS platforms, return the default config directory. On Chrome OS | 102 // On non-Chrome OS platforms, return the default config directory. On Chrome OS |
| 101 // test images, return a read-only directory with fake root CA certs (which are | 103 // test images, return a read-only directory with fake root CA certs (which are |
| 102 // used by the local Google Accounts server mock we use when testing our login | 104 // used by the local Google Accounts server mock we use when testing our login |
| 103 // code). On Chrome OS non-test images (where the read-only directory doesn't | 105 // code). On Chrome OS non-test images (where the read-only directory doesn't |
| 104 // exist), return an empty path. | 106 // exist), return an empty path. |
| 105 base::FilePath GetInitialConfigDirectory() { | 107 base::FilePath GetInitialConfigDirectory() { |
| 106 #if defined(OS_CHROMEOS) | 108 #if defined(OS_CHROMEOS) |
| 107 base::FilePath database_dir = base::FilePath(kReadOnlyCertDB); | 109 base::FilePath database_dir = base::FilePath(kReadOnlyCertDB); |
| 108 if (!base::PathExists(database_dir)) | 110 if (!base::PathExists(database_dir)) |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 209 base::debug::Alias(&nss_error); | 211 base::debug::Alias(&nss_error); |
| 210 base::debug::Alias(&os_error); | 212 base::debug::Alias(&os_error); |
| 211 LOG(ERROR) << "Error initializing NSS without a persistent database: " | 213 LOG(ERROR) << "Error initializing NSS without a persistent database: " |
| 212 << GetNSSErrorMessage(); | 214 << GetNSSErrorMessage(); |
| 213 LOG(FATAL) << "nss_error=" << nss_error << ", os_error=" << os_error; | 215 LOG(FATAL) << "nss_error=" << nss_error << ", os_error=" << os_error; |
| 214 } | 216 } |
| 215 | 217 |
| 216 #if defined(OS_CHROMEOS) | 218 #if defined(OS_CHROMEOS) |
| 217 class ChromeOSUserData { | 219 class ChromeOSUserData { |
| 218 public: | 220 public: |
| 219 ChromeOSUserData(ScopedPK11Slot public_slot, bool is_primary_user) | 221 ChromeOSUserData(ScopedPK11Slot public_slot, bool provisional) |
| 220 : public_slot_(public_slot.Pass()), | 222 : public_slot_(public_slot.Pass()), |
| 221 is_primary_user_(is_primary_user) {} | 223 provisional_(provisional) {} |
| 222 ~ChromeOSUserData() { | 224 ~ChromeOSUserData() { |
| 223 if (public_slot_ && !is_primary_user_) { | 225 if (public_slot_) { |
| 224 SECStatus status = SECMOD_CloseUserDB(public_slot_.get()); | 226 SECStatus status = SECMOD_CloseUserDB(public_slot_.get()); |
| 225 if (status != SECSuccess) | 227 if (status != SECSuccess) |
| 226 PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError(); | 228 PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError(); |
| 227 } | 229 } |
| 228 } | 230 } |
| 229 | 231 |
| 230 ScopedPK11Slot GetPublicSlot() { | 232 ScopedPK11Slot GetPublicSlot() { |
| 231 return ScopedPK11Slot( | 233 return ScopedPK11Slot( |
| 232 public_slot_ ? PK11_ReferenceSlot(public_slot_.get()) : NULL); | 234 !provisional_ && public_slot_ ? |
| 235 PK11_ReferenceSlot(public_slot_.get()) : | |
| 236 NULL); | |
| 233 } | 237 } |
| 234 | 238 |
| 235 ScopedPK11Slot GetPrivateSlot( | 239 ScopedPK11Slot GetPrivateSlot( |
| 236 const base::Callback<void(ScopedPK11Slot)>& callback) { | 240 const base::Callback<void(ScopedPK11Slot)>& callback) { |
| 237 if (private_slot_) | 241 if (private_slot_ && !provisional_) |
| 238 return ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get())); | 242 return ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get())); |
| 239 if (!callback.is_null()) | 243 if (!callback.is_null()) |
| 240 tpm_ready_callback_list_.push_back(callback); | 244 tpm_ready_callback_list_.push_back(callback); |
| 241 return ScopedPK11Slot(); | 245 return ScopedPK11Slot(); |
| 242 } | 246 } |
| 243 | 247 |
| 244 void SetPrivateSlot(ScopedPK11Slot private_slot) { | 248 void SetPrivateSlot(ScopedPK11Slot private_slot) { |
| 245 DCHECK(!private_slot_); | 249 DCHECK(!private_slot_); |
| 250 DCHECK(!provisional_); | |
| 246 private_slot_ = private_slot.Pass(); | 251 private_slot_ = private_slot.Pass(); |
| 247 | 252 |
| 248 SlotReadyCallbackList callback_list; | 253 SlotReadyCallbackList callback_list; |
| 249 callback_list.swap(tpm_ready_callback_list_); | 254 callback_list.swap(tpm_ready_callback_list_); |
| 250 for (SlotReadyCallbackList::iterator i = callback_list.begin(); | 255 for (SlotReadyCallbackList::iterator i = callback_list.begin(); |
| 251 i != callback_list.end(); | 256 i != callback_list.end(); |
| 252 ++i) { | 257 ++i) { |
| 253 (*i).Run(ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get()))); | 258 (*i).Run(ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get()))); |
| 254 } | 259 } |
| 255 } | 260 } |
| 256 | 261 |
| 262 bool provisional() { return provisional_; } | |
| 263 | |
| 264 void set_provisional(bool value) { provisional_ = value; } | |
| 265 | |
| 257 private: | 266 private: |
| 258 ScopedPK11Slot public_slot_; | 267 ScopedPK11Slot public_slot_; |
| 259 ScopedPK11Slot private_slot_; | 268 ScopedPK11Slot private_slot_; |
| 260 bool is_primary_user_; | 269 |
| 270 bool provisional_; | |
| 261 | 271 |
| 262 typedef std::vector<base::Callback<void(ScopedPK11Slot)> > | 272 typedef std::vector<base::Callback<void(ScopedPK11Slot)> > |
| 263 SlotReadyCallbackList; | 273 SlotReadyCallbackList; |
| 264 SlotReadyCallbackList tpm_ready_callback_list_; | 274 SlotReadyCallbackList tpm_ready_callback_list_; |
| 265 }; | 275 }; |
| 266 #endif // defined(OS_CHROMEOS) | 276 #endif // defined(OS_CHROMEOS) |
| 267 | 277 |
| 268 class NSSInitSingleton { | 278 class NSSInitSingleton { |
| 269 public: | 279 public: |
| 270 #if defined(OS_CHROMEOS) | 280 #if defined(OS_CHROMEOS) |
| 271 // Used with PostTaskAndReply to pass handles to worker thread and back. | 281 // Used with PostTaskAndReply to pass handles to worker thread and back. |
| 272 struct TPMModuleAndSlot { | 282 struct TPMModuleAndSlot { |
| 273 explicit TPMModuleAndSlot(SECMODModule* init_chaps_module) | 283 explicit TPMModuleAndSlot(SECMODModule* init_chaps_module) |
| 274 : chaps_module(init_chaps_module), tpm_slot(NULL) {} | 284 : chaps_module(init_chaps_module), tpm_slot(NULL) {} |
| 275 SECMODModule* chaps_module; | 285 SECMODModule* chaps_module; |
| 276 PK11SlotInfo* tpm_slot; | 286 PK11SlotInfo* tpm_slot; |
| 277 }; | 287 }; |
| 278 | 288 |
| 279 void OpenPersistentNSSDB() { | |
| 280 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 281 | |
| 282 if (!chromeos_user_logged_in_) { | |
| 283 // GetDefaultConfigDirectory causes us to do blocking IO on UI thread. | |
| 284 // Temporarily allow it until we fix http://crbug.com/70119 | |
| 285 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
| 286 chromeos_user_logged_in_ = true; | |
| 287 | |
| 288 // This creates another DB slot in NSS that is read/write, unlike | |
| 289 // the fake root CA cert DB and the "default" crypto key | |
| 290 // provider, which are still read-only (because we initialized | |
| 291 // NSS before we had a cryptohome mounted). | |
| 292 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), | |
| 293 kNSSDatabaseName); | |
| 294 } | |
| 295 } | |
| 296 | |
| 297 PK11SlotInfo* OpenPersistentNSSDBForPath(const base::FilePath& path) { | 289 PK11SlotInfo* OpenPersistentNSSDBForPath(const base::FilePath& path) { |
| 298 DCHECK(thread_checker_.CalledOnValidThread()); | 290 DCHECK(thread_checker_.CalledOnValidThread()); |
| 299 // NSS is allowed to do IO on the current thread since dispatching | 291 // NSS is allowed to do IO on the current thread since dispatching |
| 300 // to a dedicated thread would still have the affect of blocking | 292 // to a dedicated thread would still have the affect of blocking |
| 301 // the current thread, due to NSS's internal locking requirements | 293 // the current thread, due to NSS's internal locking requirements |
| 302 base::ThreadRestrictions::ScopedAllowIO allow_io; | 294 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 303 | 295 |
| 304 base::FilePath nssdb_path = path.AppendASCII(".pki").AppendASCII("nssdb"); | 296 base::FilePath nssdb_path = path.AppendASCII(".pki").AppendASCII("nssdb"); |
| 305 if (!base::CreateDirectory(nssdb_path)) { | 297 if (!base::CreateDirectory(nssdb_path)) { |
| 306 LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory."; | 298 LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory."; |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 452 | 444 |
| 453 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module->moduleID, slot_id); | 445 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module->moduleID, slot_id); |
| 454 if (!slot) | 446 if (!slot) |
| 455 LOG(ERROR) << "TPM slot " << slot_id << " not found."; | 447 LOG(ERROR) << "TPM slot " << slot_id << " not found."; |
| 456 return slot; | 448 return slot; |
| 457 } | 449 } |
| 458 | 450 |
| 459 bool InitializeNSSForChromeOSUser( | 451 bool InitializeNSSForChromeOSUser( |
| 460 const std::string& email, | 452 const std::string& email, |
| 461 const std::string& username_hash, | 453 const std::string& username_hash, |
| 462 bool is_primary_user, | 454 const base::FilePath& path, |
| 463 const base::FilePath& path) { | 455 bool provisional) { |
| 464 DCHECK(thread_checker_.CalledOnValidThread()); | 456 DCHECK(thread_checker_.CalledOnValidThread()); |
| 465 if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) { | 457 if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) { |
| 466 // This user already exists in our mapping. | 458 // This user already exists in our mapping. |
| 467 DVLOG(2) << username_hash << " already initialized."; | 459 DVLOG(2) << username_hash << " already initialized."; |
| 460 if (!chromeos_user_map_[username_hash]->provisional()) | |
| 461 return false; | |
| 462 | |
| 463 chromeos_user_map_[username_hash]->set_provisional(provisional); | |
| 464 return true; | |
| 465 } | |
|
Ryan Sleevi
2014/07/01 18:51:33
This logic strikes me as a little weird, as the co
tbarzic
2014/07/01 19:25:39
Yeah, I'm not to content with semantics here.. I n
| |
| 466 | |
| 467 // If test slot is set, slot getter methods will short circuit | |
| 468 // checking |chromeos_user_map_|, so there is nothing left to be | |
| 469 // initialized. | |
| 470 if (test_slot_) | |
| 468 return false; | 471 return false; |
| 469 } | 472 |
| 470 ScopedPK11Slot public_slot; | 473 DVLOG(2) << "Opening NSS DB " << path.value(); |
| 471 if (is_primary_user) { | 474 ScopedPK11Slot public_slot(OpenPersistentNSSDBForPath(path)); |
| 472 DVLOG(2) << "Primary user, using GetPublicNSSKeySlot()"; | |
| 473 public_slot.reset(GetPublicNSSKeySlot()); | |
| 474 } else { | |
| 475 DVLOG(2) << "Opening NSS DB " << path.value(); | |
| 476 public_slot.reset(OpenPersistentNSSDBForPath(path)); | |
| 477 } | |
| 478 chromeos_user_map_[username_hash] = | 475 chromeos_user_map_[username_hash] = |
| 479 new ChromeOSUserData(public_slot.Pass(), is_primary_user); | 476 new ChromeOSUserData(public_slot.Pass(), provisional); |
| 480 return true; | 477 return true; |
| 481 } | 478 } |
| 482 | 479 |
| 483 void InitializeTPMForChromeOSUser(const std::string& username_hash, | 480 void InitializeTPMForChromeOSUser(const std::string& username_hash, |
| 484 CK_SLOT_ID slot_id) { | 481 CK_SLOT_ID slot_id) { |
| 485 DCHECK(thread_checker_.CalledOnValidThread()); | 482 DCHECK(thread_checker_.CalledOnValidThread()); |
| 486 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); | 483 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); |
| 484 DCHECK(!chromeos_user_map_[username_hash]->provisional()); | |
| 487 | 485 |
| 488 if (!chaps_module_) | 486 if (!chaps_module_) |
| 489 return; | 487 return; |
| 490 | 488 |
| 491 // Note that a reference is not taken to chaps_module_. This is safe since | 489 // Note that a reference is not taken to chaps_module_. This is safe since |
| 492 // NSSInitSingleton is Leaky, so the reference it holds is never released. | 490 // NSSInitSingleton is Leaky, so the reference it holds is never released. |
| 493 scoped_ptr<TPMModuleAndSlot> tpm_args(new TPMModuleAndSlot(chaps_module_)); | 491 scoped_ptr<TPMModuleAndSlot> tpm_args(new TPMModuleAndSlot(chaps_module_)); |
| 494 TPMModuleAndSlot* tpm_args_ptr = tpm_args.get(); | 492 TPMModuleAndSlot* tpm_args_ptr = tpm_args.get(); |
| 495 base::WorkerPool::PostTaskAndReply( | 493 base::WorkerPool::PostTaskAndReply( |
| 496 FROM_HERE, | 494 FROM_HERE, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 512 << !!tpm_args->tpm_slot; | 510 << !!tpm_args->tpm_slot; |
| 513 chromeos_user_map_[username_hash]->SetPrivateSlot( | 511 chromeos_user_map_[username_hash]->SetPrivateSlot( |
| 514 ScopedPK11Slot(tpm_args->tpm_slot)); | 512 ScopedPK11Slot(tpm_args->tpm_slot)); |
| 515 } | 513 } |
| 516 | 514 |
| 517 void InitializePrivateSoftwareSlotForChromeOSUser( | 515 void InitializePrivateSoftwareSlotForChromeOSUser( |
| 518 const std::string& username_hash) { | 516 const std::string& username_hash) { |
| 519 DCHECK(thread_checker_.CalledOnValidThread()); | 517 DCHECK(thread_checker_.CalledOnValidThread()); |
| 520 VLOG(1) << "using software private slot for " << username_hash; | 518 VLOG(1) << "using software private slot for " << username_hash; |
| 521 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); | 519 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); |
| 520 DCHECK(!chromeos_user_map_[username_hash]->provisional()); | |
| 522 chromeos_user_map_[username_hash]->SetPrivateSlot( | 521 chromeos_user_map_[username_hash]->SetPrivateSlot( |
| 523 chromeos_user_map_[username_hash]->GetPublicSlot()); | 522 chromeos_user_map_[username_hash]->GetPublicSlot()); |
| 524 } | 523 } |
| 525 | 524 |
| 526 ScopedPK11Slot GetPublicSlotForChromeOSUser( | 525 ScopedPK11Slot GetPublicSlotForChromeOSUser( |
| 527 const std::string& username_hash) { | 526 const std::string& username_hash) { |
| 528 DCHECK(thread_checker_.CalledOnValidThread()); | 527 DCHECK(thread_checker_.CalledOnValidThread()); |
| 529 | 528 |
| 530 if (username_hash.empty()) { | 529 if (username_hash.empty()) { |
| 531 DVLOG(2) << "empty username_hash"; | 530 DVLOG(2) << "empty username_hash"; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 612 | 611 |
| 613 PK11SlotInfo* GetPublicNSSKeySlot() { | 612 PK11SlotInfo* GetPublicNSSKeySlot() { |
| 614 // TODO(mattm): Change to DCHECK when callers have been fixed. | 613 // TODO(mattm): Change to DCHECK when callers have been fixed. |
| 615 if (!thread_checker_.CalledOnValidThread()) { | 614 if (!thread_checker_.CalledOnValidThread()) { |
| 616 DVLOG(1) << "Called on wrong thread.\n" | 615 DVLOG(1) << "Called on wrong thread.\n" |
| 617 << base::debug::StackTrace().ToString(); | 616 << base::debug::StackTrace().ToString(); |
| 618 } | 617 } |
| 619 | 618 |
| 620 if (test_slot_) | 619 if (test_slot_) |
| 621 return PK11_ReferenceSlot(test_slot_); | 620 return PK11_ReferenceSlot(test_slot_); |
| 622 if (software_slot_) | |
| 623 return PK11_ReferenceSlot(software_slot_); | |
| 624 return PK11_GetInternalKeySlot(); | 621 return PK11_GetInternalKeySlot(); |
| 625 } | 622 } |
| 626 | 623 |
| 627 PK11SlotInfo* GetPrivateNSSKeySlot() { | 624 PK11SlotInfo* GetPrivateNSSKeySlot() { |
| 628 // TODO(mattm): Change to DCHECK when callers have been fixed. | 625 // TODO(mattm): Change to DCHECK when callers have been fixed. |
| 629 if (!thread_checker_.CalledOnValidThread()) { | 626 if (!thread_checker_.CalledOnValidThread()) { |
| 630 DVLOG(1) << "Called on wrong thread.\n" | 627 DVLOG(1) << "Called on wrong thread.\n" |
| 631 << base::debug::StackTrace().ToString(); | 628 << base::debug::StackTrace().ToString(); |
| 632 } | 629 } |
| 633 | 630 |
| 634 if (test_slot_) | 631 if (test_slot_) |
| 635 return PK11_ReferenceSlot(test_slot_); | 632 return PK11_ReferenceSlot(test_slot_); |
| 636 | 633 |
| 637 #if defined(OS_CHROMEOS) | 634 #if defined(OS_CHROMEOS) |
| 638 if (tpm_token_enabled_for_nss_) { | 635 if (tpm_token_enabled_for_nss_) { |
| 639 if (IsTPMTokenReady(base::Closure())) { | 636 if (IsTPMTokenReady(base::Closure())) { |
| 640 return PK11_ReferenceSlot(tpm_slot_); | 637 return PK11_ReferenceSlot(tpm_slot_); |
| 641 } else { | 638 } else { |
| 642 // If we were supposed to get the hardware token, but were | 639 // If we were supposed to get the hardware token, but were |
| 643 // unable to, return NULL rather than fall back to sofware. | 640 // unable to, return NULL rather than fall back to sofware. |
| 644 return NULL; | 641 return NULL; |
| 645 } | 642 } |
| 646 } | 643 } |
| 647 #endif | 644 #endif |
| 648 // If we weren't supposed to enable the TPM for NSS, then return | |
| 649 // the software slot. | |
| 650 if (software_slot_) | |
| 651 return PK11_ReferenceSlot(software_slot_); | |
| 652 return PK11_GetInternalKeySlot(); | 645 return PK11_GetInternalKeySlot(); |
| 653 } | 646 } |
| 654 | 647 |
| 655 #if defined(USE_NSS) | 648 #if defined(USE_NSS) |
| 656 base::Lock* write_lock() { | 649 base::Lock* write_lock() { |
| 657 return &write_lock_; | 650 return &write_lock_; |
| 658 } | 651 } |
| 659 #endif // defined(USE_NSS) | 652 #endif // defined(USE_NSS) |
| 660 | 653 |
| 661 // This method is used to force NSS to be initialized without a DB. | 654 // This method is used to force NSS to be initialized without a DB. |
| 662 // Call this method before NSSInitSingleton() is constructed. | 655 // Call this method before NSSInitSingleton() is constructed. |
| 663 static void ForceNoDBInit() { | 656 static void ForceNoDBInit() { |
| 664 force_nodb_init_ = true; | 657 force_nodb_init_ = true; |
| 665 } | 658 } |
| 666 | 659 |
| 667 private: | 660 private: |
| 668 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; | 661 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; |
| 669 | 662 |
| 670 NSSInitSingleton() | 663 NSSInitSingleton() |
| 671 : tpm_token_enabled_for_nss_(false), | 664 : tpm_token_enabled_for_nss_(false), |
| 672 initializing_tpm_token_(false), | 665 initializing_tpm_token_(false), |
| 673 chaps_module_(NULL), | 666 chaps_module_(NULL), |
| 674 software_slot_(NULL), | |
| 675 test_slot_(NULL), | 667 test_slot_(NULL), |
| 676 tpm_slot_(NULL), | 668 tpm_slot_(NULL), |
| 677 root_(NULL), | 669 root_(NULL) { |
| 678 chromeos_user_logged_in_(false) { | |
| 679 base::TimeTicks start_time = base::TimeTicks::Now(); | 670 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 680 | 671 |
| 681 // It's safe to construct on any thread, since LazyInstance will prevent any | 672 // It's safe to construct on any thread, since LazyInstance will prevent any |
| 682 // other threads from accessing until the constructor is done. | 673 // other threads from accessing until the constructor is done. |
| 683 thread_checker_.DetachFromThread(); | 674 thread_checker_.DetachFromThread(); |
| 684 | 675 |
| 685 DisableAESNIIfNeeded(); | 676 DisableAESNIIfNeeded(); |
| 686 | 677 |
| 687 EnsureNSPRInit(); | 678 EnsureNSPRInit(); |
| 688 | 679 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 788 // prevent non-joinable threads from using NSS after it's already been shut | 779 // prevent non-joinable threads from using NSS after it's already been shut |
| 789 // down. | 780 // down. |
| 790 ~NSSInitSingleton() { | 781 ~NSSInitSingleton() { |
| 791 #if defined(OS_CHROMEOS) | 782 #if defined(OS_CHROMEOS) |
| 792 STLDeleteValues(&chromeos_user_map_); | 783 STLDeleteValues(&chromeos_user_map_); |
| 793 #endif | 784 #endif |
| 794 if (tpm_slot_) { | 785 if (tpm_slot_) { |
| 795 PK11_FreeSlot(tpm_slot_); | 786 PK11_FreeSlot(tpm_slot_); |
| 796 tpm_slot_ = NULL; | 787 tpm_slot_ = NULL; |
| 797 } | 788 } |
| 798 if (software_slot_) { | |
| 799 SECMOD_CloseUserDB(software_slot_); | |
| 800 PK11_FreeSlot(software_slot_); | |
| 801 software_slot_ = NULL; | |
| 802 } | |
| 803 CloseTestNSSDB(); | 789 CloseTestNSSDB(); |
| 804 if (root_) { | 790 if (root_) { |
| 805 SECMOD_UnloadUserModule(root_); | 791 SECMOD_UnloadUserModule(root_); |
| 806 SECMOD_DestroyModule(root_); | 792 SECMOD_DestroyModule(root_); |
| 807 root_ = NULL; | 793 root_ = NULL; |
| 808 } | 794 } |
| 809 if (chaps_module_) { | 795 if (chaps_module_) { |
| 810 SECMOD_UnloadUserModule(chaps_module_); | 796 SECMOD_UnloadUserModule(chaps_module_); |
| 811 SECMOD_DestroyModule(chaps_module_); | 797 SECMOD_DestroyModule(chaps_module_); |
| 812 chaps_module_ = NULL; | 798 chaps_module_ = NULL; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 895 } | 881 } |
| 896 | 882 |
| 897 // If this is set to true NSS is forced to be initialized without a DB. | 883 // If this is set to true NSS is forced to be initialized without a DB. |
| 898 static bool force_nodb_init_; | 884 static bool force_nodb_init_; |
| 899 | 885 |
| 900 bool tpm_token_enabled_for_nss_; | 886 bool tpm_token_enabled_for_nss_; |
| 901 bool initializing_tpm_token_; | 887 bool initializing_tpm_token_; |
| 902 typedef std::vector<base::Closure> TPMReadyCallbackList; | 888 typedef std::vector<base::Closure> TPMReadyCallbackList; |
| 903 TPMReadyCallbackList tpm_ready_callback_list_; | 889 TPMReadyCallbackList tpm_ready_callback_list_; |
| 904 SECMODModule* chaps_module_; | 890 SECMODModule* chaps_module_; |
| 905 PK11SlotInfo* software_slot_; | |
| 906 PK11SlotInfo* test_slot_; | 891 PK11SlotInfo* test_slot_; |
| 907 PK11SlotInfo* tpm_slot_; | 892 PK11SlotInfo* tpm_slot_; |
| 908 SECMODModule* root_; | 893 SECMODModule* root_; |
| 909 bool chromeos_user_logged_in_; | |
| 910 #if defined(OS_CHROMEOS) | 894 #if defined(OS_CHROMEOS) |
| 911 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap; | 895 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap; |
| 912 ChromeOSUserMap chromeos_user_map_; | 896 ChromeOSUserMap chromeos_user_map_; |
| 913 #endif | 897 #endif |
| 914 #if defined(USE_NSS) | 898 #if defined(USE_NSS) |
| 915 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 | 899 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 |
| 916 // is fixed, we will no longer need the lock. | 900 // is fixed, we will no longer need the lock. |
| 917 base::Lock write_lock_; | 901 base::Lock write_lock_; |
| 918 #endif // defined(USE_NSS) | 902 #endif // defined(USE_NSS) |
| 919 | 903 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1063 SECMOD_GetReadLock(lock_); | 1047 SECMOD_GetReadLock(lock_); |
| 1064 } | 1048 } |
| 1065 | 1049 |
| 1066 AutoSECMODListReadLock::~AutoSECMODListReadLock() { | 1050 AutoSECMODListReadLock::~AutoSECMODListReadLock() { |
| 1067 SECMOD_ReleaseReadLock(lock_); | 1051 SECMOD_ReleaseReadLock(lock_); |
| 1068 } | 1052 } |
| 1069 | 1053 |
| 1070 #endif // defined(USE_NSS) | 1054 #endif // defined(USE_NSS) |
| 1071 | 1055 |
| 1072 #if defined(OS_CHROMEOS) | 1056 #if defined(OS_CHROMEOS) |
| 1073 void OpenPersistentNSSDB() { | |
| 1074 g_nss_singleton.Get().OpenPersistentNSSDB(); | |
| 1075 } | |
| 1076 | |
| 1077 void EnableTPMTokenForNSS() { | 1057 void EnableTPMTokenForNSS() { |
| 1078 g_nss_singleton.Get().EnableTPMTokenForNSS(); | 1058 g_nss_singleton.Get().EnableTPMTokenForNSS(); |
| 1079 } | 1059 } |
| 1080 | 1060 |
| 1081 bool IsTPMTokenEnabledForNSS() { | 1061 bool IsTPMTokenEnabledForNSS() { |
| 1082 return g_nss_singleton.Get().IsTPMTokenEnabledForNSS(); | 1062 return g_nss_singleton.Get().IsTPMTokenEnabledForNSS(); |
| 1083 } | 1063 } |
| 1084 | 1064 |
| 1085 bool IsTPMTokenReady(const base::Closure& callback) { | 1065 bool IsTPMTokenReady(const base::Closure& callback) { |
| 1086 return g_nss_singleton.Get().IsTPMTokenReady(callback); | 1066 return g_nss_singleton.Get().IsTPMTokenReady(callback); |
| 1087 } | 1067 } |
| 1088 | 1068 |
| 1089 void InitializeTPMToken(int token_slot_id, | 1069 void InitializeTPMToken(int token_slot_id, |
| 1090 const base::Callback<void(bool)>& callback) { | 1070 const base::Callback<void(bool)>& callback) { |
| 1091 g_nss_singleton.Get().InitializeTPMToken(token_slot_id, callback); | 1071 g_nss_singleton.Get().InitializeTPMToken(token_slot_id, callback); |
| 1092 } | 1072 } |
| 1093 | 1073 |
| 1094 ScopedTestNSSChromeOSUser::ScopedTestNSSChromeOSUser( | 1074 ScopedTestNSSChromeOSUser::ScopedTestNSSChromeOSUser( |
| 1095 const std::string& username_hash) | 1075 const std::string& username_hash) |
| 1096 : username_hash_(username_hash), constructed_successfully_(false) { | 1076 : username_hash_(username_hash), constructed_successfully_(false) { |
| 1097 if (!temp_dir_.CreateUniqueTempDir()) | 1077 if (!temp_dir_.CreateUniqueTempDir()) |
| 1098 return; | 1078 return; |
| 1099 constructed_successfully_ = | 1079 constructed_successfully_ = |
| 1100 InitializeNSSForChromeOSUser(username_hash, | 1080 InitializeNSSForChromeOSUser(username_hash, |
| 1101 username_hash, | 1081 username_hash, |
| 1102 false /* is_primary_user */, | 1082 temp_dir_.path(), |
| 1103 temp_dir_.path()); | 1083 false /* not provisional */); |
| 1104 } | 1084 } |
| 1105 | 1085 |
| 1106 ScopedTestNSSChromeOSUser::~ScopedTestNSSChromeOSUser() { | 1086 ScopedTestNSSChromeOSUser::~ScopedTestNSSChromeOSUser() { |
| 1107 if (constructed_successfully_) | 1087 if (constructed_successfully_) |
| 1108 g_nss_singleton.Get().CloseTestChromeOSUser(username_hash_); | 1088 g_nss_singleton.Get().CloseTestChromeOSUser(username_hash_); |
| 1109 } | 1089 } |
| 1110 | 1090 |
| 1111 void ScopedTestNSSChromeOSUser::FinishInit() { | 1091 void ScopedTestNSSChromeOSUser::FinishInit() { |
| 1112 InitializePrivateSoftwareSlotForChromeOSUser(username_hash_); | 1092 InitializePrivateSoftwareSlotForChromeOSUser(username_hash_); |
| 1113 } | 1093 } |
| 1114 | 1094 |
| 1115 bool InitializeNSSForChromeOSUser( | 1095 bool InitializeNSSForChromeOSUser( |
| 1116 const std::string& email, | 1096 const std::string& email, |
| 1117 const std::string& username_hash, | 1097 const std::string& username_hash, |
| 1118 bool is_primary_user, | 1098 const base::FilePath& path, |
| 1119 const base::FilePath& path) { | 1099 bool provisional) { |
| 1120 return g_nss_singleton.Get().InitializeNSSForChromeOSUser( | 1100 return g_nss_singleton.Get().InitializeNSSForChromeOSUser( |
| 1121 email, username_hash, is_primary_user, path); | 1101 email, username_hash, path, provisional); |
| 1122 } | 1102 } |
| 1123 void InitializeTPMForChromeOSUser( | 1103 void InitializeTPMForChromeOSUser( |
| 1124 const std::string& username_hash, | 1104 const std::string& username_hash, |
| 1125 CK_SLOT_ID slot_id) { | 1105 CK_SLOT_ID slot_id) { |
| 1126 g_nss_singleton.Get().InitializeTPMForChromeOSUser(username_hash, slot_id); | 1106 g_nss_singleton.Get().InitializeTPMForChromeOSUser(username_hash, slot_id); |
| 1127 } | 1107 } |
| 1128 void InitializePrivateSoftwareSlotForChromeOSUser( | 1108 void InitializePrivateSoftwareSlotForChromeOSUser( |
| 1129 const std::string& username_hash) { | 1109 const std::string& username_hash) { |
| 1130 g_nss_singleton.Get().InitializePrivateSoftwareSlotForChromeOSUser( | 1110 g_nss_singleton.Get().InitializePrivateSoftwareSlotForChromeOSUser( |
| 1131 username_hash); | 1111 username_hash); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1152 | 1132 |
| 1153 PK11SlotInfo* GetPublicNSSKeySlot() { | 1133 PK11SlotInfo* GetPublicNSSKeySlot() { |
| 1154 return g_nss_singleton.Get().GetPublicNSSKeySlot(); | 1134 return g_nss_singleton.Get().GetPublicNSSKeySlot(); |
| 1155 } | 1135 } |
| 1156 | 1136 |
| 1157 PK11SlotInfo* GetPrivateNSSKeySlot() { | 1137 PK11SlotInfo* GetPrivateNSSKeySlot() { |
| 1158 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); | 1138 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); |
| 1159 } | 1139 } |
| 1160 | 1140 |
| 1161 } // namespace crypto | 1141 } // namespace crypto |
| OLD | NEW |