Use Iso7816ExchangeEx in eMRTD

This commit is contained in:
Philippe Teuwen
2021-06-04 21:58:38 +02:00
parent 56daa155b5
commit 61d5a87c4f
6 changed files with 193 additions and 207 deletions
+1 -1
View File
@@ -1680,7 +1680,7 @@ static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen,
*dataoutlen += dlen;
if (maxdataoutlen && *dataoutlen > maxdataoutlen) {
PrintAndLogEx(ERR, "APDU: buffer too small(%d), needs %d bytes", *dataoutlen, maxdataoutlen);
PrintAndLogEx(ERR, "APDU: buffer too small(%d), needs %d bytes", maxdataoutlen, *dataoutlen);
return PM3_ESOFT;
}
+131 -199
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -16,7 +16,7 @@
typedef struct emrtd_dg_s {
uint8_t tag;
uint8_t dgnum;
const char *fileid;
uint16_t fileid;
const char *filename;
const char *desc;
bool pace;
+1 -1
View File
@@ -266,7 +266,7 @@ struct tlvdb *GetdCVVRawFromTrack2(const struct tlv *track2) {
}
static int EMVExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, sAPDU apdu, bool IncludeLe, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
int res = Iso7816ExchangeEx(channel, ActivateField, LeaveFieldON, apdu, IncludeLe, Result, MaxResultLen, ResultLen, sw);
int res = Iso7816ExchangeEx(channel, ActivateField, LeaveFieldON, apdu, IncludeLe, 0, Result, MaxResultLen, ResultLen, sw);
// add to tlv tree
if ((res == PM3_SUCCESS) && tlv) {
struct tlvdb *t = tlvdb_parse_multi(Result, *ResultLen);
+55 -4
View File
@@ -19,6 +19,7 @@
#include "ui.h"
#include "cmdhf14a.h"
#include "cmdhf14b.h"
#include "iso14b.h" // iso14b_raw_cmd_t
#include "util_posix.h"
//iceman: this logging setting, should be unified with client debug etc.
@@ -35,13 +36,56 @@ static isodep_state_t isodep_state = ISODEP_INACTIVE;
void SetISODEPState(isodep_state_t state) {
isodep_state = state;
if (APDULogging) {
PrintAndLogEx(SUCCESS, ">>>> ISODEP -> %s%s%s", isodep_state == ISODEP_INACTIVE ? "inactive" : "", isodep_state == ISODEP_NFCA ? "NFC-A" : "", isodep_state == ISODEP_NFCB ? "NFC-B" : "");
}
}
isodep_state_t GetISODEPState(void) {
return isodep_state;
}
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, sAPDU apdu, bool IncludeLe, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
int Iso7816Connect(Iso7816CommandChannel channel) {
if (channel == CC_CONTACT) {
return PM3_ENOTIMPL;
}
// Try to 14a
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0);
PacketResponseNG resp;
bool failed_14a = false;
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
DropField();
failed_14a = true;
}
if ((!failed_14a) && resp.oldarg[0] != 0) {
SetISODEPState(ISODEP_NFCA);
return PM3_SUCCESS;
}
PrintAndLogEx(DEBUG, "No 14a tag spotted, trying 14b");
// If not 14a, try to 14b
iso14b_raw_cmd_t packet = {
.flags = (ISO14B_CONNECT | ISO14B_SELECT_STD),
.timeout = 0,
.rawlen = 0,
};
clearCommandBuffer();
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t));
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000) == false) {
PrintAndLogEx(DEBUG, "Timeout, no 14b tag spotted, exiting");
return PM3_ETIMEOUT;
}
if (resp.oldarg[0] != 0) {
PrintAndLogEx(DEBUG, "No 14b tag spotted, failed to find any tag.");
return PM3_ENODATA;
}
SetISODEPState(ISODEP_NFCB);
return PM3_SUCCESS;
}
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, sAPDU apdu, bool includeLe, uint16_t Le, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
uint8_t data[APDU_RES_LEN] = {0};
*ResultLen = 0;
@@ -56,7 +100,14 @@ int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool Le
// COMPUTE APDU
int datalen = 0;
if (APDUEncodeS(&apdu, false, IncludeLe ? 0x100 : 0x00, data, &datalen)) {
if (includeLe) {
if (Le == 0) {
Le = 0x100;
}
} else {
Le = 0;
}
if (APDUEncodeS(&apdu, false, Le, data, &datalen)) {
PrintAndLogEx(ERR, "APDU encoding error.");
return 201;
}
@@ -125,9 +176,9 @@ int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool Le
}
int Iso7816Exchange(Iso7816CommandChannel channel, bool LeaveFieldON, sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
return Iso7816ExchangeEx(channel, false, LeaveFieldON, apdu, false, Result, MaxResultLen, ResultLen, sw);
return Iso7816ExchangeEx(channel, false, LeaveFieldON, apdu, false, 0, Result, MaxResultLen, ResultLen, sw);
}
int Iso7816Select(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t *AID, size_t AIDLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
return Iso7816ExchangeEx(channel, ActivateField, LeaveFieldON, (sAPDU) {0x00, 0xa4, 0x04, 0x00, AIDLen, AID}, (channel == CC_CONTACTLESS), Result, MaxResultLen, ResultLen, sw);
return Iso7816ExchangeEx(channel, ActivateField, LeaveFieldON, (sAPDU) {0x00, 0xa4, 0x04, 0x00, AIDLen, AID}, (channel == CC_CONTACTLESS), 0, Result, MaxResultLen, ResultLen, sw);
}
+4 -1
View File
@@ -37,9 +37,12 @@ bool GetAPDULogging(void);
void SetISODEPState(isodep_state_t state);
isodep_state_t GetISODEPState(void);
// connect
int Iso7816Connect(Iso7816CommandChannel channel);
// exchange
int Iso7816Exchange(Iso7816CommandChannel channel, bool LeaveFieldON, sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, sAPDU apdu, bool IncludeLe, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, sAPDU apdu, bool IncludeLe, uint16_t Le, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
// search application
int Iso7816Select(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t *AID, size_t AIDLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);