Skip to content

Commit 18931c8

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

File tree

13 files changed

+77
-87
lines changed

13 files changed

+77
-87
lines changed

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

src/electronic-ids/pkcs11/Pkcs11ElectronicID.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,9 @@ ElectronicID::PinMinMaxLength Pkcs11ElectronicID::authPinMinMaxLength() const
255255
return {authToken.minPinLen, authToken.maxPinLen};
256256
}
257257

258-
ElectronicID::PinRetriesRemainingAndMax Pkcs11ElectronicID::authPinRetriesLeft() const
258+
ElectronicID::PinInfo Pkcs11ElectronicID::authPinInfo() const
259259
{
260-
return {authToken.retry, module.retryMax};
260+
return {authToken.retry, module.retryMax, true};
261261
}
262262

263263
pcsc_cpp::byte_vector Pkcs11ElectronicID::signWithAuthKey(byte_vector&& pin,
@@ -295,9 +295,9 @@ ElectronicID::PinMinMaxLength Pkcs11ElectronicID::signingPinMinMaxLength() const
295295
return {signingToken.minPinLen, signingToken.maxPinLen};
296296
}
297297

298-
ElectronicID::PinRetriesRemainingAndMax Pkcs11ElectronicID::signingPinRetriesLeft() const
298+
ElectronicID::PinInfo Pkcs11ElectronicID::signingPinInfo() const
299299
{
300-
return {signingToken.retry, module.retryMax};
300+
return {signingToken.retry, module.retryMax, true};
301301
}
302302

303303
ElectronicID::Signature Pkcs11ElectronicID::signWithSigningKey(byte_vector&& pin,

src/electronic-ids/pkcs11/Pkcs11ElectronicID.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ class Pkcs11ElectronicID : public ElectronicID
5858
JsonWebSignatureAlgorithm authSignatureAlgorithm() const override;
5959
PinMinMaxLength authPinMinMaxLength() const override;
6060

61-
PinRetriesRemainingAndMax authPinRetriesLeft() const override;
61+
PinInfo authPinInfo() const override;
6262
byte_vector signWithAuthKey(byte_vector&& pin, const byte_vector& hash) const override;
6363

6464
const std::set<SignatureAlgorithm>& supportedSigningAlgorithms() const override;
6565
PinMinMaxLength signingPinMinMaxLength() const override;
6666

67-
PinRetriesRemainingAndMax signingPinRetriesLeft() const override;
67+
PinInfo signingPinInfo() const override;
6868
Signature signWithSigningKey(byte_vector&& pin, const byte_vector& hash,
6969
const HashAlgorithm hashAlgo) const override;
7070

0 commit comments

Comments
 (0)