mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-01-09 17:56:53 +08:00
Fixing some ISO7816-4 logic.
- Fixing overflow in BigBuffer if requesting to much data - Fixing integer wrapping with the SIM module by capping APDU data length - Fixing chaining logic which was loosing previously received data
This commit is contained in:
parent
b557291a00
commit
b70320d47d
2 changed files with 25 additions and 5 deletions
|
@ -317,6 +317,7 @@ static int smart_wait(uint8_t *out, int maxoutlen, bool verbose) {
|
|||
static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) {
|
||||
|
||||
int datalen = smart_wait(out, maxoutlen, verbose);
|
||||
int totallen = datalen;
|
||||
bool needGetData = false;
|
||||
|
||||
if (datalen < 2) {
|
||||
|
@ -327,8 +328,21 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) {
|
|||
needGetData = true;
|
||||
}
|
||||
|
||||
if (needGetData) {
|
||||
if (needGetData == true) {
|
||||
// Don't discard data we already received except the SW code
|
||||
totallen -= 2;
|
||||
int ofs = totallen;
|
||||
maxoutlen -= totallen;
|
||||
|
||||
int len = out[datalen - 1];
|
||||
if (len == 0 || len > MAX_APDU_SIZE) {
|
||||
// Cap the data length or the smartcard may send us a buffer we can't handle
|
||||
len = MAX_APDU_SIZE;
|
||||
}
|
||||
if (maxoutlen < len) {
|
||||
// We don't have enough buffer to hold the next part
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (verbose) PrintAndLogEx(INFO, "Requesting " _YELLOW_("0x%02X") " bytes response", len);
|
||||
|
||||
|
@ -342,7 +356,7 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) {
|
|||
SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + sizeof(cmd_getresp));
|
||||
free(payload);
|
||||
|
||||
datalen = smart_wait(out, maxoutlen, verbose);
|
||||
datalen = smart_wait(&out[ofs], maxoutlen, verbose);
|
||||
|
||||
if (datalen < 2) {
|
||||
goto out;
|
||||
|
@ -352,7 +366,7 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) {
|
|||
if (datalen != len + 2) {
|
||||
// data with ACK
|
||||
if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK
|
||||
if (out[0] != ISO7816_GET_RESPONSE) {
|
||||
if (out[ofs] != ISO7816_GET_RESPONSE) {
|
||||
if (verbose) {
|
||||
PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, out[0]);
|
||||
}
|
||||
|
@ -361,7 +375,8 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) {
|
|||
}
|
||||
|
||||
datalen--;
|
||||
memmove(out, &out[1], datalen);
|
||||
memmove(&out[ofs], &out[ofs + 1], datalen);
|
||||
totallen += datalen;
|
||||
} else {
|
||||
// wrong length
|
||||
if (verbose) {
|
||||
|
@ -372,7 +387,7 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) {
|
|||
}
|
||||
|
||||
out:
|
||||
return datalen;
|
||||
return totallen;
|
||||
}
|
||||
|
||||
static int smart_response(uint8_t *out, int maxoutlen) {
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
#include "common.h"
|
||||
#include "pm3_cmd.h" // structs
|
||||
|
||||
// On ARM side, ISO7816_MAX_FRAME is set to 255
|
||||
// This means we can't receive more than 250 bytes of data to leave enough room for
|
||||
// SW status code and surrounding metadata without creating a buffer overflow.
|
||||
#define MAX_APDU_SIZE 250
|
||||
|
||||
int CmdSmartcard(const char *Cmd);
|
||||
|
||||
bool smart_select(bool verbose, smart_card_atr_t *atr);
|
||||
|
|
Loading…
Reference in a new issue