| 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 | 6 |
| 7 #include <nss.h> | 7 #include <nss.h> |
| 8 #include <pk11pub.h> | 8 #include <pk11pub.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 <secmod.h> | 13 #include <secmod.h> |
| 14 |
| 15 #include <memory> |
| 14 #include <utility> | 16 #include <utility> |
| 15 | 17 |
| 16 #include "crypto/nss_util_internal.h" | 18 #include "crypto/nss_util_internal.h" |
| 17 | 19 |
| 18 #if defined(OS_OPENBSD) | 20 #if defined(OS_OPENBSD) |
| 19 #include <sys/mount.h> | 21 #include <sys/mount.h> |
| 20 #include <sys/param.h> | 22 #include <sys/param.h> |
| 21 #endif | 23 #endif |
| 22 | 24 |
| 23 #if defined(OS_CHROMEOS) | 25 #if defined(OS_CHROMEOS) |
| 24 #include <dlfcn.h> | 26 #include <dlfcn.h> |
| 25 #endif | 27 #endif |
| 26 | 28 |
| 27 #include <map> | 29 #include <map> |
| 28 #include <vector> | 30 #include <vector> |
| 29 | 31 |
| 30 #include "base/base_paths.h" | 32 #include "base/base_paths.h" |
| 31 #include "base/bind.h" | 33 #include "base/bind.h" |
| 32 #include "base/cpu.h" | 34 #include "base/cpu.h" |
| 33 #include "base/debug/alias.h" | 35 #include "base/debug/alias.h" |
| 34 #include "base/debug/stack_trace.h" | 36 #include "base/debug/stack_trace.h" |
| 35 #include "base/environment.h" | 37 #include "base/environment.h" |
| 36 #include "base/files/file_path.h" | 38 #include "base/files/file_path.h" |
| 37 #include "base/files/file_util.h" | 39 #include "base/files/file_util.h" |
| 38 #include "base/lazy_instance.h" | 40 #include "base/lazy_instance.h" |
| 39 #include "base/logging.h" | 41 #include "base/logging.h" |
| 40 #include "base/memory/scoped_ptr.h" | |
| 41 #include "base/message_loop/message_loop.h" | 42 #include "base/message_loop/message_loop.h" |
| 42 #include "base/native_library.h" | 43 #include "base/native_library.h" |
| 43 #include "base/path_service.h" | 44 #include "base/path_service.h" |
| 44 #include "base/stl_util.h" | 45 #include "base/stl_util.h" |
| 45 #include "base/strings/stringprintf.h" | 46 #include "base/strings/stringprintf.h" |
| 46 #include "base/threading/thread_checker.h" | 47 #include "base/threading/thread_checker.h" |
| 47 #include "base/threading/thread_restrictions.h" | 48 #include "base/threading/thread_restrictions.h" |
| 48 #include "base/threading/worker_pool.h" | 49 #include "base/threading/worker_pool.h" |
| 49 #include "build/build_config.h" | 50 #include "build/build_config.h" |
| 50 | 51 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 68 const char kChapsPath[] = "libchaps.so"; | 69 const char kChapsPath[] = "libchaps.so"; |
| 69 | 70 |
| 70 // Fake certificate authority database used for testing. | 71 // Fake certificate authority database used for testing. |
| 71 static const base::FilePath::CharType kReadOnlyCertDB[] = | 72 static const base::FilePath::CharType kReadOnlyCertDB[] = |
| 72 FILE_PATH_LITERAL("/etc/fake_root_ca/nssdb"); | 73 FILE_PATH_LITERAL("/etc/fake_root_ca/nssdb"); |
| 73 #endif // defined(OS_CHROMEOS) | 74 #endif // defined(OS_CHROMEOS) |
| 74 | 75 |
| 75 std::string GetNSSErrorMessage() { | 76 std::string GetNSSErrorMessage() { |
| 76 std::string result; | 77 std::string result; |
| 77 if (PR_GetErrorTextLength()) { | 78 if (PR_GetErrorTextLength()) { |
| 78 scoped_ptr<char[]> error_text(new char[PR_GetErrorTextLength() + 1]); | 79 std::unique_ptr<char[]> error_text(new char[PR_GetErrorTextLength() + 1]); |
| 79 PRInt32 copied = PR_GetErrorText(error_text.get()); | 80 PRInt32 copied = PR_GetErrorText(error_text.get()); |
| 80 result = std::string(error_text.get(), copied); | 81 result = std::string(error_text.get(), copied); |
| 81 } else { | 82 } else { |
| 82 result = base::StringPrintf("NSS error code: %d", PR_GetError()); | 83 result = base::StringPrintf("NSS error code: %d", PR_GetError()); |
| 83 } | 84 } |
| 84 return result; | 85 return result; |
| 85 } | 86 } |
| 86 | 87 |
| 87 #if defined(USE_NSS_CERTS) | 88 #if defined(USE_NSS_CERTS) |
| 88 #if !defined(OS_CHROMEOS) | 89 #if !defined(OS_CHROMEOS) |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 db_on_nfs = (fs_type == base::FILE_SYSTEM_NFS); | 161 db_on_nfs = (fs_type == base::FILE_SYSTEM_NFS); |
| 161 #elif defined(OS_OPENBSD) | 162 #elif defined(OS_OPENBSD) |
| 162 struct statfs buf; | 163 struct statfs buf; |
| 163 if (statfs(database_dir.value().c_str(), &buf) == 0) | 164 if (statfs(database_dir.value().c_str(), &buf) == 0) |
| 164 db_on_nfs = (strcmp(buf.f_fstypename, MOUNT_NFS) == 0); | 165 db_on_nfs = (strcmp(buf.f_fstypename, MOUNT_NFS) == 0); |
| 165 #else | 166 #else |
| 166 NOTIMPLEMENTED(); | 167 NOTIMPLEMENTED(); |
| 167 #endif | 168 #endif |
| 168 | 169 |
| 169 if (db_on_nfs) { | 170 if (db_on_nfs) { |
| 170 scoped_ptr<base::Environment> env(base::Environment::Create()); | 171 std::unique_ptr<base::Environment> env(base::Environment::Create()); |
| 171 static const char kUseCacheEnvVar[] = "NSS_SDB_USE_CACHE"; | 172 static const char kUseCacheEnvVar[] = "NSS_SDB_USE_CACHE"; |
| 172 if (!env->HasVar(kUseCacheEnvVar)) | 173 if (!env->HasVar(kUseCacheEnvVar)) |
| 173 env->SetVar(kUseCacheEnvVar, "yes"); | 174 env->SetVar(kUseCacheEnvVar, "yes"); |
| 174 } | 175 } |
| 175 } | 176 } |
| 176 | 177 |
| 177 #endif // defined(USE_NSS_CERTS) | 178 #endif // defined(USE_NSS_CERTS) |
| 178 | 179 |
| 179 // A singleton to initialize/deinitialize NSPR. | 180 // A singleton to initialize/deinitialize NSPR. |
| 180 // Separate from the NSS singleton because we initialize NSPR on the UI thread. | 181 // Separate from the NSS singleton because we initialize NSPR on the UI thread. |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 // Note that only |tpm_slot_| is checked, since |chaps_module_| could be | 366 // Note that only |tpm_slot_| is checked, since |chaps_module_| could be |
| 366 // NULL in tests while |tpm_slot_| has been set to the test DB. | 367 // NULL in tests while |tpm_slot_| has been set to the test DB. |
| 367 if (tpm_slot_) { | 368 if (tpm_slot_) { |
| 368 base::MessageLoop::current()->PostTask(FROM_HERE, | 369 base::MessageLoop::current()->PostTask(FROM_HERE, |
| 369 base::Bind(callback, true)); | 370 base::Bind(callback, true)); |
| 370 return; | 371 return; |
| 371 } | 372 } |
| 372 | 373 |
| 373 // Note that a reference is not taken to chaps_module_. This is safe since | 374 // Note that a reference is not taken to chaps_module_. This is safe since |
| 374 // NSSInitSingleton is Leaky, so the reference it holds is never released. | 375 // NSSInitSingleton is Leaky, so the reference it holds is never released. |
| 375 scoped_ptr<TPMModuleAndSlot> tpm_args(new TPMModuleAndSlot(chaps_module_)); | 376 std::unique_ptr<TPMModuleAndSlot> tpm_args( |
| 377 new TPMModuleAndSlot(chaps_module_)); |
| 376 TPMModuleAndSlot* tpm_args_ptr = tpm_args.get(); | 378 TPMModuleAndSlot* tpm_args_ptr = tpm_args.get(); |
| 377 if (base::WorkerPool::PostTaskAndReply( | 379 if (base::WorkerPool::PostTaskAndReply( |
| 378 FROM_HERE, | 380 FROM_HERE, |
| 379 base::Bind(&NSSInitSingleton::InitializeTPMTokenOnWorkerThread, | 381 base::Bind(&NSSInitSingleton::InitializeTPMTokenOnWorkerThread, |
| 380 system_slot_id, | 382 system_slot_id, |
| 381 tpm_args_ptr), | 383 tpm_args_ptr), |
| 382 base::Bind(&NSSInitSingleton::OnInitializedTPMTokenAndSystemSlot, | 384 base::Bind(&NSSInitSingleton::OnInitializedTPMTokenAndSystemSlot, |
| 383 base::Unretained(this), // NSSInitSingleton is leaky | 385 base::Unretained(this), // NSSInitSingleton is leaky |
| 384 callback, | 386 callback, |
| 385 base::Passed(&tpm_args)), | 387 base::Passed(&tpm_args)), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 411 "NSS=\"slotParams=(0={slotFlags=[PublicCerts] askpw=only})\""); | 413 "NSS=\"slotParams=(0={slotFlags=[PublicCerts] askpw=only})\""); |
| 412 } | 414 } |
| 413 if (tpm_args->chaps_module) { | 415 if (tpm_args->chaps_module) { |
| 414 tpm_args->tpm_slot = | 416 tpm_args->tpm_slot = |
| 415 GetTPMSlotForIdOnWorkerThread(tpm_args->chaps_module, token_slot_id); | 417 GetTPMSlotForIdOnWorkerThread(tpm_args->chaps_module, token_slot_id); |
| 416 } | 418 } |
| 417 } | 419 } |
| 418 | 420 |
| 419 void OnInitializedTPMTokenAndSystemSlot( | 421 void OnInitializedTPMTokenAndSystemSlot( |
| 420 const base::Callback<void(bool)>& callback, | 422 const base::Callback<void(bool)>& callback, |
| 421 scoped_ptr<TPMModuleAndSlot> tpm_args) { | 423 std::unique_ptr<TPMModuleAndSlot> tpm_args) { |
| 422 DCHECK(thread_checker_.CalledOnValidThread()); | 424 DCHECK(thread_checker_.CalledOnValidThread()); |
| 423 DVLOG(2) << "Loaded chaps: " << !!tpm_args->chaps_module | 425 DVLOG(2) << "Loaded chaps: " << !!tpm_args->chaps_module |
| 424 << ", got tpm slot: " << !!tpm_args->tpm_slot; | 426 << ", got tpm slot: " << !!tpm_args->tpm_slot; |
| 425 | 427 |
| 426 chaps_module_ = tpm_args->chaps_module; | 428 chaps_module_ = tpm_args->chaps_module; |
| 427 tpm_slot_ = std::move(tpm_args->tpm_slot); | 429 tpm_slot_ = std::move(tpm_args->tpm_slot); |
| 428 if (!chaps_module_ && test_system_slot_) { | 430 if (!chaps_module_ && test_system_slot_) { |
| 429 // chromeos_unittests try to test the TPM initialization process. If we | 431 // chromeos_unittests try to test the TPM initialization process. If we |
| 430 // have a test DB open, pretend that it is the TPM slot. | 432 // have a test DB open, pretend that it is the TPM slot. |
| 431 tpm_slot_.reset(PK11_ReferenceSlot(test_system_slot_.get())); | 433 tpm_slot_.reset(PK11_ReferenceSlot(test_system_slot_.get())); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 DCHECK(thread_checker_.CalledOnValidThread()); | 529 DCHECK(thread_checker_.CalledOnValidThread()); |
| 528 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); | 530 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); |
| 529 DCHECK(chromeos_user_map_[username_hash]-> | 531 DCHECK(chromeos_user_map_[username_hash]-> |
| 530 private_slot_initialization_started()); | 532 private_slot_initialization_started()); |
| 531 | 533 |
| 532 if (!chaps_module_) | 534 if (!chaps_module_) |
| 533 return; | 535 return; |
| 534 | 536 |
| 535 // Note that a reference is not taken to chaps_module_. This is safe since | 537 // Note that a reference is not taken to chaps_module_. This is safe since |
| 536 // NSSInitSingleton is Leaky, so the reference it holds is never released. | 538 // NSSInitSingleton is Leaky, so the reference it holds is never released. |
| 537 scoped_ptr<TPMModuleAndSlot> tpm_args(new TPMModuleAndSlot(chaps_module_)); | 539 std::unique_ptr<TPMModuleAndSlot> tpm_args( |
| 540 new TPMModuleAndSlot(chaps_module_)); |
| 538 TPMModuleAndSlot* tpm_args_ptr = tpm_args.get(); | 541 TPMModuleAndSlot* tpm_args_ptr = tpm_args.get(); |
| 539 base::WorkerPool::PostTaskAndReply( | 542 base::WorkerPool::PostTaskAndReply( |
| 540 FROM_HERE, | 543 FROM_HERE, |
| 541 base::Bind(&NSSInitSingleton::InitializeTPMTokenOnWorkerThread, | 544 base::Bind(&NSSInitSingleton::InitializeTPMTokenOnWorkerThread, |
| 542 slot_id, | 545 slot_id, |
| 543 tpm_args_ptr), | 546 tpm_args_ptr), |
| 544 base::Bind(&NSSInitSingleton::OnInitializedTPMForChromeOSUser, | 547 base::Bind(&NSSInitSingleton::OnInitializedTPMForChromeOSUser, |
| 545 base::Unretained(this), // NSSInitSingleton is leaky | 548 base::Unretained(this), // NSSInitSingleton is leaky |
| 546 username_hash, | 549 username_hash, |
| 547 base::Passed(&tpm_args)), | 550 base::Passed(&tpm_args)), |
| 548 true /* task_is_slow */ | 551 true /* task_is_slow */ |
| 549 ); | 552 ); |
| 550 } | 553 } |
| 551 | 554 |
| 552 void OnInitializedTPMForChromeOSUser(const std::string& username_hash, | 555 void OnInitializedTPMForChromeOSUser( |
| 553 scoped_ptr<TPMModuleAndSlot> tpm_args) { | 556 const std::string& username_hash, |
| 557 std::unique_ptr<TPMModuleAndSlot> tpm_args) { |
| 554 DCHECK(thread_checker_.CalledOnValidThread()); | 558 DCHECK(thread_checker_.CalledOnValidThread()); |
| 555 DVLOG(2) << "Got tpm slot for " << username_hash << " " | 559 DVLOG(2) << "Got tpm slot for " << username_hash << " " |
| 556 << !!tpm_args->tpm_slot; | 560 << !!tpm_args->tpm_slot; |
| 557 chromeos_user_map_[username_hash]->SetPrivateSlot( | 561 chromeos_user_map_[username_hash]->SetPrivateSlot( |
| 558 std::move(tpm_args->tpm_slot)); | 562 std::move(tpm_args->tpm_slot)); |
| 559 } | 563 } |
| 560 | 564 |
| 561 void InitializePrivateSoftwareSlotForChromeOSUser( | 565 void InitializePrivateSoftwareSlotForChromeOSUser( |
| 562 const std::string& username_hash) { | 566 const std::string& username_hash) { |
| 563 DCHECK(thread_checker_.CalledOnValidThread()); | 567 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1018 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); | 1022 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); |
| 1019 } | 1023 } |
| 1020 | 1024 |
| 1021 #if !defined(OS_CHROMEOS) | 1025 #if !defined(OS_CHROMEOS) |
| 1022 PK11SlotInfo* GetPersistentNSSKeySlot() { | 1026 PK11SlotInfo* GetPersistentNSSKeySlot() { |
| 1023 return g_nss_singleton.Get().GetPersistentNSSKeySlot(); | 1027 return g_nss_singleton.Get().GetPersistentNSSKeySlot(); |
| 1024 } | 1028 } |
| 1025 #endif | 1029 #endif |
| 1026 | 1030 |
| 1027 } // namespace crypto | 1031 } // namespace crypto |
| OLD | NEW |