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 3 // found in the LICENSE file. 4 5 #ifndef CRYPTO_NSS_UTIL_H_ 6 #define CRYPTO_NSS_UTIL_H_ 7 8 #include <string> 9 #include "base/basictypes.h" 10 #include "base/callback_forward.h" 11 #include "base/compiler_specific.h" 12 #include "crypto/crypto_export.h" 13 14 namespace base { 15 class FilePath; 16 class Lock; 17 class Time; 18 } // namespace base 19 20 // This file specifically doesn't depend on any NSS or NSPR headers because it 21 // is included by various (non-crypto) parts of chrome to call the 22 // initialization functions. 23 namespace crypto { 24 25 // The TPMToken name used for the NSS slot opened by ScopedTestNSSDB. 26 CRYPTO_EXPORT extern const char kTestTPMTokenName[]; 27 28 #if defined(USE_NSS) 29 // EarlySetupForNSSInit performs lightweight setup which must occur before the 30 // process goes multithreaded. This does not initialise NSS. For test, see 31 // EnsureNSSInit. 32 CRYPTO_EXPORT void EarlySetupForNSSInit(); 33 #endif 34 35 // Initialize NRPR if it isn't already initialized. This function is 36 // thread-safe, and NSPR will only ever be initialized once. 37 CRYPTO_EXPORT void EnsureNSPRInit(); 38 39 // Initialize NSS safely for strict sandboxing. This function tells NSS to not 40 // load user security modules, and makes sure NSS will have proper entropy in a 41 // restricted, sandboxed environment. 42 // 43 // As a defense in depth measure, this function should be called in a sandboxed 44 // environment. That way, in the event of a bug, NSS will still not be able to 45 // load security modules that could expose private data and keys. 46 // 47 // Make sure to get an LGTM from the Chrome Security Team if you use this. 48 CRYPTO_EXPORT void InitNSSSafely(); 49 50 // Initialize NSS if it isn't already initialized. This must be called before 51 // any other NSS functions. This function is thread-safe, and NSS will only 52 // ever be initialized once. 53 CRYPTO_EXPORT void EnsureNSSInit(); 54 55 // Call this before calling EnsureNSSInit() will force NSS to initialize 56 // without a persistent DB. This is used for the special case where access of 57 // persistent DB is prohibited. 58 // 59 // TODO(hclam): Isolate loading default root certs. 60 // 61 // NSS will be initialized without loading any user security modules, including 62 // the built-in root certificates module. User security modules need to be 63 // loaded manually after NSS initialization. 64 // 65 // If EnsureNSSInit() is called before then this function has no effect. 66 // 67 // Calling this method only has effect on Linux. 68 // 69 // WARNING: Use this with caution. 70 CRYPTO_EXPORT void ForceNSSNoDBInit(); 71 72 // This method is used to disable checks in NSS when used in a forked process. 73 // NSS checks whether it is running a forked process to avoid problems when 74 // using user security modules in a forked process. However if we are sure 75 // there are no modules loaded before the process is forked then there is no 76 // harm disabling the check. 77 // 78 // This method must be called before EnsureNSSInit() to take effect. 79 // 80 // WARNING: Use this with caution. 81 CRYPTO_EXPORT void DisableNSSForkCheck(); 82 83 // Load NSS library files. This function has no effect on Mac and Windows. 84 // This loads the necessary NSS library files so that NSS can be initialized 85 // after loading additional library files is disallowed, for example when the 86 // sandbox is active. 87 // 88 // Note that this does not load libnssckbi.so which contains the root 89 // certificates. 90 CRYPTO_EXPORT void LoadNSSLibraries(); 91 92 // Check if the current NSS version is greater than or equals to |version|. 93 // A sample version string is "3.12.3". 94 bool CheckNSSVersion(const char* version); 95 96 #if defined(OS_CHROMEOS) 97 // Open the r/w nssdb that's stored inside the user's encrypted home 98 // directory. This is the default slot returned by 99 // GetPublicNSSKeySlot(). 100 CRYPTO_EXPORT void OpenPersistentNSSDB(); 101 102 // Indicates that NSS should load the Chaps library so that we 103 // can access the TPM through NSS. Once this is called, 104 // GetPrivateNSSKeySlot() will return the TPM slot if one was found. 105 CRYPTO_EXPORT void EnableTPMTokenForNSS(); 106 107 // Returns true if EnableTPMTokenForNSS has been called. 108 CRYPTO_EXPORT bool IsTPMTokenEnabledForNSS(); 109 110 // Returns true if the TPM is owned and PKCS#11 initialized with the 111 // user and security officer PINs, and has been enabled in NSS by 112 // calling EnableTPMForNSS, and Chaps has been successfully 113 // loaded into NSS. 114 // If |callback| is non-null and the function returns false, the |callback| will 115 // be run once the TPM is ready. |callback| will never be run if the function 116 // returns true. 117 CRYPTO_EXPORT bool IsTPMTokenReady(const base::Closure& callback) 118 WARN_UNUSED_RESULT; 119 120 // Initialize the TPM token. Does nothing if it is already initialized. 121 CRYPTO_EXPORT bool InitializeTPMToken(int token_slot_id); 122 #endif 123 124 // Convert a NSS PRTime value into a base::Time object. 125 // We use a int64 instead of PRTime here to avoid depending on NSPR headers. 126 CRYPTO_EXPORT base::Time PRTimeToBaseTime(int64 prtime); 127 128 // Convert a base::Time object into a PRTime value. 129 // We use a int64 instead of PRTime here to avoid depending on NSPR headers. 130 CRYPTO_EXPORT int64 BaseTimeToPRTime(base::Time time); 131 132 #if defined(USE_NSS) 133 // Exposed for unittests only. 134 // TODO(mattm): When NSS 3.14 is the minimum version required, 135 // switch back to using a separate user DB for each test. 136 // Because of https://bugzilla.mozilla.org/show_bug.cgi?id=588269 , the 137 // opened user DB is not automatically closed. 138 class CRYPTO_EXPORT_PRIVATE ScopedTestNSSDB { 139 public: 140 ScopedTestNSSDB(); 141 ~ScopedTestNSSDB(); 142 is_open()143 bool is_open() { return is_open_; } 144 145 private: 146 bool is_open_; 147 DISALLOW_COPY_AND_ASSIGN(ScopedTestNSSDB); 148 }; 149 150 // NSS has a bug which can cause a deadlock or stall in some cases when writing 151 // to the certDB and keyDB. It also has a bug which causes concurrent key pair 152 // generations to scribble over each other. To work around this, we synchronize 153 // writes to the NSS databases with a global lock. The lock is hidden beneath a 154 // function for easy disabling when the bug is fixed. Callers should allow for 155 // it to return NULL in the future. 156 // 157 // See https://bugzilla.mozilla.org/show_bug.cgi?id=564011 158 base::Lock* GetNSSWriteLock(); 159 160 // A helper class that acquires the NSS write Lock while the AutoNSSWriteLock 161 // is in scope. 162 class CRYPTO_EXPORT AutoNSSWriteLock { 163 public: 164 AutoNSSWriteLock(); 165 ~AutoNSSWriteLock(); 166 private: 167 base::Lock *lock_; 168 DISALLOW_COPY_AND_ASSIGN(AutoNSSWriteLock); 169 }; 170 171 #endif // defined(USE_NSS) 172 173 } // namespace crypto 174 175 #endif // CRYPTO_NSS_UTIL_H_ 176