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 |