Skip to content

Commit 7991e0e

Browse files
committed
Add Pkcs11ElectronicID::release()
WE2-911 Signed-off-by: Mart Somermaa <[email protected]>
1 parent 2d2ab20 commit 7991e0e

File tree

4 files changed

+39
-4
lines changed

4 files changed

+39
-4
lines changed

include/electronic-id/electronic-id.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff 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

src/electronic-ids/pkcs11/PKCS11CardManager.hpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff 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
}

src/electronic-ids/pkcs11/Pkcs11ElectronicID.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff 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()
215217
pcsc_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+
}

src/electronic-ids/pkcs11/Pkcs11ElectronicID.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff 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
};

0 commit comments

Comments
 (0)