diff --git a/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp b/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp index f05c241..fc927ff 100644 --- a/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp +++ b/lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp @@ -81,6 +81,9 @@ constexpr uint16_t toSW(byte_type sw1, byte_type sw2) noexcept return uint16_t(sw1 << 8) | sw2; } +/** Convert bytes to hex string. */ +std::string bytes2hexstr(const byte_vector& bytes); + /** Struct that wraps response APDUs. */ struct ResponseApdu { @@ -120,22 +123,14 @@ struct ResponseApdu return {sw1, sw2, std::move(data)}; } - byte_vector toBytes() const - { - // makes a copy, valid both if data is empty or full - auto bytes = data; - - bytes.push_back(sw1); - bytes.push_back(sw2); - - return bytes; - } - constexpr uint16_t toSW() const noexcept { return pcsc_cpp::toSW(sw1, sw2); } constexpr bool isOK() const noexcept { return sw1 == OK && sw2 == 0x00; } - // TODO: friend function toString() in utilities.hpp + friend std::string operator+(std::string&& lhs, const ResponseApdu& rhs) + { + return lhs + pcsc_cpp::bytes2hexstr(rhs.data) + pcsc_cpp::bytes2hexstr({rhs.sw1, rhs.sw2}); + } }; /** Struct that wraps command APDUs. */ @@ -270,9 +265,6 @@ std::vector listReaders(); // Utility functions. -/** Convert bytes to hex string. */ -std::string bytes2hexstr(const byte_vector& bytes); - /** Transmit APDU command and verify that expected response is received. */ void transmitApduWithExpectedResponse(const SmartCard& card, const CommandApdu& command); diff --git a/lib/libpcsc-cpp/src/SmartCard.cpp b/lib/libpcsc-cpp/src/SmartCard.cpp index 005662b..7ac3baf 100644 --- a/lib/libpcsc-cpp/src/SmartCard.cpp +++ b/lib/libpcsc-cpp/src/SmartCard.cpp @@ -243,8 +243,7 @@ class CardImpl break; default: THROW(Error, - "Error response: '" + bytes2hexstr({response.sw1, response.sw2}) + "', protocol " - + std::to_string(protocol())); + "Error response: '" + response + "', protocol " + std::to_string(protocol())); } if (response.sw1 == ResponseApdu::WRONG_LE_LENGTH) { diff --git a/lib/libpcsc-cpp/src/utils.cpp b/lib/libpcsc-cpp/src/utils.cpp index f6214e6..ce171f6 100644 --- a/lib/libpcsc-cpp/src/utils.cpp +++ b/lib/libpcsc-cpp/src/utils.cpp @@ -58,9 +58,9 @@ class UnexpectedResponseError : public Error const char* file, const int line, const char* callerFunctionName) : Error("transmitApduWithExpectedResponse(): Unexpected response to command '"s - + bytes2hexstr(command) + "' - expected '9000', got '"s - + bytes2hexstr(response.toBytes()) + "' in " + removeAbsolutePathPrefix(file) + ':' - + std::to_string(line) + ':' + callerFunctionName) + + bytes2hexstr(command) + "' - expected '9000', got '"s + response + "' in " + + removeAbsolutePathPrefix(file) + ':' + std::to_string(line) + ':' + + callerFunctionName) { } }; diff --git a/src/electronic-id.cpp b/src/electronic-id.cpp index 5bb65fb..f840d1c 100644 --- a/src/electronic-id.cpp +++ b/src/electronic-id.cpp @@ -289,7 +289,7 @@ AutoSelectFailed::AutoSelectFailed(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)) - + (ra ? ", response: " + pcsc_cpp::bytes2hexstr(ra->toBytes()) : "")), + + (ra ? ", response: " + *ra : "")), _status(s), _retries(r) { } diff --git a/src/electronic-ids/pcsc/EIDIDEMIA.cpp b/src/electronic-ids/pcsc/EIDIDEMIA.cpp index 72a9cde..471a670 100644 --- a/src/electronic-ids/pcsc/EIDIDEMIA.cpp +++ b/src/electronic-ids/pcsc/EIDIDEMIA.cpp @@ -152,9 +152,7 @@ ElectronicID::PinRetriesRemainingAndMax EIDIDEMIA::pinRetriesLeft(byte_type pinR 0x00}; const auto response = card->transmit(GET_DATA_ODD); if (!response.isOK()) { - THROW(SmartCardError, - "Command GET DATA ODD failed with error " - + pcsc_cpp::bytes2hexstr(response.toBytes())); + THROW(SmartCardError, "Command GET DATA ODD failed with error " + response); } if (response.data.size() < 14) { THROW(SmartCardError, diff --git a/src/electronic-ids/pcsc/FinEID.cpp b/src/electronic-ids/pcsc/FinEID.cpp index 464dcb9..3b4fb12 100644 --- a/src/electronic-ids/pcsc/FinEID.cpp +++ b/src/electronic-ids/pcsc/FinEID.cpp @@ -148,25 +148,20 @@ byte_vector FinEIDv3::sign(const HashAlgorithm hashAlgo, const byte_vector& hash if (response.sw1 == ResponseApdu::WRONG_LENGTH) { THROW(SmartCardError, - "Wrong data length in command COMPUTE SIGNATURE argument: " - + bytes2hexstr(response.toBytes())); + "Wrong data length in command COMPUTE SIGNATURE argument: " + response); } if (!response.isOK()) { - THROW(SmartCardError, - "Command COMPUTE SIGNATURE failed with error " + bytes2hexstr(response.toBytes())); + THROW(SmartCardError, "Command COMPUTE SIGNATURE failed with error " + response); } const CommandApdu getSignature {0x00, 0x2A, 0x9E, 0x9A, LE}; const auto signature = card->transmit(getSignature); if (signature.sw1 == ResponseApdu::WRONG_LENGTH) { - THROW(SmartCardError, - "Wrong data length in command GET SIGNATURE argument: " - + bytes2hexstr(response.toBytes())); + THROW(SmartCardError, "Wrong data length in command GET SIGNATURE argument: " + response); } if (!signature.isOK()) { - THROW(SmartCardError, - "Command GET SIGNATURE failed with error " + bytes2hexstr(signature.toBytes())); + THROW(SmartCardError, "Command GET SIGNATURE failed with error " + signature); } return signature.data; @@ -178,8 +173,7 @@ ElectronicID::PinRetriesRemainingAndMax FinEIDv3::pinRetriesLeft(byte_type pinRe 0x00, 0xCB, 0x00, 0xFF, {0xA0, 0x03, 0x83, 0x01, pinReference}}; const auto response = card->transmit(GET_DATA); if (!response.isOK()) { - THROW(SmartCardError, - "Command GET DATA failed with error " + pcsc_cpp::bytes2hexstr(response.toBytes())); + THROW(SmartCardError, "Command GET DATA failed with error " + response); } if (response.data.size() < 21) { THROW(SmartCardError, diff --git a/src/electronic-ids/pcsc/pcsc-common.hpp b/src/electronic-ids/pcsc/pcsc-common.hpp index bf6e2ae..2d56178 100644 --- a/src/electronic-ids/pcsc/pcsc-common.hpp +++ b/src/electronic-ids/pcsc/pcsc-common.hpp @@ -123,13 +123,12 @@ inline pcsc_cpp::byte_vector internalAuthenticate(pcsc_cpp::SmartCard& card, if (response.sw1 == pcsc_cpp::ResponseApdu::WRONG_LENGTH) { THROW(SmartCardError, - cardType + ": Wrong data length in command INTERNAL AUTHENTICATE argument: " - + pcsc_cpp::bytes2hexstr(response.toBytes())); + cardType + + ": Wrong data length in command INTERNAL AUTHENTICATE argument: " + response); } if (!response.isOK()) { THROW(SmartCardError, - cardType + ": Command INTERNAL AUTHENTICATE failed with error " - + pcsc_cpp::bytes2hexstr(response.toBytes())); + cardType + ": Command INTERNAL AUTHENTICATE failed with error " + response); } return response.data; @@ -144,13 +143,11 @@ inline pcsc_cpp::byte_vector computeSignature(pcsc_cpp::SmartCard& card, if (response.sw1 == pcsc_cpp::ResponseApdu::WRONG_LENGTH) { THROW(SmartCardError, - cardType + ": Wrong data length in command COMPUTE SIGNATURE argument: " - + pcsc_cpp::bytes2hexstr(response.toBytes())); + cardType + ": Wrong data length in command COMPUTE SIGNATURE argument: " + response); } if (!response.isOK()) { THROW(SmartCardError, - cardType + ": Command COMPUTE SIGNATURE failed with error " - + pcsc_cpp::bytes2hexstr(response.toBytes())); + cardType + ": Command COMPUTE SIGNATURE failed with error " + response); } return response.data; @@ -165,9 +162,7 @@ inline pcsc_cpp::byte_type selectSecurityEnv(pcsc_cpp::SmartCard& card, pcsc_cpp {0x00, 0x22, 0x41, env, {0x80, 0x01, signatureAlgo, 0x84, 0x01, keyReference}}); if (!response.isOK()) { - THROW(SmartCardError, - cardType + ": Command SET ENV failed with error " - + pcsc_cpp::bytes2hexstr(response.toBytes())); + THROW(SmartCardError, cardType + ": Command SET ENV failed with error " + response); } return signatureAlgo; }