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