| 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 <plarena.h> | 9 #include <plarena.h> |
| 10 #include <prerror.h> | 10 #include <prerror.h> |
| 11 #include <prinit.h> | 11 #include <prinit.h> |
| 12 #include <prtime.h> | 12 #include <prtime.h> |
| 13 #include <pk11pub.h> | 13 #include <pk11pub.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 <vector> | 24 #include <vector> |
| 25 | 25 |
| 26 #include "base/bind.h" | |
| 27 #include "base/environment.h" | 26 #include "base/environment.h" |
| 28 #include "base/file_path.h" | 27 #include "base/file_path.h" |
| 29 #include "base/file_util.h" | 28 #include "base/file_util.h" |
| 30 #include "base/lazy_instance.h" | 29 #include "base/lazy_instance.h" |
| 31 #include "base/logging.h" | 30 #include "base/logging.h" |
| 32 #include "base/memory/scoped_ptr.h" | 31 #include "base/memory/scoped_ptr.h" |
| 33 #include "base/message_loop.h" | |
| 34 #include "base/native_library.h" | 32 #include "base/native_library.h" |
| 35 #include "base/scoped_temp_dir.h" | 33 #include "base/scoped_temp_dir.h" |
| 36 #include "base/stringprintf.h" | 34 #include "base/stringprintf.h" |
| 37 #include "base/threading/thread_restrictions.h" | 35 #include "base/threading/thread_restrictions.h" |
| 38 #include "build/build_config.h" | 36 #include "build/build_config.h" |
| 39 #include "crypto/scoped_nss_types.h" | |
| 40 | 37 |
| 41 #if defined(OS_CHROMEOS) | 38 #if defined(OS_CHROMEOS) |
| 42 #include "crypto/symmetric_key.h" | 39 #include "crypto/symmetric_key.h" |
| 43 #endif | 40 #endif |
| 44 | 41 |
| 45 // USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not | 42 // USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not |
| 46 // defined, such as on Mac and Windows, we use NSS for SSL only -- we don't | 43 // defined, such as on Mac and Windows, we use NSS for SSL only -- we don't |
| 47 // use NSS for crypto or certificate verification, and we don't use the NSS | 44 // use NSS for crypto or certificate verification, and we don't use the NSS |
| 48 // certificate and key databases. | 45 // certificate and key databases. |
| 49 #if defined(USE_NSS) | 46 #if defined(USE_NSS) |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 NSPRInitSingleton() { | 204 NSPRInitSingleton() { |
| 208 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); | 205 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); |
| 209 } | 206 } |
| 210 | 207 |
| 211 // NOTE(willchan): We don't actually execute this code since we leak NSS to | 208 // NOTE(willchan): We don't actually execute this code since we leak NSS to |
| 212 // prevent non-joinable threads from using NSS after it's already been shut | 209 // prevent non-joinable threads from using NSS after it's already been shut |
| 213 // down. | 210 // down. |
| 214 ~NSPRInitSingleton() { | 211 ~NSPRInitSingleton() { |
| 215 PL_ArenaFinish(); | 212 PL_ArenaFinish(); |
| 216 PRStatus prstatus = PR_Cleanup(); | 213 PRStatus prstatus = PR_Cleanup(); |
| 217 if (prstatus != PR_SUCCESS) { | 214 if (prstatus != PR_SUCCESS) |
| 218 LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?"; | 215 LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?"; |
| 219 } | |
| 220 } | 216 } |
| 221 }; | 217 }; |
| 222 | 218 |
| 223 base::LazyInstance<NSPRInitSingleton>::Leaky | 219 base::LazyInstance<NSPRInitSingleton>::Leaky |
| 224 g_nspr_singleton = LAZY_INSTANCE_INITIALIZER; | 220 g_nspr_singleton = LAZY_INSTANCE_INITIALIZER; |
| 225 | 221 |
| 226 // This is a LazyInstance so that it will be deleted automatically when the | 222 // This is a LazyInstance so that it will be deleted automatically when the |
| 227 // unittest exits. NSSInitSingleton is a LeakySingleton, so it would not be | 223 // unittest exits. NSSInitSingleton is a LeakySingleton, so it would not be |
| 228 // deleted if it were a regular member. | 224 // deleted if it were a regular member. |
| 229 base::LazyInstance<ScopedTempDir> g_test_nss_db_dir = LAZY_INSTANCE_INITIALIZER; | 225 base::LazyInstance<ScopedTempDir> g_test_nss_db_dir = LAZY_INSTANCE_INITIALIZER; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 240 | 236 |
| 241 // This creates another DB slot in NSS that is read/write, unlike | 237 // This creates another DB slot in NSS that is read/write, unlike |
| 242 // the fake root CA cert DB and the "default" crypto key | 238 // the fake root CA cert DB and the "default" crypto key |
| 243 // provider, which are still read-only (because we initialized | 239 // provider, which are still read-only (because we initialized |
| 244 // NSS before we had a cryptohome mounted). | 240 // NSS before we had a cryptohome mounted). |
| 245 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), | 241 software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), |
| 246 kNSSDatabaseName); | 242 kNSSDatabaseName); |
| 247 } | 243 } |
| 248 } | 244 } |
| 249 | 245 |
| 250 void EnableTPMTokenForNSS(TPMTokenInfoDelegate* info_delegate) { | 246 void EnableTPMTokenForNSS() { |
| 251 CHECK(info_delegate); | 247 tpm_token_enabled_for_nss_ = true; |
| 252 tpm_token_info_delegate_.reset(info_delegate); | |
| 253 } | 248 } |
| 254 | 249 |
| 255 void InitializeTPMToken(InitializeTPMTokenCallback callback) { | 250 bool InitializeTPMToken(const std::string& token_name, |
| 256 // If EnableTPMTokenForNSS hasn't been called, run |callback| with false. | 251 const std::string& user_pin) { |
| 257 if (tpm_token_info_delegate_.get() == NULL) { | 252 // If EnableTPMTokenForNSS hasn't been called, return false. |
| 258 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, false)); | 253 if (!tpm_token_enabled_for_nss_) |
| 259 return; | 254 return false; |
| 255 |
| 256 // If everything is already initialized, then return true. |
| 257 if (chaps_module_ && tpm_slot_) |
| 258 return true; |
| 259 |
| 260 tpm_token_name_ = token_name; |
| 261 tpm_user_pin_ = user_pin; |
| 262 |
| 263 // This tries to load the Chaps module so NSS can talk to the hardware |
| 264 // TPM. |
| 265 if (!chaps_module_) { |
| 266 chaps_module_ = LoadModule( |
| 267 kChapsModuleName, |
| 268 kChapsPath, |
| 269 // For more details on these parameters, see: |
| 270 // https://developer.mozilla.org/en/PKCS11_Module_Specs |
| 271 // slotFlags=[PublicCerts] -- Certificates and public keys can be |
| 272 // read from this slot without requiring a call to C_Login. |
| 273 // askpw=only -- Only authenticate to the token when necessary. |
| 274 "NSS=\"slotParams=(0={slotFlags=[PublicCerts] askpw=only})\""); |
| 260 } | 275 } |
| 276 if (chaps_module_){ |
| 277 // If this gets set, then we'll use the TPM for certs with |
| 278 // private keys, otherwise we'll fall back to the software |
| 279 // implementation. |
| 280 tpm_slot_ = GetTPMSlot(); |
| 261 | 281 |
| 262 // If everything is already initialized, then run |callback| with true. | 282 return tpm_slot_ != NULL; |
| 263 if (chaps_module_ && tpm_slot_) { | |
| 264 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); | |
| 265 return; | |
| 266 } | 283 } |
| 267 tpm_token_info_delegate_->RequestIsTokenReady( | 284 return false; |
| 268 base::Bind(&NSSInitSingleton::InitializeTPMTokenInternal, | |
| 269 weak_ptr_factory_.GetWeakPtr(), | |
| 270 callback)); | |
| 271 } | 285 } |
| 272 | 286 |
| 273 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { | 287 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { |
| 274 if (tpm_token_info_delegate_.get() == NULL) { | 288 if (!tpm_token_enabled_for_nss_) { |
| 275 LOG(ERROR) << "GetTPMTokenInfo called before TPM Token is ready."; | 289 LOG(ERROR) << "GetTPMTokenInfo called before TPM Token is ready."; |
| 276 return; | 290 return; |
| 277 } | 291 } |
| 278 tpm_token_info_delegate_->GetTokenInfo(token_name, user_pin); | 292 if (token_name) |
| 293 *token_name = tpm_token_name_; |
| 294 if (user_pin) |
| 295 *user_pin = tpm_user_pin_; |
| 279 } | 296 } |
| 280 | 297 |
| 281 bool IsTPMTokenReady() { | 298 bool IsTPMTokenReady() { |
| 282 return tpm_slot_ != NULL; | 299 return tpm_slot_ != NULL; |
| 283 } | 300 } |
| 284 | 301 |
| 285 PK11SlotInfo* GetTPMSlot() { | 302 PK11SlotInfo* GetTPMSlot() { |
| 286 std::string token_name; | 303 std::string token_name; |
| 287 GetTPMTokenInfo(&token_name, NULL); | 304 GetTPMTokenInfo(&token_name, NULL); |
| 288 return FindSlotWithTokenName(token_name); | 305 return FindSlotWithTokenName(token_name); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 if (software_slot_) | 368 if (software_slot_) |
| 352 return PK11_ReferenceSlot(software_slot_); | 369 return PK11_ReferenceSlot(software_slot_); |
| 353 return PK11_GetInternalKeySlot(); | 370 return PK11_GetInternalKeySlot(); |
| 354 } | 371 } |
| 355 | 372 |
| 356 PK11SlotInfo* GetPrivateNSSKeySlot() { | 373 PK11SlotInfo* GetPrivateNSSKeySlot() { |
| 357 if (test_slot_) | 374 if (test_slot_) |
| 358 return PK11_ReferenceSlot(test_slot_); | 375 return PK11_ReferenceSlot(test_slot_); |
| 359 | 376 |
| 360 #if defined(OS_CHROMEOS) | 377 #if defined(OS_CHROMEOS) |
| 361 if (tpm_token_info_delegate_.get() != NULL) { | 378 if (tpm_token_enabled_for_nss_) { |
| 362 if (IsTPMTokenReady()) { | 379 if (IsTPMTokenReady()) { |
| 363 return PK11_ReferenceSlot(tpm_slot_); | 380 return PK11_ReferenceSlot(tpm_slot_); |
| 364 } else { | 381 } else { |
| 365 // If we were supposed to get the hardware token, but were | 382 // If we were supposed to get the hardware token, but were |
| 366 // unable to, return NULL rather than fall back to sofware. | 383 // unable to, return NULL rather than fall back to sofware. |
| 367 return NULL; | 384 return NULL; |
| 368 } | 385 } |
| 369 } | 386 } |
| 370 #endif | 387 #endif |
| 371 // If we weren't supposed to enable the TPM for NSS, then return | 388 // If we weren't supposed to enable the TPM for NSS, then return |
| (...skipping 12 matching lines...) Expand all Loading... |
| 384 // This method is used to force NSS to be initialized without a DB. | 401 // This method is used to force NSS to be initialized without a DB. |
| 385 // Call this method before NSSInitSingleton() is constructed. | 402 // Call this method before NSSInitSingleton() is constructed. |
| 386 static void ForceNoDBInit() { | 403 static void ForceNoDBInit() { |
| 387 force_nodb_init_ = true; | 404 force_nodb_init_ = true; |
| 388 } | 405 } |
| 389 | 406 |
| 390 private: | 407 private: |
| 391 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; | 408 friend struct base::DefaultLazyInstanceTraits<NSSInitSingleton>; |
| 392 | 409 |
| 393 NSSInitSingleton() | 410 NSSInitSingleton() |
| 394 : chaps_module_(NULL), | 411 : tpm_token_enabled_for_nss_(false), |
| 412 chaps_module_(NULL), |
| 395 software_slot_(NULL), | 413 software_slot_(NULL), |
| 396 test_slot_(NULL), | 414 test_slot_(NULL), |
| 397 tpm_slot_(NULL), | 415 tpm_slot_(NULL), |
| 398 root_(NULL), | 416 root_(NULL), |
| 399 chromeos_user_logged_in_(false), | 417 chromeos_user_logged_in_(false) { |
| 400 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | |
| 401 EnsureNSPRInit(); | 418 EnsureNSPRInit(); |
| 402 | 419 |
| 403 // We *must* have NSS >= 3.12.3. See bug 26448. | 420 // We *must* have NSS >= 3.12.3. See bug 26448. |
| 404 COMPILE_ASSERT( | 421 COMPILE_ASSERT( |
| 405 (NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH >= 3) || | 422 (NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH >= 3) || |
| 406 (NSS_VMAJOR == 3 && NSS_VMINOR > 12) || | 423 (NSS_VMAJOR == 3 && NSS_VMINOR > 12) || |
| 407 (NSS_VMAJOR > 3), | 424 (NSS_VMAJOR > 3), |
| 408 nss_version_check_failed); | 425 nss_version_check_failed); |
| 409 // Also check the run-time NSS version. | 426 // Also check the run-time NSS version. |
| 410 // NSS_VersionCheck is a >= check, not strict equality. | 427 // NSS_VersionCheck is a >= check, not strict equality. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 } | 531 } |
| 515 | 532 |
| 516 SECStatus status = NSS_Shutdown(); | 533 SECStatus status = NSS_Shutdown(); |
| 517 if (status != SECSuccess) { | 534 if (status != SECSuccess) { |
| 518 // We VLOG(1) because this failure is relatively harmless (leaking, but | 535 // We VLOG(1) because this failure is relatively harmless (leaking, but |
| 519 // we're shutting down anyway). | 536 // we're shutting down anyway). |
| 520 VLOG(1) << "NSS_Shutdown failed; see http://crbug.com/4609"; | 537 VLOG(1) << "NSS_Shutdown failed; see http://crbug.com/4609"; |
| 521 } | 538 } |
| 522 } | 539 } |
| 523 | 540 |
| 524 #if defined(OS_CHROMEOS) | |
| 525 // This method is used to implement InitializeTPMToken. | |
| 526 void InitializeTPMTokenInternal(InitializeTPMTokenCallback callback, | |
| 527 bool is_token_ready) { | |
| 528 if (is_token_ready) { | |
| 529 // This tries to load the Chaps module so NSS can talk to the hardware | |
| 530 // TPM. | |
| 531 if (!chaps_module_) { | |
| 532 chaps_module_ = LoadModule( | |
| 533 kChapsModuleName, | |
| 534 kChapsPath, | |
| 535 // For more details on these parameters, see: | |
| 536 // https://developer.mozilla.org/en/PKCS11_Module_Specs | |
| 537 // slotFlags=[PublicCerts] -- Certificates and public keys can be | |
| 538 // read from this slot without requiring a call to C_Login. | |
| 539 // askpw=only -- Only authenticate to the token when necessary. | |
| 540 "NSS=\"slotParams=(0={slotFlags=[PublicCerts] askpw=only})\""); | |
| 541 } | |
| 542 if (chaps_module_) { | |
| 543 // If this gets set, then we'll use the TPM for certs with | |
| 544 // private keys, otherwise we'll fall back to the software | |
| 545 // implementation. | |
| 546 tpm_slot_ = GetTPMSlot(); | |
| 547 | |
| 548 callback.Run(tpm_slot_ != NULL); | |
| 549 return; | |
| 550 } | |
| 551 } | |
| 552 callback.Run(false); | |
| 553 } | |
| 554 #endif // defined(OS_CHROMEOS) | |
| 555 | |
| 556 #if defined(USE_NSS) | 541 #if defined(USE_NSS) |
| 557 // Load nss's built-in root certs. | 542 // Load nss's built-in root certs. |
| 558 SECMODModule* InitDefaultRootCerts() { | 543 SECMODModule* InitDefaultRootCerts() { |
| 559 SECMODModule* root = LoadModule("Root Certs", "libnssckbi.so", NULL); | 544 SECMODModule* root = LoadModule("Root Certs", "libnssckbi.so", NULL); |
| 560 if (root) | 545 if (root) |
| 561 return root; | 546 return root; |
| 562 | 547 |
| 563 // Aw, snap. Can't find/load root cert shared library. | 548 // Aw, snap. Can't find/load root cert shared library. |
| 564 // This will make it hard to talk to anybody via https. | 549 // This will make it hard to talk to anybody via https. |
| 565 NOTREACHED(); | 550 NOTREACHED(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 else { | 587 else { |
| 603 LOG(ERROR) << "Error opening persistent database (" << modspec | 588 LOG(ERROR) << "Error opening persistent database (" << modspec |
| 604 << "): " << GetNSSErrorMessage(); | 589 << "): " << GetNSSErrorMessage(); |
| 605 } | 590 } |
| 606 return db_slot; | 591 return db_slot; |
| 607 } | 592 } |
| 608 | 593 |
| 609 // If this is set to true NSS is forced to be initialized without a DB. | 594 // If this is set to true NSS is forced to be initialized without a DB. |
| 610 static bool force_nodb_init_; | 595 static bool force_nodb_init_; |
| 611 | 596 |
| 612 #if defined(OS_CHROMEOS) | 597 bool tpm_token_enabled_for_nss_; |
| 613 scoped_ptr<TPMTokenInfoDelegate> tpm_token_info_delegate_; | 598 std::string tpm_token_name_; |
| 614 #endif | 599 std::string tpm_user_pin_; |
| 615 | |
| 616 SECMODModule* chaps_module_; | 600 SECMODModule* chaps_module_; |
| 617 PK11SlotInfo* software_slot_; | 601 PK11SlotInfo* software_slot_; |
| 618 PK11SlotInfo* test_slot_; | 602 PK11SlotInfo* test_slot_; |
| 619 PK11SlotInfo* tpm_slot_; | 603 PK11SlotInfo* tpm_slot_; |
| 620 SECMODModule* root_; | 604 SECMODModule* root_; |
| 621 bool chromeos_user_logged_in_; | 605 bool chromeos_user_logged_in_; |
| 622 base::WeakPtrFactory<NSSInitSingleton> weak_ptr_factory_; | |
| 623 #if defined(USE_NSS) | 606 #if defined(USE_NSS) |
| 624 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 | 607 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 |
| 625 // is fixed, we will no longer need the lock. | 608 // is fixed, we will no longer need the lock. |
| 626 base::Lock write_lock_; | 609 base::Lock write_lock_; |
| 627 #endif // defined(USE_NSS) | 610 #endif // defined(USE_NSS) |
| 628 }; | 611 }; |
| 629 | 612 |
| 630 // static | 613 // static |
| 631 bool NSSInitSingleton::force_nodb_init_ = false; | 614 bool NSSInitSingleton::force_nodb_init_ = false; |
| 632 | 615 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 SECMOD_ReleaseReadLock(lock_); | 729 SECMOD_ReleaseReadLock(lock_); |
| 747 } | 730 } |
| 748 | 731 |
| 749 #endif // defined(USE_NSS) | 732 #endif // defined(USE_NSS) |
| 750 | 733 |
| 751 #if defined(OS_CHROMEOS) | 734 #if defined(OS_CHROMEOS) |
| 752 void OpenPersistentNSSDB() { | 735 void OpenPersistentNSSDB() { |
| 753 g_nss_singleton.Get().OpenPersistentNSSDB(); | 736 g_nss_singleton.Get().OpenPersistentNSSDB(); |
| 754 } | 737 } |
| 755 | 738 |
| 756 TPMTokenInfoDelegate::TPMTokenInfoDelegate() {} | 739 void EnableTPMTokenForNSS() { |
| 757 TPMTokenInfoDelegate::~TPMTokenInfoDelegate() {} | 740 g_nss_singleton.Get().EnableTPMTokenForNSS(); |
| 758 | |
| 759 void EnableTPMTokenForNSS(TPMTokenInfoDelegate* info_delegate) { | |
| 760 g_nss_singleton.Get().EnableTPMTokenForNSS(info_delegate); | |
| 761 } | 741 } |
| 762 | 742 |
| 763 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { | 743 void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) { |
| 764 g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin); | 744 g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin); |
| 765 } | 745 } |
| 766 | 746 |
| 767 bool IsTPMTokenReady() { | 747 bool IsTPMTokenReady() { |
| 768 return g_nss_singleton.Get().IsTPMTokenReady(); | 748 return g_nss_singleton.Get().IsTPMTokenReady(); |
| 769 } | 749 } |
| 770 | 750 |
| 771 void InitializeTPMToken(InitializeTPMTokenCallback callback) { | 751 bool InitializeTPMToken(const std::string& token_name, |
| 772 g_nss_singleton.Get().InitializeTPMToken(callback); | 752 const std::string& user_pin) { |
| 753 return g_nss_singleton.Get().InitializeTPMToken(token_name, user_pin); |
| 773 } | 754 } |
| 774 | 755 |
| 775 SymmetricKey* GetSupplementalUserKey() { | 756 SymmetricKey* GetSupplementalUserKey() { |
| 776 return g_nss_singleton.Get().GetSupplementalUserKey(); | 757 return g_nss_singleton.Get().GetSupplementalUserKey(); |
| 777 } | 758 } |
| 778 #endif // defined(OS_CHROMEOS) | 759 #endif // defined(OS_CHROMEOS) |
| 779 | 760 |
| 780 base::Time PRTimeToBaseTime(PRTime prtime) { | 761 base::Time PRTimeToBaseTime(PRTime prtime) { |
| 781 return base::Time::FromInternalValue( | 762 return base::Time::FromInternalValue( |
| 782 prtime + base::Time::UnixEpoch().ToInternalValue()); | 763 prtime + base::Time::UnixEpoch().ToInternalValue()); |
| 783 } | 764 } |
| 784 | 765 |
| 785 PRTime BaseTimeToPRTime(base::Time time) { | 766 PRTime BaseTimeToPRTime(base::Time time) { |
| 786 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); | 767 return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue(); |
| 787 } | 768 } |
| 788 | 769 |
| 789 PK11SlotInfo* GetPublicNSSKeySlot() { | 770 PK11SlotInfo* GetPublicNSSKeySlot() { |
| 790 return g_nss_singleton.Get().GetPublicNSSKeySlot(); | 771 return g_nss_singleton.Get().GetPublicNSSKeySlot(); |
| 791 } | 772 } |
| 792 | 773 |
| 793 PK11SlotInfo* GetPrivateNSSKeySlot() { | 774 PK11SlotInfo* GetPrivateNSSKeySlot() { |
| 794 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); | 775 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); |
| 795 } | 776 } |
| 796 | 777 |
| 797 } // namespace crypto | 778 } // namespace crypto |
| OLD | NEW |