-
Notifications
You must be signed in to change notification settings - Fork 27
Thales card support #125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Thales card support #125
Conversation
a47ad42 to
77fdd42
Compare
af2527a to
9d0c75f
Compare
1ddfbbb to
e517837
Compare
c0a5df5 to
1b0e367
Compare
9fff0ce to
38f9454
Compare
lib/libpcsc-cpp/src/SmartCard.cpp
Outdated
|
|
||
| void getResponseWithLE(ResponseApdu& response, byte_vector command) const | ||
| { | ||
| size_t pos = command.size() <= 5 ? 4 : 5 + command[4]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's follow defensive programming principles and protect against out of bounds writes.
Consider the following two cases:
Short command:
std::vector<uint8_t> cmd = {0x00,0x84,0x00,0x00}; // size()==4
size_t pos = cmd.size() <= 5 ? 4 : 5+cmd[4]; // pos==4
cmd[pos] = 0x08; // write past endInvalid Lc:
std::vector<uint8_t> cmd = {0x00,0xD0,0x00,0x00,0x10, // Lc = 16
0xAA,0xBB,0xCC,0xDD,0xEE}; // only 5 data bytes, size()==10
size_t pos = 5 + cmd[4]; // 5 + 0x10 = 21
cmd[pos] = 0x08; // write past endWe should throw cleanly and not write past end in these cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@metsma correctly pointed out that the command byte vector is always converted from a CommandApdu that internally guarantees that Lc is valid.
So the issue is actually more about type safety - getResponseWithLE() and transitively transmitBytes() should use a CommandApdu parameter, not a raw byte vector, something like this:
void getResponseWithLE(ResponseApdu& response, const CommandApdu& command) const
{
...
}
ResponseApdu transmitBytes(const CommandApdu& command) const
{
byte_vector commandBytes = command;
byte_vector responseBytes(ResponseApdu::MAX_SIZE, 0);
auto responseLength = DWORD(responseBytes.size());
SCard(Transmit, cardHandle, &_protocol, commandBytes.data(), DWORD(commandBytes.size()),
nullptr, responseBytes.data(), &responseLength);
auto response = toResponse(std::move(responseBytes), responseLength);
if (response.sw1 == ResponseApdu::WRONG_LE_LENGTH) {
getResponseWithLE(response, command);
}
...
}79ceae6 to
e7050c0
Compare
f02342c to
a40cdf0
Compare
87e9b98 to
2849ce1
Compare
IB-8171 Signed-off-by: Raul Metsma <[email protected]>
|
|
||
| #include <algorithm> | ||
|
|
||
| using namespace std::string_literals; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be top level as it leaks everywhere the header is used, let's move it into readBinary() scope where it used.
IB-8171
Signed-off-by: Raul Metsma [email protected]