Skip to content

Commit c0a5df5

Browse files
committed
Thales card support
IB-8171 Signed-off-by: Raul Metsma <[email protected]>
1 parent 7ff9480 commit c0a5df5

File tree

14 files changed

+192
-183
lines changed

14 files changed

+192
-183
lines changed

lib/libpcsc-cpp/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ add_library(${PROJECT_NAME}
1414
src/SCardCall.hpp
1515
src/SmartCard.cpp
1616
src/listReaders.cpp
17-
src/utils.cpp
1817
)
1918

2019
target_include_directories(${PROJECT_NAME}

lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp-utils.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@
2929
namespace pcsc_cpp
3030
{
3131

32+
/** Convert bytes to hex string. */
33+
inline std::ostream& operator<<(std::ostream& os, const byte_vector& data)
34+
{
35+
os << std::setfill('0') << std::hex;
36+
for (const auto byte : data)
37+
os << std::setw(2) << short(byte);
38+
return os << std::setfill(' ') << std::dec;
39+
}
40+
41+
inline std::string operator+(std::string lhs, const byte_vector& rhs)
42+
{
43+
lhs.reserve(lhs.size() + rhs.size() * 2);
44+
std::ostringstream hexStringBuilder(std::move(lhs), std::ios::ate);
45+
hexStringBuilder << rhs;
46+
return hexStringBuilder.str();
47+
}
48+
3249
/** Convert the given integer to a hex string. */
3350
template <typename T>
3451
inline std::string int2hexstr(const T value)

lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ constexpr uint16_t toSW(byte_type sw1, byte_type sw2) noexcept
8585
}
8686

8787
/** Convert bytes to hex string. */
88-
std::ostream& operator<<(std::ostream& os, const pcsc_cpp::byte_vector& data);
89-
9088
std::string operator+(std::string lhs, const byte_vector& rhs);
9189

9290
/** Struct that wraps response APDUs. */
@@ -303,16 +301,6 @@ struct Reader
303301
*/
304302
std::vector<Reader> listReaders();
305303

306-
// Utility functions.
307-
308-
/** Transmit APDU command and verify that expected response is received. */
309-
void transmitApduWithExpectedResponse(const SmartCard::Session& session,
310-
const CommandApdu& command);
311-
312-
/** Read lenght bytes from currently selected binary file in blockLength-sized chunks. */
313-
byte_vector readBinary(const SmartCard::Session& session, const uint16_t length,
314-
byte_type blockLength = 0x00);
315-
316304
// Errors.
317305

318306
/** Base class for all pcsc-cpp errors. */

lib/libpcsc-cpp/src/SmartCard.cpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ class CardImpl
140140

141141
auto response = toResponse(std::move(responseBytes), responseLength);
142142

143+
if (response.sw1 == ResponseApdu::WRONG_LE_LENGTH) {
144+
getResponseWithLE(response, commandBytes);
145+
}
143146
if (response.sw1 == ResponseApdu::MORE_DATA_AVAILABLE) {
144147
getMoreResponseData(response);
145148
}
@@ -224,26 +227,21 @@ class CardImpl
224227

225228
// Let expected errors through for handling in upper layers or in if blocks below.
226229
switch (response.sw1) {
227-
case ResponseApdu::OK:
228-
case ResponseApdu::MORE_DATA_AVAILABLE: // See the if block after next.
229-
case ResponseApdu::VERIFICATION_FAILED:
230-
case ResponseApdu::VERIFICATION_CANCELLED:
231-
case ResponseApdu::WRONG_LENGTH:
232-
case ResponseApdu::COMMAND_NOT_ALLOWED:
233-
case ResponseApdu::WRONG_PARAMETERS:
234-
case ResponseApdu::WRONG_LE_LENGTH: // See next if block.
235-
break;
230+
using enum ResponseApdu::Status;
231+
case OK:
232+
case MORE_DATA_AVAILABLE:
233+
case WRONG_LE_LENGTH:
234+
case VERIFICATION_FAILED:
235+
case VERIFICATION_CANCELLED:
236+
case WRONG_LENGTH:
237+
case COMMAND_NOT_ALLOWED:
238+
case WRONG_PARAMETERS:
239+
return response;
236240
default:
237241
THROW(Error,
238242
"Error response: '" + response + "', protocol "
239243
+ std::to_string(_protocol.dwProtocol));
240244
}
241-
242-
if (response.sw1 == ResponseApdu::WRONG_LE_LENGTH) {
243-
THROW(Error, "Wrong LE length (SW1=0x6C) in response, please set LE");
244-
}
245-
246-
return response;
247245
}
248246

249247
void getMoreResponseData(ResponseApdu& response) const
@@ -262,6 +260,13 @@ class CardImpl
262260
response.sw1 = ResponseApdu::OK;
263261
response.sw2 = 0;
264262
}
263+
264+
void getResponseWithLE(ResponseApdu& response, byte_vector command) const
265+
{
266+
size_t pos = command.size() <= 5 ? 4 : 5 + command[4];
267+
command[pos] = response.sw2;
268+
response = transmitBytes(command);
269+
}
265270
};
266271

267272
SmartCard::Session::Session(const CardImpl& card) : card(card)

lib/libpcsc-cpp/src/utils.cpp

Lines changed: 0 additions & 102 deletions
This file was deleted.

src/electronic-id.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ const std::map<byte_vector, ElectronicIDConstructor, VectorComparator> SUPPORTED
6060
{{0x3b, 0xdc, 0x96, 0x00, 0x80, 0xb1, 0xfe, 0x45, 0x1f, 0x83, 0x00, 0x12,
6161
0x23, 0x3f, 0x54, 0x65, 0x49, 0x44, 0x32, 0x0f, 0x90, 0x00, 0xc3},
6262
constructor<EstEIDIDEMIAV1>},
63+
// EstEID Thales v1.0
64+
{{0x3b, 0xff, 0x96, 0x00, 0x00, 0x80, 0x31, 0xfe, 0x43, 0x80, 0x31, 0xb8, 0x53,
65+
0x65, 0x49, 0x44, 0x64, 0xb0, 0x85, 0x05, 0x10, 0x12, 0x23, 0x3f, 0x1d},
66+
constructor<EstEIDTHALES>},
6367
// FinEID v3.0
6468
{{0x3B, 0x7F, 0x96, 0x00, 0x00, 0x80, 0x31, 0xB8, 0x65, 0xB0,
6569
0x85, 0x03, 0x00, 0xEF, 0x12, 0x00, 0xF6, 0x82, 0x90, 0x00},

src/electronic-ids/pcsc/EIDIDEMIA.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,17 @@ const auto SIGN_CERT = CommandApdu::selectEF(0x09, {0xAD, 0xF2, 0x34, 0x1F});
5353

5454
void EIDIDEMIA::selectMain(const SmartCard::Session& session)
5555
{
56-
transmitApduWithExpectedResponse(session, MAIN_AID);
56+
selectFile(session, MAIN_AID);
5757
}
5858

5959
void EIDIDEMIA::selectADF1(const pcsc_cpp::SmartCard::Session& session)
6060
{
61-
transmitApduWithExpectedResponse(session, ADF1_AID);
61+
selectFile(session, ADF1_AID);
6262
}
6363

6464
void EIDIDEMIA::selectADF2(const pcsc_cpp::SmartCard::Session& session)
6565
{
66-
transmitApduWithExpectedResponse(session, ADF2_AID);
66+
selectFile(session, ADF2_AID);
6767
}
6868

6969
byte_vector EIDIDEMIA::getCertificateImpl(const pcsc_cpp::SmartCard::Session& session,
@@ -86,8 +86,7 @@ byte_vector EIDIDEMIA::signWithAuthKeyImpl(const pcsc_cpp::SmartCard::Session& s
8686
auto [keyId, isECC] = authKeyRef(session);
8787
selectSecurityEnv(session, 0xA4, isECC ? 0x04 : 0x02, keyId, name());
8888

89-
verifyPin(session, AUTH_PIN_REFERENCE, std::move(pin), authPinMinMaxLength().first,
90-
authPinMinMaxLength().second, PIN_PADDING_CHAR);
89+
verifyPin(session, AUTH_PIN_REFERENCE, std::move(pin), authPinMinMaxLength(), PIN_PADDING_CHAR);
9190

9291
return internalAuthenticate(session,
9392
authSignatureAlgorithm().isRSAWithPKCS1Padding()
@@ -115,8 +114,8 @@ EIDIDEMIA::signWithSigningKeyImpl(const pcsc_cpp::SmartCard::Session& session, b
115114
selectADF2(session);
116115
auto [keyRef, isECC] = signKeyRef(session);
117116
selectSecurityEnv(session, 0xB6, isECC ? 0x54 : 0x42, keyRef, name());
118-
verifyPin(session, SIGN_PIN_REFERENCE, std::move(pin), signingPinMinMaxLength().first,
119-
signingPinMinMaxLength().second, PIN_PADDING_CHAR);
117+
verifyPin(session, SIGN_PIN_REFERENCE, std::move(pin), signingPinMinMaxLength(),
118+
PIN_PADDING_CHAR);
120119
auto tmp = hash;
121120
if (isECC) {
122121
constexpr size_t ECDSA384_INPUT_LENGTH = 384 / 8;

0 commit comments

Comments
 (0)