Skip to content

Commit

Permalink
Remove CardInfo
Browse files Browse the repository at this point in the history
Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed Feb 7, 2025
1 parent f47fc15 commit 2ca94da
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 115 deletions.
20 changes: 1 addition & 19 deletions include/electronic-id/electronic-id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,27 +114,9 @@ bool isCardSupported(const pcsc_cpp::byte_vector& atr);

ElectronicID::ptr getElectronicID(const pcsc_cpp::Reader& reader);

/** Aggregates reader and electronic ID objects for communicating with and inspecting the eID card.
*/
class CardInfo
{
public:
using ptr = std::shared_ptr<CardInfo>;

CardInfo(pcsc_cpp::Reader r, ElectronicID::ptr e) : _reader(std::move(r)), _eid(std::move(e)) {}

const pcsc_cpp::Reader& reader() const { return _reader; }
const ElectronicID& eid() const { return *_eid; }
const ElectronicID::ptr eidPtr() const { return _eid; }

private:
pcsc_cpp::Reader _reader;
ElectronicID::ptr _eid;
};

/** Automatic card selection that either returns a vector of card info pointers with available
* supported cards or throws AutoSelectFailed. */
std::vector<CardInfo::ptr> availableSupportedCards();
std::vector<ElectronicID::ptr> availableSupportedCards();

/** Base class for fatal errors in parameters or environment conditions that do not allow retrying.
*/
Expand Down
5 changes: 4 additions & 1 deletion lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ class SmartCard
bool& inProgress;
};

SmartCard(const ContextPtr& context, const string_t& readerName, byte_vector atr);
SmartCard(ContextPtr context, string_t readerName, byte_vector atr);
SmartCard(); // Null object constructor.
~SmartCard();
PCSC_CPP_DISABLE_COPY_MOVE(SmartCard);
Expand All @@ -244,9 +244,12 @@ class SmartCard

Protocol protocol() const { return _protocol; }
const byte_vector& atr() const { return _atr; }
const string_t& name() const { return _name; }

private:
ContextPtr ctx;
CardImplPtr card;
string_t _name;
byte_vector _atr;
Protocol _protocol = Protocol::UNDEFINED;
bool transactionInProgress = false;
Expand Down
7 changes: 4 additions & 3 deletions lib/libpcsc-cpp/src/SmartCard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,10 @@ SmartCard::TransactionGuard::~TransactionGuard()
}
}

SmartCard::SmartCard(const ContextPtr& contex, const string_t& readerName, byte_vector atr) :
card(std::make_unique<CardImpl>(connectToCard(contex->handle(), readerName))),
_atr(std::move(atr)), _protocol(convertToSmartCardProtocol(card->protocol()))
SmartCard::SmartCard(ContextPtr contex, string_t readerName, byte_vector atr) :
ctx(contex), card(std::make_unique<CardImpl>(connectToCard(contex->handle(), readerName))),
_name(std::move(readerName)), _atr(std::move(atr)),
_protocol(convertToSmartCardProtocol(card->protocol()))
{
// TODO: debug("Card ATR -> " + bytes2hexstr(atr))
}
Expand Down
19 changes: 3 additions & 16 deletions src/availableSupportedCards.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,15 @@
#include "electronic-ids/ms-cryptoapi/listMsCryptoApiElectronicIDs.hpp"
#endif

namespace
{

using namespace electronic_id;

inline CardInfo::ptr connectToCard(const pcsc_cpp::Reader& reader)
{
auto eid = getElectronicID(reader);
return std::make_shared<CardInfo>(reader, eid);
}

} // namespace

namespace electronic_id
{

std::vector<CardInfo::ptr> availableSupportedCards()
std::vector<ElectronicID::ptr> availableSupportedCards()
{
std::vector<pcsc_cpp::Reader> readers;
try {
readers = pcsc_cpp::listReaders();
std::vector<CardInfo::ptr> cards;
std::vector<ElectronicID::ptr> cards;

auto seenCard = false;
// The list may be empty, but we cannot throw yet due to the listMsCryptoApiElectronicIDs()
Expand All @@ -58,7 +45,7 @@ std::vector<CardInfo::ptr> availableSupportedCards()
}
seenCard = true;
if (isCardSupported(reader.cardAtr)) {
cards.push_back(connectToCard(reader));
cards.push_back(getElectronicID(reader));
}
}

Expand Down
15 changes: 4 additions & 11 deletions src/electronic-ids/ms-cryptoapi/listMsCryptoApiElectronicIDs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace electronic_id

// Enumerates all certificates and converts the valid hardware-based ones to MsCryptoApiElectronicID
// objects.
std::vector<CardInfo::ptr> listMsCryptoApiElectronicIDs()
std::vector<ElectronicID::ptr> listMsCryptoApiElectronicIDs()
{
HCERTSTORE sys =
CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING, 0,
Expand All @@ -46,13 +46,7 @@ std::vector<CardInfo::ptr> listMsCryptoApiElectronicIDs()
}
auto closeCertStore = stdext::make_scope_exit([=]() { CertCloseStore(sys, 0); });

std::vector<CardInfo::ptr> msCryptoApiElectronicIDs;
pcsc_cpp::Reader dummyReader {
nullptr,
L"Dummy reader for MS CryptoAPI tokens"s,
{},
flag_set<pcsc_cpp::Reader::Status> {pcsc_cpp::Reader::Status::PRESENT},
};
std::vector<ElectronicID::ptr> msCryptoApiElectronicIDs;

PCCERT_CONTEXT cert = nullptr;
while ((cert = CertEnumCertificatesInStore(sys, cert)) != nullptr) {
Expand Down Expand Up @@ -121,8 +115,7 @@ std::vector<CardInfo::ptr> listMsCryptoApiElectronicIDs()
continue; // TODO: log.
}
algo.resize(size / 2 - 1);
// TODO: use algo.starts_with(L"EC") when migrating to C++20.
if (algo != L"RSA" && algo.rfind(L"EC", 0) != 0) {
if (algo != L"RSA" && !algo.starts_with(L"EC")) {
// We only support RSA and ECC algorithms.
continue; // TODO: log.
}
Expand All @@ -147,7 +140,7 @@ std::vector<CardInfo::ptr> listMsCryptoApiElectronicIDs()
std::move(certData), certType,
algo == L"RSA", key, freeKey);

msCryptoApiElectronicIDs.push_back(std::make_shared<CardInfo>(dummyReader, std::move(eid)));
msCryptoApiElectronicIDs.push_back(std::move(eid));
}

// CertEnumCertificatesInStore() function frees the CERT_CONTEXT referenced by non-NULL values
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@
namespace electronic_id
{

std::vector<CardInfo::ptr> listMsCryptoApiElectronicIDs();
std::vector<ElectronicID::ptr> listMsCryptoApiElectronicIDs();

}
2 changes: 1 addition & 1 deletion tests/common/selectcard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include <stdexcept>

