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> |
| 11 #include <prerror.h> | 11 #include <prerror.h> |
| 12 #include <prinit.h> | 12 #include <prinit.h> |
| 13 #include <prtime.h> | 13 #include <prtime.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 <map> | |
| 24 #include <vector> | 25 #include <vector> |
| 25 | 26 |
| 27 #include "base/callback.h" | |
| 26 #include "base/debug/alias.h" | 28 #include "base/debug/alias.h" |
| 27 #include "base/debug/stack_trace.h" | 29 #include "base/debug/stack_trace.h" |
| 28 #include "base/environment.h" | 30 #include "base/environment.h" |
| 29 #include "base/file_util.h" | 31 #include "base/file_util.h" |
| 30 #include "base/files/file_path.h" | 32 #include "base/files/file_path.h" |
| 31 #include "base/files/scoped_temp_dir.h" | 33 #include "base/files/scoped_temp_dir.h" |
| 32 #include "base/lazy_instance.h" | 34 #include "base/lazy_instance.h" |
| 33 #include "base/logging.h" | 35 #include "base/logging.h" |
| 34 #include "base/memory/scoped_ptr.h" | 36 #include "base/memory/scoped_ptr.h" |
| 35 #include "base/metrics/histogram.h" | 37 #include "base/metrics/histogram.h" |
| 36 #include "base/native_library.h" | 38 #include "base/native_library.h" |
| 39 #include "base/stl_util.h" | |
| 37 #include "base/strings/stringprintf.h" | 40 #include "base/strings/stringprintf.h" |
| 38 #include "base/threading/thread_checker.h" | 41 #include "base/threading/thread_checker.h" |
| 39 #include "base/threading/thread_restrictions.h" | 42 #include "base/threading/thread_restrictions.h" |
| 40 #include "build/build_config.h" | 43 #include "build/build_config.h" |
| 41 | 44 |
| 42 // USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not | 45 // USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not |
| 43 // defined, such as on Mac and Windows, we use NSS for SSL only -- we don't | 46 // defined, such as on Mac and Windows, we use NSS for SSL only -- we don't |
| 44 // use NSS for crypto or certificate verification, and we don't use the NSS | 47 // use NSS for crypto or certificate verification, and we don't use the NSS |
| 45 // certificate and key databases. | 48 // certificate and key databases. |
| 46 #if defined(USE_NSS) | 49 #if defined(USE_NSS) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 base::FilePath dir = file_util::GetHomeDir(); | 84 base::FilePath dir = file_util::GetHomeDir(); |
| 82 if (dir.empty()) { | 85 if (dir.empty()) { |
| 83 LOG(ERROR) << "Failed to get home directory."; | 86 LOG(ERROR) << "Failed to get home directory."; |
| 84 return dir; | 87 return dir; |
| 85 } | 88 } |
| 86 dir = dir.AppendASCII(".pki").AppendASCII("nssdb"); | 89 dir = dir.AppendASCII(".pki").AppendASCII("nssdb"); |
| 87 if (!file_util::CreateDirectory(dir)) { | 90 if (!file_util::CreateDirectory(dir)) { |
| 88 LOG(ERROR) << "Failed to create " << dir.value() << " directory."; | 91 LOG(ERROR) << "Failed to create " << dir.value() << " directory."; |
| 89 dir.clear(); | 92 dir.clear(); |
| 90 } | 93 } |
| 94 VLOG(1) << "DefaultConfigDirectory: " << dir.value(); | |
| 91 return dir; | 95 return dir; |
| 92 } | 96 } |
| 93 | 97 |
| 94 // On non-Chrome OS platforms, return the default config directory. On Chrome OS | 98 // On non-Chrome OS platforms, return the default config directory. On Chrome OS |
| 95 // test images, return a read-only directory with fake root CA certs (which are | 99 // test images, return a read-only directory with fake root CA certs (which are |
| 96 // used by the local Google Accounts server mock we use when testing our login | 100 // used by the local Google Accounts server mock we use when testing our login |
| 97 // code). On Chrome OS non-test images (where the read-only directory doesn't | 101 // code). On Chrome OS non-test images (where the read-only directory doesn't |
| 98 // exist), return an empty path. | 102 // exist), return an empty path. |
| 99 base::FilePath GetInitialConfigDirectory() { | 103 base::FilePath GetInitialConfigDirectory() { |
| 100 #if defined(OS_CHROMEOS) | 104 #if defined(OS_CHROMEOS) |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 void CrashOnNSSInitFailure() { | 212 void CrashOnNSSInitFailure() { |
| 209 int nss_error = PR_GetError(); | 213 int nss_error = PR_GetError(); |
| 210 int os_error = PR_GetOSError(); | 214 int os_error = PR_GetOSError(); |
| 211 base::debug::Alias(&nss_error); | 215 base::debug::Alias(&nss_error); |
| 212 base::debug::Alias(&os_error); | 216 base::debug::Alias(&os_error); |
| 213 LOG(ERROR) << "Error initializing NSS without a persistent database: " | 217 LOG(ERROR) << "Error initializing NSS without a persistent database: " |
| 214 << GetNSSErrorMessage(); | 218 << GetNSSErrorMessage(); |
| 215 LOG(FATAL) << "nss_error=" << nss_error << ", os_error=" << os_error; | 219 LOG(FATAL) << "nss_error=" << nss_error << ", os_error=" << os_error; |
| 216 } | 220 } |
| 217 | 221 |
| 222 #if defined(OS_CHROMEOS) | |
| 223 class ChromeOSUserData { | |
| 224 public: | |
| 225 ChromeOSUserData(ScopedPK11Slot public_slot, bool is_primary_user) | |
| 226 : public_slot_(public_slot.Pass()), is_primary_user_(is_primary_user) {} | |
| 227 ~ChromeOSUserData() { | |
| 228 // Don't close when NSS is < 3.15.1, because it would require an additional | |
| 229 // sleep for 1 second after closing the database, due to | |
| 230 // http://bugzil.la/875601. | |
| 231 if (NSS_VersionCheck("3.15.1")) { | |
| 232 if (public_slot_ && !is_primary_user_) { | |
| 233 SECStatus status = SECMOD_CloseUserDB(public_slot_.get()); | |
| 234 if (status != SECSuccess) | |
| 235 PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError(); | |
|
Ryan Sleevi
2013/11/27 00:24:11
ChromeOS is always at 3.15.1 now, soon to be at 3.
mattm
2013/11/27 04:12:23
Done.
| |
| 236 } | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 ScopedPK11Slot GetPublicSlot() { | |
| 241 return ScopedPK11Slot(public_slot_ ? PK11_ReferenceSlot(public_slot_.get()) | |
| 242 : NULL); | |
| 243 } | |
| 244 | |
| 245 ScopedPK11Slot GetPrivateSlot() { | |
| 246 return ScopedPK11Slot( | |
| 247 private_slot_ ? PK11_ReferenceSlot(private_slot_.get()) : NULL); | |
|
Ryan Sleevi
2013/11/27 00:24:11
Why the differing indent style compared with 241?
mattm
2013/11/27 04:12:23
That's what clang-format decided to do, this one w
| |
| 248 } | |
| 249 | |
| 250 void OnPrivateSlotReady( | |
| 251 const base::Callback<void(ScopedPK11Slot)>& callback) { | |
| 252 if (private_slot_) | |
| 253 callback.Run(GetPrivateSlot()); | |
| 254 else | |
| 255 tpm_ready_callback_list_.push_back(callback); | |
| 256 } | |
| 257 | |
| 258 void SetPrivateSlot(ScopedPK11Slot private_slot) { | |
| 259 DCHECK(!private_slot_); | |
| 260 private_slot_ = private_slot.Pass(); | |
| 261 | |
| 262 for (SlotReadyCallbackList::iterator i = tpm_ready_callback_list_.begin(); | |
| 263 i != tpm_ready_callback_list_.end(); | |
| 264 ++i) { | |
| 265 (*i).Run(GetPrivateSlot()); | |
| 266 } | |
| 267 tpm_ready_callback_list_.clear(); | |
|
Ryan Sleevi
2013/11/27 00:24:11
DANGER: This strikes me as a dangerous pattern, in
mattm
2013/11/27 04:12:23
Good call. Done.
| |
| 268 } | |
| 269 | |
| 270 private: | |
| 271 ScopedPK11Slot public_slot_; | |
| 272 ScopedPK11Slot private_slot_; | |
| 273 bool is_primary_user_; | |
| 274 | |
| 275 typedef std::vector<base::Callback<void(ScopedPK11Slot)> > | |
| 276 SlotReadyCallbackList; | |
| 277 SlotReadyCallbackList tpm_ready_callback_list_; | |
| 278 }; | |
| 279 #endif // defined(OS_CHROMEOS) | |
| 280 | |
| 218 class NSSInitSingleton { | 281 class NSSInitSingleton { |
| 219 public: | 282 public: |
| 220 #if defined(OS_CHROMEOS) | 283 #if defined(OS_CHROMEOS) |
| 221 void OpenPersistentNSSDB() { | 284 void OpenPersistentNSSDB() { |
| 222 DCHECK(thread_checker_.CalledOnValidThread()); | 285 DCHECK(thread_checker_.CalledOnValidThread()); |
| 223 | 286 |
| 224 if (!chromeos_user_logged_in_) { | 287 if (!chromeos_user_logged_in_) { |
| 225 // GetDefaultConfigDirectory causes us to do blocking IO on UI thread. | 288 // GetDefaultConfigDirectory causes us to do blocking IO on UI thread. |
| 226 // Temporarily allow it until we fix http://crbug.com/70119 | 289 // Temporarily allow it until we fix http://crbug.com/70119 |
| 227 base::ThreadRestrictions::ScopedAllowIO allow_io; | 290 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 228 chromeos_user_logged_in_ = true; | 291 chromeos_user_logged_in_ = true; |
| 229 | 292 |
| 230 // This creates another DB slot in NSS that is read/write, unlike | 293 // This creates another DB slot in NSS that is read/write, unlike |
| 231 // the fake root CA cert DB and the "default" crypto key | 294 // the fake root CA cert DB and the "default" crypto key |
| 232 // provider, which are still read-only (because we initialized | 295 // provider, which are still read-only (because we initialized |
| 233 // NSS before we had a cryptohome mounted). | 296 // NSS before we had a cryptohome mounted). |
| 234 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), | 297 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), |
| 235 kNSSDatabaseName); | 298 kNSSDatabaseName); |
| 236 } | 299 } |
| 237 } | 300 } |
| 238 | 301 |
| 302 PK11SlotInfo* OpenPersistentNSSDBForPath(const base::FilePath& path) { | |
| 303 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 304 VLOG(1) << __func__ << " " << path.value(); | |
| 305 // We do NSS file io on the IO thread. | |
| 306 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
| 307 | |
| 308 base::FilePath nssdb_path = path.AppendASCII(".pki").AppendASCII("nssdb"); | |
| 309 if (!file_util::CreateDirectory(nssdb_path)) { | |
| 310 LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory."; | |
| 311 return NULL; | |
| 312 } | |
| 313 return OpenUserDB(nssdb_path, kNSSDatabaseName); | |
| 314 } | |
| 315 | |
| 239 void EnableTPMTokenForNSS() { | 316 void EnableTPMTokenForNSS() { |
| 240 DCHECK(thread_checker_.CalledOnValidThread()); | 317 DCHECK(thread_checker_.CalledOnValidThread()); |
| 241 | 318 |
| 242 // If this gets set, then we'll use the TPM for certs with | 319 // If this gets set, then we'll use the TPM for certs with |
| 243 // private keys, otherwise we'll fall back to the software | 320 // private keys, otherwise we'll fall back to the software |
| 244 // implementation. | 321 // implementation. |
| 245 tpm_token_enabled_for_nss_ = true; | 322 tpm_token_enabled_for_nss_ = true; |
| 246 } | 323 } |
| 247 | 324 |
| 325 bool IsTPMTokenEnabledForNSS() { | |
| 326 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 327 return tpm_token_enabled_for_nss_; | |
| 328 } | |
| 329 | |
| 248 bool InitializeTPMToken(const std::string& token_name, | 330 bool InitializeTPMToken(const std::string& token_name, |
| 249 int token_slot_id, | 331 int token_slot_id, |
| 250 const std::string& user_pin) { | 332 const std::string& user_pin) { |
| 251 DCHECK(thread_checker_.CalledOnValidThread()); | 333 DCHECK(thread_checker_.CalledOnValidThread()); |
| 252 | 334 |
| 253 // If EnableTPMTokenForNSS hasn't been called, return false. | 335 // If EnableTPMTokenForNSS hasn't been called, return false. |
| 254 if (!tpm_token_enabled_for_nss_) | 336 if (!tpm_token_enabled_for_nss_) |
| 255 return false; | 337 return false; |
| 256 | 338 |
| 257 // If everything is already initialized, then return true. | 339 // If everything is already initialized, then return true. |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 276 if (!chaps_module_ && test_slot_) { | 358 if (!chaps_module_ && test_slot_) { |
| 277 // chromeos_unittests try to test the TPM initialization process. If we | 359 // chromeos_unittests try to test the TPM initialization process. If we |
| 278 // have a test DB open, pretend that it is the TPM slot. | 360 // have a test DB open, pretend that it is the TPM slot. |
| 279 tpm_slot_ = PK11_ReferenceSlot(test_slot_); | 361 tpm_slot_ = PK11_ReferenceSlot(test_slot_); |
| 280 return true; | 362 return true; |
| 281 } | 363 } |
| 282 } | 364 } |
| 283 if (chaps_module_){ | 365 if (chaps_module_){ |
| 284 tpm_slot_ = GetTPMSlotForId(token_slot_id); | 366 tpm_slot_ = GetTPMSlotForId(token_slot_id); |
| 285 | 367 |
| 368 if (tpm_slot_) { | |
| 369 for (TPMReadyCallbackList::iterator i = | |
| 370 tpm_ready_callback_list_.begin(); | |
| 371 i != tpm_ready_callback_list_.end(); | |
| 372 ++i) { | |
| 373 (*i).Run(); | |
| 374 } | |
| 375 tpm_ready_callback_list_.clear(); | |
|
Ryan Sleevi
2013/11/27 00:24:11
Ditto RE: danger.
I'm also not thrilled with the
mattm
2013/11/27 04:12:23
Done.
| |
| 376 } | |
| 377 | |
| 286 return tpm_slot_ != NULL; | 378 return tpm_slot_ != NULL; |
| 287 } | 379 } |
| 288 return false; | 380 return false; |
| 289 } | 381 } |
| 290 | 382 |
| 291 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { | 383 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { |
| 292 // TODO(mattm): Change to DCHECK when callers have been fixed. | 384 // TODO(mattm): Change to DCHECK when callers have been fixed. |
| 293 if (!thread_checker_.CalledOnValidThread()) { | 385 if (!thread_checker_.CalledOnValidThread()) { |
| 294 DVLOG(1) << "Called on wrong thread.\n" | 386 DVLOG(1) << "Called on wrong thread.\n" |
| 295 << base::debug::StackTrace().ToString(); | 387 << base::debug::StackTrace().ToString(); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 308 bool IsTPMTokenReady() { | 400 bool IsTPMTokenReady() { |
| 309 // TODO(mattm): Change to DCHECK when callers have been fixed. | 401 // TODO(mattm): Change to DCHECK when callers have been fixed. |
| 310 if (!thread_checker_.CalledOnValidThread()) { | 402 if (!thread_checker_.CalledOnValidThread()) { |
| 311 DVLOG(1) << "Called on wrong thread.\n" | 403 DVLOG(1) << "Called on wrong thread.\n" |
| 312 << base::debug::StackTrace().ToString(); | 404 << base::debug::StackTrace().ToString(); |
| 313 } | 405 } |
| 314 | 406 |
| 315 return tpm_slot_ != NULL; | 407 return tpm_slot_ != NULL; |
| 316 } | 408 } |
| 317 | 409 |
| 410 void OnTPMReady(const base::Closure& callback) { | |
| 411 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 412 if (IsTPMTokenReady()) | |
| 413 callback.Run(); | |
| 414 else | |
| 415 tpm_ready_callback_list_.push_back(callback); | |
| 416 } | |
| 417 | |
| 318 // Note that CK_SLOT_ID is an unsigned long, but cryptohome gives us the slot | 418 // Note that CK_SLOT_ID is an unsigned long, but cryptohome gives us the slot |
| 319 // id as an int. This should be safe since this is only used with chaps, which | 419 // id as an int. This should be safe since this is only used with chaps, which |
| 320 // we also control. | 420 // we also control. |
| 321 PK11SlotInfo* GetTPMSlotForId(CK_SLOT_ID slot_id) { | 421 PK11SlotInfo* GetTPMSlotForId(CK_SLOT_ID slot_id) { |
| 322 DCHECK(thread_checker_.CalledOnValidThread()); | 422 DCHECK(thread_checker_.CalledOnValidThread()); |
| 323 | 423 |
| 324 if (!chaps_module_) | 424 if (!chaps_module_) |
| 325 return NULL; | 425 return NULL; |
| 326 | 426 |
| 327 VLOG(1) << "Poking chaps module."; | 427 VLOG(1) << "Poking chaps module."; |
| 328 SECStatus rv = SECMOD_UpdateSlotList(chaps_module_); | 428 SECStatus rv = SECMOD_UpdateSlotList(chaps_module_); |
| 329 if (rv != SECSuccess) | 429 if (rv != SECSuccess) |
| 330 PLOG(ERROR) << "SECMOD_UpdateSlotList failed: " << PORT_GetError(); | 430 PLOG(ERROR) << "SECMOD_UpdateSlotList failed: " << PORT_GetError(); |
| 331 | 431 |
| 332 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module_->moduleID, slot_id); | 432 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module_->moduleID, slot_id); |
| 333 if (!slot) | 433 if (!slot) |
| 334 LOG(ERROR) << "TPM slot " << slot_id << " not found."; | 434 LOG(ERROR) << "TPM slot " << slot_id << " not found."; |
| 335 return slot; | 435 return slot; |
| 336 } | 436 } |
| 437 | |
| 438 bool InitializeNSSForChromeOSUser( | |
| 439 const std::string& email, | |
| 440 const std::string& username_hash, | |
| 441 bool is_primary_user, | |
| 442 const base::FilePath& path) { | |
| 443 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 444 if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) { | |
| 445 // This user already exists in our mapping. | |
| 446 VLOG(1) << username_hash << " already initialized."; | |
|
Ryan Sleevi
2013/11/27 00:24:11
Way too chatty logging
mattm
2013/11/27 04:12:23
Changed things to DVLOG(2). These ones shouldn't a
| |
| 447 return false; | |
| 448 } | |
| 449 ScopedPK11Slot public_slot; | |
| 450 if (is_primary_user) { | |
| 451 VLOG(1) << "Primary user, using GetPublicNSSKeySlot()"; | |
| 452 public_slot.reset(GetPublicNSSKeySlot()); | |
| 453 } else { | |
| 454 VLOG(1) << "Opening NSS DB"; | |
| 455 public_slot.reset(OpenPersistentNSSDBForPath(path)); | |
| 456 } | |
| 457 chromeos_user_map_[username_hash] = | |
| 458 new ChromeOSUserData(public_slot.Pass(), is_primary_user); | |
| 459 return true; | |
| 460 } | |
| 461 | |
| 462 void InitializeTPMForChromeOSUser(const std::string& username_hash, | |
| 463 CK_SLOT_ID slot_id) { | |
| 464 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 465 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); | |
| 466 chromeos_user_map_[username_hash] | |
| 467 ->SetPrivateSlot(ScopedPK11Slot(GetTPMSlotForId(slot_id))); | |
| 468 } | |
| 469 | |
| 470 void InitializePrivateSoftwareSlotForChromeOSUser( | |
| 471 const std::string& username_hash) { | |
| 472 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 473 LOG(WARNING) << "using software private slot for " << username_hash; | |
| 474 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); | |
| 475 chromeos_user_map_[username_hash]->SetPrivateSlot( | |
| 476 chromeos_user_map_[username_hash]->GetPublicSlot()); | |
| 477 } | |
| 478 | |
| 479 ScopedPK11Slot GetPublicSlotForChromeOSUser( | |
| 480 const std::string& username_hash) { | |
| 481 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 482 if (test_slot_) { | |
| 483 VLOG(1) << "returning test_slot_ for " << username_hash; | |
| 484 return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_)); | |
| 485 } | |
| 486 | |
| 487 if (chromeos_user_map_.find(username_hash) == chromeos_user_map_.end()) { | |
| 488 LOG(ERROR) << username_hash << " not initialized."; | |
| 489 return ScopedPK11Slot(); | |
| 490 } | |
| 491 return chromeos_user_map_[username_hash]->GetPublicSlot(); | |
| 492 } | |
| 493 | |
| 494 void OnPrivateSlotReadyForChromeOSUser( | |
| 495 const std::string& username_hash, | |
| 496 const base::Callback<void(ScopedPK11Slot)>& callback) { | |
| 497 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 498 if (test_slot_) { | |
| 499 VLOG(1) << "returning test_slot_ for " << username_hash; | |
| 500 callback.Run(ScopedPK11Slot(PK11_ReferenceSlot(test_slot_))); | |
| 501 return; | |
| 502 } | |
| 503 | |
| 504 if (chromeos_user_map_.find(username_hash) == chromeos_user_map_.end()) { | |
| 505 LOG(ERROR) << username_hash << " not initialized."; | |
| 506 callback.Run(ScopedPK11Slot()); | |
| 507 return; | |
| 508 } | |
| 509 chromeos_user_map_[username_hash]->OnPrivateSlotReady(callback); | |
| 510 } | |
| 337 #endif // defined(OS_CHROMEOS) | 511 #endif // defined(OS_CHROMEOS) |
| 338 | 512 |
| 339 | 513 |
| 340 bool OpenTestNSSDB() { | 514 bool OpenTestNSSDB() { |
| 341 DCHECK(thread_checker_.CalledOnValidThread()); | 515 DCHECK(thread_checker_.CalledOnValidThread()); |
| 342 | 516 |
| 343 if (test_slot_) | 517 if (test_slot_) |
| 344 return true; | 518 return true; |
| 345 if (!g_test_nss_db_dir.Get().CreateUniqueTempDir()) | 519 if (!g_test_nss_db_dir.Get().CreateUniqueTempDir()) |
| 346 return false; | 520 return false; |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 529 base::TimeTicks::Now() - start_time, | 703 base::TimeTicks::Now() - start_time, |
| 530 base::TimeDelta::FromMilliseconds(10), | 704 base::TimeDelta::FromMilliseconds(10), |
| 531 base::TimeDelta::FromHours(1), | 705 base::TimeDelta::FromHours(1), |
| 532 50); | 706 50); |
| 533 } | 707 } |
| 534 | 708 |
| 535 // NOTE(willchan): We don't actually execute this code since we leak NSS to | 709 // NOTE(willchan): We don't actually execute this code since we leak NSS to |
| 536 // prevent non-joinable threads from using NSS after it's already been shut | 710 // prevent non-joinable threads from using NSS after it's already been shut |
| 537 // down. | 711 // down. |
| 538 ~NSSInitSingleton() { | 712 ~NSSInitSingleton() { |
| 713 #if defined(OS_CHROMEOS) | |
| 714 STLDeleteValues(&chromeos_user_map_); | |
| 715 #endif | |
| 539 if (tpm_slot_) { | 716 if (tpm_slot_) { |
| 540 PK11_FreeSlot(tpm_slot_); | 717 PK11_FreeSlot(tpm_slot_); |
| 541 tpm_slot_ = NULL; | 718 tpm_slot_ = NULL; |
| 542 } | 719 } |
| 543 if (software_slot_) { | 720 if (software_slot_) { |
| 544 SECMOD_CloseUserDB(software_slot_); | 721 SECMOD_CloseUserDB(software_slot_); |
| 545 PK11_FreeSlot(software_slot_); | 722 PK11_FreeSlot(software_slot_); |
| 546 software_slot_ = NULL; | 723 software_slot_ = NULL; |
| 547 } | 724 } |
| 548 CloseTestNSSDB(); | 725 CloseTestNSSDB(); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 623 } | 800 } |
| 624 return db_slot; | 801 return db_slot; |
| 625 } | 802 } |
| 626 | 803 |
| 627 // If this is set to true NSS is forced to be initialized without a DB. | 804 // If this is set to true NSS is forced to be initialized without a DB. |
| 628 static bool force_nodb_init_; | 805 static bool force_nodb_init_; |
| 629 | 806 |
| 630 bool tpm_token_enabled_for_nss_; | 807 bool tpm_token_enabled_for_nss_; |
| 631 std::string tpm_token_name_; | 808 std::string tpm_token_name_; |
| 632 std::string tpm_user_pin_; | 809 std::string tpm_user_pin_; |
| 810 typedef std::vector<base::Closure> TPMReadyCallbackList; | |
| 811 TPMReadyCallbackList tpm_ready_callback_list_; | |
| 633 SECMODModule* chaps_module_; | 812 SECMODModule* chaps_module_; |
| 634 PK11SlotInfo* software_slot_; | 813 PK11SlotInfo* software_slot_; |
| 635 PK11SlotInfo* test_slot_; | 814 PK11SlotInfo* test_slot_; |
| 636 PK11SlotInfo* tpm_slot_; | 815 PK11SlotInfo* tpm_slot_; |
| 637 SECMODModule* root_; | 816 SECMODModule* root_; |
| 638 bool chromeos_user_logged_in_; | 817 bool chromeos_user_logged_in_; |
| 818 #if defined(OS_CHROMEOS) | |
| 819 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap; | |
| 820 ChromeOSUserMap chromeos_user_map_; | |
| 821 #endif | |
| 639 #if defined(USE_NSS) | 822 #if defined(USE_NSS) |
| 640 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 | 823 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 |
| 641 // is fixed, we will no longer need the lock. | 824 // is fixed, we will no longer need the lock. |
| 642 base::Lock write_lock_; | 825 base::Lock write_lock_; |
| 643 #endif // defined(USE_NSS) | 826 #endif // defined(USE_NSS) |
| 644 | 827 |
| 645 base::ThreadChecker thread_checker_; | 828 base::ThreadChecker thread_checker_; |
| 646 }; | 829 }; |
| 647 | 830 |
| 648 // static | 831 // static |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 792 | 975 |
| 793 #if defined(OS_CHROMEOS) | 976 #if defined(OS_CHROMEOS) |
| 794 void OpenPersistentNSSDB() { | 977 void OpenPersistentNSSDB() { |
| 795 g_nss_singleton.Get().OpenPersistentNSSDB(); | 978 g_nss_singleton.Get().OpenPersistentNSSDB(); |
| 796 } | 979 } |
| 797 | 980 |
| 798 void EnableTPMTokenForNSS() { | 981 void EnableTPMTokenForNSS() { |
| 799 g_nss_singleton.Get().EnableTPMTokenForNSS(); | 982 g_nss_singleton.Get().EnableTPMTokenForNSS(); |
| 800 } | 983 } |
| 801 | 984 |
| 985 bool IsTPMTokenEnabledForNSS() { | |
| 986 return g_nss_singleton.Get().IsTPMTokenEnabledForNSS(); | |
| 987 } | |
| 988 | |
| 802 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { | 989 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { |
| 803 g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin); | 990 g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin); |
| 804 } | 991 } |
| 805 | 992 |
| 806 bool IsTPMTokenReady() { | 993 bool IsTPMTokenReady() { |
| 807 return g_nss_singleton.Get().IsTPMTokenReady(); | 994 return g_nss_singleton.Get().IsTPMTokenReady(); |
| 808 } | 995 } |
| 809 | 996 |
| 997 void OnTPMReady(const base::Closure& callback) { | |
| 998 g_nss_singleton.Get().OnTPMReady(callback); | |
| 999 } | |
| 1000 | |
| 810 bool InitializeTPMToken(const std::string& token_name, | 1001 bool InitializeTPMToken(const std::string& token_name, |
| 811 int token_slot_id, | 1002 int token_slot_id, |
| 812 const std::string& user_pin) { | 1003 const std::string& user_pin) { |
| 813 return g_nss_singleton.Get().InitializeTPMToken( | 1004 return g_nss_singleton.Get().InitializeTPMToken( |
| 814 token_name, token_slot_id, user_pin); | 1005 token_name, token_slot_id, user_pin); |
| 815 } | 1006 } |
| 1007 | |
| 1008 bool InitializeNSSForChromeOSUser( | |
| 1009 const std::string& email, | |
| 1010 const std::string& username_hash, | |
| 1011 bool is_primary_user, | |
| 1012 const base::FilePath& path) { | |
| 1013 return g_nss_singleton.Get().InitializeNSSForChromeOSUser( | |
| 1014 email, username_hash, is_primary_user, path); | |
| 1015 } | |
| 1016 void InitializeTPMForChromeOSUser( | |
| 1017 const std::string& username_hash, | |
| 1018 CK_SLOT_ID slot_id) { | |
| 1019 g_nss_singleton.Get().InitializeTPMForChromeOSUser(username_hash, slot_id); | |
| 1020 } | |
| 1021 void InitializePrivateSoftwareSlotForChromeOSUser( | |
| 1022 const std::string& username_hash) { | |
| 1023 g_nss_singleton.Get().InitializePrivateSoftwareSlotForChromeOSUser( | |
| 1024 username_hash); | |
| 1025 } | |
| 1026 ScopedPK11Slot GetPublicSlotForChromeOSUser(const std::string& username_hash) { | |
| 1027 return g_nss_singleton.Get().GetPublicSlotForChromeOSUser(username_hash); | |
| 1028 } | |
| 1029 void OnPrivateSlotReadyForChromeOSUser( | |
| 1030 const std::string& username_hash, | |
| 1031 const base::Callback<void(ScopedPK11Slot)>& callback) { | |
| 1032 g_nss_singleton.Get().OnPrivateSlotReadyForChromeOSUser(username_hash, | |
| 1033 callback); | |
| 1034 } | |
| 816 #endif // defined(OS_CHROMEOS) | 1035 #endif // defined(OS_CHROMEOS) |
| 817 | 1036 |
| 818 base::Time PRTimeToBaseTime(PRTime prtime) { | 1037 base::Time PRTimeToBaseTime(PRTime prtime) { |
| 819 return base::Time::FromInternalValue( | 1038 return base::Time::FromInternalValue( |
| 820 prtime + base::Time::UnixEpoch().ToInternalValue()); | 1039 prtime + base::Time::UnixEpoch().ToInternalValue()); |
| 821 } | 1040 } |
| 822 | 1041 |
| 823 PRTime BaseTimeToPRTime(base::Time time) { | 1042 PRTime BaseTimeToPRTime(base::Time time) { |
| 824 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); | 1043 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); |
| 825 } | 1044 } |
| 826 | 1045 |
| 827 PK11SlotInfo* GetPublicNSSKeySlot() { | 1046 PK11SlotInfo* GetPublicNSSKeySlot() { |
| 828 return g_nss_singleton.Get().GetPublicNSSKeySlot(); | 1047 return g_nss_singleton.Get().GetPublicNSSKeySlot(); |
| 829 } | 1048 } |
| 830 | 1049 |
| 831 PK11SlotInfo* GetPrivateNSSKeySlot() { | 1050 PK11SlotInfo* GetPrivateNSSKeySlot() { |
| 832 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); | 1051 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); |
| 833 } | 1052 } |
| 834 | 1053 |
| 835 } // namespace crypto | 1054 } // namespace crypto |
| OLD | NEW |