diff --git a/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp b/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp index 4d8dd5e..c4ffc96 100644 --- a/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp +++ b/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp @@ -156,7 +156,8 @@ struct CommandApdu byte_vector data, byte_type le) : CommandApdu {cls, ins, p1, p2, std::move(data)} { -#if defined(__GNUC__) && __GNUC__ == 15 // Apply workaround for GCC 15 + // https://gcc.gnu.org/pipermail/gcc-patches/2025-February/676226.html +#if defined(__GNUC__) && (__GNUC__ == 15 || __GNUC__ == 16) // Apply workaround for GCC 15, 16 d.reserve(d.size() + 1); #endif d.push_back(le); diff --git a/src/electronic-ids/pkcs11/Pkcs11ElectronicID.cpp b/src/electronic-ids/pkcs11/Pkcs11ElectronicID.cpp index 63d0867..b47631c 100644 --- a/src/electronic-ids/pkcs11/Pkcs11ElectronicID.cpp +++ b/src/electronic-ids/pkcs11/Pkcs11ElectronicID.cpp @@ -21,7 +21,9 @@ */ #include "Pkcs11ElectronicID.hpp" +#include "../scope.hpp" +#include #include #ifdef _WIN32 @@ -211,7 +213,7 @@ const Pkcs11ElectronicIDModule& getModule(ElectronicID::Type eidType) return SUPPORTED_PKCS11_MODULES.at(eidType); } catch (const std::out_of_range&) { THROW(ProgrammingError, - "Unknown Pkcs11ElectronicIDType enum value '" + std::to_string(int(eidType)) + "'"); + "Unknown Pkcs11ElectronicIDType enum value '" + std::to_string(int(eidType)) + '\''); } } @@ -222,57 +224,54 @@ Pkcs11ElectronicID::Pkcs11ElectronicID(ElectronicID::Type type) : { REQUIRE_NON_NULL(manager) - bool seenAuthToken = false; - bool seenSigningToken = false; - for (const auto& token : manager->tokens()) { const auto certType = certificateType(token.cert); if (certType.isAuthentication()) { authToken = token; - seenAuthToken = true; } else if (certType.isSigning()) { signingToken = token; - seenSigningToken = true; } } - if (!(seenAuthToken && seenSigningToken)) { - THROW(SmartCardChangeRequiredError, "Either authentication or signing token is missing"); - } } pcsc_cpp::byte_vector Pkcs11ElectronicID::getCertificate(const CertificateType type) const { - return type.isAuthentication() ? authToken.cert : signingToken.cert; + return token(type).cert; } JsonWebSignatureAlgorithm Pkcs11ElectronicID::authSignatureAlgorithm() const { - return getAuthAlgorithmFromCert(authToken.cert); + return getAuthAlgorithmFromCert(token(CertificateType::AUTHENTICATION).cert); } ElectronicID::PinMinMaxLength Pkcs11ElectronicID::authPinMinMaxLength() const { - return {authToken.minPinLen, authToken.maxPinLen}; + const auto& t = token(CertificateType::AUTHENTICATION); + return {t.minPinLen, t.maxPinLen}; } ElectronicID::PinInfo Pkcs11ElectronicID::authPinInfo() const { - return {authToken.retry, module.retryMax, true}; + return {token(CertificateType::AUTHENTICATION).retry, module.retryMax, true}; } pcsc_cpp::byte_vector Pkcs11ElectronicID::signWithAuthKey(byte_vector&& pin, const byte_vector& hash) const { + auto clearPin = stdext::make_scope_exit([&pin] { + std::fill(pin.begin(), pin.end(), byte_type(0)); + pin.clear(); + }); REQUIRE_NON_NULL(manager) try { validateAuthHashLength(authSignatureAlgorithm(), name(), hash); - const auto signature = - manager->sign(authToken, hash, authSignatureAlgorithm().hashAlgorithm(), - module.providesExternalPinDialog, - reinterpret_cast(pin.data()), pin.size()); - return signature.first; + auto signature = manager->sign(token(CertificateType::AUTHENTICATION), hash, + authSignatureAlgorithm().hashAlgorithm(), + module.providesExternalPinDialog, + reinterpret_cast(pin.data()), pin.size()); + return std::move(signature.first); } catch (const VerifyPinFailed& e) { // Catch and rethrow the VerifyPinFailed error with -1 to inform the caller of the special // case where the card does not return the remaining retry count. This is arguably a @@ -287,34 +286,39 @@ pcsc_cpp::byte_vector Pkcs11ElectronicID::signWithAuthKey(byte_vector&& pin, const std::set& Pkcs11ElectronicID::supportedSigningAlgorithms() const { - return getSignAlgorithmFromCert(signingToken.cert); + return getSignAlgorithmFromCert(token(CertificateType::SIGNING).cert); } ElectronicID::PinMinMaxLength Pkcs11ElectronicID::signingPinMinMaxLength() const { - return {signingToken.minPinLen, signingToken.maxPinLen}; + const auto& t = token(CertificateType::SIGNING); + return {t.minPinLen, t.maxPinLen}; } ElectronicID::PinInfo Pkcs11ElectronicID::signingPinInfo() const { - return {signingToken.retry, module.retryMax, true}; + return {token(CertificateType::SIGNING).retry, module.retryMax, true}; } ElectronicID::Signature Pkcs11ElectronicID::signWithSigningKey(byte_vector&& pin, const byte_vector& hash, const HashAlgorithm hashAlgo) const { + auto clearPin = stdext::make_scope_exit([&pin] { + std::fill(pin.begin(), pin.end(), byte_type(0)); + pin.clear(); + }); REQUIRE_NON_NULL(manager) try { validateSigningHash(*this, hashAlgo, hash); // TODO: add step for supported algo detection before sign(), see if () below. - auto signature = - manager->sign(signingToken, hash, hashAlgo, module.providesExternalPinDialog, - reinterpret_cast(pin.data()), pin.size()); + auto signature = manager->sign(token(CertificateType::SIGNING), hash, hashAlgo, + module.providesExternalPinDialog, + reinterpret_cast(pin.data()), pin.size()); - if (!supportedSigningAlgorithms().count(signature.second)) { + if (!supportedSigningAlgorithms().contains(signature.second)) { THROW(SmartCardChangeRequiredError, "Signature algorithm " + std::string(signature.second) + " is not supported by " + name()); @@ -330,6 +334,20 @@ ElectronicID::Signature Pkcs11ElectronicID::signWithSigningKey(byte_vector&& pin } } +const PKCS11CardManager::Token& Pkcs11ElectronicID::token(CertificateType type) const +{ + if (type.isAuthentication()) { + if (authToken.cert.empty()) { + THROW(SmartCardChangeRequiredError, "Authentication token is missing"); + } + return authToken; + } + if (signingToken.cert.empty()) { + THROW(SmartCardChangeRequiredError, "Signing token is missing"); + } + return signingToken; +} + void Pkcs11ElectronicID::release() const { manager.reset(); diff --git a/src/electronic-ids/pkcs11/Pkcs11ElectronicID.hpp b/src/electronic-ids/pkcs11/Pkcs11ElectronicID.hpp index 8eb573a..4498af5 100644 --- a/src/electronic-ids/pkcs11/Pkcs11ElectronicID.hpp +++ b/src/electronic-ids/pkcs11/Pkcs11ElectronicID.hpp @@ -72,6 +72,8 @@ class Pkcs11ElectronicID : public ElectronicID std::string name() const override { return module.name; } Type type() const override { return module.type; } + const PKCS11CardManager::Token& token(CertificateType type) const; + const Pkcs11ElectronicIDModule& module; mutable std::shared_ptr manager; PKCS11CardManager::Token authToken;