inline electronic_id::CardInfo::ptr autoSelectSupportedCard() {
inline electronic_id::ElectronicID::ptr autoSelectSupportedCard() {
using namespace electronic_id;

auto cardList = availableSupportedCards();
Expand Down
14 changes: 7 additions & 7 deletions tests/integration/test-authenticate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ TEST(electronic_id_test, authenticate)

EXPECT_TRUE(cardInfo);

std::cout << "Selected card: " << cardInfo->eid().name() << '\n';
std::cout << "Selected card: " << cardInfo->name() << '\n';

byte_vector cert = cardInfo->eid().getCertificate(CertificateType::AUTHENTICATION);
byte_vector cert = cardInfo->getCertificate(CertificateType::AUTHENTICATION);

std::cout << "Does the reader have a PIN-pad? "
<< (cardInfo->eid().smartcard().readerHasPinPad() ? "yes" : "no") << '\n';
<< (cardInfo->smartcard().readerHasPinPad() ? "yes" : "no") << '\n';

switch (cardInfo->eid().authSignatureAlgorithm()) {
switch (cardInfo->authSignatureAlgorithm()) {
case JsonWebSignatureAlgorithm::ES384:
case JsonWebSignatureAlgorithm::RS256:
case JsonWebSignatureAlgorithm::PS256:
Expand All @@ -55,7 +55,7 @@ TEST(electronic_id_test, authenticate)
"currently supported");
}

GTEST_ASSERT_GE(cardInfo->eid().authPinRetriesLeft().first, 0U);
GTEST_ASSERT_GE(cardInfo->authPinRetriesLeft().first, 0U);

byte_vector pin {'1', '2', '3', '4'};
pin.reserve(64);
Expand All @@ -64,9 +64,9 @@ TEST(electronic_id_test, authenticate)
<< std::string_view(reinterpret_cast<const char*>(pin.data()), pin.size()) << '\n';

const byte_vector dataToSign {'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'};
const JsonWebSignatureAlgorithm hashAlgo = cardInfo->eid().authSignatureAlgorithm();
const JsonWebSignatureAlgorithm hashAlgo = cardInfo->authSignatureAlgorithm();
const byte_vector hash = calculateDigest(hashAlgo.hashAlgorithm(), dataToSign);
auto signature = cardInfo->eid().signWithAuthKey(std::move(pin), hash);
auto signature = cardInfo->signWithAuthKey(std::move(pin), hash);

std::cout << "Authentication signature: " << signature << '\n';

Expand Down
6 changes: 3 additions & 3 deletions tests/integration/test-get-certificate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ TEST(electronic_id_test, getCertificate)

EXPECT_TRUE(cardInfo);

std::cout << "Selected card: " << cardInfo->eid().name() << '\n';
std::cout << "Selected card: " << cardInfo->name() << '\n';

auto certificate = cardInfo->eid().getCertificate(CertificateType::AUTHENTICATION);
auto certificate = cardInfo->getCertificate(CertificateType::AUTHENTICATION);

std::cout << "Authentication certificate: " << certificate << '\n';

certificate = cardInfo->eid().getCertificate(CertificateType::SIGNING);
certificate = cardInfo->getCertificate(CertificateType::SIGNING);

std::cout << "Signing certificate: " << certificate << '\n';
}
17 changes: 8 additions & 9 deletions tests/integration/test-signing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,24 @@ static void signing(HashAlgorithm hashAlgo)

EXPECT_TRUE(cardInfo);

std::cout << "Selected card: " << cardInfo->eid().name() << '\n';
std::cout << "Selected card: " << cardInfo->name() << '\n';

if (!cardInfo->eid().isSupportedSigningHashAlgorithm(hashAlgo)) {
if (!cardInfo->isSupportedSigningHashAlgorithm(hashAlgo)) {
std::string skip = "Card does not support hashing algorithm: " + std::string(hashAlgo);
GTEST_SUCCESS_(skip.c_str());
return;
}

byte_vector cert = cardInfo->eid().getCertificate(CertificateType::SIGNING);
byte_vector cert = cardInfo->getCertificate(CertificateType::SIGNING);

GTEST_ASSERT_GE(cardInfo->eid().signingPinRetriesLeft().first, 0U);
GTEST_ASSERT_GE(cardInfo->signingPinRetriesLeft().first, 0U);

byte_vector pin;
if (cardInfo->eid().name() == "EstEID IDEMIA v1")
if (cardInfo->name() == "EstEID IDEMIA v1")
pin = {'1', '2', '3', '4', '5'}; // EstIDEMIA test card default PIN2
else if (cardInfo->eid().name() == "LatEID IDEMIA v1"
|| cardInfo->eid().name() == "LatEID IDEMIA v2")
else if (cardInfo->name() == "LatEID IDEMIA v1" || cardInfo->name() == "LatEID IDEMIA v2")
pin = {'1', '2', '3', '4', '5', '6'}; // LatIDEMIA test card default PIN2
else if (cardInfo->eid().name() == "FinEID v3" || cardInfo->eid().name() == "FinEID v4")
else if (cardInfo->name() == "FinEID v3" || cardInfo->name() == "FinEID v4")
pin = {'1', '2', '3', '4', '5', '6'}; // FinEID custom PIN
else
throw std::runtime_error("TEST signing: Unknown card");
Expand All @@ -66,7 +65,7 @@ static void signing(HashAlgorithm hashAlgo)
const byte_vector dataToSign {'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'};
const byte_vector hash = calculateDigest(hashAlgo, dataToSign);

auto signature = cardInfo->eid().signWithSigningKey(std::move(pin), hash, hashAlgo);
auto signature = cardInfo->signWithSigningKey(std::move(pin), hash, hashAlgo);

std::cout << "Signing signature: " << signature.first << '\n';

Expand Down
8 changes: 4 additions & 4 deletions tests/mock/test-autoselect-card.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ TEST(electronic_id_test, autoSelectSuccessWithSupportedCardEstIDEMIA)
PcscMock::setAtr(ESTEID_IDEMIA_V1_ATR);
auto result = autoSelectSupportedCard();
EXPECT_TRUE(result);
EXPECT_EQ(result->eid().name(), "EstEID IDEMIA v1");
EXPECT_EQ(result->name(), "EstEID IDEMIA v1");
PcscMock::reset();
}

Expand All @@ -47,7 +47,7 @@ TEST(electronic_id_test, autoSelectSuccessWithSupportedCardLatV2)
PcscMock::setAtr(LATEID_IDEMIA_V2_ATR);
auto result = autoSelectSupportedCard();
EXPECT_TRUE(result);
EXPECT_EQ(result->eid().name(), "LatEID IDEMIA v2");
EXPECT_EQ(result->name(), "LatEID IDEMIA v2");
PcscMock::reset();
}

Expand All @@ -56,7 +56,7 @@ TEST(electronic_id_test, autoSelectSuccessWithSupportedCardFinV3)
PcscMock::setAtr(FINEID_V3_ATR);
auto result = autoSelectSupportedCard();
EXPECT_TRUE(result);
EXPECT_EQ(result->eid().name(), "FinEID v3");
EXPECT_EQ(result->name(), "FinEID v3");
PcscMock::reset();
}

Expand All @@ -65,6 +65,6 @@ TEST(electronic_id_test, autoSelectSuccessWithSupportedCardFinV4)
PcscMock::setAtr(FINEID_V4_ATR);
auto result = autoSelectSupportedCard();
EXPECT_TRUE(result);
EXPECT_EQ(result->eid().name(), "FinEID v4");
EXPECT_EQ(result->name(), "FinEID v4");
PcscMock::reset();
}
Loading

0 comments on commit 2ca94da

Please sign in to comment.