2222
2323#include " FinEID.hpp"
2424
25+ #include " ../TLV.hpp"
26+
2527#include " pcsc-common.hpp"
2628
29+ #include < array>
30+
2731// FINEID specification:
2832// App 3.0:
2933// https://dvv.fi/documents/16079645/17324923/S1v30.pdf/0bad6ff1-1617-1b1f-ab49-56a2f36ecd38/S1v30.pdf
@@ -44,15 +48,19 @@ namespace
4448const auto SELECT_MAIN_AID = CommandApdu::select(
4549 0x04 , {0xa0 , 0x00 , 0x00 , 0x00 , 0x63 , 0x50 , 0x4b , 0x43 , 0x53 , 0x2d , 0x31 , 0x35 });
4650const auto SELECT_AUTH_CERT_FILE = CommandApdu::selectEF(0x08 , {0x43 , 0x31 });
51+ const auto SELECT_AUTH_CERT_FILE_EST = CommandApdu::selectEF(0x08 , {0xAD , 0xF1 , 0x34 , 0x11 });
4752const auto SELECT_SIGN_CERT_FILE_V3 = CommandApdu::selectEF(0x08 , {0x50 , 0x16 , 0x43 , 0x35 });
4853const auto SELECT_SIGN_CERT_FILE_V4 = CommandApdu::selectEF(0x08 , {0x50 , 0x16 , 0x43 , 0x32 });
54+ const auto SELECT_SIGN_CERT_FILE_EST = CommandApdu::selectEF(0x08 , {0xAD , 0xF2 , 0x34 , 0x21 });
4955
5056constexpr byte_type PIN_PADDING_CHAR = 0x00 ;
5157constexpr byte_type AUTH_PIN_REFERENCE = 0x11 ;
58+ constexpr byte_type AUTH_PIN_REFERENCE_EST = 0x81 ;
5259constexpr byte_type SIGNING_PIN_REFERENCE = 0x82 ;
5360constexpr byte_type AUTH_KEY_REFERENCE = 0x01 ;
5461constexpr byte_type SIGNING_KEY_REFERENCE_V3 = 0x03 ;
5562constexpr byte_type SIGNING_KEY_REFERENCE_V4 = 0x02 ;
63+ constexpr byte_type SIGNING_KEY_REFERENCE_EST = 0x05 ;
5664constexpr byte_type ECDSA_ALGO = 0x04 ;
5765constexpr byte_type RSA_PSS_ALGO = 0x05 ;
5866
@@ -71,7 +79,7 @@ byte_vector FinEIDv3::getCertificateImpl(const CertificateType type) const
7179byte_vector FinEIDv3::signWithAuthKeyImpl (byte_vector&& pin, const byte_vector& hash) const
7280{
7381 return sign (authSignatureAlgorithm ().hashAlgorithm (), hash, std::move (pin), AUTH_PIN_REFERENCE,
74- authPinMinMaxLength (), AUTH_KEY_REFERENCE, RSA_PSS_ALGO, 0x00 );
82+ authPinMinMaxLength (), AUTH_KEY_REFERENCE, RSA_PSS_ALGO);
7583}
7684
7785ElectronicID::PinRetriesRemainingAndMax FinEIDv3::authPinRetriesLeftImpl () const
@@ -88,7 +96,7 @@ ElectronicID::Signature FinEIDv3::signWithSigningKeyImpl(byte_vector&& pin, cons
8896 const HashAlgorithm hashAlgo) const
8997{
9098 return {sign (hashAlgo, hash, std::move (pin), SIGNING_PIN_REFERENCE, signingPinMinMaxLength (),
91- SIGNING_KEY_REFERENCE_V3, ECDSA_ALGO, 0x40 ),
99+ SIGNING_KEY_REFERENCE_V3, ECDSA_ALGO),
92100 {SignatureAlgorithm::ES, hashAlgo}};
93101}
94102
@@ -99,7 +107,7 @@ ElectronicID::PinRetriesRemainingAndMax FinEIDv3::signingPinRetriesLeftImpl() co
99107
100108byte_vector FinEIDv3::sign (const HashAlgorithm hashAlgo, const byte_vector& hash, byte_vector&& pin,
101109 byte_type pinReference, PinMinMaxLength pinMinMaxLength,
102- byte_type keyReference, byte_type signatureAlgo, byte_type LE ) const
110+ byte_type keyReference, byte_type signatureAlgo) const
103111{
104112 if (signatureAlgo != ECDSA_ALGO && hashAlgo.isSHA3 ()) {
105113 THROW (ArgumentFatalError, " No OID for algorithm " + std::string (hashAlgo));
@@ -127,8 +135,7 @@ byte_vector FinEIDv3::sign(const HashAlgorithm hashAlgo, const byte_vector& hash
127135 THROW (ArgumentFatalError, " No OID for algorithm " + std::string (hashAlgo));
128136 }
129137
130- verifyPin (*card, pinReference, std::move (pin), pinMinMaxLength.first , pinMinMaxLength.second ,
131- PIN_PADDING_CHAR);
138+ verifyPin (*card, pinReference, std::move (pin), pinMinMaxLength, PIN_PADDING_CHAR);
132139 // Select security environment for COMPUTE SIGNATURE.
133140 selectSecurityEnv (*card, 0xB6 , signatureAlgo, keyReference, name ());
134141
@@ -146,8 +153,8 @@ byte_vector FinEIDv3::sign(const HashAlgorithm hashAlgo, const byte_vector& hash
146153 THROW (SmartCardError, " Command COMPUTE SIGNATURE failed with error " + response);
147154 }
148155
149- const CommandApdu getSignature {0x00 , 0x2A , 0x9E , 0x9A , LE };
150- const auto signature = card->transmit (getSignature);
156+ const CommandApdu getSignature {0x00 , 0x2A , 0x9E , 0x9A , 0x00 };
157+ auto signature = card->transmit (getSignature);
151158
152159 if (signature.sw1 == ResponseApdu::WRONG_LENGTH) {
153160 THROW (SmartCardError, " Wrong data length in command GET SIGNATURE argument: " + response);
@@ -156,7 +163,7 @@ byte_vector FinEIDv3::sign(const HashAlgorithm hashAlgo, const byte_vector& hash
156163 THROW (SmartCardError, " Command GET SIGNATURE failed with error " + signature);
157164 }
158165
159- return signature.data ;
166+ return std::move ( signature.data ) ;
160167}
161168
162169ElectronicID::PinRetriesRemainingAndMax FinEIDv3::pinRetriesLeft (byte_type pinReference) const
@@ -168,12 +175,13 @@ ElectronicID::PinRetriesRemainingAndMax FinEIDv3::pinRetriesLeft(byte_type pinRe
168175 if (!response.isOK ()) {
169176 THROW (SmartCardError, " Command GET DATA failed with error " + response);
170177 }
171- if (response.data . size () < 21 ) {
172- THROW (SmartCardError,
173- " Command GET DATA failed: received data size " + std::to_string (response. data . size ())
174- + " is less than the expected size of the PIN remaining retries offset 21 " );
178+ if (TLV tlv ( response.data ); tlv. tag == 0xA0 ) {
179+ if (TLV info = tlv[ 0xdf21 ]) {
180+ return {*info. begin , maximumPinRetries ()};
181+ }
175182 }
176- return {uint8_t (response.data [20 ]), int8_t (5 )};
183+ THROW (SmartCardError,
184+ " Command GET DATA failed: received data does not contain the PIN remaining retries info" );
177185}
178186
179187byte_vector FinEIDv4::getCertificateImpl (const CertificateType type) const
@@ -186,14 +194,41 @@ byte_vector FinEIDv4::getCertificateImpl(const CertificateType type) const
186194byte_vector FinEIDv4::signWithAuthKeyImpl (byte_vector&& pin, const byte_vector& hash) const
187195{
188196 return sign (authSignatureAlgorithm ().hashAlgorithm (), hash, std::move (pin), AUTH_PIN_REFERENCE,
189- authPinMinMaxLength (), AUTH_KEY_REFERENCE, ECDSA_ALGO, 0x60 );
197+ authPinMinMaxLength (), AUTH_KEY_REFERENCE, ECDSA_ALGO);
190198}
191199
192200ElectronicID::Signature FinEIDv4::signWithSigningKeyImpl (byte_vector&& pin, const byte_vector& hash,
193201 const HashAlgorithm hashAlgo) const
194202{
195203 return {sign (hashAlgo, hash, std::move (pin), SIGNING_PIN_REFERENCE, signingPinMinMaxLength (),
196- SIGNING_KEY_REFERENCE_V4, ECDSA_ALGO, 0x60 ),
204+ SIGNING_KEY_REFERENCE_V4, ECDSA_ALGO),
205+ {SignatureAlgorithm::ES, hashAlgo}};
206+ }
207+
208+ byte_vector EstEIDTHALES::getCertificateImpl (const CertificateType type) const
209+ {
210+ transmitApduWithExpectedResponse (*card, SELECT_MAIN_AID);
211+ return readFile (
212+ *card, type.isAuthentication () ? SELECT_AUTH_CERT_FILE_EST : SELECT_SIGN_CERT_FILE_EST);
213+ }
214+
215+ byte_vector EstEIDTHALES::signWithAuthKeyImpl (byte_vector&& pin, const byte_vector& hash) const
216+ {
217+ return sign (authSignatureAlgorithm ().hashAlgorithm (), hash, std::move (pin),
218+ AUTH_PIN_REFERENCE_EST, authPinMinMaxLength (), AUTH_KEY_REFERENCE, ECDSA_ALGO);
219+ }
220+
221+ ElectronicID::PinRetriesRemainingAndMax EstEIDTHALES::authPinRetriesLeftImpl () const
222+ {
223+ return pinRetriesLeft (AUTH_PIN_REFERENCE_EST);
224+ }
225+
226+ ElectronicID::Signature EstEIDTHALES::signWithSigningKeyImpl (byte_vector&& pin,
227+ const byte_vector& hash,
228+ const HashAlgorithm hashAlgo) const
229+ {
230+ return {sign (hashAlgo, hash, std::move (pin), SIGNING_PIN_REFERENCE, signingPinMinMaxLength (),
231+ SIGNING_KEY_REFERENCE_EST, ECDSA_ALGO),
197232 {SignatureAlgorithm::ES, hashAlgo}};
198233}
199234
0 commit comments