mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
making sure apdu logging is turned off after command execution. Still some commands when failing, hasnt been adapted to it.
This commit is contained in:
parent
29712bfde6
commit
82294d71f6
1 changed files with 129 additions and 67 deletions
|
@ -544,8 +544,7 @@ static int emv_parse_card_details(uint8_t *response, size_t reslen, bool verbose
|
|||
|
||||
// Track 3 Data
|
||||
// to be impl.
|
||||
|
||||
|
||||
|
||||
// Unpredicable Number (UN)
|
||||
struct tlvdb *un1_full = tlvdb_find_full(root, 0x9f37);
|
||||
if (un1_full != NULL) {
|
||||
|
@ -601,7 +600,7 @@ static int CmdEMVSelect(const char *Cmd) {
|
|||
|
||||
bool activateField = arg_get_lit(ctx, 1);
|
||||
bool leaveSignalON = arg_get_lit(ctx, 2);
|
||||
bool APDULogging = arg_get_lit(ctx, 3);
|
||||
bool show_apdu = arg_get_lit(ctx, 3);
|
||||
bool decodeTLV = arg_get_lit(ctx, 4);
|
||||
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
||||
if (arg_get_lit(ctx, 5))
|
||||
|
@ -610,7 +609,7 @@ static int CmdEMVSelect(const char *Cmd) {
|
|||
CLIGetHexWithReturn(ctx, 6, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
// exec
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
|
@ -627,6 +626,7 @@ static int CmdEMVSelect(const char *Cmd) {
|
|||
if (decodeTLV)
|
||||
TLVPrintFromBuffer(buf, len);
|
||||
|
||||
SetAPDULogging(false);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -651,7 +651,7 @@ static int CmdEMVSearch(const char *Cmd) {
|
|||
|
||||
bool activateField = arg_get_lit(ctx, 1);
|
||||
bool leaveSignalON = arg_get_lit(ctx, 2);
|
||||
bool APDULogging = arg_get_lit(ctx, 3);
|
||||
bool show_apdu = arg_get_lit(ctx, 3);
|
||||
bool decodeTLV = arg_get_lit(ctx, 4);
|
||||
|
||||
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
||||
|
@ -662,13 +662,14 @@ static int CmdEMVSearch(const char *Cmd) {
|
|||
PrintChannel(channel);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
const char *al = "Applets list";
|
||||
struct tlvdb *t = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
|
||||
|
||||
if (EMVSearch(channel, activateField, leaveSignalON, decodeTLV, t, false)) {
|
||||
tlvdb_free(t);
|
||||
SetAPDULogging(false);
|
||||
return PM3_ERFTRANS;
|
||||
}
|
||||
|
||||
|
@ -681,6 +682,7 @@ static int CmdEMVSearch(const char *Cmd) {
|
|||
|
||||
tlvdb_free(t);
|
||||
|
||||
SetAPDULogging(false);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -708,19 +710,23 @@ static int CmdEMVPPSE(const char *Cmd) {
|
|||
bool activateField = arg_get_lit(ctx, 1);
|
||||
bool leaveSignalON = arg_get_lit(ctx, 2);
|
||||
uint8_t PSENum = 2;
|
||||
if (arg_get_lit(ctx, 3))
|
||||
if (arg_get_lit(ctx, 3)) {
|
||||
PSENum = 1;
|
||||
if (arg_get_lit(ctx, 4))
|
||||
}
|
||||
if (arg_get_lit(ctx, 4)) {
|
||||
PSENum = 2;
|
||||
bool APDULogging = arg_get_lit(ctx, 5);
|
||||
}
|
||||
bool show_apdu = arg_get_lit(ctx, 5);
|
||||
bool decodeTLV = arg_get_lit(ctx, 6);
|
||||
|
||||
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
||||
if (arg_get_lit(ctx, 7))
|
||||
if (arg_get_lit(ctx, 7)) {
|
||||
channel = CC_CONTACT;
|
||||
}
|
||||
PrintChannel(channel);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
// exec
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
|
@ -737,6 +743,7 @@ static int CmdEMVPPSE(const char *Cmd) {
|
|||
if (decodeTLV)
|
||||
TLVPrintFromBuffer(buf, len);
|
||||
|
||||
SetAPDULogging(false);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -768,16 +775,17 @@ static int CmdEMVGPO(const char *Cmd) {
|
|||
bool leaveSignalON = arg_get_lit(ctx, 1);
|
||||
bool paramsLoadFromFile = arg_get_lit(ctx, 2);
|
||||
bool dataMakeFromPDOL = arg_get_lit(ctx, 3);
|
||||
bool APDULogging = arg_get_lit(ctx, 4);
|
||||
bool show_apdu = arg_get_lit(ctx, 4);
|
||||
bool decodeTLV = arg_get_lit(ctx, 5);
|
||||
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
||||
if (arg_get_lit(ctx, 6))
|
||||
if (arg_get_lit(ctx, 6)) {
|
||||
channel = CC_CONTACT;
|
||||
}
|
||||
PrintChannel(channel);
|
||||
CLIGetHexWithReturn(ctx, 7, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
// Init TLV tree
|
||||
const char *alr = "Root terminal TLV tree";
|
||||
|
@ -805,6 +813,7 @@ static int CmdEMVGPO(const char *Cmd) {
|
|||
PrintAndLogEx(ERR, "Can't create PDOL TLV.");
|
||||
tlvdb_free(tmp_ext);
|
||||
tlvdb_free(tlvRoot);
|
||||
SetAPDULogging(false);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
} else {
|
||||
|
@ -820,8 +829,10 @@ static int CmdEMVGPO(const char *Cmd) {
|
|||
PrintAndLogEx(ERR, "Can't create PDOL data.");
|
||||
tlvdb_free(tmp_ext);
|
||||
tlvdb_free(tlvRoot);
|
||||
if (pdol_data_tlv != &data_tlv)
|
||||
if (pdol_data_tlv != &data_tlv) {
|
||||
free(pdol_data_tlv);
|
||||
}
|
||||
SetAPDULogging(false);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
PrintAndLogEx(INFO, "PDOL data[%zu]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
|
||||
|
@ -847,6 +858,7 @@ static int CmdEMVGPO(const char *Cmd) {
|
|||
if (decodeTLV)
|
||||
TLVPrintFromBuffer(buf, len);
|
||||
|
||||
SetAPDULogging(false);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -873,11 +885,12 @@ static int CmdEMVReadRecord(const char *Cmd) {
|
|||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool leaveSignalON = arg_get_lit(ctx, 1);
|
||||
bool APDULogging = arg_get_lit(ctx, 2);
|
||||
bool show_apdu = arg_get_lit(ctx, 2);
|
||||
bool decodeTLV = arg_get_lit(ctx, 3);
|
||||
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
||||
if (arg_get_lit(ctx, 4))
|
||||
if (arg_get_lit(ctx, 4)) {
|
||||
channel = CC_CONTACT;
|
||||
}
|
||||
PrintChannel(channel);
|
||||
CLIGetHexWithReturn(ctx, 5, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
@ -887,13 +900,14 @@ static int CmdEMVReadRecord(const char *Cmd) {
|
|||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
// exec
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
size_t len = 0;
|
||||
uint16_t sw = 0;
|
||||
int res = EMVReadRecord(channel, leaveSignalON, data[0], data[1], buf, sizeof(buf), &len, &sw, NULL);
|
||||
SetAPDULogging(false);
|
||||
|
||||
if (sw)
|
||||
PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
|
@ -940,14 +954,17 @@ static int CmdEMVAC(const char *Cmd) {
|
|||
bool trTypeCDA = arg_get_lit(ctx, 2);
|
||||
uint8_t termDecision = 0xff;
|
||||
if (arg_get_str_len(ctx, 3)) {
|
||||
if (!strncmp(arg_get_str(ctx, 3)->sval[0], "aac", 4))
|
||||
if (!strncmp(arg_get_str(ctx, 3)->sval[0], "aac", 4)) {
|
||||
termDecision = EMVAC_AAC;
|
||||
if (!strncmp(arg_get_str(ctx, 3)->sval[0], "tc", 4))
|
||||
}
|
||||
if (!strncmp(arg_get_str(ctx, 3)->sval[0], "tc", 4)) {
|
||||
termDecision = EMVAC_TC;
|
||||
if (!strncmp(arg_get_str(ctx, 3)->sval[0], "arqc", 4))
|
||||
}
|
||||
if (!strncmp(arg_get_str(ctx, 3)->sval[0], "arqc", 4)) {
|
||||
termDecision = EMVAC_ARQC;
|
||||
}
|
||||
|
||||
if (termDecision == 0xff) {
|
||||
if (termDecision == 0xFF) {
|
||||
PrintAndLogEx(ERR, "ERROR: can't find terminal decision '%s'", arg_get_str(ctx, 3)->sval[0]);
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
|
@ -955,22 +972,25 @@ static int CmdEMVAC(const char *Cmd) {
|
|||
} else {
|
||||
termDecision = EMVAC_TC;
|
||||
}
|
||||
if (trTypeCDA)
|
||||
|
||||
if (trTypeCDA) {
|
||||
termDecision = termDecision | EMVAC_CDAREQ;
|
||||
}
|
||||
bool paramsLoadFromFile = arg_get_lit(ctx, 4);
|
||||
bool dataMakeFromCDOL = arg_get_lit(ctx, 5);
|
||||
bool APDULogging = arg_get_lit(ctx, 6);
|
||||
bool show_apdu = arg_get_lit(ctx, 6);
|
||||
bool decodeTLV = arg_get_lit(ctx, 7);
|
||||
|
||||
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
||||
if (arg_get_lit(ctx, 8))
|
||||
if (arg_get_lit(ctx, 8)) {
|
||||
channel = CC_CONTACT;
|
||||
}
|
||||
|
||||
PrintChannel(channel);
|
||||
CLIGetHexWithReturn(ctx, 9, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
// Init TLV tree
|
||||
const char *alr = "Root terminal TLV tree";
|
||||
|
@ -999,6 +1019,7 @@ static int CmdEMVAC(const char *Cmd) {
|
|||
PrintAndLogEx(ERR, "Can't create CDOL TLV.");
|
||||
tlvdb_free(tmp_ext);
|
||||
tlvdb_free(tlvRoot);
|
||||
SetAPDULogging(false);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
} else {
|
||||
|
@ -1015,6 +1036,7 @@ static int CmdEMVAC(const char *Cmd) {
|
|||
size_t len = 0;
|
||||
uint16_t sw = 0;
|
||||
int res = EMVAC(channel, leaveSignalON, termDecision, (uint8_t *)cdol_data_tlv->value, cdol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
|
||||
SetAPDULogging(false);
|
||||
|
||||
if (cdol_data_tlv != &data_tlv)
|
||||
free(cdol_data_tlv);
|
||||
|
@ -1053,20 +1075,22 @@ static int CmdEMVGenerateChallenge(const char *Cmd) {
|
|||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool leaveSignalON = arg_get_lit(ctx, 1);
|
||||
bool APDULogging = arg_get_lit(ctx, 2);
|
||||
bool show_apdu = arg_get_lit(ctx, 2);
|
||||
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
||||
if (arg_get_lit(ctx, 3))
|
||||
if (arg_get_lit(ctx, 3)) {
|
||||
channel = CC_CONTACT;
|
||||
}
|
||||
PrintChannel(channel);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
// exec
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
size_t len = 0;
|
||||
uint16_t sw = 0;
|
||||
int res = EMVGenerateChallenge(channel, leaveSignalON, buf, sizeof(buf), &len, &sw, NULL);
|
||||
SetAPDULogging(false);
|
||||
|
||||
if (sw)
|
||||
PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
|
@ -1076,8 +1100,9 @@ static int CmdEMVGenerateChallenge(const char *Cmd) {
|
|||
|
||||
PrintAndLogEx(SUCCESS, "Challenge: %s", sprint_hex(buf, len));
|
||||
|
||||
if (len != 4 && len != 8)
|
||||
PrintAndLogEx(WARNING, "Length of challenge must be 4 or 8, but it %zu", len);
|
||||
if (len != 4 && len != 8) {
|
||||
PrintAndLogEx(WARNING, "Length of challenge must be 4 or 8, got " _YELLOW_("%zu"), len);
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
@ -1111,16 +1136,17 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) {
|
|||
bool leaveSignalON = arg_get_lit(ctx, 1);
|
||||
bool paramsLoadFromFile = arg_get_lit(ctx, 2);
|
||||
bool dataMakeFromDDOL = arg_get_lit(ctx, 3);
|
||||
bool APDULogging = arg_get_lit(ctx, 4);
|
||||
bool show_apdu = arg_get_lit(ctx, 4);
|
||||
bool decodeTLV = arg_get_lit(ctx, 5);
|
||||
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
||||
if (arg_get_lit(ctx, 6))
|
||||
if (arg_get_lit(ctx, 6)) {
|
||||
channel = CC_CONTACT;
|
||||
}
|
||||
PrintChannel(channel);
|
||||
CLIGetHexWithReturn(ctx, 7, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
// Init TLV tree
|
||||
const char *alr = "Root terminal TLV tree";
|
||||
|
@ -1149,6 +1175,7 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) {
|
|||
PrintAndLogEx(ERR, "Can't create DDOL TLV.");
|
||||
tlvdb_free(tmp_ext);
|
||||
tlvdb_free(tlvRoot);
|
||||
SetAPDULogging(false);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
} else {
|
||||
|
@ -1165,6 +1192,7 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) {
|
|||
size_t len = 0;
|
||||
uint16_t sw = 0;
|
||||
int res = EMVInternalAuthenticate(channel, leaveSignalON, data, datalen, buf, sizeof(buf), &len, &sw, NULL);
|
||||
SetAPDULogging(false);
|
||||
|
||||
if (ddol_data_tlv != &data_tlv)
|
||||
free(ddol_data_tlv);
|
||||
|
@ -1184,7 +1212,14 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
#define dreturn(n) {free(pdol_data_tlv); tlvdb_free(tlvSelect); tlvdb_free(tlvRoot); DropFieldEx( channel ); return n;}
|
||||
#define dreturn(n) { \
|
||||
free(pdol_data_tlv); \
|
||||
tlvdb_free(tlvSelect); \
|
||||
tlvdb_free(tlvRoot); \
|
||||
DropFieldEx( channel ); \
|
||||
SetAPDULogging(false); \
|
||||
return n; \
|
||||
}
|
||||
|
||||
static void InitTransactionParameters(struct tlvdb *tlvRoot, bool paramLoadJSON, enum TransactionType TrType, bool GenACGPO) {
|
||||
|
||||
|
@ -1327,21 +1362,24 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool activateField = arg_get_lit(ctx, 1);
|
||||
bool showAPDU = arg_get_lit(ctx, 2);
|
||||
bool show_apdu = arg_get_lit(ctx, 2);
|
||||
bool decodeTLV = arg_get_lit(ctx, 3);
|
||||
bool paramLoadJSON = arg_get_lit(ctx, 4);
|
||||
bool forceSearch = arg_get_lit(ctx, 5);
|
||||
|
||||
enum TransactionType TrType = TT_MSD;
|
||||
|
||||
if (arg_get_lit(ctx, 7))
|
||||
if (arg_get_lit(ctx, 7)) {
|
||||
TrType = TT_QVSDCMCHIP;
|
||||
}
|
||||
|
||||
if (arg_get_lit(ctx, 8))
|
||||
if (arg_get_lit(ctx, 8)) {
|
||||
TrType = TT_CDA;
|
||||
}
|
||||
|
||||
if (arg_get_lit(ctx, 9))
|
||||
if (arg_get_lit(ctx, 9)) {
|
||||
TrType = TT_VSDC;
|
||||
}
|
||||
|
||||
bool GenACGPO = arg_get_lit(ctx, 10);
|
||||
|
||||
|
@ -1354,14 +1392,14 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
uint8_t psenum = (channel == CC_CONTACT) ? 1 : 2;
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (!IfPm3Smartcard()) {
|
||||
if (IfPm3Smartcard() == false) {
|
||||
if (channel == CC_CONTACT) {
|
||||
PrintAndLogEx(WARNING, "PM3 does not have SMARTCARD support. Exiting.");
|
||||
return PM3_EDEVNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
SetAPDULogging(showAPDU);
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
size_t len = 0;
|
||||
|
@ -1387,7 +1425,7 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
// PPSE
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "* PPSE.");
|
||||
SetAPDULogging(showAPDU);
|
||||
SetAPDULogging(show_apdu);
|
||||
res = EMVSearchPSE(channel, activateField, true, psenum, decodeTLV, tlvSelect);
|
||||
|
||||
// check PPSE instead of PSE and vice versa
|
||||
|
@ -1428,7 +1466,7 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
|
||||
// Select
|
||||
PrintAndLogEx(INFO, "\n* Selecting AID:%s", sprint_hex_inrow(AID, AIDlen));
|
||||
SetAPDULogging(showAPDU);
|
||||
SetAPDULogging(show_apdu);
|
||||
res = EMVSelect(channel, false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot);
|
||||
|
||||
if (res) {
|
||||
|
@ -1436,8 +1474,9 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
dreturn(PM3_ERFTRANS);
|
||||
}
|
||||
|
||||
if (decodeTLV)
|
||||
if (decodeTLV) {
|
||||
TLVPrintFromBuffer(buf, len);
|
||||
}
|
||||
PrintAndLogEx(INFO, "* Selected.");
|
||||
|
||||
PrintAndLogEx(INFO, "\n* Init transaction parameters.");
|
||||
|
@ -1492,8 +1531,9 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "\n* Read records from AFL.");
|
||||
const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
|
||||
|
||||
if (!AFL || !AFL->len)
|
||||
if (!AFL || !AFL->len) {
|
||||
PrintAndLogEx(WARNING, "WARNING: AFL not found.");
|
||||
}
|
||||
|
||||
while (AFL && AFL->len) {
|
||||
if (AFL->len % 4) {
|
||||
|
@ -1614,19 +1654,24 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
TLVPrintFromTLVLev(cvr, 1);
|
||||
PrintAndLogEx(INFO, " IDD option id: 0x%02x", IAD->value[8]);
|
||||
PrintAndLogEx(INFO, " IDD: %s", sprint_hex(&IAD->value[9], 23));
|
||||
|
||||
} else if (IAD->len >= IAD->value[0] + 1) {
|
||||
PrintAndLogEx(INFO, " Key index: 0x%02x", IAD->value[1]);
|
||||
PrintAndLogEx(INFO, " Crypto ver: 0x%02x(%03d)", IAD->value[2], IAD->value[2]);
|
||||
PrintAndLogEx(INFO, " CVR: %s", sprint_hex(&IAD->value[3], IAD->value[0] - 2));
|
||||
struct tlvdb *cvr = tlvdb_fixed(0x20, IAD->value[0] - 2, &IAD->value[3]);
|
||||
TLVPrintFromTLVLev(cvr, 1);
|
||||
|
||||
if (IAD->len >= 8) {
|
||||
int iddLen = IAD->value[7];
|
||||
PrintAndLogEx(NORMAL, " IDD length: %d", iddLen);
|
||||
if (iddLen >= 1)
|
||||
if (iddLen >= 1) {
|
||||
PrintAndLogEx(NORMAL, " IDD option id: 0x%02x", IAD->value[8]);
|
||||
if (iddLen >= 2)
|
||||
}
|
||||
|
||||
if (iddLen >= 2) {
|
||||
PrintAndLogEx(NORMAL, " IDD: %s", sprint_hex(&IAD->value[9], iddLen - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1641,6 +1686,7 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
|
||||
// Mastercard M/CHIP
|
||||
if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD && (TrType == TT_QVSDCMCHIP || TrType == TT_CDA)) {
|
||||
|
||||
const struct tlv *CDOL1 = tlvdb_get(tlvRoot, 0x8c, NULL);
|
||||
if (CDOL1 && GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) { // and m/chip transaction flag
|
||||
PrintAndLogEx(INFO, "\n--> Mastercard M/Chip transaction.");
|
||||
|
@ -1651,6 +1697,7 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
PrintAndLogEx(ERR, "Error GetChallenge. APDU error %4x", sw);
|
||||
dreturn(PM3_ERFTRANS);
|
||||
}
|
||||
|
||||
if (len < 4) {
|
||||
PrintAndLogEx(ERR, "Error GetChallenge. Wrong challenge length %zu", len);
|
||||
dreturn(PM3_ESOFT);
|
||||
|
@ -1681,8 +1728,9 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
dreturn(PM3_ERFTRANS);
|
||||
}
|
||||
|
||||
if (decodeTLV)
|
||||
if (decodeTLV) {
|
||||
TLVPrintFromBuffer(buf, len);
|
||||
}
|
||||
|
||||
// CDA
|
||||
PrintAndLogEx(INFO, "\n* CDA:");
|
||||
|
@ -1705,7 +1753,8 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
if (CID) {
|
||||
emv_tag_dump(CID, 1);
|
||||
PrintAndLogEx(INFO, "------------------------------");
|
||||
if (CID->len > 0) {
|
||||
|
||||
if (CID->len) {
|
||||
switch (CID->value[0] & EMVAC_AC_MASK) {
|
||||
case EMVAC_AAC:
|
||||
PrintAndLogEx(INFO, "Transaction DECLINED.");
|
||||
|
@ -1755,8 +1804,9 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
.len = 3,
|
||||
.value = (uint8_t *)"\x9f\x6a\x04",
|
||||
};
|
||||
if (!UDOL)
|
||||
if (!UDOL) {
|
||||
PrintAndLogEx(INFO, "Use default UDOL.");
|
||||
}
|
||||
|
||||
struct tlv *udol_data_tlv = dol_process(UDOL ? UDOL : &defUDOL, tlvRoot, 0x01); // 0x01 - dummy tag
|
||||
if (!udol_data_tlv) {
|
||||
|
@ -1831,6 +1881,7 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
uint8_t IDDlen = 0; // Issuer discretionary data length
|
||||
PrintAndLogEx(INFO, "IAD length: %zu", IAD->len);
|
||||
PrintAndLogEx(INFO, "VDDlen: %d", VDDlen);
|
||||
|
||||
if (VDDlen < IAD->len - 1) {
|
||||
IDDlen = IAD->value[VDDlen + 1];
|
||||
}
|
||||
|
@ -1852,9 +1903,11 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
PrintAndLogEx(WARNING, "Wrong CVR length! CVR: %s", sprint_hex(&IAD->value[3], VDDlen - 2));
|
||||
}
|
||||
}
|
||||
|
||||
if (IDDlen) {
|
||||
PrintAndLogEx(INFO, "IDD: %s", sprint_hex(&IAD->value[VDDlen + 1], IDDlen));
|
||||
}
|
||||
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Issuer Application Data (IAD) not found.");
|
||||
}
|
||||
|
@ -1928,6 +1981,7 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
tlvdb_free(tlvRoot);
|
||||
|
||||
PrintAndLogEx(SUCCESS, "\n* Transaction completed.");
|
||||
SetAPDULogging(false);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1958,25 +2012,29 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool showAPDU = arg_get_lit(ctx, 1);
|
||||
bool show_apdu = arg_get_lit(ctx, 1);
|
||||
bool decodeTLV = arg_get_lit(ctx, 2);
|
||||
bool extractTLVElements = arg_get_lit(ctx, 3);
|
||||
bool paramLoadJSON = arg_get_lit(ctx, 4);
|
||||
|
||||
enum TransactionType TrType = TT_MSD;
|
||||
if (arg_get_lit(ctx, 6))
|
||||
if (arg_get_lit(ctx, 6)){
|
||||
TrType = TT_QVSDCMCHIP;
|
||||
if (arg_get_lit(ctx, 7))
|
||||
}
|
||||
if (arg_get_lit(ctx, 7)) {
|
||||
TrType = TT_CDA;
|
||||
if (arg_get_lit(ctx, 8))
|
||||
}
|
||||
if (arg_get_lit(ctx, 8)) {
|
||||
TrType = TT_VSDC;
|
||||
}
|
||||
|
||||
bool GenACGPO = arg_get_lit(ctx, 9);
|
||||
bool MergeJSON = arg_get_lit(ctx, 10);
|
||||
|
||||
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
||||
if (arg_get_lit(ctx, 11))
|
||||
if (arg_get_lit(ctx, 11)) {
|
||||
channel = CC_CONTACT;
|
||||
}
|
||||
|
||||
PrintChannel(channel);
|
||||
|
||||
|
@ -1988,15 +2046,13 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (!IfPm3Smartcard()) {
|
||||
if (IfPm3Smartcard() == false) {
|
||||
if (channel == CC_CONTACT) {
|
||||
PrintAndLogEx(WARNING, "PM3 does not have SMARTCARD support, exiting");
|
||||
return PM3_EDEVNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
SetAPDULogging(showAPDU);
|
||||
|
||||
uint8_t AID[APDU_AID_LEN] = {0};
|
||||
size_t AIDlen = 0;
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
|
@ -2026,6 +2082,8 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
root = json_object();
|
||||
}
|
||||
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
// drop field at start
|
||||
DropFieldEx(channel);
|
||||
|
||||
|
@ -2103,7 +2161,7 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
}
|
||||
|
||||
// EMV SELECT application
|
||||
SetAPDULogging(showAPDU);
|
||||
SetAPDULogging(show_apdu);
|
||||
EMVSelectApplication(tlvSelect, AID, &AIDlen);
|
||||
|
||||
tlvdb_free(tlvSelect);
|
||||
|
@ -2123,7 +2181,7 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
// EMV SELECT applet
|
||||
|
||||
PrintAndLogEx(INFO, "Selecting AID: " _GREEN_("%s"), sprint_hex_inrow(AID, AIDlen));
|
||||
SetAPDULogging(showAPDU);
|
||||
SetAPDULogging(show_apdu);
|
||||
res = EMVSelect(channel, false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot);
|
||||
|
||||
if (res) {
|
||||
|
@ -2214,10 +2272,12 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
|
||||
sfijson = json_path_get(root, "$.Application.Records");
|
||||
}
|
||||
|
||||
if (!json_is_array(sfijson)) {
|
||||
PrintAndLogEx(ERR, "Internal logic error. `$.Application.Records` is not an array.");
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < AFL->len / 4; i++) {
|
||||
uint8_t SFI = AFL->value[i * 4 + 0] >> 3;
|
||||
uint8_t SFIstart = AFL->value[i * 4 + 1];
|
||||
|
@ -2273,11 +2333,11 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
JsonSaveHex(jsonelm, "Offline", SFIoffline, 1);
|
||||
|
||||
struct tlvdb *rsfi = tlvdb_parse_multi(buf, len);
|
||||
if (extractTLVElements)
|
||||
if (extractTLVElements) {
|
||||
JsonSaveTLVTree(root, jsonelm, "$.Data", rsfi);
|
||||
else
|
||||
} else {
|
||||
JsonSaveTLVTreeElm(jsonelm, "$.Data", rsfi, true, true, false);
|
||||
|
||||
}
|
||||
tlvdb_free(rsfi);
|
||||
}
|
||||
}
|
||||
|
@ -2303,7 +2363,7 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
tlvdb_free(tlvRoot);
|
||||
|
||||
DropFieldEx(channel);
|
||||
|
||||
SetAPDULogging(false);
|
||||
|
||||
if (MergeJSON == false) {
|
||||
// create unique new name
|
||||
|
@ -2386,7 +2446,7 @@ static int CmdEMVRoca(const char *Cmd) {
|
|||
CLIParserFree(ctx);
|
||||
PrintChannel(channel);
|
||||
|
||||
if (!IfPm3Smartcard()) {
|
||||
if (IfPm3Smartcard() == false) {
|
||||
if (channel == CC_CONTACT) {
|
||||
PrintAndLogEx(WARNING, "PM3 does not have SMARTCARD support, exiting");
|
||||
return PM3_EDEVNOTSUPP;
|
||||
|
@ -2425,6 +2485,7 @@ static int CmdEMVRoca(const char *Cmd) {
|
|||
PrintAndLogEx(ERR, "Can't found any of EMV AID, exiting");
|
||||
tlvdb_free(tlvSelect);
|
||||
DropFieldEx(channel);
|
||||
SetAPDULogging(false);
|
||||
return PM3_ERFTRANS;
|
||||
}
|
||||
|
||||
|
@ -2620,6 +2681,7 @@ static int CmdEMVRoca(const char *Cmd) {
|
|||
}
|
||||
|
||||
out:
|
||||
SetAPDULogging(false);
|
||||
tlvdb_free(tlvRoot);
|
||||
DropFieldEx(channel);
|
||||
return ret;
|
||||
|
@ -2715,7 +2777,6 @@ static int CmdEMVReader(const char *Cmd) {
|
|||
uint8_t log_file_records = 31;
|
||||
struct tlvdb *tlogDB = NULL;
|
||||
|
||||
|
||||
// try getting the LOG TEMPLATE.
|
||||
bool log_found = false;
|
||||
bool log_template_found = false;
|
||||
|
@ -2807,8 +2868,9 @@ static int CmdEMVReader(const char *Cmd) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (sw == 0x6A83)
|
||||
if (sw == 0x6A83) {
|
||||
break;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "");
|
||||
PrintAndLogEx(INFO, "Transaction log # " _YELLOW_("%u"), i);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue