From df1dd71d14139e9c0e8fdb578ff17d603bb40c3c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 15 Jul 2019 17:26:42 +0300 Subject: [PATCH] apdu format and print works --- client/cmdhf14a.c | 20 +++++++++++++------- client/emv/apduinfo.c | 6 +++--- client/emv/apduinfo.h | 4 ++-- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index fb8753921..c7dc037a4 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -859,9 +859,9 @@ static int CmdHF14AAPDU(const char *Cmd) { arg_lit0("kK", "keep", "leave the signal field ON after receive response"), arg_lit0("tT", "tlv", "executes TLV decoder if it possible"), arg_lit0("dD", "decapdu", "decode apdu request if it possible"), - arg_lit0("mM", "make", "", "make apdu with head from this field and data from data field. Must be 4 bytes length: "), + arg_str0("mM", "make", "", "make apdu with head from this field and data from data field. Must be 4 bytes length: "), arg_lit0("eE", "extended", "make extended length apdu if `m` parameter included"), - arg_lit0("lL", "le", "Le apdu parameter if `m` parameter included"), + arg_int0("lL", "le", "", "Le apdu parameter if `m` parameter included"), arg_strx1(NULL, NULL, "", "data if `m` parameter included"), arg_param_end }; @@ -871,9 +871,15 @@ static int CmdHF14AAPDU(const char *Cmd) { leaveSignalON = arg_get_lit(2); decodeTLV = arg_get_lit(3); decodeAPDU = arg_get_lit(4); - makeAPDU = arg_get_lit(5); + + CLIGetHexWithReturn(5, header, &headerlen); + makeAPDU = headerlen > 0; + if (makeAPDU && headerlen != 4) { + PrintAndLogEx(ERR, "header length must be 4 bytes instead of %d", headerlen); + return 1; + } extendedAPDU = arg_get_lit(6); - le = arg_get_lit(7); + le = arg_get_int_def(7, 0); if (makeAPDU) { uint8_t apdudata[PM3_CMD_DATA_SIZE] = {0}; @@ -895,17 +901,17 @@ static int CmdHF14AAPDU(const char *Cmd) { if (APDUEncode(&apdu, data, &datalen)) { PrintAndLogEx(ERR, "can't make apdu with provided parameters."); - return 1; + return 2; } } else { if (extendedAPDU) { PrintAndLogEx(ERR, "make mode not set but here `e` option."); - return 2; + return 3; } if (le > 0) { PrintAndLogEx(ERR, "make mode not set but here `l` option."); - return 2; + return 3; } // len = data + PCB(1b) + CRC(2b) diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 3b3664e4b..1e6975107 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -317,7 +317,7 @@ const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2) { return APDUCodeTable[0].Description; //empty string } -int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { +int APDUDecode(uint8_t *data, int len, APDUStruct *apdu) { ExtAPDUHeader *hapdu = (ExtAPDUHeader *)data; apdu->cla = hapdu->cla; @@ -417,11 +417,11 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { return 0; } -int APDUEncode(APDUStruct *apdu, uint8_t *data, size_t *len) { +int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len) { if (len) *len = 0; - if (apdu->le > 0x10000 || apdu->lc != 0xffff) + if (apdu->le > 0x10000 || apdu->lc > 0xffff) return 1; size_t dptr = 0; diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index 7f1e8fd72..5d5173e2f 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -52,8 +52,8 @@ typedef struct { uint8_t case_type; } __attribute__((packed)) APDUStruct; -extern int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu); -extern int APDUEncode(APDUStruct *apdu, uint8_t *data, size_t *len); +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); #endif