diff --git a/client/src/emv/cmdemv.c b/client/src/emv/cmdemv.c index ea101f43d..d149a381a 100644 --- a/client/src/emv/cmdemv.c +++ b/client/src/emv/cmdemv.c @@ -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);