Skip to content

Commit

Permalink
Don't handle OMNIKEY 3x21 / 6121 as pinpad readers
Browse files Browse the repository at this point in the history
WE2-859

Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed Feb 10, 2024
1 parent 4d935f1 commit 18581df
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cmake-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ jobs:
run: cmake --build build --config ${env:BUILD_TYPE}

- name: Test
run: ctest -V -C ${env:BUILD_TYPE}--test-dir build
run: ctest -V -C ${env:BUILD_TYPE} --test-dir build
15 changes: 15 additions & 0 deletions lib/libpcsc-cpp/include/pcsc-cpp/comp_winscard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,21 @@ enum DRIVER_FEATURES : uint8_t {
FEATURE_CCID_ESC_COMMAND = 0x13
};

enum TLV_PROPERTIES : uint8_t {
TLV_PROPERTY_wLcdLayout = 0x01,
TLV_PROPERTY_bEntryValidationCondition = 0x02,
TLV_PROPERTY_bTimeOut2 = 0x03,
TLV_PROPERTY_wLcdMaxCharacters = 0x04,
TLV_PROPERTY_wLcdMaxLines = 0x05,
TLV_PROPERTY_bMinPINSize = 0x06,
TLV_PROPERTY_bMaxPINSize = 0x07,
TLV_PROPERTY_sFirmwareID = 0x08,
TLV_PROPERTY_bPPDUSupport = 0x09,
TLV_PROPERTY_dwMaxAPDUDataSize = 0x0A,
TLV_PROPERTY_wIdVendor = 0x0B,
TLV_PROPERTY_wIdProduct = 0x0C,
};

using PCSC_TLV_STRUCTURE = struct
{
uint8_t tag;
Expand Down
50 changes: 38 additions & 12 deletions lib/libpcsc-cpp/src/SmartCard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ std::pair<SCARDHANDLE, DWORD> connectToCard(const SCARDCONTEXT ctx, const string
return std::pair<SCARDHANDLE, DWORD> {cardHandle, protocolOut};
}

template <class K, class V = uint32_t, class D, size_t dsize, typename Func>
constexpr std::map<K, V> parseTLV(const std::array<D, dsize>& data, DWORD size, Func transfrom)
{
std::map<K, V> result;
for (auto p = data.cbegin(); DWORD(std::distance(data.cbegin(), p)) < size;) {
auto tag = K(*p++);
V value {};
for (unsigned int i = 0, len = *p++; i < len; ++i)
value |= V(*p++) << 8 * i;
result[tag] = transfrom(value);
}
return result;
}

} // namespace

namespace pcsc_cpp
Expand All @@ -84,15 +98,21 @@ class CardImpl
// TODO: debug("Protocol: " + to_string(protocol()))
try {
DWORD size = 0;
std::array<BYTE, 256> feature {};
SCard(Control, cardHandle, DWORD(CM_IOCTL_GET_FEATURE_REQUEST), nullptr, 0U,
feature.data(), DWORD(feature.size()), &size);
for (auto p = feature.cbegin(); DWORD(std::distance(feature.cbegin(), p)) < size;) {
auto tag = DRIVER_FEATURES(*p++);
uint32_t value = 0;
for (unsigned int i = 0, len = *p++; i < len; ++i)
value |= uint32_t(*p++) << 8 * i;
features[tag] = ntohl(value);
std::array<BYTE, 256> buf {};
SCard(Control, cardHandle, DWORD(CM_IOCTL_GET_FEATURE_REQUEST), nullptr, 0U, buf.data(),
DWORD(buf.size()), &size);
features = parseTLV<DRIVER_FEATURES>(buf, size, [](uint32_t t) { return ntohl(t); });

if (auto ioctl = features.find(FEATURE_GET_TLV_PROPERTIES); ioctl != features.cend()) {
SCard(Control, cardHandle, ioctl->second, nullptr, 0U, buf.data(),
DWORD(buf.size()), &size);
auto properties = parseTLV<TLV_PROPERTIES>(buf, size, [](uint32_t t) { return t; });
if (auto vendor = properties.find(TLV_PROPERTY_wIdVendor);
vendor != properties.cend())
id_vendor = vendor->second;
if (auto product = properties.find(TLV_PROPERTY_wIdProduct);
product != properties.cend())
id_product = product->second;
}
} catch (const ScardError&) {
// Ignore driver errors during card feature requests.
Expand All @@ -114,6 +134,11 @@ class CardImpl

bool readerHasPinPad() const
{
// Some readers claim to have PinPAD support even if they have not
// HID Global OMNIKEY 3x21 Smart Card Reader / HID Global OMNIKEY 6121 Smart Card Reader
if ((id_vendor == 0x076B && id_product == 0x3031)
|| (id_vendor == 0x076B && id_product == 0x6632))
return false;
if (getenv("SMARTCARDPP_NOPINPAD"))
return false;
return features.find(FEATURE_VERIFY_PIN_START) != features.cend()
Expand Down Expand Up @@ -168,10 +193,9 @@ class CardImpl
SCard(Control, cardHandle, ioctl, cmd.data(), DWORD(cmd.size()),
LPVOID(responseBytes.data()), DWORD(responseBytes.size()), &responseLength);

if (features.find(FEATURE_VERIFY_PIN_FINISH) != features.cend()) {
DWORD finish = features.at(FEATURE_VERIFY_PIN_FINISH);
if (auto finish = features.find(FEATURE_VERIFY_PIN_FINISH); finish != features.cend()) {
responseLength = DWORD(responseBytes.size());
SCard(Control, cardHandle, finish, nullptr, 0U, LPVOID(responseBytes.data()),
SCard(Control, cardHandle, finish->second, nullptr, 0U, LPVOID(responseBytes.data()),
DWORD(responseBytes.size()), &responseLength);
}

Expand All @@ -188,6 +212,8 @@ class CardImpl
SCARDHANDLE cardHandle;
const SCARD_IO_REQUEST _protocol;
std::map<DRIVER_FEATURES, uint32_t> features;
uint32_t id_vendor {};
uint32_t id_product {};

ResponseApdu toResponse(byte_vector& responseBytes, size_t responseLength) const
{
Expand Down
2 changes: 1 addition & 1 deletion src/electronic-ids/pcsc/pcsc-common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ inline pcsc_cpp::byte_vector computeSignature(pcsc_cpp::SmartCard& card,
inline pcsc_cpp::byte_type selectSecurityEnv(pcsc_cpp::SmartCard& card, pcsc_cpp::byte_type env,
pcsc_cpp::byte_type signatureAlgo,
pcsc_cpp::byte_type keyReference,
const std::string& cardType)
const std::string& cardType)
{
const auto response = card.transmit(
{0x00, 0x22, 0x41, env, {0x80, 0x01, signatureAlgo, 0x84, 0x01, keyReference}});
Expand Down

0 comments on commit 18581df

Please sign in to comment.