Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
5 changes: 3 additions & 2 deletions include/electronic-id/electronic-id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <functional>
#include <optional>
#include <set>

namespace electronic_id
{
Expand Down Expand Up @@ -99,15 +100,15 @@ 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;

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;
};
Expand Down
62 changes: 31 additions & 31 deletions include/electronic-id/enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

#include "pcsc-cpp/pcsc-cpp.hpp"

#include <set>
#include <string>

namespace electronic_id
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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
{
Expand All @@ -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;
Expand Down
1 change: 0 additions & 1 deletion lib/libpcsc-cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 1 addition & 3 deletions lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp-utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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); \
}
51 changes: 27 additions & 24 deletions src/electronic-id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,11 @@ const std::vector<MaskedATREntry> MASKED_ATRS = {
constructor<ElectronicID::Type::LuxEID>},
};

const auto SUPPORTED_ALGORITHMS = std::map<std::string, HashAlgorithm> {
{"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<std::string_view, HashAlgorithm> {
{"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
Expand Down Expand Up @@ -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<pcsc_cpp::ResponseApdu> 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)
{
Expand All @@ -288,68 +288,71 @@ 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()
{
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:
THROW(ArgumentFatalError, "No OID for algorithm " + std::string(HashAlgorithm(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
4 changes: 2 additions & 2 deletions src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand All @@ -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 "
Expand Down
Loading