From fe1aaf2337eda0909046f2a427b82258de75b19e Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 7 Nov 2025 13:38:41 +0200 Subject: [PATCH] Move magic enum to local and avoid allocation WE2-1204 Signed-off-by: Raul Metsma --- CMakeLists.txt | 1 + include/electronic-id/electronic-id.hpp | 5 +- include/electronic-id/enums.hpp | 62 +++++++++---------- lib/libpcsc-cpp/CMakeLists.txt | 1 - .../include/pcsc-cpp/pcsc-cpp-utils.hpp | 4 +- src/electronic-id.cpp | 51 ++++++++------- .../ms-cryptoapi/MsCryptoApiElectronicID.cpp | 4 +- .../include => src}/magic_enum/magic_enum.hpp | 0 8 files changed, 65 insertions(+), 63 deletions(-) rename {lib/libpcsc-cpp/include => src}/magic_enum/magic_enum.hpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index b616409..1b787f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ add_library(${PROJECT_NAME} src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.cpp src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.hpp > + src/magic_enum/magic_enum.hpp ) target_include_directories(${PROJECT_NAME} diff --git a/include/electronic-id/electronic-id.hpp b/include/electronic-id/electronic-id.hpp index 81290ec..06ba6a4 100644 --- a/include/electronic-id/electronic-id.hpp +++ b/include/electronic-id/electronic-id.hpp @@ -26,6 +26,7 @@ #include #include +#include namespace electronic_id { @@ -99,7 +100,7 @@ class ElectronicID * By default, this function does nothing. It serves as an extension point for * Pkcs11ElectronicID which needs to release the PKCS#11 module before the application exits to * prevent potential crashes. */ - virtual void release() const {} + virtual void release() const { } virtual std::string name() const = 0; virtual Type type() const = 0; @@ -107,7 +108,7 @@ class ElectronicID virtual pcsc_cpp::SmartCard const& smartcard() const { return card; } protected: - ElectronicID(pcsc_cpp::SmartCard&& _card) noexcept : card(std::move(_card)) {} + ElectronicID(pcsc_cpp::SmartCard&& _card) noexcept : card(std::move(_card)) { } pcsc_cpp::SmartCard card; }; diff --git a/include/electronic-id/enums.hpp b/include/electronic-id/enums.hpp index cb58b6f..00e114c 100644 --- a/include/electronic-id/enums.hpp +++ b/include/electronic-id/enums.hpp @@ -24,7 +24,6 @@ #include "pcsc-cpp/pcsc-cpp.hpp" -#include #include namespace electronic_id @@ -35,15 +34,17 @@ class CertificateType public: enum CertificateTypeEnum : int8_t { AUTHENTICATION, SIGNING, NONE = -1 }; - CertificateType() = default; - constexpr CertificateType(const CertificateTypeEnum _value) : value(_value) {} + constexpr CertificateType() noexcept = default; + constexpr CertificateType(const CertificateTypeEnum _value) noexcept : value(_value) { } - bool isAuthentication() const { return value == AUTHENTICATION; } + constexpr bool isAuthentication() const noexcept { return value == AUTHENTICATION; } + constexpr bool isSigning() const noexcept { return value == SIGNING; } - bool isSigning() const { return value == SIGNING; } - - constexpr bool operator==(const CertificateType other) const { return value == other.value; } - operator std::string() const; + constexpr bool operator==(const CertificateType other) const noexcept + { + return value == other.value; + } + operator std::string_view() const noexcept; private: CertificateTypeEnum value = NONE; @@ -66,27 +67,27 @@ class HashAlgorithm NONE = -1 }; - HashAlgorithm() = default; - constexpr HashAlgorithm(const HashAlgorithmEnum _value) : value(_value) {} + constexpr HashAlgorithm() = default; + constexpr HashAlgorithm(const HashAlgorithmEnum _value) noexcept : value(_value) { } // String conversion constructor. - HashAlgorithm(const std::string&); + explicit HashAlgorithm(const std::string&); constexpr bool operator==(HashAlgorithmEnum other) const { return value == other; } - constexpr operator HashAlgorithmEnum() const { return value; } + constexpr operator HashAlgorithmEnum() const noexcept { return value; } - operator std::string() const; + operator std::string_view() const noexcept; - constexpr size_t hashByteLength() const + constexpr size_t hashByteLength() const noexcept { - return size_t(value <= SHA512 ? value / 8 : (value / 10) / 8); + return size_t((value <= SHA512 ? value : (value / 10)) / 8); } - constexpr bool isSHA2() const + constexpr bool isSHA2() const noexcept { return value >= HashAlgorithm::SHA224 && value <= HashAlgorithm::SHA512; } - constexpr bool isSHA3() const + constexpr bool isSHA3() const noexcept { return value >= HashAlgorithm::SHA3_224 && value <= HashAlgorithm::SHA3_512; } @@ -136,26 +137,25 @@ class SignatureAlgorithm NONE = -1 }; - constexpr SignatureAlgorithm(const SignatureAlgorithmEnum _value) : value(_value) {} - constexpr SignatureAlgorithm(const SignatureAlgorithmEnum key, const HashAlgorithm hash) : + constexpr SignatureAlgorithm(const SignatureAlgorithmEnum _value) noexcept : value(_value) { } + constexpr SignatureAlgorithm(const SignatureAlgorithmEnum key, + const HashAlgorithm hash) noexcept : value(SignatureAlgorithmEnum(key | int16_t(hash))) { } - constexpr bool operator==(HashAlgorithm other) const + constexpr bool operator==(HashAlgorithm other) const noexcept { return other.operator==(operator HashAlgorithm()); } - constexpr bool operator==(SignatureAlgorithmEnum other) const { return value == other; } - - constexpr operator HashAlgorithm() const + constexpr operator HashAlgorithm() const noexcept { return HashAlgorithm::HashAlgorithmEnum(value & ~(ES | PS | RS)); } - constexpr operator SignatureAlgorithmEnum() const { return value; } + constexpr operator SignatureAlgorithmEnum() const noexcept { return value; } - operator std::string() const; + operator std::string_view() const noexcept; private: SignatureAlgorithmEnum value = NONE; @@ -178,14 +178,14 @@ class JsonWebSignatureAlgorithm NONE = -1 }; - constexpr JsonWebSignatureAlgorithm(const JsonWebSignatureAlgorithmEnum _value) : value(_value) + constexpr JsonWebSignatureAlgorithm(const JsonWebSignatureAlgorithmEnum _value) noexcept : + value(_value) { } - constexpr bool operator==(JsonWebSignatureAlgorithmEnum other) const { return value == other; } - constexpr operator JsonWebSignatureAlgorithmEnum() const { return value; } + constexpr operator JsonWebSignatureAlgorithmEnum() const noexcept { return value; } - operator std::string() const; + operator std::string_view() const noexcept; constexpr HashAlgorithm hashAlgorithm() const { @@ -208,12 +208,12 @@ class JsonWebSignatureAlgorithm } } - constexpr bool isRSAWithPKCS1Padding() + constexpr bool isRSAWithPKCS1Padding() const noexcept { return value == RS256 || value == RS384 || value == RS512; } - constexpr size_t hashByteLength() const { return hashAlgorithm().hashByteLength(); } + constexpr size_t hashByteLength() const noexcept { return hashAlgorithm().hashByteLength(); } private: JsonWebSignatureAlgorithmEnum value = NONE; diff --git a/lib/libpcsc-cpp/CMakeLists.txt b/lib/libpcsc-cpp/CMakeLists.txt index ac7ff8d..632dd71 100644 --- a/lib/libpcsc-cpp/CMakeLists.txt +++ b/lib/libpcsc-cpp/CMakeLists.txt @@ -9,7 +9,6 @@ add_library(${PROJECT_NAME} include/${PROJECT_NAME}/${PROJECT_NAME}.hpp include/${PROJECT_NAME}/${PROJECT_NAME}-utils.hpp include/${PROJECT_NAME}/comp_winscard.hpp - include/magic_enum/magic_enum.hpp src/Context.hpp src/SCardCall.hpp src/SmartCard.cpp diff --git a/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp-utils.hpp b/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp-utils.hpp index 2b9d12d..4380065 100644 --- a/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp-utils.hpp +++ b/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp-utils.hpp @@ -69,7 +69,5 @@ constexpr const char* removeAbsolutePathPrefix(std::string_view filePath) #define REQUIRE_NON_NULL(val) \ if (!(val)) { \ - throw std::logic_error("Null " + std::string(#val) + " in " \ - + pcsc_cpp::removeAbsolutePathPrefix(__FILE__) + ':' \ - + std::to_string(__LINE__) + ':' + __func__); \ + THROW(std::logic_error, "Null " #val); \ } diff --git a/src/electronic-id.cpp b/src/electronic-id.cpp index d767139..15d11b3 100644 --- a/src/electronic-id.cpp +++ b/src/electronic-id.cpp @@ -211,11 +211,11 @@ const std::vector MASKED_ATRS = { constructor}, }; -const auto SUPPORTED_ALGORITHMS = std::map { - {"SHA-224"s, HashAlgorithm::SHA224}, {"SHA-256"s, HashAlgorithm::SHA256}, - {"SHA-384"s, HashAlgorithm::SHA384}, {"SHA-512"s, HashAlgorithm::SHA512}, - {"SHA3-224"s, HashAlgorithm::SHA3_224}, {"SHA3-256"s, HashAlgorithm::SHA3_256}, - {"SHA3-384"s, HashAlgorithm::SHA3_384}, {"SHA3-512"s, HashAlgorithm::SHA3_512}, +const auto SUPPORTED_ALGORITHMS = std::map { + {"SHA-224", HashAlgorithm::SHA224}, {"SHA-256", HashAlgorithm::SHA256}, + {"SHA-384", HashAlgorithm::SHA384}, {"SHA-512", HashAlgorithm::SHA512}, + {"SHA3-224", HashAlgorithm::SHA3_224}, {"SHA3-256", HashAlgorithm::SHA3_256}, + {"SHA3-384", HashAlgorithm::SHA3_384}, {"SHA3-512", HashAlgorithm::SHA3_512}, }; } // namespace @@ -265,14 +265,14 @@ bool ElectronicID::isSupportedSigningHashAlgorithm(const HashAlgorithm hashAlgo) } AutoSelectFailed::AutoSelectFailed(Reason r) : - Error(std::string("Auto-select card failed, reason: ") + std::string(magic_enum::enum_name(r))), + Error(std::string("Auto-select card failed, reason: ").append(magic_enum::enum_name(r))), _reason(r) { } VerifyPinFailed::VerifyPinFailed(const Status s, const observer_ptr ra, const int8_t r) : - Error(std::string("Verify PIN failed, status: ") + std::string(magic_enum::enum_name(s)) + Error(std::string("Verify PIN failed, status: ").append(magic_enum::enum_name(s)) + (ra ? ", response: " + *ra : "")), _status(s), _retries(r) { @@ -288,12 +288,14 @@ HashAlgorithm::HashAlgorithm(const std::string& algoName) value = SUPPORTED_ALGORITHMS.at(algoName); } -HashAlgorithm::operator std::string() const +HashAlgorithm::operator std::string_view() const noexcept { const auto algoNameValuePair = std::find_if(SUPPORTED_ALGORITHMS.cbegin(), SUPPORTED_ALGORITHMS.cend(), [this](const auto& pair) { return pair.second == value; }); - return algoNameValuePair != SUPPORTED_ALGORITHMS.cend() ? algoNameValuePair->first : "UNKNOWN"; + if (algoNameValuePair != SUPPORTED_ALGORITHMS.cend()) + return algoNameValuePair->first; + return "UNKNOWN"; } std::string HashAlgorithm::allSupportedAlgorithmNames() @@ -301,35 +303,36 @@ std::string HashAlgorithm::allSupportedAlgorithmNames() static const auto SUPPORTED_ALGORITHM_NAMES = std::accumulate( std::next(SUPPORTED_ALGORITHMS.begin()), SUPPORTED_ALGORITHMS.end(), std::string(SUPPORTED_ALGORITHMS.begin()->first), - [](auto result, const auto& value) { return result + ", "s + std::string(value.first); }); + [](auto result, const auto& value) { return (result + ", ").append(value.first); }); return SUPPORTED_ALGORITHM_NAMES; } pcsc_cpp::byte_vector HashAlgorithm::rsaOID(const HashAlgorithmEnum hash) { switch (hash) { - case HashAlgorithm::SHA224: + using enum HashAlgorithm::HashAlgorithmEnum; + case SHA224: return {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c}; - case HashAlgorithm::SHA256: + case SHA256: return {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; - case HashAlgorithm::SHA384: + case SHA384: return {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; - case HashAlgorithm::SHA512: + case SHA512: return {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; - case HashAlgorithm::SHA3_224: + case SHA3_224: return {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x07, 0x05, 0x00, 0x04, 0x1c}; - case HashAlgorithm::SHA3_256: + case SHA3_256: return {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, 0x20}; - case HashAlgorithm::SHA3_384: + case SHA3_384: return {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04, 0x30}; - case HashAlgorithm::SHA3_512: + case SHA3_512: return {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0A, 0x05, 0x00, 0x04, 0x40}; default: @@ -337,19 +340,19 @@ pcsc_cpp::byte_vector HashAlgorithm::rsaOID(const HashAlgorithmEnum hash) } } -CertificateType::operator std::string() const +CertificateType::operator std::string_view() const noexcept { - return std::string(magic_enum::enum_name(value)); + return magic_enum::enum_name(value); } -JsonWebSignatureAlgorithm::operator std::string() const +JsonWebSignatureAlgorithm::operator std::string_view() const noexcept { - return std::string(magic_enum::enum_name(value)); + return magic_enum::enum_name(value); } -SignatureAlgorithm::operator std::string() const +SignatureAlgorithm::operator std::string_view() const noexcept { - return std::string(magic_enum::enum_name(value)); + return magic_enum::enum_name(value); } } // namespace electronic_id diff --git a/src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.cpp b/src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.cpp index a513a78..89069f0 100644 --- a/src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.cpp +++ b/src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.cpp @@ -37,7 +37,7 @@ JsonWebSignatureAlgorithm MsCryptoApiElectronicID::authSignatureAlgorithm() cons byte_vector MsCryptoApiElectronicID::signWithAuthKey(byte_vector&& /* pin */, const byte_vector& hash) const { - if (certType != CertificateType::AUTHENTICATION) { + if (!certType.isAuthentication()) { THROW(WrongCertificateTypeError, "This electronic ID does not support signing with the authentication key. " "It contains a " @@ -59,7 +59,7 @@ ElectronicID::Signature MsCryptoApiElectronicID::signWithSigningKey(byte_vector&& /* pin */, const byte_vector& hash, const HashAlgorithm hashAlgo) const { - if (certType != CertificateType::SIGNING) { + if (!certType.isSigning()) { THROW(WrongCertificateTypeError, "This electronic ID does not support signing with the digital signature key. " "It contains a " diff --git a/lib/libpcsc-cpp/include/magic_enum/magic_enum.hpp b/src/magic_enum/magic_enum.hpp similarity index 100% rename from lib/libpcsc-cpp/include/magic_enum/magic_enum.hpp rename to src/magic_enum/magic_enum.hpp