1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef CRYPTO_NSS_UTIL_INTERNAL_H_ 6*6777b538SAndroid Build Coastguard Worker #define CRYPTO_NSS_UTIL_INTERNAL_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <secmodt.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <string> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 14*6777b538SAndroid Build Coastguard Worker #include "build/chromeos_buildflags.h" 15*6777b538SAndroid Build Coastguard Worker #include "components/nacl/common/buildflags.h" 16*6777b538SAndroid Build Coastguard Worker #include "crypto/crypto_export.h" 17*6777b538SAndroid Build Coastguard Worker #include "crypto/scoped_nss_types.h" 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker namespace base { 20*6777b538SAndroid Build Coastguard Worker class FilePath; 21*6777b538SAndroid Build Coastguard Worker } 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker // These functions return a type defined in an NSS header, and so cannot be 24*6777b538SAndroid Build Coastguard Worker // declared in nss_util.h. Hence, they are declared here. 25*6777b538SAndroid Build Coastguard Worker 26*6777b538SAndroid Build Coastguard Worker namespace crypto { 27*6777b538SAndroid Build Coastguard Worker 28*6777b538SAndroid Build Coastguard Worker // Opens an NSS software database in folder `path`, with the (potentially) 29*6777b538SAndroid Build Coastguard Worker // user-visible description `description`. Returns the slot for the opened 30*6777b538SAndroid Build Coastguard Worker // database, or nullptr if the database could not be opened. Can be called 31*6777b538SAndroid Build Coastguard Worker // multiple times for the same `path`, thread-safe. 32*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT ScopedPK11Slot OpenSoftwareNSSDB(const base::FilePath& path, 33*6777b538SAndroid Build Coastguard Worker const std::string& description); 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker // Closes the underlying database for the `slot`. All remaining slots 36*6777b538SAndroid Build Coastguard Worker // referencing the same database will remain valid objects, but won't be able to 37*6777b538SAndroid Build Coastguard Worker // successfully retrieve certificates, etc. Should be used for all databases 38*6777b538SAndroid Build Coastguard Worker // that were opened with `OpenSoftwareNSSDB` (instead of `SECMOD_CloseUserDB`). 39*6777b538SAndroid Build Coastguard Worker // Can be called multiple times. Returns `SECSuccess` if the database was 40*6777b538SAndroid Build Coastguard Worker // successfully closed, returns `SECFailure` if it was never opened, was already 41*6777b538SAndroid Build Coastguard Worker // closed by an earlier call, or failed to close. Thread-safe. 42*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT SECStatus CloseSoftwareNSSDB(PK11SlotInfo* slot); 43*6777b538SAndroid Build Coastguard Worker 44*6777b538SAndroid Build Coastguard Worker // A helper class that acquires the SECMOD list read lock while the 45*6777b538SAndroid Build Coastguard Worker // AutoSECMODListReadLock is in scope. 46*6777b538SAndroid Build Coastguard Worker class CRYPTO_EXPORT AutoSECMODListReadLock { 47*6777b538SAndroid Build Coastguard Worker public: 48*6777b538SAndroid Build Coastguard Worker AutoSECMODListReadLock(); 49*6777b538SAndroid Build Coastguard Worker 50*6777b538SAndroid Build Coastguard Worker AutoSECMODListReadLock(const AutoSECMODListReadLock&) = delete; 51*6777b538SAndroid Build Coastguard Worker AutoSECMODListReadLock& operator=(const AutoSECMODListReadLock&) = delete; 52*6777b538SAndroid Build Coastguard Worker 53*6777b538SAndroid Build Coastguard Worker ~AutoSECMODListReadLock(); 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard Worker private: 56*6777b538SAndroid Build Coastguard Worker raw_ptr<SECMODListLock> lock_; 57*6777b538SAndroid Build Coastguard Worker }; 58*6777b538SAndroid Build Coastguard Worker 59*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_MINIMAL_TOOLCHAIN) 60*6777b538SAndroid Build Coastguard Worker // Returns path to the NSS database file in the provided profile 61*6777b538SAndroid Build Coastguard Worker // directory. 62*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT base::FilePath GetSoftwareNSSDBPath( 63*6777b538SAndroid Build Coastguard Worker const base::FilePath& profile_directory_path); 64*6777b538SAndroid Build Coastguard Worker 65*6777b538SAndroid Build Coastguard Worker // Returns a reference to the system-wide TPM slot (or nullptr if it will never 66*6777b538SAndroid Build Coastguard Worker // be loaded). 67*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT void GetSystemNSSKeySlot( 68*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(ScopedPK11Slot)> callback); 69*6777b538SAndroid Build Coastguard Worker 70*6777b538SAndroid Build Coastguard Worker // Injects the given |slot| as a system slot set by the future 71*6777b538SAndroid Build Coastguard Worker // |InitializeTPMTokenAndSystemSlot| call. 72*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT void PrepareSystemSlotForTesting(ScopedPK11Slot slot); 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Worker // Attempt to unset the testing system slot. 75*6777b538SAndroid Build Coastguard Worker // Note: After this method is called, the system is in an undefined state; it is 76*6777b538SAndroid Build Coastguard Worker // NOT possible to call `PrepareSystemSlotForTesting()` and have it return to a 77*6777b538SAndroid Build Coastguard Worker // known-good state. The primary purpose is to attempt to release system 78*6777b538SAndroid Build Coastguard Worker // resources, such as file handles, to allow the cleanup of files on disk, but 79*6777b538SAndroid Build Coastguard Worker // because of the process-wide effect, it's not possible to unwind any/all 80*6777b538SAndroid Build Coastguard Worker // initialization that depended on this previously-configured system slot. 81*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT void ResetSystemSlotForTesting(); 82*6777b538SAndroid Build Coastguard Worker 83*6777b538SAndroid Build Coastguard Worker // Reset the global ChromeOSTokenManager. This is used between tests, so 84*6777b538SAndroid Build Coastguard Worker // tests that run in the same process won't hit DCHECKS because they have 85*6777b538SAndroid Build Coastguard Worker // different BrowserIO threads. 86*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT void ResetTokenManagerForTesting(); 87*6777b538SAndroid Build Coastguard Worker 88*6777b538SAndroid Build Coastguard Worker // Prepare per-user NSS slot mapping. It is safe to call this function multiple 89*6777b538SAndroid Build Coastguard Worker // times. Returns true if the user was added, or false if it already existed. 90*6777b538SAndroid Build Coastguard Worker // Loads the database from `path` to use as a public slot. 91*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT bool InitializeNSSForChromeOSUser( 92*6777b538SAndroid Build Coastguard Worker const std::string& username_hash, 93*6777b538SAndroid Build Coastguard Worker const base::FilePath& path); 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard Worker // Prepare per-user NSS slot mapping. It is safe to call this function multiple 96*6777b538SAndroid Build Coastguard Worker // times. Returns true if the user was added, or false if it already existed. 97*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT bool InitializeNSSForChromeOSUserWithSlot( 98*6777b538SAndroid Build Coastguard Worker const std::string& username_hash, 99*6777b538SAndroid Build Coastguard Worker ScopedPK11Slot public_slot); 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker // Returns whether TPM for ChromeOS user still needs initialization. If 102*6777b538SAndroid Build Coastguard Worker // true is returned, the caller can proceed to initialize TPM slot for the 103*6777b538SAndroid Build Coastguard Worker // user, but should call |WillInitializeTPMForChromeOSUser| first. 104*6777b538SAndroid Build Coastguard Worker // |InitializeNSSForChromeOSUser| must have been called first. 105*6777b538SAndroid Build Coastguard Worker [[nodiscard]] CRYPTO_EXPORT bool ShouldInitializeTPMForChromeOSUser( 106*6777b538SAndroid Build Coastguard Worker const std::string& username_hash); 107*6777b538SAndroid Build Coastguard Worker 108*6777b538SAndroid Build Coastguard Worker // Makes |ShouldInitializeTPMForChromeOSUser| start returning false. 109*6777b538SAndroid Build Coastguard Worker // Should be called before starting TPM initialization for the user. 110*6777b538SAndroid Build Coastguard Worker // Assumes |InitializeNSSForChromeOSUser| had already been called. 111*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT void WillInitializeTPMForChromeOSUser( 112*6777b538SAndroid Build Coastguard Worker const std::string& username_hash); 113*6777b538SAndroid Build Coastguard Worker 114*6777b538SAndroid Build Coastguard Worker // Use TPM slot |slot_id| for user. InitializeNSSForChromeOSUser must have been 115*6777b538SAndroid Build Coastguard Worker // called first. 116*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT void InitializeTPMForChromeOSUser( 117*6777b538SAndroid Build Coastguard Worker const std::string& username_hash, 118*6777b538SAndroid Build Coastguard Worker CK_SLOT_ID slot_id); 119*6777b538SAndroid Build Coastguard Worker 120*6777b538SAndroid Build Coastguard Worker // Use the software slot as the private slot for user. 121*6777b538SAndroid Build Coastguard Worker // InitializeNSSForChromeOSUser must have been called first. 122*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT void InitializePrivateSoftwareSlotForChromeOSUser( 123*6777b538SAndroid Build Coastguard Worker const std::string& username_hash); 124*6777b538SAndroid Build Coastguard Worker 125*6777b538SAndroid Build Coastguard Worker // Returns a reference to the public slot for user. 126*6777b538SAndroid Build Coastguard Worker [[nodiscard]] CRYPTO_EXPORT ScopedPK11Slot 127*6777b538SAndroid Build Coastguard Worker GetPublicSlotForChromeOSUser(const std::string& username_hash); 128*6777b538SAndroid Build Coastguard Worker 129*6777b538SAndroid Build Coastguard Worker // Returns the private slot for |username_hash| if it is loaded. If it is not 130*6777b538SAndroid Build Coastguard Worker // loaded and |callback| is non-null, the |callback| will be run once the slot 131*6777b538SAndroid Build Coastguard Worker // is loaded. 132*6777b538SAndroid Build Coastguard Worker [[nodiscard]] CRYPTO_EXPORT ScopedPK11Slot GetPrivateSlotForChromeOSUser( 133*6777b538SAndroid Build Coastguard Worker const std::string& username_hash, 134*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(ScopedPK11Slot)> callback); 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard Worker // Closes the NSS DB for |username_hash| that was previously opened by the 137*6777b538SAndroid Build Coastguard Worker // *Initialize*ForChromeOSUser functions. 138*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT void CloseChromeOSUserForTesting( 139*6777b538SAndroid Build Coastguard Worker const std::string& username_hash); 140*6777b538SAndroid Build Coastguard Worker 141*6777b538SAndroid Build Coastguard Worker // Sets the slot which should be used as private slot for the next 142*6777b538SAndroid Build Coastguard Worker // |InitializePrivateSoftwareSlotForChromeOSUser| called. This is intended for 143*6777b538SAndroid Build Coastguard Worker // simulating a separate private slot in Chrome OS browser tests. 144*6777b538SAndroid Build Coastguard Worker // As a sanity check, it is recommended to check that the private slot of the 145*6777b538SAndroid Build Coastguard Worker // profile's certificate database is set to |slot| when the profile is 146*6777b538SAndroid Build Coastguard Worker // available, because |slot| will be used as private slot for whichever profile 147*6777b538SAndroid Build Coastguard Worker // is initialized next. 148*6777b538SAndroid Build Coastguard Worker CRYPTO_EXPORT void SetPrivateSoftwareSlotForChromeOSUserForTesting( 149*6777b538SAndroid Build Coastguard Worker ScopedPK11Slot slot); 150*6777b538SAndroid Build Coastguard Worker 151*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_MINIMAL_TOOLCHAIN) 152*6777b538SAndroid Build Coastguard Worker 153*6777b538SAndroid Build Coastguard Worker // Loads the given module for this NSS session. 154*6777b538SAndroid Build Coastguard Worker SECMODModule* LoadNSSModule(const char* name, 155*6777b538SAndroid Build Coastguard Worker const char* library_path, 156*6777b538SAndroid Build Coastguard Worker const char* params); 157*6777b538SAndroid Build Coastguard Worker 158*6777b538SAndroid Build Coastguard Worker // Returns the current NSS error message. 159*6777b538SAndroid Build Coastguard Worker std::string GetNSSErrorMessage(); 160*6777b538SAndroid Build Coastguard Worker 161*6777b538SAndroid Build Coastguard Worker } // namespace crypto 162*6777b538SAndroid Build Coastguard Worker 163*6777b538SAndroid Build Coastguard Worker #endif // CRYPTO_NSS_UTIL_INTERNAL_H_ 164