mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-19 19:38:52 +08:00
use PrintAndLogEx() instead of PrintAndLog()
This commit is contained in:
parent
7a9612036d
commit
39f44c33a4
1 changed files with 139 additions and 139 deletions
|
@ -14,16 +14,16 @@
|
|||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
int usage_emv_select(void) {
|
||||
PrintAndLog("Executes select applet command:\n");
|
||||
PrintAndLog("Usage: hf emv select [-s][-k][-a][-t] <HEX applet AID>\n");
|
||||
PrintAndLog("Options:");
|
||||
PrintAndLog(" -s : select card");
|
||||
PrintAndLog(" -k : keep field for next command");
|
||||
PrintAndLog(" -a : show APDU reqests and responses\n");
|
||||
PrintAndLog(" -t : TLV decode results\n");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" hf emv select -s a00000000101 -> select card, select applet");
|
||||
PrintAndLog(" hf emv select -s -t a00000000101 -> select card, select applet, show result in TLV");
|
||||
PrintAndLogEx(NORMAL, "Executes select applet command:\n");
|
||||
PrintAndLogEx(NORMAL, "Usage: hf emv select [-s][-k][-a][-t] <HEX applet AID>\n");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " -s : select card");
|
||||
PrintAndLogEx(NORMAL, " -k : keep field for next command");
|
||||
PrintAndLogEx(NORMAL, " -a : show APDU reqests and responses\n");
|
||||
PrintAndLogEx(NORMAL, " -t : TLV decode results\n");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf emv select -s a00000000101 -> select card, select applet");
|
||||
PrintAndLogEx(NORMAL, " hf emv select -s -t a00000000101 -> select card, select applet, show result in TLV");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -64,20 +64,20 @@ int CmdHFEMVSelect(const char *cmd) {
|
|||
decodeTLV = true;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (isxdigit(c)) {
|
||||
switch(param_gethex_to_eol(cmd, cmdp, data, sizeof(data), &datalen)) {
|
||||
case 1:
|
||||
PrintAndLog("Invalid HEX value.");
|
||||
PrintAndLogEx(WARNING, "Invalid HEX value.");
|
||||
return 1;
|
||||
case 2:
|
||||
PrintAndLog("AID too large.");
|
||||
PrintAndLogEx(WARNING, "AID too large.");
|
||||
return 1;
|
||||
case 3:
|
||||
PrintAndLog("Hex must have even number of digits.");
|
||||
PrintAndLogEx(WARNING, "Hex must have even number of digits.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ int CmdHFEMVSelect(const char *cmd) {
|
|||
int res = EMVSelect(activateField, leaveSignalON, data, datalen, buf, sizeof(buf), &len, &sw, NULL);
|
||||
|
||||
if (sw)
|
||||
PrintAndLog("APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
PrintAndLogEx(NORMAL, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
|
||||
if (res)
|
||||
return res;
|
||||
|
@ -106,16 +106,16 @@ int CmdHFEMVSelect(const char *cmd) {
|
|||
}
|
||||
|
||||
int usage_emv_search(void) {
|
||||
PrintAndLog("Tries to select all applets from applet list:\n");
|
||||
PrintAndLog("Usage: hf emv search [-s][-k][-a][-t]\n");
|
||||
PrintAndLog("Options:");
|
||||
PrintAndLog(" -s : select card");
|
||||
PrintAndLog(" -k : keep field for next command");
|
||||
PrintAndLog(" -a : show APDU reqests and responses\n");
|
||||
PrintAndLog(" -t : TLV decode results of selected applets\n");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" hf emv search -s -> select card and search");
|
||||
PrintAndLog(" hf emv search -s -t -> select card, search and show result in TLV");
|
||||
PrintAndLogEx(NORMAL, "Tries to select all applets from applet list:\n");
|
||||
PrintAndLogEx(NORMAL, "Usage: hf emv search [-s][-k][-a][-t]\n");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " -s : select card");
|
||||
PrintAndLogEx(NORMAL, " -k : keep field for next command");
|
||||
PrintAndLogEx(NORMAL, " -a : show APDU reqests and responses\n");
|
||||
PrintAndLogEx(NORMAL, " -t : TLV decode results of selected applets\n");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf emv search -s -> select card and search");
|
||||
PrintAndLogEx(NORMAL, " hf emv search -s -t -> select card, search and show result in TLV");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ int CmdHFEMVSearch(const char *cmd) {
|
|||
decodeTLV = true;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
|
||||
return 1;
|
||||
}
|
||||
cmdp++;
|
||||
|
@ -170,7 +170,7 @@ int CmdHFEMVSearch(const char *cmd) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
PrintAndLog("Search completed.");
|
||||
PrintAndLogEx(NORMAL, "Search completed.");
|
||||
|
||||
// print list here
|
||||
if (!decodeTLV) {
|
||||
|
@ -183,19 +183,19 @@ int CmdHFEMVSearch(const char *cmd) {
|
|||
}
|
||||
|
||||
int usage_emv_ppse(void) {
|
||||
PrintAndLog("Executes PSE/PPSE select command. It returns list of applet on the card:\n");
|
||||
PrintAndLog("Usage: hf emv pse [-s][-k][-1][-2][-a][-t]\n");
|
||||
PrintAndLog("Options:");
|
||||
PrintAndLog(" -s : select card");
|
||||
PrintAndLog(" -k : keep field for next command");
|
||||
PrintAndLog(" -1 : ppse (1PAY.SYS.DDF01)");
|
||||
PrintAndLog(" -2 : pse (2PAY.SYS.DDF01)");
|
||||
PrintAndLog(" -a : show APDU reqests and responses\n");
|
||||
PrintAndLog(" -t : TLV decode results\n");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" hf emv pse -s -1 -> select, get pse");
|
||||
PrintAndLog(" hf emv pse -s -k -2 -> select, get ppse, keep field");
|
||||
PrintAndLog(" hf emv pse -s -t -2 -> select, get ppse, show result in TLV");
|
||||
PrintAndLogEx(NORMAL, "Executes PSE/PPSE select command. It returns list of applet on the card:\n");
|
||||
PrintAndLogEx(NORMAL, "Usage: hf emv pse [-s][-k][-1][-2][-a][-t]\n");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " -s : select card");
|
||||
PrintAndLogEx(NORMAL, " -k : keep field for next command");
|
||||
PrintAndLogEx(NORMAL, " -1 : ppse (1PAY.SYS.DDF01)");
|
||||
PrintAndLogEx(NORMAL, " -2 : pse (2PAY.SYS.DDF01)");
|
||||
PrintAndLogEx(NORMAL, " -a : show APDU reqests and responses\n");
|
||||
PrintAndLogEx(NORMAL, " -t : TLV decode results\n");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf emv pse -s -1 -> select, get pse");
|
||||
PrintAndLogEx(NORMAL, " hf emv pse -s -k -2 -> select, get ppse, keep field");
|
||||
PrintAndLogEx(NORMAL, " hf emv pse -s -t -2 -> select, get ppse, show result in TLV");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ int CmdHFEMVPPSE(const char *cmd) {
|
|||
PSENum = 2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
|
||||
return 1;
|
||||
}
|
||||
cmdp++;
|
||||
|
@ -255,7 +255,7 @@ int CmdHFEMVPPSE(const char *cmd) {
|
|||
int res = EMVSelectPSE(activateField, leaveSignalON, PSENum, buf, sizeof(buf), &len, &sw);
|
||||
|
||||
if (sw)
|
||||
PrintAndLog("APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
PrintAndLogEx(NORMAL, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
|
||||
if (res)
|
||||
return res;
|
||||
|
@ -267,21 +267,21 @@ int CmdHFEMVPPSE(const char *cmd) {
|
|||
}
|
||||
|
||||
int usage_emv_exec(void) {
|
||||
PrintAndLog("Executes EMV contactless transaction:\n");
|
||||
PrintAndLog("Usage: hf emv exec [-s][-a][-t][-f][-v][-c][-x][-g]\n");
|
||||
PrintAndLog("Options:");
|
||||
PrintAndLog(" -s : select card");
|
||||
PrintAndLog(" -a : show APDU reqests and responses\n");
|
||||
PrintAndLog(" -t : TLV decode results\n");
|
||||
PrintAndLog(" -f : force search AID. Search AID instead of execute PPSE.\n");
|
||||
PrintAndLog(" -v : transaction type - qVSDC or M/Chip.\n");
|
||||
PrintAndLog(" -c : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n");
|
||||
PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
|
||||
PrintAndLog(" -g : VISA. generate AC from GPO\n");
|
||||
PrintAndLog("By default : transaction type - MSD.\n");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" hf emv exec -s -a -t -> execute MSD transaction");
|
||||
PrintAndLog(" hf emv exec -s -a -t -c -> execute CDA transaction");
|
||||
PrintAndLogEx(NORMAL, "Executes EMV contactless transaction:\n");
|
||||
PrintAndLogEx(NORMAL, "Usage: hf emv exec [-s][-a][-t][-f][-v][-c][-x][-g]\n");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " -s : select card");
|
||||
PrintAndLogEx(NORMAL, " -a : show APDU reqests and responses\n");
|
||||
PrintAndLogEx(NORMAL, " -t : TLV decode results\n");
|
||||
PrintAndLogEx(NORMAL, " -f : force search AID. Search AID instead of execute PPSE.\n");
|
||||
PrintAndLogEx(NORMAL, " -v : transaction type - qVSDC or M/Chip.\n");
|
||||
PrintAndLogEx(NORMAL, " -c : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n");
|
||||
PrintAndLogEx(NORMAL, " -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
|
||||
PrintAndLogEx(NORMAL, " -g : VISA. generate AC from GPO\n");
|
||||
PrintAndLogEx(NORMAL, "By default : transaction type - MSD.\n");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf emv exec -s -a -t -> execute MSD transaction");
|
||||
PrintAndLogEx(NORMAL, " hf emv exec -s -a -t -c -> execute CDA transaction");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -353,7 +353,7 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
GenACGPO = true;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
|
||||
return 1;
|
||||
}
|
||||
cmdp++;
|
||||
|
@ -367,7 +367,7 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
// https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html
|
||||
if (!forceSearch) {
|
||||
// PPSE
|
||||
PrintAndLog("\n* PPSE.");
|
||||
PrintAndLogEx(NORMAL, "\n* PPSE.");
|
||||
SetAPDULogging(showAPDU);
|
||||
res = EMVSearchPSE(activateField, true, decodeTLV, tlvSelect);
|
||||
|
||||
|
@ -380,7 +380,7 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
|
||||
// Search
|
||||
if (!AIDlen) {
|
||||
PrintAndLog("\n* Search AID in list.");
|
||||
PrintAndLogEx(NORMAL, "\n* Search AID in list.");
|
||||
SetAPDULogging(false);
|
||||
if (EMVSearch(activateField, true, decodeTLV, tlvSelect)) {
|
||||
dreturn(2);
|
||||
|
@ -397,25 +397,25 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
|
||||
// check if we found EMV application on card
|
||||
if (!AIDlen) {
|
||||
PrintAndLog("Can't select AID. EMV AID not found");
|
||||
PrintAndLogEx(WARNING, "Can't select AID. EMV AID not found");
|
||||
dreturn(2);
|
||||
}
|
||||
|
||||
// Select
|
||||
PrintAndLog("\n* Selecting AID:%s", sprint_hex_inrow(AID, AIDlen));
|
||||
PrintAndLogEx(NORMAL, "\n* Selecting AID:%s", sprint_hex_inrow(AID, AIDlen));
|
||||
SetAPDULogging(showAPDU);
|
||||
res = EMVSelect(false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot);
|
||||
|
||||
if (res) {
|
||||
PrintAndLog("Can't select AID (%d). Exit...", res);
|
||||
PrintAndLogEx(WARNING, "Can't select AID (%d). Exit...", res);
|
||||
dreturn(3);
|
||||
}
|
||||
|
||||
if (decodeTLV)
|
||||
TLVPrintFromBuffer(buf, len);
|
||||
|
||||
PrintAndLog("* Selected.");
|
||||
PrintAndLog("\n* Init transaction parameters.");
|
||||
PrintAndLogEx(NORMAL, "* Selected.");
|
||||
PrintAndLogEx(NORMAL, "\n* Init transaction parameters.");
|
||||
|
||||
//9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
|
||||
char *qVSDC = "\x26\x00\x00\x00";
|
||||
|
@ -459,47 +459,47 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
|
||||
TLVPrintFromTLV(tlvRoot); // TODO delete!!!
|
||||
|
||||
PrintAndLog("\n* Calc PDOL.");
|
||||
PrintAndLogEx(NORMAL, "\n* Calc PDOL.");
|
||||
pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83);
|
||||
if (!pdol_data_tlv){
|
||||
PrintAndLog("ERROR: can't create PDOL TLV.");
|
||||
PrintAndLogEx(WARNING, "Error: can't create PDOL TLV.");
|
||||
dreturn(4);
|
||||
}
|
||||
|
||||
size_t pdol_data_tlv_data_len;
|
||||
unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len);
|
||||
if (!pdol_data_tlv_data) {
|
||||
PrintAndLog("ERROR: can't create PDOL data.");
|
||||
PrintAndLogEx(WARNING, "Error: can't create PDOL data.");
|
||||
dreturn(4);
|
||||
}
|
||||
PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
|
||||
PrintAndLogEx(NORMAL, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
|
||||
|
||||
PrintAndLog("\n* GPO.");
|
||||
PrintAndLogEx(NORMAL, "\n* GPO.");
|
||||
res = EMVGPO(true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot);
|
||||
|
||||
free(pdol_data_tlv_data);
|
||||
//free(pdol_data_tlv); --- free on exit.
|
||||
|
||||
if (res) {
|
||||
PrintAndLog("GPO error(%d): %4x. Exit...", res, sw);
|
||||
PrintAndLogEx(NORMAL, "GPO error(%d): %4x. Exit...", res, sw);
|
||||
dreturn(5);
|
||||
}
|
||||
|
||||
// process response template format 1 [id:80 2b AIP + x4b AFL] and format 2 [id:77 TLV]
|
||||
if (buf[0] == 0x80) {
|
||||
if (decodeTLV){
|
||||
PrintAndLog("GPO response format1:");
|
||||
PrintAndLogEx(NORMAL, "GPO response format1:");
|
||||
TLVPrintFromBuffer(buf, len);
|
||||
}
|
||||
|
||||
if (len < 4 || (len - 4) % 4) {
|
||||
PrintAndLog("ERROR: GPO response format1 parsing error. length=%d", len);
|
||||
PrintAndLogEx(WARNING, "Error: GPO response format1 parsing error. length=%d", len);
|
||||
} else {
|
||||
// AIP
|
||||
struct tlvdb * f1AIP = tlvdb_fixed(0x82, 2, buf + 2);
|
||||
tlvdb_add(tlvRoot, f1AIP);
|
||||
if (decodeTLV){
|
||||
PrintAndLog("\n* * Decode response format 1 (0x80) AIP and AFL:");
|
||||
PrintAndLogEx(NORMAL, "\n* * Decode response format 1 (0x80) AIP and AFL:");
|
||||
TLVPrintFromTLV(f1AIP);
|
||||
}
|
||||
|
||||
|
@ -523,22 +523,22 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
tlvdb_add(tlvRoot, pan);
|
||||
|
||||
const struct tlv *pantlv = tlvdb_get(tlvRoot, 0x5a, NULL);
|
||||
PrintAndLog("\n* * Extracted PAN from track2: %s", sprint_hex(pantlv->value, pantlv->len));
|
||||
PrintAndLogEx(NORMAL, "\n* * Extracted PAN from track2: %s", sprint_hex(pantlv->value, pantlv->len));
|
||||
} else {
|
||||
PrintAndLog("\n* * WARNING: Can't extract PAN from track2.");
|
||||
PrintAndLogEx(NORMAL, "\n* * WARNING: Can't extract PAN from track2.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLog("\n* Read records from AFL.");
|
||||
PrintAndLogEx(NORMAL, "\n* Read records from AFL.");
|
||||
const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
|
||||
|
||||
if (!AFL || !AFL->len)
|
||||
PrintAndLog("WARNING: AFL not found.");
|
||||
PrintAndLogEx(NORMAL, "WARNING: AFL not found.");
|
||||
|
||||
while (AFL && AFL->len) {
|
||||
if (AFL->len % 4) {
|
||||
PrintAndLog("ERROR: Wrong AFL length: %d", AFL->len);
|
||||
PrintAndLogEx(WARNING, "Error: Wrong AFL length: %d", AFL->len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -548,24 +548,24 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
uint8_t SFIend = AFL->value[i * 4 + 2];
|
||||
uint8_t SFIoffline = AFL->value[i * 4 + 3];
|
||||
|
||||
PrintAndLog("* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline);
|
||||
PrintAndLogEx(NORMAL, "* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline);
|
||||
if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) {
|
||||
PrintAndLog("SFI ERROR! Skipped...");
|
||||
PrintAndLogEx(NORMAL, "SFI ERROR! Skipped...");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int n = SFIstart; n <= SFIend; n++) {
|
||||
PrintAndLog("* * * SFI[%02x] %d", SFI, n);
|
||||
PrintAndLogEx(NORMAL, "* * * SFI[%02x] %d", SFI, n);
|
||||
|
||||
res = EMVReadRecord(true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot);
|
||||
if (res) {
|
||||
PrintAndLog("ERROR SFI[%02x]. APDU error %4x", SFI, sw);
|
||||
PrintAndLogEx(WARNING, "Error SFI[%02x]. APDU error %4x", SFI, sw);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (decodeTLV) {
|
||||
TLVPrintFromBuffer(buf, len);
|
||||
PrintAndLog("");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
||||
// Build Input list for Offline Data Authentication
|
||||
|
@ -579,7 +579,7 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
memcpy(&ODAiList[ODAiListLen], &buf[len - elmlen], elmlen);
|
||||
ODAiListLen += elmlen;
|
||||
} else {
|
||||
PrintAndLog("ERROR SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI);
|
||||
PrintAndLogEx(WARNING, "Error SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI);
|
||||
}
|
||||
} else {
|
||||
memcpy(&ODAiList[ODAiListLen], buf, len);
|
||||
|
@ -596,23 +596,23 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
if (ODAiListLen) {
|
||||
struct tlvdb *oda = tlvdb_fixed(0x21, ODAiListLen, ODAiList); // not a standard tag
|
||||
tlvdb_add(tlvRoot, oda);
|
||||
PrintAndLog("* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen);
|
||||
PrintAndLogEx(NORMAL, "* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen);
|
||||
}
|
||||
|
||||
// get AIP
|
||||
const struct tlv *AIPtlv = tlvdb_get(tlvRoot, 0x82, NULL);
|
||||
uint16_t AIP = AIPtlv->value[0] + AIPtlv->value[1] * 0x100;
|
||||
PrintAndLog("* * AIP=%04x", AIP);
|
||||
PrintAndLogEx(NORMAL, "* * AIP=%04x", AIP);
|
||||
|
||||
// SDA
|
||||
if (AIP & 0x0040) {
|
||||
PrintAndLog("\n* SDA");
|
||||
PrintAndLogEx(NORMAL, "\n* SDA");
|
||||
trSDA(tlvRoot);
|
||||
}
|
||||
|
||||
// DDA
|
||||
if (AIP & 0x0020) {
|
||||
PrintAndLog("\n* DDA");
|
||||
PrintAndLogEx(NORMAL, "\n* DDA");
|
||||
trDDA(decodeTLV, tlvRoot);
|
||||
}
|
||||
|
||||
|
@ -623,8 +623,8 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
// 9F26: Application Cryptogram
|
||||
const struct tlv *AC = tlvdb_get(tlvRoot, 0x9F26, NULL);
|
||||
if (AC) {
|
||||
PrintAndLog("\n--> qVSDC transaction.");
|
||||
PrintAndLog("* AC path");
|
||||
PrintAndLogEx(NORMAL, "\n--> qVSDC transaction.");
|
||||
PrintAndLogEx(NORMAL, "* AC path");
|
||||
|
||||
// 9F36: Application Transaction Counter (ATC)
|
||||
const struct tlv *ATC = tlvdb_get(tlvRoot, 0x9F36, NULL);
|
||||
|
@ -634,24 +634,24 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
const struct tlv *IAD = tlvdb_get(tlvRoot, 0x9F10, NULL);
|
||||
|
||||
// print AC data
|
||||
PrintAndLog("ATC: %s", sprint_hex(ATC->value, ATC->len));
|
||||
PrintAndLog("AC: %s", sprint_hex(AC->value, AC->len));
|
||||
PrintAndLogEx(NORMAL, "ATC: %s", sprint_hex(ATC->value, ATC->len));
|
||||
PrintAndLogEx(NORMAL, "AC: %s", sprint_hex(AC->value, AC->len));
|
||||
if (IAD){
|
||||
PrintAndLog("IAD: %s", sprint_hex(IAD->value, IAD->len));
|
||||
PrintAndLogEx(NORMAL, "IAD: %s", sprint_hex(IAD->value, IAD->len));
|
||||
|
||||
if (IAD->len >= IAD->value[0] + 1) {
|
||||
PrintAndLog("\tKey index: 0x%02x", IAD->value[1]);
|
||||
PrintAndLog("\tCrypto ver: 0x%02x(%03d)", IAD->value[2], IAD->value[2]);
|
||||
PrintAndLog("\tCVR:", sprint_hex(&IAD->value[3], IAD->value[0] - 2));
|
||||
PrintAndLogEx(NORMAL, "\tKey index: 0x%02x", IAD->value[1]);
|
||||
PrintAndLogEx(NORMAL, "\tCrypto ver: 0x%02x(%03d)", IAD->value[2], IAD->value[2]);
|
||||
PrintAndLogEx(NORMAL, "\tCVR:", 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);
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("WARNING: IAD not found.");
|
||||
PrintAndLogEx(NORMAL, "WARNING: IAD not found.");
|
||||
}
|
||||
|
||||
} else {
|
||||
PrintAndLog("ERROR AC: Application Transaction Counter (ATC) not found.");
|
||||
PrintAndLogEx(WARNING, "Error AC: Application Transaction Counter (ATC) not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -660,16 +660,16 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
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
|
||||
PrintAndLog("\n--> Mastercard M/Chip transaction.");
|
||||
PrintAndLogEx(NORMAL, "\n--> Mastercard M/Chip transaction.");
|
||||
|
||||
PrintAndLog("* * Generate challenge");
|
||||
PrintAndLogEx(NORMAL, "* * Generate challenge");
|
||||
res = EMVGenerateChallenge(true, buf, sizeof(buf), &len, &sw, tlvRoot);
|
||||
if (res) {
|
||||
PrintAndLog("ERROR GetChallenge. APDU error %4x", sw);
|
||||
PrintAndLogEx(WARNING, "Error GetChallenge. APDU error %4x", sw);
|
||||
dreturn(6);
|
||||
}
|
||||
if (len < 4) {
|
||||
PrintAndLog("ERROR GetChallenge. Wrong challenge length %d", len);
|
||||
PrintAndLogEx(WARNING, "Error GetChallenge. Wrong challenge length %d", len);
|
||||
dreturn(6);
|
||||
}
|
||||
|
||||
|
@ -677,24 +677,24 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
struct tlvdb * ICCDynN = tlvdb_fixed(0x9f4c, len, buf);
|
||||
tlvdb_add(tlvRoot, ICCDynN);
|
||||
if (decodeTLV){
|
||||
PrintAndLog("\n* * ICC Dynamic Number:");
|
||||
PrintAndLogEx(NORMAL, "\n* * ICC Dynamic Number:");
|
||||
TLVPrintFromTLV(ICCDynN);
|
||||
}
|
||||
|
||||
PrintAndLog("* * Calc CDOL1");
|
||||
PrintAndLogEx(NORMAL, "* * Calc CDOL1");
|
||||
struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
|
||||
if (!cdol_data_tlv){
|
||||
PrintAndLog("ERROR: can't create CDOL1 TLV.");
|
||||
PrintAndLogEx(WARNING, "Error: can't create CDOL1 TLV.");
|
||||
dreturn(6);
|
||||
}
|
||||
PrintAndLog("CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len));
|
||||
PrintAndLogEx(NORMAL, "CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len));
|
||||
|
||||
PrintAndLog("* * AC1");
|
||||
PrintAndLogEx(NORMAL, "* * AC1");
|
||||
// EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
|
||||
res = EMVAC(true, (TrType == TT_CDA) ? EMVAC_TC + EMVAC_CDAREQ : EMVAC_TC, (uint8_t *)cdol_data_tlv->value, cdol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
|
||||
|
||||
if (res) {
|
||||
PrintAndLog("AC1 error(%d): %4x. Exit...", res, sw);
|
||||
PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw);
|
||||
dreturn(7);
|
||||
}
|
||||
|
||||
|
@ -702,41 +702,41 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
TLVPrintFromBuffer(buf, len);
|
||||
|
||||
// CDA
|
||||
PrintAndLog("\n* CDA:");
|
||||
PrintAndLogEx(NORMAL, "\n* CDA:");
|
||||
struct tlvdb *ac_tlv = tlvdb_parse_multi(buf, len);
|
||||
res = trCDA(tlvRoot, ac_tlv, pdol_data_tlv, cdol_data_tlv);
|
||||
if (res) {
|
||||
PrintAndLog("CDA error (%d)", res);
|
||||
PrintAndLogEx(NORMAL, "CDA error (%d)", res);
|
||||
}
|
||||
free(ac_tlv);
|
||||
free(cdol_data_tlv);
|
||||
|
||||
PrintAndLog("\n* M/Chip transaction result:");
|
||||
PrintAndLogEx(NORMAL, "\n* M/Chip transaction result:");
|
||||
// 9F27: Cryptogram Information Data (CID)
|
||||
const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL);
|
||||
if (CID) {
|
||||
emv_tag_dump(CID, stdout, 0);
|
||||
PrintAndLog("------------------------------");
|
||||
PrintAndLogEx(NORMAL, "------------------------------");
|
||||
if (CID->len > 0) {
|
||||
switch(CID->value[0] & EMVAC_AC_MASK){
|
||||
case EMVAC_AAC:
|
||||
PrintAndLog("Transaction DECLINED.");
|
||||
PrintAndLogEx(NORMAL, "Transaction DECLINED.");
|
||||
break;
|
||||
case EMVAC_TC:
|
||||
PrintAndLog("Transaction approved OFFLINE.");
|
||||
PrintAndLogEx(NORMAL, "Transaction approved OFFLINE.");
|
||||
break;
|
||||
case EMVAC_ARQC:
|
||||
PrintAndLog("Transaction approved ONLINE.");
|
||||
PrintAndLogEx(NORMAL, "Transaction approved ONLINE.");
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("ERROR: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK);
|
||||
PrintAndLogEx(WARNING, "Error: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("ERROR: Wrong CID length %d", CID->len);
|
||||
PrintAndLogEx(WARNING, "Error: Wrong CID length %d", CID->len);
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("ERROR: CID(9F27) not found.");
|
||||
PrintAndLogEx(WARNING, "Error: CID(9F27) not found.");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -744,20 +744,20 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
|
||||
// MSD
|
||||
if (AIP & 0x8000 && TrType == TT_MSD) {
|
||||
PrintAndLog("\n--> MSD transaction.");
|
||||
PrintAndLogEx(NORMAL, "\n--> MSD transaction.");
|
||||
|
||||
PrintAndLog("* MSD dCVV path. Check dCVV");
|
||||
PrintAndLogEx(NORMAL, "* MSD dCVV path. Check dCVV");
|
||||
|
||||
const struct tlv *track2 = tlvdb_get(tlvRoot, 0x57, NULL);
|
||||
if (track2) {
|
||||
PrintAndLog("Track2: %s", sprint_hex(track2->value, track2->len));
|
||||
PrintAndLogEx(NORMAL, "Track2: %s", sprint_hex(track2->value, track2->len));
|
||||
|
||||
struct tlvdb *dCVV = GetdCVVRawFromTrack2(track2);
|
||||
PrintAndLog("dCVV raw data:");
|
||||
PrintAndLogEx(NORMAL, "dCVV raw data:");
|
||||
TLVPrintFromTLV(dCVV);
|
||||
|
||||
if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) {
|
||||
PrintAndLog("\n* Mastercard calculate UDOL");
|
||||
PrintAndLogEx(NORMAL, "\n* Mastercard calculate UDOL");
|
||||
|
||||
// UDOL (9F69)
|
||||
const struct tlv *UDOL = tlvdb_get(tlvRoot, 0x9F69, NULL);
|
||||
|
@ -768,34 +768,34 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
.value = (uint8_t *)"\x9f\x6a\x04",
|
||||
};
|
||||
if (!UDOL)
|
||||
PrintAndLog("Use default UDOL.");
|
||||
PrintAndLogEx(NORMAL, "Use default UDOL.");
|
||||
|
||||
struct tlv *udol_data_tlv = dol_process(UDOL ? UDOL : &defUDOL, tlvRoot, 0x01); // 0x01 - dummy tag
|
||||
if (!udol_data_tlv){
|
||||
PrintAndLog("ERROR: can't create UDOL TLV.");
|
||||
PrintAndLogEx(WARNING, "Error: can't create UDOL TLV.");
|
||||
dreturn(8);
|
||||
}
|
||||
|
||||
PrintAndLog("UDOL data[%d]: %s", udol_data_tlv->len, sprint_hex(udol_data_tlv->value, udol_data_tlv->len));
|
||||
PrintAndLogEx(NORMAL, "UDOL data[%d]: %s", udol_data_tlv->len, sprint_hex(udol_data_tlv->value, udol_data_tlv->len));
|
||||
|
||||
PrintAndLog("\n* Mastercard compute cryptographic checksum(UDOL)");
|
||||
PrintAndLogEx(NORMAL, "\n* Mastercard compute cryptographic checksum(UDOL)");
|
||||
|
||||
res = MSCComputeCryptoChecksum(true, (uint8_t *)udol_data_tlv->value, udol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
|
||||
if (res) {
|
||||
PrintAndLog("ERROR Compute Crypto Checksum. APDU error %4x", sw);
|
||||
PrintAndLogEx(WARNING, "Error Compute Crypto Checksum. APDU error %4x", sw);
|
||||
free(udol_data_tlv);
|
||||
dreturn(9);
|
||||
}
|
||||
|
||||
if (decodeTLV) {
|
||||
TLVPrintFromBuffer(buf, len);
|
||||
PrintAndLog("");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
free(udol_data_tlv);
|
||||
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("ERROR MSD: Track2 data not found.");
|
||||
PrintAndLogEx(WARNING, "Error MSD: Track2 data not found.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -806,18 +806,18 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
tlvdb_free(tlvSelect);
|
||||
tlvdb_free(tlvRoot);
|
||||
|
||||
PrintAndLog("\n* Transaction completed.");
|
||||
PrintAndLogEx(NORMAL, "\n* Transaction completed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usage_emv_getrnd(void){
|
||||
PrintAndLog("retrieve the UN number from a terminal");
|
||||
PrintAndLog("Usage: hf emv getrnd [h]");
|
||||
PrintAndLog("Options:");
|
||||
PrintAndLog(" h : this help");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" hf emv getrnd");
|
||||
PrintAndLogEx(NORMAL, "retrieve the UN number from a terminal");
|
||||
PrintAndLogEx(NORMAL, "Usage: hf emv getrnd [h]");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : this help");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf emv getrnd");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue