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 = base::GetHomeDir(); | 85 base::FilePath dir = base::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 (!base::CreateDirectory(dir)) { | 91 if (!base::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()), |
| 216 is_primary_user_(is_primary_user) {} |
| 217 ~ChromeOSUserData() { |
| 218 if (public_slot_ && !is_primary_user_) { |
| 219 SECStatus status = SECMOD_CloseUserDB(public_slot_.get()); |
| 220 if (status != SECSuccess) |
| 221 PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError(); |
| 222 } |
| 223 } |
| 224 |
| 225 ScopedPK11Slot GetPublicSlot() { |
| 226 return ScopedPK11Slot( |
| 227 public_slot_ ? PK11_ReferenceSlot(public_slot_.get()) : NULL); |
| 228 } |
| 229 |
| 230 ScopedPK11Slot GetPrivateSlot( |
| 231 const base::Callback<void(ScopedPK11Slot)>& callback) { |
| 232 if (private_slot_) |
| 233 return ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get())); |
| 234 if (!callback.is_null()) |
| 235 tpm_ready_callback_list_.push_back(callback); |
| 236 return ScopedPK11Slot(); |
| 237 } |
| 238 |
| 239 void SetPrivateSlot(ScopedPK11Slot private_slot) { |
| 240 DCHECK(!private_slot_); |
| 241 private_slot_ = private_slot.Pass(); |
| 242 |
| 243 SlotReadyCallbackList callback_list; |
| 244 callback_list.swap(tpm_ready_callback_list_); |
| 245 for (SlotReadyCallbackList::iterator i = callback_list.begin(); |
| 246 i != callback_list.end(); |
| 247 ++i) { |
| 248 (*i).Run(ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get()))); |
| 249 } |
| 250 } |
| 251 |
| 252 private: |
| 253 ScopedPK11Slot public_slot_; |
| 254 ScopedPK11Slot private_slot_; |
| 255 bool is_primary_user_; |
| 256 |
| 257 typedef std::vector<base::Callback<void(ScopedPK11Slot)> > |
| 258 SlotReadyCallbackList; |
| 259 SlotReadyCallbackList tpm_ready_callback_list_; |
| 260 }; |
| 261 #endif // defined(OS_CHROMEOS) |
| 262 |
207 class NSSInitSingleton { | 263 class NSSInitSingleton { |
208 public: | 264 public: |
209 #if defined(OS_CHROMEOS) | 265 #if defined(OS_CHROMEOS) |
210 void OpenPersistentNSSDB() { | 266 void OpenPersistentNSSDB() { |
211 DCHECK(thread_checker_.CalledOnValidThread()); | 267 DCHECK(thread_checker_.CalledOnValidThread()); |
212 | 268 |
213 if (!chromeos_user_logged_in_) { | 269 if (!chromeos_user_logged_in_) { |
214 // GetDefaultConfigDirectory causes us to do blocking IO on UI thread. | 270 // GetDefaultConfigDirectory causes us to do blocking IO on UI thread. |
215 // Temporarily allow it until we fix http://crbug.com/70119 | 271 // Temporarily allow it until we fix http://crbug.com/70119 |
216 base::ThreadRestrictions::ScopedAllowIO allow_io; | 272 base::ThreadRestrictions::ScopedAllowIO allow_io; |
217 chromeos_user_logged_in_ = true; | 273 chromeos_user_logged_in_ = true; |
218 | 274 |
219 // This creates another DB slot in NSS that is read/write, unlike | 275 // This creates another DB slot in NSS that is read/write, unlike |
220 // the fake root CA cert DB and the "default" crypto key | 276 // the fake root CA cert DB and the "default" crypto key |
221 // provider, which are still read-only (because we initialized | 277 // provider, which are still read-only (because we initialized |
222 // NSS before we had a cryptohome mounted). | 278 // NSS before we had a cryptohome mounted). |
223 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), | 279 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), |
224 kNSSDatabaseName); | 280 kNSSDatabaseName); |
225 } | 281 } |
226 } | 282 } |
227 | 283 |
| 284 PK11SlotInfo* OpenPersistentNSSDBForPath(const base::FilePath& path) { |
| 285 DCHECK(thread_checker_.CalledOnValidThread()); |
| 286 // NSS is allowed to do IO on the current thread since dispatching |
| 287 // to a dedicated thread would still have the affect of blocking |
| 288 // the current thread, due to NSS's internal locking requirements |
| 289 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 290 |
| 291 base::FilePath nssdb_path = path.AppendASCII(".pki").AppendASCII("nssdb"); |
| 292 if (!base::CreateDirectory(nssdb_path)) { |
| 293 LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory."; |
| 294 return NULL; |
| 295 } |
| 296 return OpenUserDB(nssdb_path, kNSSDatabaseName); |
| 297 } |
| 298 |
228 void EnableTPMTokenForNSS() { | 299 void EnableTPMTokenForNSS() { |
229 DCHECK(thread_checker_.CalledOnValidThread()); | 300 DCHECK(thread_checker_.CalledOnValidThread()); |
230 | 301 |
231 // If this gets set, then we'll use the TPM for certs with | 302 // If this gets set, then we'll use the TPM for certs with |
232 // private keys, otherwise we'll fall back to the software | 303 // private keys, otherwise we'll fall back to the software |
233 // implementation. | 304 // implementation. |
234 tpm_token_enabled_for_nss_ = true; | 305 tpm_token_enabled_for_nss_ = true; |
235 } | 306 } |
236 | 307 |
| 308 bool IsTPMTokenEnabledForNSS() { |
| 309 DCHECK(thread_checker_.CalledOnValidThread()); |
| 310 return tpm_token_enabled_for_nss_; |
| 311 } |
| 312 |
237 bool InitializeTPMToken(int token_slot_id) { | 313 bool InitializeTPMToken(int token_slot_id) { |
238 DCHECK(thread_checker_.CalledOnValidThread()); | 314 DCHECK(thread_checker_.CalledOnValidThread()); |
239 | 315 |
240 // If EnableTPMTokenForNSS hasn't been called, return false. | 316 // If EnableTPMTokenForNSS hasn't been called, return false. |
241 if (!tpm_token_enabled_for_nss_) | 317 if (!tpm_token_enabled_for_nss_) |
242 return false; | 318 return false; |
243 | 319 |
244 // If everything is already initialized, then return true. | 320 // If everything is already initialized, then return true. |
245 if (chaps_module_ && tpm_slot_) | 321 if (chaps_module_ && tpm_slot_) |
246 return true; | 322 return true; |
(...skipping 13 matching lines...) Expand all Loading... |
260 if (!chaps_module_ && test_slot_) { | 336 if (!chaps_module_ && test_slot_) { |
261 // chromeos_unittests try to test the TPM initialization process. If we | 337 // chromeos_unittests try to test the TPM initialization process. If we |
262 // have a test DB open, pretend that it is the TPM slot. | 338 // have a test DB open, pretend that it is the TPM slot. |
263 tpm_slot_ = PK11_ReferenceSlot(test_slot_); | 339 tpm_slot_ = PK11_ReferenceSlot(test_slot_); |
264 return true; | 340 return true; |
265 } | 341 } |
266 } | 342 } |
267 if (chaps_module_){ | 343 if (chaps_module_){ |
268 tpm_slot_ = GetTPMSlotForId(token_slot_id); | 344 tpm_slot_ = GetTPMSlotForId(token_slot_id); |
269 | 345 |
270 return tpm_slot_ != NULL; | 346 if (!tpm_slot_) |
| 347 return false; |
| 348 |
| 349 TPMReadyCallbackList callback_list; |
| 350 callback_list.swap(tpm_ready_callback_list_); |
| 351 for (TPMReadyCallbackList::iterator i = |
| 352 callback_list.begin(); |
| 353 i != callback_list.end(); |
| 354 ++i) { |
| 355 (*i).Run(); |
| 356 } |
| 357 |
| 358 return true; |
271 } | 359 } |
272 return false; | 360 return false; |
273 } | 361 } |
274 | 362 |
275 bool IsTPMTokenReady() { | 363 bool IsTPMTokenReady(const base::Closure& callback) { |
276 // TODO(mattm): Change to DCHECK when callers have been fixed. | 364 if (!callback.is_null()) { |
277 if (!thread_checker_.CalledOnValidThread()) { | 365 // Cannot DCHECK in the general case yet, but since the callback is |
| 366 // a new addition to the API, DCHECK to make sure at least the new uses |
| 367 // don't regress. |
| 368 DCHECK(thread_checker_.CalledOnValidThread()); |
| 369 } else if (!thread_checker_.CalledOnValidThread()) { |
| 370 // TODO(mattm): Change to DCHECK when callers have been fixed. |
278 DVLOG(1) << "Called on wrong thread.\n" | 371 DVLOG(1) << "Called on wrong thread.\n" |
279 << base::debug::StackTrace().ToString(); | 372 << base::debug::StackTrace().ToString(); |
280 } | 373 } |
281 | 374 |
282 return tpm_slot_ != NULL; | 375 if (tpm_slot_ != NULL) |
| 376 return true; |
| 377 |
| 378 if (!callback.is_null()) |
| 379 tpm_ready_callback_list_.push_back(callback); |
| 380 |
| 381 return false; |
283 } | 382 } |
284 | 383 |
285 // Note that CK_SLOT_ID is an unsigned long, but cryptohome gives us the slot | 384 // 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 | 385 // id as an int. This should be safe since this is only used with chaps, which |
287 // we also control. | 386 // we also control. |
288 PK11SlotInfo* GetTPMSlotForId(CK_SLOT_ID slot_id) { | 387 PK11SlotInfo* GetTPMSlotForId(CK_SLOT_ID slot_id) { |
289 DCHECK(thread_checker_.CalledOnValidThread()); | 388 DCHECK(thread_checker_.CalledOnValidThread()); |
290 | 389 |
291 if (!chaps_module_) | 390 if (!chaps_module_) |
292 return NULL; | 391 return NULL; |
293 | 392 |
294 VLOG(1) << "Poking chaps module."; | 393 DVLOG(3) << "Poking chaps module."; |
295 SECStatus rv = SECMOD_UpdateSlotList(chaps_module_); | 394 SECStatus rv = SECMOD_UpdateSlotList(chaps_module_); |
296 if (rv != SECSuccess) | 395 if (rv != SECSuccess) |
297 PLOG(ERROR) << "SECMOD_UpdateSlotList failed: " << PORT_GetError(); | 396 PLOG(ERROR) << "SECMOD_UpdateSlotList failed: " << PORT_GetError(); |
298 | 397 |
299 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module_->moduleID, slot_id); | 398 PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module_->moduleID, slot_id); |
300 if (!slot) | 399 if (!slot) |
301 LOG(ERROR) << "TPM slot " << slot_id << " not found."; | 400 LOG(ERROR) << "TPM slot " << slot_id << " not found."; |
302 return slot; | 401 return slot; |
303 } | 402 } |
| 403 |
| 404 bool InitializeNSSForChromeOSUser( |
| 405 const std::string& email, |
| 406 const std::string& username_hash, |
| 407 bool is_primary_user, |
| 408 const base::FilePath& path) { |
| 409 DCHECK(thread_checker_.CalledOnValidThread()); |
| 410 if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) { |
| 411 // This user already exists in our mapping. |
| 412 DVLOG(2) << username_hash << " already initialized."; |
| 413 return false; |
| 414 } |
| 415 ScopedPK11Slot public_slot; |
| 416 if (is_primary_user) { |
| 417 DVLOG(2) << "Primary user, using GetPublicNSSKeySlot()"; |
| 418 public_slot.reset(GetPublicNSSKeySlot()); |
| 419 } else { |
| 420 DVLOG(2) << "Opening NSS DB " << path.value(); |
| 421 public_slot.reset(OpenPersistentNSSDBForPath(path)); |
| 422 } |
| 423 chromeos_user_map_[username_hash] = |
| 424 new ChromeOSUserData(public_slot.Pass(), is_primary_user); |
| 425 return true; |
| 426 } |
| 427 |
| 428 void InitializeTPMForChromeOSUser(const std::string& username_hash, |
| 429 CK_SLOT_ID slot_id) { |
| 430 DCHECK(thread_checker_.CalledOnValidThread()); |
| 431 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); |
| 432 chromeos_user_map_[username_hash] |
| 433 ->SetPrivateSlot(ScopedPK11Slot(GetTPMSlotForId(slot_id))); |
| 434 } |
| 435 |
| 436 void InitializePrivateSoftwareSlotForChromeOSUser( |
| 437 const std::string& username_hash) { |
| 438 DCHECK(thread_checker_.CalledOnValidThread()); |
| 439 LOG(WARNING) << "using software private slot for " << username_hash; |
| 440 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); |
| 441 chromeos_user_map_[username_hash]->SetPrivateSlot( |
| 442 chromeos_user_map_[username_hash]->GetPublicSlot()); |
| 443 } |
| 444 |
| 445 ScopedPK11Slot GetPublicSlotForChromeOSUser( |
| 446 const std::string& username_hash) { |
| 447 DCHECK(thread_checker_.CalledOnValidThread()); |
| 448 if (test_slot_) { |
| 449 DVLOG(2) << "returning test_slot_ for " << username_hash; |
| 450 return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_)); |
| 451 } |
| 452 |
| 453 if (chromeos_user_map_.find(username_hash) == chromeos_user_map_.end()) { |
| 454 LOG(ERROR) << username_hash << " not initialized."; |
| 455 return ScopedPK11Slot(); |
| 456 } |
| 457 return chromeos_user_map_[username_hash]->GetPublicSlot(); |
| 458 } |
| 459 |
| 460 ScopedPK11Slot GetPrivateSlotForChromeOSUser( |
| 461 const std::string& username_hash, |
| 462 const base::Callback<void(ScopedPK11Slot)>& callback) { |
| 463 DCHECK(thread_checker_.CalledOnValidThread()); |
| 464 DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()); |
| 465 |
| 466 if (test_slot_) { |
| 467 DVLOG(2) << "returning test_slot_ for " << username_hash; |
| 468 return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_)); |
| 469 } |
| 470 |
| 471 return chromeos_user_map_[username_hash]->GetPrivateSlot(callback); |
| 472 } |
304 #endif // defined(OS_CHROMEOS) | 473 #endif // defined(OS_CHROMEOS) |
305 | 474 |
306 | 475 |
307 bool OpenTestNSSDB() { | 476 bool OpenTestNSSDB() { |
308 DCHECK(thread_checker_.CalledOnValidThread()); | 477 DCHECK(thread_checker_.CalledOnValidThread()); |
| 478 // NSS is allowed to do IO on the current thread since dispatching |
| 479 // to a dedicated thread would still have the affect of blocking |
| 480 // the current thread, due to NSS's internal locking requirements |
| 481 base::ThreadRestrictions::ScopedAllowIO allow_io; |
309 | 482 |
310 if (test_slot_) | 483 if (test_slot_) |
311 return true; | 484 return true; |
312 if (!g_test_nss_db_dir.Get().CreateUniqueTempDir()) | 485 if (!g_test_nss_db_dir.Get().CreateUniqueTempDir()) |
313 return false; | 486 return false; |
314 test_slot_ = OpenUserDB(g_test_nss_db_dir.Get().path(), kTestTPMTokenName); | 487 test_slot_ = OpenUserDB(g_test_nss_db_dir.Get().path(), kTestTPMTokenName); |
315 return !!test_slot_; | 488 return !!test_slot_; |
316 } | 489 } |
317 | 490 |
318 void CloseTestNSSDB() { | 491 void CloseTestNSSDB() { |
319 DCHECK(thread_checker_.CalledOnValidThread()); | 492 DCHECK(thread_checker_.CalledOnValidThread()); |
| 493 // NSS is allowed to do IO on the current thread since dispatching |
| 494 // to a dedicated thread would still have the affect of blocking |
| 495 // the current thread, due to NSS's internal locking requirements |
| 496 base::ThreadRestrictions::ScopedAllowIO allow_io; |
320 | 497 |
321 if (!test_slot_) | 498 if (!test_slot_) |
322 return; | 499 return; |
323 SECStatus status = SECMOD_CloseUserDB(test_slot_); | 500 SECStatus status = SECMOD_CloseUserDB(test_slot_); |
324 if (status != SECSuccess) | 501 if (status != SECSuccess) |
325 PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError(); | 502 PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError(); |
326 PK11_FreeSlot(test_slot_); | 503 PK11_FreeSlot(test_slot_); |
327 test_slot_ = NULL; | 504 test_slot_ = NULL; |
328 ignore_result(g_test_nss_db_dir.Get().Delete()); | 505 ignore_result(g_test_nss_db_dir.Get().Delete()); |
329 } | 506 } |
(...skipping 17 matching lines...) Expand all Loading... |
347 if (!thread_checker_.CalledOnValidThread()) { | 524 if (!thread_checker_.CalledOnValidThread()) { |
348 DVLOG(1) << "Called on wrong thread.\n" | 525 DVLOG(1) << "Called on wrong thread.\n" |
349 << base::debug::StackTrace().ToString(); | 526 << base::debug::StackTrace().ToString(); |
350 } | 527 } |
351 | 528 |
352 if (test_slot_) | 529 if (test_slot_) |
353 return PK11_ReferenceSlot(test_slot_); | 530 return PK11_ReferenceSlot(test_slot_); |
354 | 531 |
355 #if defined(OS_CHROMEOS) | 532 #if defined(OS_CHROMEOS) |
356 if (tpm_token_enabled_for_nss_) { | 533 if (tpm_token_enabled_for_nss_) { |
357 if (IsTPMTokenReady()) { | 534 if (IsTPMTokenReady(base::Closure())) { |
358 return PK11_ReferenceSlot(tpm_slot_); | 535 return PK11_ReferenceSlot(tpm_slot_); |
359 } else { | 536 } else { |
360 // If we were supposed to get the hardware token, but were | 537 // If we were supposed to get the hardware token, but were |
361 // unable to, return NULL rather than fall back to sofware. | 538 // unable to, return NULL rather than fall back to sofware. |
362 return NULL; | 539 return NULL; |
363 } | 540 } |
364 } | 541 } |
365 #endif | 542 #endif |
366 // If we weren't supposed to enable the TPM for NSS, then return | 543 // If we weren't supposed to enable the TPM for NSS, then return |
367 // the software slot. | 544 // the software slot. |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 base::TimeTicks::Now() - start_time, | 675 base::TimeTicks::Now() - start_time, |
499 base::TimeDelta::FromMilliseconds(10), | 676 base::TimeDelta::FromMilliseconds(10), |
500 base::TimeDelta::FromHours(1), | 677 base::TimeDelta::FromHours(1), |
501 50); | 678 50); |
502 } | 679 } |
503 | 680 |
504 // NOTE(willchan): We don't actually execute this code since we leak NSS to | 681 // 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 | 682 // prevent non-joinable threads from using NSS after it's already been shut |
506 // down. | 683 // down. |
507 ~NSSInitSingleton() { | 684 ~NSSInitSingleton() { |
| 685 #if defined(OS_CHROMEOS) |
| 686 STLDeleteValues(&chromeos_user_map_); |
| 687 #endif |
508 if (tpm_slot_) { | 688 if (tpm_slot_) { |
509 PK11_FreeSlot(tpm_slot_); | 689 PK11_FreeSlot(tpm_slot_); |
510 tpm_slot_ = NULL; | 690 tpm_slot_ = NULL; |
511 } | 691 } |
512 if (software_slot_) { | 692 if (software_slot_) { |
513 SECMOD_CloseUserDB(software_slot_); | 693 SECMOD_CloseUserDB(software_slot_); |
514 PK11_FreeSlot(software_slot_); | 694 PK11_FreeSlot(software_slot_); |
515 software_slot_ = NULL; | 695 software_slot_ = NULL; |
516 } | 696 } |
517 CloseTestNSSDB(); | 697 CloseTestNSSDB(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 if (cpu.has_avx_hardware() && !cpu.has_avx()) { | 785 if (cpu.has_avx_hardware() && !cpu.has_avx()) { |
606 base::Environment::Create()->SetVar("NSS_DISABLE_HW_AES", "1"); | 786 base::Environment::Create()->SetVar("NSS_DISABLE_HW_AES", "1"); |
607 } | 787 } |
608 } | 788 } |
609 } | 789 } |
610 | 790 |
611 // If this is set to true NSS is forced to be initialized without a DB. | 791 // If this is set to true NSS is forced to be initialized without a DB. |
612 static bool force_nodb_init_; | 792 static bool force_nodb_init_; |
613 | 793 |
614 bool tpm_token_enabled_for_nss_; | 794 bool tpm_token_enabled_for_nss_; |
| 795 typedef std::vector<base::Closure> TPMReadyCallbackList; |
| 796 TPMReadyCallbackList tpm_ready_callback_list_; |
615 SECMODModule* chaps_module_; | 797 SECMODModule* chaps_module_; |
616 PK11SlotInfo* software_slot_; | 798 PK11SlotInfo* software_slot_; |
617 PK11SlotInfo* test_slot_; | 799 PK11SlotInfo* test_slot_; |
618 PK11SlotInfo* tpm_slot_; | 800 PK11SlotInfo* tpm_slot_; |
619 SECMODModule* root_; | 801 SECMODModule* root_; |
620 bool chromeos_user_logged_in_; | 802 bool chromeos_user_logged_in_; |
| 803 #if defined(OS_CHROMEOS) |
| 804 typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap; |
| 805 ChromeOSUserMap chromeos_user_map_; |
| 806 #endif |
621 #if defined(USE_NSS) | 807 #if defined(USE_NSS) |
622 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 | 808 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 |
623 // is fixed, we will no longer need the lock. | 809 // is fixed, we will no longer need the lock. |
624 base::Lock write_lock_; | 810 base::Lock write_lock_; |
625 #endif // defined(USE_NSS) | 811 #endif // defined(USE_NSS) |
626 | 812 |
627 base::ThreadChecker thread_checker_; | 813 base::ThreadChecker thread_checker_; |
628 }; | 814 }; |
629 | 815 |
630 // static | 816 // static |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 | 960 |
775 #if defined(OS_CHROMEOS) | 961 #if defined(OS_CHROMEOS) |
776 void OpenPersistentNSSDB() { | 962 void OpenPersistentNSSDB() { |
777 g_nss_singleton.Get().OpenPersistentNSSDB(); | 963 g_nss_singleton.Get().OpenPersistentNSSDB(); |
778 } | 964 } |
779 | 965 |
780 void EnableTPMTokenForNSS() { | 966 void EnableTPMTokenForNSS() { |
781 g_nss_singleton.Get().EnableTPMTokenForNSS(); | 967 g_nss_singleton.Get().EnableTPMTokenForNSS(); |
782 } | 968 } |
783 | 969 |
784 bool IsTPMTokenReady() { | 970 bool IsTPMTokenEnabledForNSS() { |
785 return g_nss_singleton.Get().IsTPMTokenReady(); | 971 return g_nss_singleton.Get().IsTPMTokenEnabledForNSS(); |
| 972 } |
| 973 |
| 974 bool IsTPMTokenReady(const base::Closure& callback) { |
| 975 return g_nss_singleton.Get().IsTPMTokenReady(callback); |
786 } | 976 } |
787 | 977 |
788 bool InitializeTPMToken(int token_slot_id) { | 978 bool InitializeTPMToken(int token_slot_id) { |
789 return g_nss_singleton.Get().InitializeTPMToken(token_slot_id); | 979 return g_nss_singleton.Get().InitializeTPMToken(token_slot_id); |
790 } | 980 } |
| 981 |
| 982 bool InitializeNSSForChromeOSUser( |
| 983 const std::string& email, |
| 984 const std::string& username_hash, |
| 985 bool is_primary_user, |
| 986 const base::FilePath& path) { |
| 987 return g_nss_singleton.Get().InitializeNSSForChromeOSUser( |
| 988 email, username_hash, is_primary_user, path); |
| 989 } |
| 990 void InitializeTPMForChromeOSUser( |
| 991 const std::string& username_hash, |
| 992 CK_SLOT_ID slot_id) { |
| 993 g_nss_singleton.Get().InitializeTPMForChromeOSUser(username_hash, slot_id); |
| 994 } |
| 995 void InitializePrivateSoftwareSlotForChromeOSUser( |
| 996 const std::string& username_hash) { |
| 997 g_nss_singleton.Get().InitializePrivateSoftwareSlotForChromeOSUser( |
| 998 username_hash); |
| 999 } |
| 1000 ScopedPK11Slot GetPublicSlotForChromeOSUser(const std::string& username_hash) { |
| 1001 return g_nss_singleton.Get().GetPublicSlotForChromeOSUser(username_hash); |
| 1002 } |
| 1003 ScopedPK11Slot GetPrivateSlotForChromeOSUser( |
| 1004 const std::string& username_hash, |
| 1005 const base::Callback<void(ScopedPK11Slot)>& callback) { |
| 1006 return g_nss_singleton.Get().GetPrivateSlotForChromeOSUser(username_hash, |
| 1007 callback); |
| 1008 } |
791 #endif // defined(OS_CHROMEOS) | 1009 #endif // defined(OS_CHROMEOS) |
792 | 1010 |
793 base::Time PRTimeToBaseTime(PRTime prtime) { | 1011 base::Time PRTimeToBaseTime(PRTime prtime) { |
794 return base::Time::FromInternalValue( | 1012 return base::Time::FromInternalValue( |
795 prtime + base::Time::UnixEpoch().ToInternalValue()); | 1013 prtime + base::Time::UnixEpoch().ToInternalValue()); |
796 } | 1014 } |
797 | 1015 |
798 PRTime BaseTimeToPRTime(base::Time time) { | 1016 PRTime BaseTimeToPRTime(base::Time time) { |
799 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); | 1017 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); |
800 } | 1018 } |
801 | 1019 |
802 PK11SlotInfo* GetPublicNSSKeySlot() { | 1020 PK11SlotInfo* GetPublicNSSKeySlot() { |
803 return g_nss_singleton.Get().GetPublicNSSKeySlot(); | 1021 return g_nss_singleton.Get().GetPublicNSSKeySlot(); |
804 } | 1022 } |
805 | 1023 |
806 PK11SlotInfo* GetPrivateNSSKeySlot() { | 1024 PK11SlotInfo* GetPrivateNSSKeySlot() { |
807 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); | 1025 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); |
808 } | 1026 } |
809 | 1027 |
810 } // namespace crypto | 1028 } // namespace crypto |
OLD | NEW |