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/cpu.h" | 28 #include "base/cpu.h" |
| 27 #include "base/debug/alias.h" | 29 #include "base/debug/alias.h" |
| 28 #include "base/debug/stack_trace.h" | 30 #include "base/debug/stack_trace.h" |
| 29 #include "base/environment.h" | 31 #include "base/environment.h" |
| 30 #include "base/file_util.h" | 32 #include "base/file_util.h" |
| 31 #include "base/files/file_path.h" | 33 #include "base/files/file_path.h" |
| 32 #include "base/files/scoped_temp_dir.h" | 34 #include "base/files/scoped_temp_dir.h" |
| 33 #include "base/lazy_instance.h" | 35 #include "base/lazy_instance.h" |
| 34 #include "base/logging.h" | 36 #include "base/logging.h" |
| 35 #include "base/memory/scoped_ptr.h" | 37 #include "base/memory/scoped_ptr.h" |
| 36 #include "base/metrics/histogram.h" | 38 #include "base/metrics/histogram.h" |
| 37 #include "base/native_library.h" | 39 #include "base/native_library.h" |
| 40 #include "base/stl_util.h" | |
| 38 #include "base/strings/stringprintf.h" | 41 #include "base/strings/stringprintf.h" |
| 39 #include "base/threading/thread_checker.h" | 42 #include "base/threading/thread_checker.h" |
| 40 #include "base/threading/thread_restrictions.h" | 43 #include "base/threading/thread_restrictions.h" |
| 41 #include "build/build_config.h" | 44 #include "build/build_config.h" |
| 42 | 45 |
| 43 // USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not | 46 // USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not |
| 44 // defined, such as on Mac and Windows, we use NSS for SSL only -- we don't | 47 // defined, such as on Mac and Windows, we use NSS for SSL only -- we don't |
| 45 // use NSS for crypto or certificate verification, and we don't use the NSS | 48 // use NSS for crypto or certificate verification, and we don't use the NSS |
| 46 // certificate and key databases. | 49 // certificate and key databases. |
| 47 #if defined(USE_NSS) | 50 #if defined(USE_NSS) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 base::FilePath dir = file_util::GetHomeDir(); | 85 base::FilePath dir = file_util::GetHomeDir(); |
| 83 if (dir.empty()) { | 86 if (dir.empty()) { |
| 84 LOG(ERROR) << "Failed to get home directory."; | 87 LOG(ERROR) << "Failed to get home directory."; |
| 85 return dir; | 88 return dir; |
| 86 } | 89 } |
| 87 dir = dir.AppendASCII(".pki").AppendASCII("nssdb"); | 90 dir = dir.AppendASCII(".pki").AppendASCII("nssdb"); |
| 88 if (!file_util::CreateDirectory(dir)) { | 91 if (!file_util::CreateDirectory(dir)) { |
| 89 LOG(ERROR) << "Failed to create " << dir.value() << " directory."; | 92 LOG(ERROR) << "Failed to create " << dir.value() << " directory."; |
| 90 dir.clear(); | 93 dir.clear(); |
| 91 } | 94 } |
| 95 DVLOG(2) << "DefaultConfigDirectory: " << dir.value(); | |
| 92 return dir; | 96 return dir; |
| 93 } | 97 } |
| 94 | 98 |
| 95 // On non-Chrome OS platforms, return the default config directory. On Chrome OS | 99 // On non-Chrome OS platforms, return the default config directory. On Chrome OS |
| 96 // test images, return a read-only directory with fake root CA certs (which are | 100 // test images, return a read-only directory with fake root CA certs (which are |
| 97 // used by the local Google Accounts server mock we use when testing our login | 101 // used by the local Google Accounts server mock we use when testing our login |
| 98 // code). On Chrome OS non-test images (where the read-only directory doesn't | 102 // code). On Chrome OS non-test images (where the read-only directory doesn't |
| 99 // exist), return an empty path. | 103 // exist), return an empty path. |
| 100 base::FilePath GetInitialConfigDirectory() { | 104 base::FilePath GetInitialConfigDirectory() { |
| 101 #if defined(OS_CHROMEOS) | 105 #if defined(OS_CHROMEOS) |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 void CrashOnNSSInitFailure() { | 201 void CrashOnNSSInitFailure() { |
| 198 int nss_error = PR_GetError(); | 202 int nss_error = PR_GetError(); |
| 199 int os_error = PR_GetOSError(); | 203 int os_error = PR_GetOSError(); |
| 200 base::debug::Alias(&nss_error); | 204 base::debug::Alias(&nss_error); |
| 201 base::debug::Alias(&os_error); | 205 base::debug::Alias(&os_error); |
| 202 LOG(ERROR) << "Error initializing NSS without a persistent database: " | 206 LOG(ERROR) << "Error initializing NSS without a persistent database: " |
| 203 << GetNSSErrorMessage(); | 207 << GetNSSErrorMessage(); |
| 204 LOG(FATAL) << "nss_error=" << nss_error << ", os_error=" << os_error; | 208 LOG(FATAL) << "nss_error=" << nss_error << ", os_error=" << os_error; |
| 205 } | 209 } |
| 206 | 210 |
| 211 #if defined(OS_CHROMEOS) | |
| 212 class ChromeOSUserData { | |
| 213 public: | |
| 214 ChromeOSUserData(ScopedPK11Slot public_slot, bool is_primary_user) | |
| 215 : public_slot_(public_slot.Pass()), is_primary_user_(is_primary_user) {} | |
|
Ryan Sleevi
2013/12/04 20:59:55
Because the initializer list doesn't fit on one li
mattm
2013/12/04 22:09:28
Oddly, clang-format is what did that. fixed.
| |
| 216 ~ChromeOSUserData() { | |
| 217 if (public_slot_ && !is_primary_user_) { | |
| 218 SECStatus status = SECMOD_CloseUserDB(public_slot_.get()); | |
| 219 if (status != SECSuccess) | |
| 220 PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError(); | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 ScopedPK11Slot GetPublicSlot() { | |
| 225 return ScopedPK11Slot( | |
| 226 public_slot_ ? PK11_ReferenceSlot(public_slot_.get()) : NULL); | |
| 227 } | |
| 228 | |
| 229 ScopedPK11Slot GetPrivateSlot( | |
| 230 const base::Callback<void(ScopedPK11Slot)>& callback) { | |
| 231 if (private_slot_) | |
| 232 return ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get())); | |
| 233 if (!callback.is_null()) | |
| 234 tpm_ready_callback_list_.push_back(callback); | |
| 235 return ScopedPK11Slot(); | |
| 236 } | |
| 237 | |
| 238 void SetPrivateSlot(ScopedPK11Slot private_slot) { | |
| 239 DCHECK(!private_slot_); | |
| 240 private_slot_ = private_slot.Pass(); | |
| 241 | |
| 242 SlotReadyCallbackList callback_list; | |
| 243 callback_list.swap(tpm_ready_callback_list_); | |
| 244 for (SlotReadyCallbackList::iterator i = callback_list.begin(); | |
| 245 i != callback_list.end(); | |
| 246 ++i) { | |
| 247 (*i).Run(ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get()))); | |
| 248 } | |
| 249 } | |
| 250 | |
| 251 private: | |
| 252 ScopedPK11Slot public_slot_; | |
| 253 ScopedPK11Slot private_slot_; | |
| 254 bool is_primary_user_; | |
| 255 | |
| 256 typedef std::vector<base::Callback<void(ScopedPK11Slot)> > | |
| 257 SlotReadyCallbackList; | |
| 258 SlotReadyCallbackList tpm_ready_callback_list_; | |
| 259 }; | |
| 260 #endif // defined(OS_CHROMEOS) | |
| 261 | |
| 207 class NSSInitSingleton { | 262 class NSSInitSingleton { |
| 208 public: | 263 public: |
| 209 #if defined(OS_CHROMEOS) | 264 #if defined(OS_CHROMEOS) |
| 210 void OpenPersistentNSSDB() { | 265 void OpenPersistentNSSDB() { |
| 211 DCHECK(thread_checker_.CalledOnValidThread()); | 266 DCHECK(thread_checker_.CalledOnValidThread()); |
| 212 | 267 |
| 213 if (!chromeos_user_logged_in_) { | 268 if (!chromeos_user_logged_in_) { |
| 214 // GetDefaultConfigDirectory causes us to do blocking IO on UI thread. | 269 // GetDefaultConfigDirectory causes us to do blocking IO on UI thread. |
| 215 // Temporarily allow it until we fix http://crbug.com/70119 | 270 // Temporarily allow it until we fix http://crbug.com/70119 |
| 216 base::ThreadRestrictions::ScopedAllowIO allow_io; | 271 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 217 chromeos_user_logged_in_ = true; | 272 chromeos_user_logged_in_ = true; |
| 218 | 273 |
| 219 // This creates another DB slot in NSS that is read/write, unlike | 274 // This creates another DB slot in NSS that is read/write, unlike |
| 220 // the fake root CA cert DB and the "default" crypto key | 275 // the fake root CA cert DB and the "default" crypto key |
| 221 // provider, which are still read-only (because we initialized | 276 // provider, which are still read-only (because we initialized |
| 222 // NSS before we had a cryptohome mounted). | 277 // NSS before we had a cryptohome mounted). |
| 223 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), | 278 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), |
| 224 kNSSDatabaseName); | 279 kNSSDatabaseName); |
| 225 } | 280 } |
| 226 } | 281 } |
| 227 | 282 |
| 283 PK11SlotInfo* OpenPersistentNSSDBForPath(const base::FilePath& path) { | |
| 284 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 285 // We do NSS file io on the IO thread. | |
|
Ryan Sleevi
2013/12/04 20:59:55
comment nit: Rewrite without pronouns ( https://gr
mattm
2013/12/04 22:09:28
Done.
| |
| 286 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
| 287 | |
| 288 base::FilePath nssdb_path = path.AppendASCII(".pki").AppendASCII("nssdb"); | |
| 289 if (!file_util::CreateDirectory(nssdb_path)) { | |
| 290 LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory."; | |
| 291 return NULL; | |
| 292 } | |
| 293 return OpenUserDB(nssdb_path, kNSSDatabaseName); | |
| 294 } | |
| 295 | |
| 228 void EnableTPMTokenForNSS() { | 296 void EnableTPMTokenForNSS() { |
| 229 DCHECK(thread_checker_.CalledOnValidThread()); | 297 DCHECK(thread_checker_.CalledOnValidThread()); |
| 230 | 298 |
| 231 // If this gets set, then we'll use the TPM for certs with | 299 // If this gets set, then we'll use the TPM for certs with |
| 232 // private keys, otherwise we'll fall back to the software | 300 // private keys, otherwise we'll fall back to the software |
| 233 // implementation. | 301 // implementation. |
| 234 tpm_token_enabled_for_nss_ = true; | 302 tpm_token_enabled_for_nss_ = true; |
| 235 } | 303 } |
| 236 | 304 |
| 305 bool IsTPMTokenEnabledForNSS() { | |
| 306 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 307 return tpm_token_enabled_for_nss_; | |
| 308 } | |
| 309 | |
| 237 bool InitializeTPMToken(int token_slot_id) { | 310 bool InitializeTPMToken(int token_slot_id) { |
| 238 DCHECK(thread_checker_.CalledOnValidThread()); | 311 DCHECK(thread_checker_.CalledOnValidThread()); |
| 239 | 312 |
| 240 // If EnableTPMTokenForNSS hasn't been called, return false. | 313 // If EnableTPMTokenForNSS hasn't been called, return false. |
| 241 if (!tpm_token_enabled_for_nss_) | 314 if (!tpm_token_enabled_for_nss_) |
| 242 return false; | 315 return false; |
| 243 | 316 |
| 244 // If everything is already initialized, then return true. | 317 // If everything is already initialized, then return true. |
| 245 if (chaps_module_ && tpm_slot_) | 318 if (chaps_module_ && tpm_slot_) |
| 246 return true; | 319 return true; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 260 if (!chaps_module_ && test_slot_) { | 333 if (!chaps_module_ && test_slot_) { |
| 261 // chromeos_unittests try to test the TPM initialization process. If we | 334 // chromeos_unittests try to test the TPM initialization process. If we |
| 262 // have a test DB open, pretend that it is the TPM slot. | 335 // have a test DB open, pretend that it is the TPM slot. |
| 263 tpm_slot_ = PK11_ReferenceSlot(test_slot_); | 336 tpm_slot_ = PK11_ReferenceSlot(test_slot_); |
| 264 return true; | 337 return true; |
| 265 } | 338 } |
| 266 } | 339 } |
| 267 if (chaps_module_){ | 340 if (chaps_module_){ |
| 268 tpm_slot_ = GetTPMSlotForId(token_slot_id); | 341 tpm_slot_ = GetTPMSlotForId(token_slot_id); |
| 269 | 342 |
| 343 if (tpm_slot_) { | |
| 344 TPMReadyCallbackList callback_list; | |
| 345 callback_list.swap(tpm_ready_callback_list_); | |
| 346 for (TPMReadyCallbackList::iterator i = | |
| 347 callback_list.begin(); | |
| 348 i != callback_list.end(); | |
| 349 ++i) { | |
| 350 (*i).Run(); | |
| 351 } | |
| 352 } | |
| 353 | |
| 270 return tpm_slot_ != NULL; | 354 return tpm_slot_ != NULL; |
|
Ryan Sleevi
2013/12/04 20:59:55
Does this make sense to rewrite as
if (!tpm_slot_
mattm
2013/12/04 22:09:28
Done.
| |
| 271 } | 355 } |
| 272 return false; | 356 return false; |
| 273 } | 357 } |
| 274 | 358 |
| 275 bool IsTPMTokenReady() { | 359 bool IsTPMTokenReady(const base::Closure& callback) { |
| 276 // TODO(mattm): Change to DCHECK when callers have been fixed. | 360 if (!callback.is_null()) { |
| 277 if (!thread_checker_.CalledOnValidThread()) { | 361 // We can't add the DCHECK in the general case, but since the callback is |
| 362 // a new addition to the API, we can DCHECK when it is supplied to make | |
| 363 // sure at least some uses don't regress. | |
|
Ryan Sleevi
2013/12/04 20:59:55
same nit re: pronouns
mattm
2013/12/04 22:09:28
Done.
| |
| 364 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 365 } else if (!thread_checker_.CalledOnValidThread()) { | |
| 366 // TODO(mattm): Change to DCHECK when callers have been fixed. | |
| 278 DVLOG(1) << "Called on wrong thread.\n" | 367 DVLOG(1) << "Called on wrong thread.\n" |
| 279 << base::debug::StackTrace().ToString(); | 368 << base::debug::StackTrace().ToString(); |
| 280 } | 369 } |
| 281 | 370 |
| 282 return tpm_slot_ != NULL; | 371 if (tpm_slot_ != NULL) |
| 372 return true; | |
| 373 | |
| 374 if (!callback.is_null()) | |
| 375 tpm_ready_callback_list_.push_back(callback); | |
| 376 | |
| 377 return false; | |
| 283 } | 378 } |
| 284 | 379 |
| 285 // Note that CK_SLOT_ID is an unsigned long, but cryptohome gives us the slot | 380 // Note that CK_SLOT_ID is an unsigned long, but cryptohome gives us the slot |
| 286 // id as an int. This should be safe since this is only used with chaps, which | 381 // id as an int. This should be safe since this is only used with chaps, which |
| 287 // we also control. | 382 // we also control. |
| 288 PK11SlotInfo* GetTPMSlotForId(CK_SLOT_ID slot_id) { | 383 PK11SlotInfo* GetTPMSlotForId(CK_SLOT_ID slot_id) { |
| 289 DCHECK(thread_checker_.CalledOnValidThread()); | 384 DCHECK(thread_checker_.CalledOnValidThread()); |
| 290 | 385 |
| 291 if (!chaps_module_) | 386 if (!chaps_module_) |
| 292 return NULL; | 387 return NULL; |
| 293 | 388 |
| 294 VLOG(1) << "Poking chaps module."; | 389 DVLOG(3) << "Poking chaps module."; |
| 295 SECStatus rv = SECMOD_UpdateSlotList(chaps_module_); | 390 SECStatus rv = SECMOD_UpdateSlotList(chaps_module_); |
| 296 if (rv != SECSuccess) | 391 if (rv != SECSuccess) |
| 297 PLOG(ERROR) << "SECMOD_UpdateSlotList failed: " << PORT_GetError(); | 392 PLOG(ERROR) << "SECMOD_UpdateSlotList failed: " << PORT_GetError(); |
| 298 | 393 |
| 299 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module_->moduleID, slot_id); | 394 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module_->moduleID, slot_id); |
| 300 if (!slot) | 395 if (!slot) |
| 301 LOG(ERROR) << "TPM slot " << slot_id << " not found."; | 396 LOG(ERROR) << "TPM slot " << slot_id << " not found."; |
| 302 return slot; | 397 return slot; |
| 303 } | 398 } |
| 399 | |
| 400 bool InitializeNSSForChromeOSUser( | |
| 401 const std::string& email, | |
| 402 const std::string& username_hash, | |
| 403 bool is_primary_user, | |
| 404 const base::FilePath& path) { | |
| 405 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 406 if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) { | |
| 407 // This user already exists in our mapping. | |
| 408 DVLOG(2) << username_hash << " already initialized."; | |
| 409 return false; | |
| 410 } | |
| 411 ScopedPK11Slot public_slot; | |
| 412 if (is_primary_user) { | |
| 413 DVLOG(2) << "Primary user, using GetPublicNSSKeySlot()"; | |
| 414 public_slot.reset(GetPublicNSSKeySlot()); | |
| 415 } else { | |
| 416 DVLOG(2) << "Opening NSS DB " << path.value(); | |
| 417 public_slot.reset(OpenPersistentNSSDBForPath(path)); | |
| 418 } | |
| 419 chromeos_user_map_[username_hash] = | |
| 420 new ChromeOSUserData(public_slot.Pass(), is_primary_user); | |
| 421 return true; | |
| 422 } | |
| 423 | |
| 424 void InitializeTPMForChromeOSUser(const std::string& username_hash, | |
| 425 CK_SLOT_ID slot_id) { | |
| 426 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 427 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); | |
| 428 chromeos_user_map_[username_hash] | |
| 429 ->SetPrivateSlot(ScopedPK11Slot(GetTPMSlotForId(slot_id))); | |
| 430 } | |
| 431 | |
| 432 void InitializePrivateSoftwareSlotForChromeOSUser( | |
| 433 const std::string& username_hash) { | |
| 434 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 435 LOG(WARNING) << "using software private slot for " << username_hash; | |
| 436 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); | |
| 437 chromeos_user_map_[username_hash]->SetPrivateSlot( | |
| 438 chromeos_user_map_[username_hash]->GetPublicSlot()); | |
| 439 } | |
| 440 | |
| 441 ScopedPK11Slot GetPublicSlotForChromeOSUser( | |
| 442 const std::string& username_hash) { | |
| 443 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 444 if (test_slot_) { | |
| 445 DVLOG(2) << "returning test_slot_ for " << username_hash; | |
| 446 return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_)); | |
| 447 } | |
| 448 | |
| 449 if (chromeos_user_map_.find(username_hash) == chromeos_user_map_.end()) { | |
| 450 LOG(ERROR) << username_hash << " not initialized."; | |
| 451 return ScopedPK11Slot(); | |
| 452 } | |
| 453 return chromeos_user_map_[username_hash]->GetPublicSlot(); | |
| 454 } | |
| 455 | |
| 456 ScopedPK11Slot GetPrivateSlotForChromeOSUser( | |
| 457 const std::string& username_hash, | |
| 458 const base::Callback<void(ScopedPK11Slot)>& callback) { | |
| 459 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 460 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); | |
| 461 | |
| 462 if (test_slot_) { | |
| 463 DVLOG(2) << "returning test_slot_ for " << username_hash; | |
| 464 return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_)); | |
| 465 } | |
| 466 | |
| 467 return chromeos_user_map_[username_hash]->GetPrivateSlot(callback); | |
| 468 } | |
| 304 #endif // defined(OS_CHROMEOS) | 469 #endif // defined(OS_CHROMEOS) |
| 305 | 470 |
| 306 | 471 |
| 307 bool OpenTestNSSDB() { | 472 bool OpenTestNSSDB() { |
| 308 DCHECK(thread_checker_.CalledOnValidThread()); | 473 DCHECK(thread_checker_.CalledOnValidThread()); |
| 309 | 474 |
| 310 if (test_slot_) | 475 if (test_slot_) |
| 311 return true; | 476 return true; |
| 312 if (!g_test_nss_db_dir.Get().CreateUniqueTempDir()) | 477 if (!g_test_nss_db_dir.Get().CreateUniqueTempDir()) |
| 313 return false; | 478 return false; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 347 if (!thread_checker_.CalledOnValidThread()) { | 512 if (!thread_checker_.CalledOnValidThread()) { |
| 348 DVLOG(1) << "Called on wrong thread.\n" | 513 DVLOG(1) << "Called on wrong thread.\n" |
| 349 << base::debug::StackTrace().ToString(); | 514 << base::debug::StackTrace().ToString(); |
| 350 } | 515 } |
| 351 | 516 |
| 352 if (test_slot_) | 517 if (test_slot_) |
| 353 return PK11_ReferenceSlot(test_slot_); | 518 return PK11_ReferenceSlot(test_slot_); |
| 354 | 519 |
| 355 #if defined(OS_CHROMEOS) | 520 #if defined(OS_CHROMEOS) |
| 356 if (tpm_token_enabled_for_nss_) { | 521 if (tpm_token_enabled_for_nss_) { |
| 357 if (IsTPMTokenReady()) { | 522 if (IsTPMTokenReady(base::Closure())) { |
| 358 return PK11_ReferenceSlot(tpm_slot_); | 523 return PK11_ReferenceSlot(tpm_slot_); |
| 359 } else { | 524 } else { |
| 360 // If we were supposed to get the hardware token, but were | 525 // If we were supposed to get the hardware token, but were |
| 361 // unable to, return NULL rather than fall back to sofware. | 526 // unable to, return NULL rather than fall back to sofware. |
| 362 return NULL; | 527 return NULL; |
| 363 } | 528 } |
| 364 } | 529 } |
| 365 #endif | 530 #endif |
| 366 // If we weren't supposed to enable the TPM for NSS, then return | 531 // If we weren't supposed to enable the TPM for NSS, then return |
| 367 // the software slot. | 532 // the software slot. |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 base::TimeTicks::Now() - start_time, | 663 base::TimeTicks::Now() - start_time, |
| 499 base::TimeDelta::FromMilliseconds(10), | 664 base::TimeDelta::FromMilliseconds(10), |
| 500 base::TimeDelta::FromHours(1), | 665 base::TimeDelta::FromHours(1), |
| 501 50); | 666 50); |
| 502 } | 667 } |
| 503 | 668 |
| 504 // NOTE(willchan): We don't actually execute this code since we leak NSS to | 669 // NOTE(willchan): We don't actually execute this code since we leak NSS to |
| 505 // prevent non-joinable threads from using NSS after it's already been shut | 670 // prevent non-joinable threads from using NSS after it's already been shut |
| 506 // down. | 671 // down. |
| 507 ~NSSInitSingleton() { | 672 ~NSSInitSingleton() { |
| 673 #if defined(OS_CHROMEOS) | |
| 674 STLDeleteValues(&chromeos_user_map_); | |
| 675 #endif | |
| 508 if (tpm_slot_) { | 676 if (tpm_slot_) { |
| 509 PK11_FreeSlot(tpm_slot_); | 677 PK11_FreeSlot(tpm_slot_); |
| 510 tpm_slot_ = NULL; | 678 tpm_slot_ = NULL; |
| 511 } | 679 } |
| 512 if (software_slot_) { | 680 if (software_slot_) { |
| 513 SECMOD_CloseUserDB(software_slot_); | 681 SECMOD_CloseUserDB(software_slot_); |
| 514 PK11_FreeSlot(software_slot_); | 682 PK11_FreeSlot(software_slot_); |
| 515 software_slot_ = NULL; | 683 software_slot_ = NULL; |
| 516 } | 684 } |
| 517 CloseTestNSSDB(); | 685 CloseTestNSSDB(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 605 if (cpu.has_avx_hardware() && !cpu.has_avx()) { | 773 if (cpu.has_avx_hardware() && !cpu.has_avx()) { |
| 606 base::Environment::Create()->SetVar("NSS_DISABLE_HW_AES", "1"); | 774 base::Environment::Create()->SetVar("NSS_DISABLE_HW_AES", "1"); |
| 607 } | 775 } |
| 608 } | 776 } |
| 609 } | 777 } |
| 610 | 778 |
| 611 // If this is set to true NSS is forced to be initialized without a DB. | 779 // If this is set to true NSS is forced to be initialized without a DB. |
| 612 static bool force_nodb_init_; | 780 static bool force_nodb_init_; |
| 613 | 781 |
| 614 bool tpm_token_enabled_for_nss_; | 782 bool tpm_token_enabled_for_nss_; |
| 783 typedef std::vector<base::Closure> TPMReadyCallbackList; | |
| 784 TPMReadyCallbackList tpm_ready_callback_list_; | |
| 615 SECMODModule* chaps_module_; | 785 SECMODModule* chaps_module_; |
| 616 PK11SlotInfo* software_slot_; | 786 PK11SlotInfo* software_slot_; |
| 617 PK11SlotInfo* test_slot_; | 787 PK11SlotInfo* test_slot_; |
| 618 PK11SlotInfo* tpm_slot_; | 788 PK11SlotInfo* tpm_slot_; |
| 619 SECMODModule* root_; | 789 SECMODModule* root_; |
| 620 bool chromeos_user_logged_in_; | 790 bool chromeos_user_logged_in_; |
| 791 #if defined(OS_CHROMEOS) | |
| 792 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap; | |
| 793 ChromeOSUserMap chromeos_user_map_; | |
| 794 #endif | |
| 621 #if defined(USE_NSS) | 795 #if defined(USE_NSS) |
| 622 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 | 796 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 |
| 623 // is fixed, we will no longer need the lock. | 797 // is fixed, we will no longer need the lock. |
| 624 base::Lock write_lock_; | 798 base::Lock write_lock_; |
| 625 #endif // defined(USE_NSS) | 799 #endif // defined(USE_NSS) |
| 626 | 800 |
| 627 base::ThreadChecker thread_checker_; | 801 base::ThreadChecker thread_checker_; |
| 628 }; | 802 }; |
| 629 | 803 |
| 630 // static | 804 // static |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 774 | 948 |
| 775 #if defined(OS_CHROMEOS) | 949 #if defined(OS_CHROMEOS) |
| 776 void OpenPersistentNSSDB() { | 950 void OpenPersistentNSSDB() { |
| 777 g_nss_singleton.Get().OpenPersistentNSSDB(); | 951 g_nss_singleton.Get().OpenPersistentNSSDB(); |
| 778 } | 952 } |
| 779 | 953 |
| 780 void EnableTPMTokenForNSS() { | 954 void EnableTPMTokenForNSS() { |
| 781 g_nss_singleton.Get().EnableTPMTokenForNSS(); | 955 g_nss_singleton.Get().EnableTPMTokenForNSS(); |
| 782 } | 956 } |
| 783 | 957 |
| 784 bool IsTPMTokenReady() { | 958 bool IsTPMTokenEnabledForNSS() { |
| 785 return g_nss_singleton.Get().IsTPMTokenReady(); | 959 return g_nss_singleton.Get().IsTPMTokenEnabledForNSS(); |
| 960 } | |
| 961 | |
| 962 bool IsTPMTokenReady(const base::Closure& callback) { | |
| 963 return g_nss_singleton.Get().IsTPMTokenReady(callback); | |
| 786 } | 964 } |
| 787 | 965 |
| 788 bool InitializeTPMToken(int token_slot_id) { | 966 bool InitializeTPMToken(int token_slot_id) { |
| 789 return g_nss_singleton.Get().InitializeTPMToken(token_slot_id); | 967 return g_nss_singleton.Get().InitializeTPMToken(token_slot_id); |
| 790 } | 968 } |
| 969 | |
| 970 bool InitializeNSSForChromeOSUser( | |
| 971 const std::string& email, | |
| 972 const std::string& username_hash, | |
| 973 bool is_primary_user, | |
| 974 const base::FilePath& path) { | |
| 975 return g_nss_singleton.Get().InitializeNSSForChromeOSUser( | |
| 976 email, username_hash, is_primary_user, path); | |
| 977 } | |
| 978 void InitializeTPMForChromeOSUser( | |
| 979 const std::string& username_hash, | |
| 980 CK_SLOT_ID slot_id) { | |
| 981 g_nss_singleton.Get().InitializeTPMForChromeOSUser(username_hash, slot_id); | |
| 982 } | |
| 983 void InitializePrivateSoftwareSlotForChromeOSUser( | |
| 984 const std::string& username_hash) { | |
| 985 g_nss_singleton.Get().InitializePrivateSoftwareSlotForChromeOSUser( | |
| 986 username_hash); | |
| 987 } | |
| 988 ScopedPK11Slot GetPublicSlotForChromeOSUser(const std::string& username_hash) { | |
| 989 return g_nss_singleton.Get().GetPublicSlotForChromeOSUser(username_hash); | |
| 990 } | |
| 991 ScopedPK11Slot GetPrivateSlotForChromeOSUser( | |
| 992 const std::string& username_hash, | |
| 993 const base::Callback<void(ScopedPK11Slot)>& callback) { | |
| 994 return g_nss_singleton.Get().GetPrivateSlotForChromeOSUser(username_hash, | |
| 995 callback); | |
| 996 } | |
| 791 #endif // defined(OS_CHROMEOS) | 997 #endif // defined(OS_CHROMEOS) |
| 792 | 998 |
| 793 base::Time PRTimeToBaseTime(PRTime prtime) { | 999 base::Time PRTimeToBaseTime(PRTime prtime) { |
| 794 return base::Time::FromInternalValue( | 1000 return base::Time::FromInternalValue( |
| 795 prtime + base::Time::UnixEpoch().ToInternalValue()); | 1001 prtime + base::Time::UnixEpoch().ToInternalValue()); |
| 796 } | 1002 } |
| 797 | 1003 |
| 798 PRTime BaseTimeToPRTime(base::Time time) { | 1004 PRTime BaseTimeToPRTime(base::Time time) { |
| 799 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); | 1005 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); |
| 800 } | 1006 } |
| 801 | 1007 |
| 802 PK11SlotInfo* GetPublicNSSKeySlot() { | 1008 PK11SlotInfo* GetPublicNSSKeySlot() { |
| 803 return g_nss_singleton.Get().GetPublicNSSKeySlot(); | 1009 return g_nss_singleton.Get().GetPublicNSSKeySlot(); |
| 804 } | 1010 } |
| 805 | 1011 |
| 806 PK11SlotInfo* GetPrivateNSSKeySlot() { | 1012 PK11SlotInfo* GetPrivateNSSKeySlot() { |
| 807 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); | 1013 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); |
| 808 } | 1014 } |
| 809 | 1015 |
| 810 } // namespace crypto | 1016 } // namespace crypto |
| OLD | NEW |