Skip to content

Commit 2f00ff3

Browse files
committed
Return PIN locked info
WE2-1114 Signed-off-by: Raul Metsma <[email protected]>
1 parent dfb29b8 commit 2f00ff3

File tree

15 files changed

+99
-92
lines changed

15 files changed

+99
-92
lines changed

.github/vcpkg.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "web-eid-app",
3+
"dependencies": ["openssl", "gtest"],
4+
"builtin-baseline": "bc38a15b0bee8bc48a49ea267cc32fbb49aedfc4"
5+
}

.github/workflows/cmake-windows.yml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ on: [push, pull_request]
55
env:
66
BUILD_TYPE: RelWithDebInfo
77
CMAKE_BUILD_PARALLEL_LEVEL: 3
8+
VCPKG_MANIFEST_DIR: .github
9+
VCPKG_INSTALLED_DIR: ${{ github.workspace }}/build/vcpkg_installed
810

911
jobs:
1012
build:
@@ -14,15 +16,25 @@ jobs:
1416
- name: Checkout code
1517
uses: actions/checkout@v4
1618

19+
- name: Cache vcpkg
20+
uses: actions/cache@v4
21+
with:
22+
path: ${{ github.workspace }}/vcpkg_cache
23+
key: vcpkg-${{ hashFiles(format('{0}/vcpkg.json', env.VCPKG_MANIFEST_DIR)) }}
24+
1725
- name: Prepare vcpkg and libraries
18-
uses: lukka/run-vcpkg@v7
26+
uses: lukka/run-vcpkg@v11
1927
with:
20-
vcpkgArguments: gtest:x64-windows openssl:x64-windows
21-
vcpkgTriplet: x64-windows
22-
vcpkgGitCommitId: 031ad89ce6c575df35a8e58707ad2c898446c63e
28+
vcpkgJsonGlob: ${{ env.VCPKG_MANIFEST_DIR }}/vcpkg.json
29+
runVcpkgInstall: true
30+
env:
31+
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg_cache,readwrite
2332

2433
- name: Configure CMake
25-
run: cmake -A x64 "-DCMAKE_TOOLCHAIN_FILE=${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" "-DCMAKE_BUILD_TYPE=${env:BUILD_TYPE}" -S . -B build
34+
run: |
35+
cmake -A x64 -S . -B build "-DCMAKE_BUILD_TYPE=${env:BUILD_TYPE}" `
36+
"-DCMAKE_TOOLCHAIN_FILE=${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" `
37+
"-DVCPKG_MANIFEST_DIR=${{ env.VCPKG_MANIFEST_DIR }}"
2638
2739
- name: Build
2840
run: cmake --build build --config ${env:BUILD_TYPE}

include/electronic-id/electronic-id.hpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424

2525
#include "enums.hpp"
2626

27-
#include <optional>
2827
#include <functional>
28+
#include <optional>
2929

3030
namespace electronic_id
3131
{
@@ -37,11 +37,17 @@ class ElectronicID
3737
public:
3838
using ptr = std::shared_ptr<ElectronicID>;
3939
using PinMinMaxLength = std::pair<uint8_t, uint8_t>;
40-
using PinRetriesRemainingAndMax = std::pair<uint8_t, int8_t>;
4140
using byte_vector = pcsc_cpp::byte_vector;
4241
using byte_type = pcsc_cpp::byte_type;
4342
using Signature = std::pair<byte_vector, SignatureAlgorithm>;
4443

44+
struct PinInfo
45+
{
46+
uint8_t retryCount;
47+
int8_t maxRetry;
48+
bool pinActive;
49+
};
50+
4551
enum Type : uint8_t {
4652
EstEID,
4753
FinEID,
@@ -68,7 +74,7 @@ class ElectronicID
6874

6975
virtual PinMinMaxLength authPinMinMaxLength() const = 0;
7076

71-
virtual PinRetriesRemainingAndMax authPinRetriesLeft() const = 0;
77+
virtual PinInfo authPinInfo() const = 0;
7278

7379
virtual pcsc_cpp::byte_vector signWithAuthKey(byte_vector&& pin,
7480
const byte_vector& hash) const = 0;
@@ -80,7 +86,7 @@ class ElectronicID
8086

8187
virtual PinMinMaxLength signingPinMinMaxLength() const = 0;
8288

83-
virtual PinRetriesRemainingAndMax signingPinRetriesLeft() const = 0;
89+
virtual PinInfo signingPinInfo() const = 0;
8490

8591
virtual Signature signWithSigningKey(byte_vector&& pin, const byte_vector& hash,
8692
const HashAlgorithm hashAlgo) const = 0;

src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ class MsCryptoApiElectronicID : public ElectronicID
7878
return {PIN_LENGTH_PLACEHOLDER, PIN_LENGTH_PLACEHOLDER};
7979
}
8080

81-
PinRetriesRemainingAndMax authPinRetriesLeft() const override
81+
PinInfo authPinInfo() const override
8282
{
83-
return {uint8_t(PIN_RETRY_COUNT_PLACEHOLDER), PIN_RETRY_COUNT_PLACEHOLDER};
83+
return {uint8_t(PIN_RETRY_COUNT_PLACEHOLDER), PIN_RETRY_COUNT_PLACEHOLDER, true};
8484
}
8585

8686
byte_vector signWithAuthKey(byte_vector&& pin, const byte_vector& hash) const override;
@@ -92,9 +92,9 @@ class MsCryptoApiElectronicID : public ElectronicID
9292
return {PIN_LENGTH_PLACEHOLDER, PIN_LENGTH_PLACEHOLDER};
9393
}
9494

95-
PinRetriesRemainingAndMax signingPinRetriesLeft() const override
95+
PinInfo signingPinInfo() const override
9696
{
97-
return {uint8_t(PIN_RETRY_COUNT_PLACEHOLDER), PIN_RETRY_COUNT_PLACEHOLDER};
97+
return {uint8_t(PIN_RETRY_COUNT_PLACEHOLDER), PIN_RETRY_COUNT_PLACEHOLDER, true};
9898
}
9999

100100
Signature signWithSigningKey(byte_vector&& pin, const byte_vector& hash,

src/electronic-ids/pcsc/EIDIDEMIA.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ byte_vector EIDIDEMIA::signWithAuthKeyImpl(const SmartCard::Session& session, by
107107
return std::move(response.data);
108108
}
109109

110-
ElectronicID::PinRetriesRemainingAndMax
111-
EIDIDEMIA::authPinRetriesLeftImpl(const SmartCard::Session& session) const
110+
ElectronicID::PinInfo EIDIDEMIA::authPinInfoImpl(const SmartCard::Session& session) const
112111
{
113112
selectMain(session);
114113
return pinRetriesLeft(session, AUTH_PIN_REFERENCE);
@@ -154,15 +153,14 @@ ElectronicID::Signature EIDIDEMIA::signWithSigningKeyImpl(const SmartCard::Sessi
154153
{isECC ? SignatureAlgorithm::ES : SignatureAlgorithm::RS, hashAlgo}};
155154
}
156155

157-
ElectronicID::PinRetriesRemainingAndMax
158-
EIDIDEMIA::signingPinRetriesLeftImpl(const SmartCard::Session& session) const
156+
ElectronicID::PinInfo EIDIDEMIA::signingPinInfoImpl(const SmartCard::Session& session) const
159157
{
160158
selectADF2(session);
161159
return pinRetriesLeft(session, SIGN_PIN_REFERENCE);
162160
}
163161

164-
ElectronicID::PinRetriesRemainingAndMax EIDIDEMIA::pinRetriesLeft(const SmartCard::Session& session,
165-
byte_type pinReference)
162+
ElectronicID::PinInfo EIDIDEMIA::pinRetriesLeft(const SmartCard::Session& session,
163+
byte_type pinReference)
166164
{
167165
auto ref = byte_type(pinReference & 0x0F);
168166
const CommandApdu GET_DATA_ODD {
@@ -175,7 +173,7 @@ ElectronicID::PinRetriesRemainingAndMax EIDIDEMIA::pinRetriesLeft(const SmartCar
175173
TLV max = info[0x9A];
176174
TLV tries = info[0x9B];
177175
if (max && tries) {
178-
return {*tries.begin, *max.begin};
176+
return {*tries.begin, int8_t(*max.begin), true};
179177
}
180178
THROW(SmartCardError, "Command GET DATA ODD failed: missing expected info");
181179
}

src/electronic-ids/pcsc/EIDIDEMIA.hpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,18 @@ class EIDIDEMIA : public PcscElectronicID
4242
byte_vector getCertificateImpl(const SmartCard::Session& session,
4343
const CertificateType type) const override;
4444

45-
PinRetriesRemainingAndMax
46-
authPinRetriesLeftImpl(const SmartCard::Session& session) const override;
45+
PinInfo authPinInfoImpl(const SmartCard::Session& session) const override;
4746
virtual KeyInfo authKeyRef(const SmartCard::Session& session) const;
4847
byte_vector signWithAuthKeyImpl(const SmartCard::Session& session, byte_vector&& pin,
4948
const byte_vector& hash) const override;
5049

51-
PinRetriesRemainingAndMax
52-
signingPinRetriesLeftImpl(const SmartCard::Session& session) const override;
50+
PinInfo signingPinInfoImpl(const SmartCard::Session& session) const override;
5351
virtual KeyInfo signKeyRef(const SmartCard::Session& session) const;
5452
Signature signWithSigningKeyImpl(const SmartCard::Session& session, byte_vector&& pin,
5553
const byte_vector& hash,
5654
const HashAlgorithm hashAlgo) const override;
5755

58-
static PinRetriesRemainingAndMax pinRetriesLeft(const SmartCard::Session& session,
59-
byte_type pinReference);
56+
static PinInfo pinRetriesLeft(const SmartCard::Session& session, byte_type pinReference);
6057

6158
static void selectMain(const SmartCard::Session& session);
6259
static void selectADF1(const SmartCard::Session& session);

src/electronic-ids/pcsc/EIDThales.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,9 @@ const auto SELECT_MAIN_AID = CommandApdu::select(
5555

5656
} // namespace
5757

58-
ElectronicID::PinRetriesRemainingAndMax
59-
EIDThales::authPinRetriesLeftImpl(const SmartCard::Session& session) const
58+
ElectronicID::PinInfo EIDThales::authPinInfoImpl(const SmartCard::Session& session) const
6059
{
61-
return pinRetriesLeft(session, authPinReference());
60+
return pinRetriesLeft(session, authPinReference(), true);
6261
}
6362

6463
byte_vector EIDThales::getCertificateImpl(const SmartCard::Session& session,
@@ -68,8 +67,8 @@ byte_vector EIDThales::getCertificateImpl(const SmartCard::Session& session,
6867
return readFile(session, type.isAuthentication() ? authCertFile() : signCertFile());
6968
}
7069

71-
ElectronicID::PinRetriesRemainingAndMax EIDThales::pinRetriesLeft(const SmartCard::Session& session,
72-
byte_type pinReference) const
70+
ElectronicID::PinInfo EIDThales::pinRetriesLeft(const SmartCard::Session& session,
71+
byte_type pinReference, bool pinActive) const
7372
{
7473
const auto GET_DATA = smartcard().protocol() == SmartCard::Protocol::T1
7574
? CommandApdu {0x00, 0xCB, 0x00, 0xFF, {0xA0, 0x03, 0x83, 0x01, pinReference}, 0x00}
@@ -78,8 +77,9 @@ ElectronicID::PinRetriesRemainingAndMax EIDThales::pinRetriesLeft(const SmartCar
7877
if (!response.isOK()) {
7978
THROW(SmartCardError, "Command GET DATA failed with error " + response);
8079
}
81-
if (TLV info = TLV(response.data).find(0xA0)[0xdf21]) {
82-
return {*info.begin, maximumPinRetries()};
80+
if (TLV info = TLV(response.data).find(0xA0); TLV count = info[0xdf21]) {
81+
TLV pinChanged = info[0xdf2f];
82+
return {*count.begin, maximumPinRetries(), pinActive || *pinChanged.begin};
8383
}
8484
THROW(SmartCardError,
8585
"Command GET DATA failed: received data does not contain the PIN remaining retries info");
@@ -147,10 +147,9 @@ byte_vector EIDThales::sign(const SmartCard::Session& session, const HashAlgorit
147147
return std::move(signature.data);
148148
}
149149

150-
ElectronicID::PinRetriesRemainingAndMax
151-
EIDThales::signingPinRetriesLeftImpl(const SmartCard::Session& session) const
150+
ElectronicID::PinInfo EIDThales::signingPinInfoImpl(const SmartCard::Session& session) const
152151
{
153-
return pinRetriesLeft(session, SIGNING_PIN_REFERENCE);
152+
return pinRetriesLeft(session, SIGNING_PIN_REFERENCE, false);
154153
}
155154

156155
byte_vector EIDThales::signWithAuthKeyImpl(const SmartCard::Session& session, byte_vector&& pin,

src/electronic-ids/pcsc/EIDThales.hpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,23 @@ class EIDThales : public PcscElectronicID
4242
virtual constexpr byte_type signingKeyReference() const = 0;
4343

4444
byte_vector getCertificateImpl(const SmartCard::Session& session,
45-
const CertificateType type) const override;
46-
PinRetriesRemainingAndMax
47-
authPinRetriesLeftImpl(const SmartCard::Session& session) const override;
48-
PinRetriesRemainingAndMax
49-
signingPinRetriesLeftImpl(const SmartCard::Session& session) const override;
45+
CertificateType type) const override;
46+
PinInfo authPinInfoImpl(const SmartCard::Session& session) const override;
47+
PinInfo signingPinInfoImpl(const SmartCard::Session& session) const override;
5048
byte_vector signWithAuthKeyImpl(const SmartCard::Session& session, byte_vector&& pin,
5149
const byte_vector& hash) const override;
5250
Signature signWithSigningKeyImpl(const SmartCard::Session& session, byte_vector&& pin,
5351
const byte_vector& hash,
54-
const HashAlgorithm hashAlgo) const override;
52+
HashAlgorithm hashAlgo) const override;
5553

56-
PinRetriesRemainingAndMax pinRetriesLeft(const SmartCard::Session& session,
57-
byte_type pinReference) const;
58-
byte_vector sign(const SmartCard::Session& session, const HashAlgorithm hashAlgo,
54+
PinInfo pinRetriesLeft(const SmartCard::Session& session, byte_type pinReference,
55+
bool pinActive) const;
56+
byte_vector sign(const SmartCard::Session& session, HashAlgorithm hashAlgo,
5957
const byte_vector& hash, byte_vector&& pin, byte_type pinReference,
6058
PinMinMaxLength pinMinMaxLength, byte_type keyReference,
6159
byte_type signatureAlgo) const;
6260

6361
static constexpr byte_type AUTH_KEY_REFERENCE = 0x01;
6462
};
6563

66-
} // namespace electronic_id
64+
} // namespace electronic_id

src/electronic-ids/pcsc/PcscElectronicID.hpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,9 @@ class PcscElectronicID : public ElectronicID
6565
return signWithSigningKeyImpl(card.beginSession(), std::move(pin), hash, hashAlgo);
6666
}
6767

68-
PinRetriesRemainingAndMax signingPinRetriesLeft() const override
69-
{
70-
return signingPinRetriesLeftImpl(card.beginSession());
71-
}
68+
PinInfo signingPinInfo() const override { return signingPinInfoImpl(card.beginSession()); }
7269

73-
ElectronicID::PinRetriesRemainingAndMax authPinRetriesLeft() const override
74-
{
75-
return authPinRetriesLeftImpl(card.beginSession());
76-
}
70+
PinInfo authPinInfo() const override { return authPinInfoImpl(card.beginSession()); }
7771

7872
// The following pure virtual *Impl functions are the interface of all
7973
// PC/SC electronic ID implementations,
@@ -86,15 +80,13 @@ class PcscElectronicID : public ElectronicID
8680
virtual byte_vector signWithAuthKeyImpl(const SmartCard::Session& session, byte_vector&& pin,
8781
const byte_vector& hash) const = 0;
8882

89-
virtual PinRetriesRemainingAndMax
90-
authPinRetriesLeftImpl(const SmartCard::Session& session) const = 0;
83+
virtual PinInfo authPinInfoImpl(const SmartCard::Session& session) const = 0;
9184

9285
virtual Signature signWithSigningKeyImpl(const SmartCard::Session& session, byte_vector&& pin,
9386
const byte_vector& hash,
9487
const HashAlgorithm hashAlgo) const = 0;
9588

96-
virtual PinRetriesRemainingAndMax
97-
signingPinRetriesLeftImpl(const SmartCard::Session& session) const = 0;
89+
virtual PinInfo signingPinInfoImpl(const SmartCard::Session& session) const = 0;
9890
};
9991

10092
} // namespace electronic_id

src/electronic-ids/pkcs11/PKCS11CardManager.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class PKCS11CardManager
135135
std::string serialNumber;
136136
CK_SLOT_ID slotID;
137137
std::vector<CK_BYTE> cert, certID;
138-
int8_t retry;
138+
uint8_t retry;
139139
bool pinpad;
140140
uint8_t minPinLen, maxPinLen;
141141
};
@@ -362,7 +362,7 @@ class PKCS11CardManager
362362
return objectHandle;
363363
}
364364

365-
static constexpr int8_t pinRetryCount(CK_FLAGS flags) noexcept
365+
static constexpr uint8_t pinRetryCount(CK_FLAGS flags) noexcept
366366
{
367367
// As PKCS#11 does not provide an API for querying remaining PIN retries, we currently
368368
// simply assume max retry count of 3, which is quite common. We might need to revisit this

0 commit comments

Comments
 (0)