diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index c7dc037a4..47586a94a 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -876,15 +876,15 @@ static int CmdHF14AAPDU(const char *Cmd) { makeAPDU = headerlen > 0; if (makeAPDU && headerlen != 4) { PrintAndLogEx(ERR, "header length must be 4 bytes instead of %d", headerlen); - return 1; + return 1; } extendedAPDU = arg_get_lit(6); le = arg_get_int_def(7, 0); - + if (makeAPDU) { uint8_t apdudata[PM3_CMD_DATA_SIZE] = {0}; int apdudatalen = 0; - + CLIGetHexBLessWithReturn(8, apdudata, &apdudatalen, 1 + 2); APDUStruct apdu; @@ -892,28 +892,28 @@ static int CmdHF14AAPDU(const char *Cmd) { apdu.ins = header[1]; apdu.p1 = header[2]; apdu.p2 = header[3]; - + apdu.lc = apdudatalen; apdu.data = apdudata; - + apdu.extended_apdu = extendedAPDU; apdu.le = le; - + if (APDUEncode(&apdu, data, &datalen)) { PrintAndLogEx(ERR, "can't make apdu with provided parameters."); - return 2; + return 2; } - - } else { + + } else { if (extendedAPDU) { PrintAndLogEx(ERR, "make mode not set but here `e` option."); - return 3; + return 3; } if (le > 0) { PrintAndLogEx(ERR, "make mode not set but here `l` option."); - return 3; + return 3; } - + // len = data + PCB(1b) + CRC(2b) CLIGetHexBLessWithReturn(8, data, &datalen, 1 + 2); } @@ -922,12 +922,12 @@ static int CmdHF14AAPDU(const char *Cmd) { PrintAndLogEx(NORMAL, ">>>>[%s%s%s] %s", activateField ? "sel " : "", leaveSignalON ? "keep " : "", decodeTLV ? "TLV" : "", sprint_hex(data, datalen)); if (decodeAPDU) { - APDUStruct apdu; - + APDUStruct apdu; + if (APDUDecode(data, datalen, &apdu) == 0) APDUPrint(apdu); else - PrintAndLogEx(WARNING, "can't decode APDU."); + PrintAndLogEx(WARNING, "can't decode APDU."); } int res = ExchangeAPDU14a(data, datalen, activateField, leaveSignalON, data, PM3_CMD_DATA_SIZE, &datalen); diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 1e6975107..a7a8e1672 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -470,6 +470,12 @@ int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len) { } void APDUPrint(APDUStruct apdu) { - PrintAndLogEx(INFO, "apdu: %scase=%02x cla=%02x ins=%02x p1=%02x p2=%02x Lc=%d Le=%d\n", - apdu.extended_apdu ? "[e]" : "", apdu.case_type, apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.lc, apdu.le); + APDUPrintEx(apdu, 0); +} + +void APDUPrintEx(APDUStruct apdu, size_t maxdatalen) { + PrintAndLogEx(INFO, "APDU: %scase=0x%02x cla=0x%02x ins=0x%02x p1=0x%02x p2=0x%02x Lc=0x%02x(%d) Le=0x%02x(%d)", + apdu.extended_apdu ? "[e]" : "", apdu.case_type, apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.lc, apdu.lc, apdu.le, apdu.le); + if (maxdatalen > 0) + PrintAndLogEx(INFO, "data: %s%s", sprint_hex(apdu.data, MIN(apdu.lc, maxdatalen)), apdu.lc > maxdatalen ? "..." : ""); } diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index 5d5173e2f..1fbb3bf00 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -55,5 +55,6 @@ typedef struct { extern int APDUDecode(uint8_t *data, int len, APDUStruct *apdu); extern int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len); extern void APDUPrint(APDUStruct apdu); +extern void APDUPrintEx(APDUStruct apdu, size_t maxdatalen); #endif