File tree Expand file tree Collapse file tree 4 files changed +39
-4
lines changed
src/electronic-ids/pkcs11 Expand file tree Collapse file tree 4 files changed +39
-4
lines changed Original file line number Diff line number Diff line change @@ -83,6 +83,13 @@ class ElectronicID
8383 // General functions.
8484 virtual bool allowsUsingLettersAndSpecialCharactersInPin () const { return false ; }
8585 virtual bool providesExternalPinDialog () const { return false ; }
86+
87+ /* * Extension point for releasing the resources held by the ElectronicID object.
88+ * By default, this function does nothing. It serves as an extension point for
89+ * Pkcs11ElectronicID which needs to release the PKCS#11 module before the application exits to
90+ * prevent potential crashes. */
91+ virtual void release () const {}
92+
8693 virtual std::string name () const = 0;
8794 virtual Type type () const = 0;
8895
Original file line number Diff line number Diff line change @@ -70,7 +70,9 @@ class PKCS11CardManager
7070 static std::shared_ptr<PKCS11CardManager> instance (const std::filesystem::path& module )
7171 {
7272 static std::mutex mutex;
73- static std::unordered_map<std::string, std::shared_ptr<PKCS11CardManager>> instances;
73+ // Use weak_ptr to avoid increasing the reference count while providing safe
74+ // shared access to the PKCS11CardManager instance for the given module.
75+ static std::unordered_map<std::string, std::weak_ptr<PKCS11CardManager>> instances;
7476
7577 // There is no std::hash for std::filesystem::path, use the string value.
7678 // Note that two different path strings that refer to the same filesystem location
@@ -81,10 +83,24 @@ class PKCS11CardManager
8183
8284 auto it = instances.find (moduleStr);
8385 if (it != instances.end ()) {
84- return it->second ;
86+ // If the object has already been destroyed, weak_ptr.lock() returns an empty
87+ // shared_ptr.
88+ if (auto instancePtr = it->second .lock ()) {
89+ return instancePtr;
90+ }
8591 }
8692
87- auto newInstance = std::shared_ptr<PKCS11CardManager>(new PKCS11CardManager (module ));
93+ // Custom deleter that also removes the instance from the map.
94+ auto deleter = [moduleStr](PKCS11CardManager* manager) {
95+ {
96+ std::lock_guard<std::mutex> lock (mutex);
97+ instances.erase (moduleStr);
98+ }
99+ delete manager;
100+ };
101+
102+ auto newInstance =
103+ std::shared_ptr<PKCS11CardManager>(new PKCS11CardManager (module ), deleter);
88104 instances[moduleStr] = newInstance;
89105 return newInstance;
90106 }
Original file line number Diff line number Diff line change @@ -174,6 +174,8 @@ Pkcs11ElectronicID::Pkcs11ElectronicID(ElectronicID::Type type) :
174174 ElectronicID {std::make_unique<pcsc_cpp::SmartCard>()}, module {getModule (type)},
175175 manager {PKCS11CardManager::instance (module .path )}
176176{
177+ REQUIRE_NON_NULL (manager)
178+
177179 bool seenAuthToken = false ;
178180 bool seenSigningToken = false ;
179181
@@ -215,6 +217,8 @@ ElectronicID::PinRetriesRemainingAndMax Pkcs11ElectronicID::authPinRetriesLeft()
215217pcsc_cpp::byte_vector Pkcs11ElectronicID::signWithAuthKey (const byte_vector& pin,
216218 const byte_vector& hash) const
217219{
220+ REQUIRE_NON_NULL (manager)
221+
218222 try {
219223 validateAuthHashLength (authSignatureAlgorithm (), name (), hash);
220224
@@ -254,6 +258,8 @@ ElectronicID::Signature Pkcs11ElectronicID::signWithSigningKey(const byte_vector
254258 const byte_vector& hash,
255259 const HashAlgorithm hashAlgo) const
256260{
261+ REQUIRE_NON_NULL (manager)
262+
257263 try {
258264 validateSigningHash (*this , hashAlgo, hash);
259265
@@ -277,3 +283,8 @@ ElectronicID::Signature Pkcs11ElectronicID::signWithSigningKey(const byte_vector
277283 throw ;
278284 }
279285}
286+
287+ void Pkcs11ElectronicID::release () const
288+ {
289+ manager.reset ();
290+ }
Original file line number Diff line number Diff line change @@ -68,11 +68,12 @@ class Pkcs11ElectronicID : public ElectronicID
6868 Signature signWithSigningKey (const byte_vector& pin, const byte_vector& hash,
6969 const HashAlgorithm hashAlgo) const override ;
7070
71+ void release () const override ;
7172 std::string name () const override { return module .name ; }
7273 Type type () const override { return module .type ; }
7374
7475 const Pkcs11ElectronicIDModule& module ;
75- const std::shared_ptr<PKCS11CardManager> manager;
76+ mutable std::shared_ptr<PKCS11CardManager> manager;
7677 PKCS11CardManager::Token authToken;
7778 PKCS11CardManager::Token signingToken;
7879};
You can’t perform that action at this time.
0 commit comments