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