mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -07:00
cliparser: remove global vars
This commit is contained in:
parent
ff1f945291
commit
6326c4126c
13 changed files with 393 additions and 330 deletions
|
@ -10,50 +10,50 @@
|
|||
|
||||
#include "cliparser.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void **argtable = NULL;
|
||||
size_t argtableLen = 0;
|
||||
const char *programName = NULL;
|
||||
const char *programHint = NULL;
|
||||
const char *programHelp = NULL;
|
||||
char buf[500] = {0};
|
||||
|
||||
int CLIParserInit(const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) {
|
||||
argtable = NULL;
|
||||
argtableLen = 0;
|
||||
programName = vprogramName;
|
||||
programHint = vprogramHint;
|
||||
programHelp = vprogramHelp;
|
||||
memset(buf, 0x00, 500);
|
||||
int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) {
|
||||
*ctx = malloc(sizeof(CLIParserContext));
|
||||
if (!*ctx) {
|
||||
printf("ERROR: Insufficient memory\n");
|
||||
fflush(stdout);
|
||||
return 2;
|
||||
}
|
||||
(*ctx)->argtable = NULL;
|
||||
(*ctx)->argtableLen = 0;
|
||||
(*ctx)->programName = vprogramName;
|
||||
(*ctx)->programHint = vprogramHint;
|
||||
(*ctx)->programHelp = vprogramHelp;
|
||||
memset((*ctx)->buf, 0x00, sizeof((*ctx)->buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) {
|
||||
int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) {
|
||||
int nerrors;
|
||||
|
||||
argtable = vargtable;
|
||||
argtableLen = vargtableLen;
|
||||
ctx->argtable = vargtable;
|
||||
ctx->argtableLen = vargtableLen;
|
||||
|
||||
/* verify the argtable[] entries were allocated sucessfully */
|
||||
if (arg_nullcheck(argtable) != 0) {
|
||||
if (arg_nullcheck(ctx->argtable) != 0) {
|
||||
/* NULL entries were detected, some allocations must have failed */
|
||||
printf("ERROR: Insufficient memory\n");
|
||||
fflush(stdout);
|
||||
return 2;
|
||||
}
|
||||
/* Parse the command line as defined by argtable[] */
|
||||
nerrors = arg_parse(argc, argv, argtable);
|
||||
nerrors = arg_parse(argc, argv, ctx->argtable);
|
||||
|
||||
/* special case: '--help' takes precedence over error reporting */
|
||||
if ((argc < 2 && !allowEmptyExec) || ((struct arg_lit *)argtable[0])->count > 0) { // help must be the first record
|
||||
printf("Usage: %s", programName);
|
||||
arg_print_syntaxv(stdout, argtable, "\n");
|
||||
if (programHint)
|
||||
printf("%s\n\n", programHint);
|
||||
arg_print_glossary(stdout, argtable, " %-20s %s\n");
|
||||
if ((argc < 2 && !allowEmptyExec) || ((struct arg_lit *)(ctx->argtable)[0])->count > 0) { // help must be the first record
|
||||
printf("Usage: %s", ctx->programName);
|
||||
arg_print_syntaxv(stdout, ctx->argtable, "\n");
|
||||
if (ctx->programHint)
|
||||
printf("%s\n\n", ctx->programHint);
|
||||
arg_print_glossary(stdout, ctx->argtable, " %-20s %s\n");
|
||||
printf("\n");
|
||||
if (programHelp)
|
||||
printf("%s \n", programHelp);
|
||||
if (ctx->programHelp)
|
||||
printf("%s \n", ctx->programHelp);
|
||||
|
||||
fflush(stdout);
|
||||
return 1;
|
||||
|
@ -62,8 +62,8 @@ int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtable
|
|||
/* If the parser returned any errors then display them and exit */
|
||||
if (nerrors > 0) {
|
||||
/* Display the error details contained in the arg_end struct.*/
|
||||
arg_print_errors(stdout, ((struct arg_end *)argtable[vargtableLen - 1]), programName);
|
||||
printf("Try '%s --help' for more information.\n", programName);
|
||||
arg_print_errors(stdout, ((struct arg_end *)(ctx->argtable)[vargtableLen - 1]), ctx->programName);
|
||||
printf("Try '%s --help' for more information.\n", ctx->programName);
|
||||
fflush(stdout);
|
||||
return 3;
|
||||
}
|
||||
|
@ -79,23 +79,25 @@ enum ParserState {
|
|||
|
||||
#define isSpace(c)(c == ' ' || c == '\t')
|
||||
|
||||
int CLIParserParseString(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) {
|
||||
return CLIParserParseStringEx(str, vargtable, vargtableLen, allowEmptyExec, false);
|
||||
int CLIParserParseString(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) {
|
||||
return CLIParserParseStringEx(ctx, str, vargtable, vargtableLen, allowEmptyExec, false);
|
||||
}
|
||||
|
||||
int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) {
|
||||
int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) {
|
||||
int argc = 0;
|
||||
char *argv[200] = {NULL};
|
||||
|
||||
int len = strlen(str);
|
||||
char buf[500] = {0};
|
||||
memset(ctx->buf, 0x00, 500);
|
||||
char *bufptr = buf;
|
||||
char *spaceptr = NULL;
|
||||
enum ParserState state = PS_FIRST;
|
||||
|
||||
argv[argc++] = bufptr;
|
||||
// param0 = program name
|
||||
memcpy(buf, programName, strlen(programName) + 1); // with 0x00
|
||||
bufptr += strlen(programName) + 1;
|
||||
memcpy(buf, ctx->programName, strlen(ctx->programName) + 1); // with 0x00
|
||||
bufptr += strlen(ctx->programName) + 1;
|
||||
if (len)
|
||||
argv[argc++] = bufptr;
|
||||
|
||||
|
@ -140,13 +142,12 @@ int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableL
|
|||
}
|
||||
}
|
||||
|
||||
return CLIParserParseArg(argc, argv, vargtable, vargtableLen, allowEmptyExec);
|
||||
return CLIParserParseArg(ctx, argc, argv, vargtable, vargtableLen, allowEmptyExec);
|
||||
}
|
||||
|
||||
void CLIParserFree(void) {
|
||||
arg_freetable(argtable, argtableLen);
|
||||
argtable = NULL;
|
||||
|
||||
void CLIParserFree(CLIParserContext *ctx) {
|
||||
arg_freetable(ctx->argtable, ctx->argtableLen);
|
||||
free(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,16 +27,24 @@
|
|||
#define arg_strx1(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 1, 250, (glossary)))
|
||||
#define arg_strx0(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 0, 250, (glossary)))
|
||||
|
||||
#define CLIExecWithReturn(cmd, atbl, ifempty) if (CLIParserParseString(cmd, atbl, arg_getsize(atbl), ifempty)){CLIParserFree();return PM3_ESOFT;}
|
||||
#define CLIGetHexBLessWithReturn(paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree();return PM3_ESOFT;}
|
||||
#define CLIGetHexWithReturn(paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return PM3_ESOFT;}
|
||||
#define CLIGetStrWithReturn(paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return PM3_ESOFT;}
|
||||
#define CLIExecWithReturn(ctx, cmd, atbl, ifempty) if (CLIParserParseString(ctx, cmd, atbl, arg_getsize(atbl), ifempty)){CLIParserFree(ctx);return PM3_ESOFT;}
|
||||
#define CLIGetHexBLessWithReturn(ctx, paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree(ctx);return PM3_ESOFT;}
|
||||
#define CLIGetHexWithReturn(ctx, paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree(ctx);return PM3_ESOFT;}
|
||||
#define CLIGetStrWithReturn(ctx, paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree(ctx);return PM3_ESOFT;}
|
||||
|
||||
int CLIParserInit(const char *vprogramName, const char *vprogramHint, const char *vprogramHelp);
|
||||
int CLIParserParseString(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec);
|
||||
int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData);
|
||||
int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec);
|
||||
void CLIParserFree(void);
|
||||
typedef struct {
|
||||
void **argtable;
|
||||
size_t argtableLen;
|
||||
const char *programName;
|
||||
const char *programHint;
|
||||
const char *programHelp;
|
||||
char buf[500];
|
||||
} CLIParserContext;
|
||||
int CLIParserInit(CLIParserContext **context, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp);
|
||||
int CLIParserParseString(CLIParserContext *context, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec);
|
||||
int CLIParserParseStringEx(CLIParserContext *context, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData);
|
||||
int CLIParserParseArg(CLIParserContext *context, int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec);
|
||||
void CLIParserFree(CLIParserContext *context);
|
||||
|
||||
int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
|
||||
int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
|
||||
|
|
|
@ -2292,7 +2292,8 @@ static int CmdDataNDEF(const char *Cmd) {
|
|||
#define MAX_NDEF_LEN 2048
|
||||
#endif
|
||||
|
||||
CLIParserInit("data ndef",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "data ndef",
|
||||
"Prints NFC Data Exchange Format (NDEF)",
|
||||
"Usage:\n\tdata ndef -d 9101085402656e48656c6c6f5101085402656e576f726c64\n");
|
||||
|
||||
|
@ -2301,12 +2302,12 @@ static int CmdDataNDEF(const char *Cmd) {
|
|||
arg_strx0("dD", "data", "<hex>", "NDEF data to decode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
int datalen = 0;
|
||||
uint8_t data[MAX_NDEF_LEN] = {0};
|
||||
CLIGetHexWithReturn(1, data, &datalen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 1, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
if (datalen == 0)
|
||||
return PM3_EINVARG;
|
||||
|
||||
|
|
|
@ -254,7 +254,8 @@ int CmdHFSniff(const char *Cmd) {
|
|||
}
|
||||
|
||||
int CmdHFPlot(const char *Cmd) {
|
||||
CLIParserInit("hf plot",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf plot",
|
||||
"Plots HF signal after RF signal path and A/D conversion.",
|
||||
"This can be used after any hf command and will show the last few milliseconds of the HF signal.\n"
|
||||
"Note: If the last hf command terminated because of a timeout you will most probably see nothing.\n");
|
||||
|
@ -262,7 +263,8 @@ int CmdHFPlot(const char *Cmd) {
|
|||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
uint8_t buf[FPGA_TRACE_SIZE];
|
||||
|
||||
|
|
|
@ -364,7 +364,8 @@ static int CmdHF14AInfo(const char *Cmd) {
|
|||
bool do_nack_test = false;
|
||||
bool do_aid_search = false;
|
||||
|
||||
CLIParserInit("hf 14a info",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf 14a info",
|
||||
"This command makes more extensive tests against a ISO14443a tag in order to collect information",
|
||||
"Sample:\n\thf 14a info -nsv - shows full information about the card\n");
|
||||
|
||||
|
@ -375,13 +376,13 @@ static int CmdHF14AInfo(const char *Cmd) {
|
|||
arg_lit0("sS", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
verbose = arg_get_lit(1);
|
||||
do_nack_test = arg_get_lit(2);
|
||||
do_aid_search = arg_get_lit(3);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
infoHF14A(verbose, do_nack_test, do_aid_search);
|
||||
return 0;
|
||||
|
@ -878,7 +879,8 @@ static int CmdHF14AAPDU(const char *Cmd) {
|
|||
bool extendedAPDU = false;
|
||||
int le = 0;
|
||||
|
||||
CLIParserInit("hf 14a apdu",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf 14a apdu",
|
||||
"Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013",
|
||||
"Sample:\n\thf 14a apdu -st 00A404000E325041592E5359532E444446303100\n"
|
||||
"\thf 14a apdu -sd 00A404000E325041592E5359532E444446303100 - decode apdu\n"
|
||||
|
@ -897,14 +899,14 @@ static int CmdHF14AAPDU(const char *Cmd) {
|
|||
arg_strx1(NULL, NULL, "<APDU (hex) | data (hex)>", "data if `m` parameter included"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
activateField = arg_get_lit(1);
|
||||
leaveSignalON = arg_get_lit(2);
|
||||
decodeTLV = arg_get_lit(3);
|
||||
decodeAPDU = arg_get_lit(4);
|
||||
|
||||
CLIGetHexWithReturn(5, header, &headerlen);
|
||||
CLIGetHexWithReturn(ctx, 5, header, &headerlen);
|
||||
makeAPDU = headerlen > 0;
|
||||
if (makeAPDU && headerlen != 4) {
|
||||
PrintAndLogEx(ERR, "header length must be 4 bytes instead of %d", headerlen);
|
||||
|
@ -917,7 +919,7 @@ static int CmdHF14AAPDU(const char *Cmd) {
|
|||
uint8_t apdudata[PM3_CMD_DATA_SIZE] = {0};
|
||||
int apdudatalen = 0;
|
||||
|
||||
CLIGetHexBLessWithReturn(8, apdudata, &apdudatalen, 1 + 2);
|
||||
CLIGetHexBLessWithReturn(ctx, 8, apdudata, &apdudatalen, 1 + 2);
|
||||
|
||||
APDUStruct apdu;
|
||||
apdu.cla = header[0];
|
||||
|
@ -947,10 +949,10 @@ static int CmdHF14AAPDU(const char *Cmd) {
|
|||
}
|
||||
|
||||
// len = data + PCB(1b) + CRC(2b)
|
||||
CLIGetHexBLessWithReturn(8, data, &datalen, 1 + 2);
|
||||
CLIGetHexBLessWithReturn(ctx, 8, data, &datalen, 1 + 2);
|
||||
}
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
PrintAndLogEx(NORMAL, ">>>>[%s%s%s] %s", activateField ? "sel " : "", leaveSignalON ? "keep " : "", decodeTLV ? "TLV" : "", sprint_hex(data, datalen));
|
||||
|
||||
if (decodeAPDU) {
|
||||
|
@ -1162,7 +1164,8 @@ static int waitCmd(uint8_t iSelect) {
|
|||
|
||||
static int CmdHF14AAntiFuzz(const char *Cmd) {
|
||||
|
||||
CLIParserInit("hf 14a antifuzz",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf 14a antifuzz",
|
||||
"Tries to fuzz the ISO14443a anticollision phase",
|
||||
"Usage:\n"
|
||||
"\thf 14a antifuzz -4\n");
|
||||
|
@ -1174,7 +1177,7 @@ static int CmdHF14AAntiFuzz(const char *Cmd) {
|
|||
arg_lit0(NULL, "10", "10 byte uid"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t arg0 = FLAG_4B_UID_IN_DATA;
|
||||
if (arg_get_lit(2))
|
||||
|
@ -1182,7 +1185,7 @@ static int CmdHF14AAntiFuzz(const char *Cmd) {
|
|||
if (arg_get_lit(3))
|
||||
arg0 = FLAG_10B_UID_IN_DATA;
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ISO14443A_ANTIFUZZ, arg0, 0, 0, NULL, 0);
|
||||
return 0;
|
||||
|
@ -1190,7 +1193,8 @@ static int CmdHF14AAntiFuzz(const char *Cmd) {
|
|||
|
||||
static int CmdHF14AChaining(const char *Cmd) {
|
||||
|
||||
CLIParserInit("hf 14a chaining",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf 14a chaining",
|
||||
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
|
||||
"Usage:\n"
|
||||
"\thf 14a chaining disable -> disable chaining\n"
|
||||
|
@ -1201,7 +1205,7 @@ static int CmdHF14AChaining(const char *Cmd) {
|
|||
arg_str0(NULL, NULL, "<enable/disable or 0/1>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
struct arg_str *str = arg_get_str(1);
|
||||
int len = arg_get_str_len(1);
|
||||
|
@ -1212,7 +1216,7 @@ static int CmdHF14AChaining(const char *Cmd) {
|
|||
if (len && (!strcmp(str->sval[0], "disable") || !strcmp(str->sval[0], "0")))
|
||||
APDUInFramingEnable = false;
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", APDUInFramingEnable ? "enabled" : "disabled");
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ static int CmdHFFidoInfo(const char *cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static json_t *OpenJson(int paramnum, char *fname, void *argtable[], bool *err) {
|
||||
static json_t *OpenJson(CLIParserContext *ctx, int paramnum, char *fname, void *argtable[], bool *err) {
|
||||
json_t *root = NULL;
|
||||
json_error_t error;
|
||||
*err = false;
|
||||
|
@ -119,9 +119,9 @@ static json_t *OpenJson(int paramnum, char *fname, void *argtable[], bool *err)
|
|||
char *cjsonname = (char *)jsonname;
|
||||
int jsonnamelen = 0;
|
||||
|
||||
// CLIGetStrWithReturn(paramnum, jsonname, &jsonnamelen);
|
||||
// CLIGetStrWithReturn(ctx, paramnum, jsonname, &jsonnamelen);
|
||||
if (CLIParamStrToBuf(arg_get_str(paramnum), jsonname, sizeof(jsonname), &jsonnamelen)) {
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,8 @@ static int CmdHFFidoRegister(const char *cmd) {
|
|||
uint8_t adata[250] = {0};
|
||||
json_t *root = NULL;
|
||||
|
||||
CLIParserInit("hf fido reg",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf fido reg",
|
||||
"Initiate a U2F token registration. Needs two 32-byte hash numbers. \nchallenge parameter (32b) and application parameter (32b).",
|
||||
"Usage:\n\thf fido reg -> execute command with 2 parameters, filled 0x00\n"
|
||||
"\thf fido reg 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters"
|
||||
|
@ -179,7 +180,7 @@ static int CmdHFFidoRegister(const char *cmd) {
|
|||
arg_str0(NULL, NULL, "<HEX/ASCII application parameter (32b HEX/1..16 chars)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||
|
||||
bool APDULogging = arg_get_lit(1);
|
||||
bool verbose = arg_get_lit(2);
|
||||
|
@ -189,7 +190,7 @@ static int CmdHFFidoRegister(const char *cmd) {
|
|||
|
||||
char fname[250] = {0};
|
||||
bool err;
|
||||
root = OpenJson(5, fname, argtable, &err);
|
||||
root = OpenJson(ctx, 5, fname, argtable, &err);
|
||||
if (err)
|
||||
return 1;
|
||||
if (root) {
|
||||
|
@ -200,13 +201,13 @@ static int CmdHFFidoRegister(const char *cmd) {
|
|||
|
||||
if (paramsPlain) {
|
||||
memset(cdata, 0x00, 32);
|
||||
CLIGetStrWithReturn(6, cdata, &chlen);
|
||||
CLIGetStrWithReturn(ctx, 6, cdata, &chlen);
|
||||
if (chlen > 16) {
|
||||
PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", chlen);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
CLIGetHexWithReturn(6, cdata, &chlen);
|
||||
CLIGetHexWithReturn(ctx, 6, cdata, &chlen);
|
||||
if (chlen && chlen != 32) {
|
||||
PrintAndLogEx(ERR, "ERROR: challenge parameter length must be 32 bytes only.");
|
||||
return 1;
|
||||
|
@ -218,13 +219,13 @@ static int CmdHFFidoRegister(const char *cmd) {
|
|||
|
||||
if (paramsPlain) {
|
||||
memset(adata, 0x00, 32);
|
||||
CLIGetStrWithReturn(7, adata, &applen);
|
||||
CLIGetStrWithReturn(ctx, 7, adata, &applen);
|
||||
if (applen > 16) {
|
||||
PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", applen);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
CLIGetHexWithReturn(7, adata, &applen);
|
||||
CLIGetHexWithReturn(ctx, 7, adata, &applen);
|
||||
if (applen && applen != 32) {
|
||||
PrintAndLogEx(ERR, "ERROR: application parameter length must be 32 bytes only.");
|
||||
return 1;
|
||||
|
@ -233,7 +234,7 @@ static int CmdHFFidoRegister(const char *cmd) {
|
|||
if (applen)
|
||||
memmove(&data[32], adata, 32);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
@ -393,7 +394,8 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
|||
uint8_t keyHandleLen = 0;
|
||||
json_t *root = NULL;
|
||||
|
||||
CLIParserInit("hf fido auth",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf fido auth",
|
||||
"Initiate a U2F token authentication. Needs key handle and two 32-byte hash numbers. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).",
|
||||
"Usage:\n\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n"
|
||||
"\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f "
|
||||
|
@ -414,7 +416,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
|||
arg_str0(NULL, NULL, "<HEX/ASCII application parameter (32b HEX/1..16 chars)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||
|
||||
bool APDULogging = arg_get_lit(1);
|
||||
bool verbose = arg_get_lit(2);
|
||||
|
@ -427,7 +429,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
|||
|
||||
char fname[250] = {0};
|
||||
bool err;
|
||||
root = OpenJson(7, fname, argtable, &err);
|
||||
root = OpenJson(ctx, 7, fname, argtable, &err);
|
||||
if (err)
|
||||
return 1;
|
||||
if (root) {
|
||||
|
@ -442,7 +444,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
|||
}
|
||||
|
||||
// public key
|
||||
CLIGetHexWithReturn(8, hdata, &hdatalen);
|
||||
CLIGetHexWithReturn(ctx, 8, hdata, &hdatalen);
|
||||
if (hdatalen && hdatalen != 65) {
|
||||
PrintAndLogEx(ERR, "ERROR: public key length must be 65 bytes only.");
|
||||
return 1;
|
||||
|
@ -452,7 +454,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
|||
public_key_loaded = true;
|
||||
}
|
||||
|
||||
CLIGetHexWithReturn(9, hdata, &hdatalen);
|
||||
CLIGetHexWithReturn(ctx, 9, hdata, &hdatalen);
|
||||
if (hdatalen > 255) {
|
||||
PrintAndLogEx(ERR, "ERROR: application parameter length must be less than 255.");
|
||||
return 1;
|
||||
|
@ -465,13 +467,13 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
|||
|
||||
if (paramsPlain) {
|
||||
memset(hdata, 0x00, 32);
|
||||
CLIGetStrWithReturn(9, hdata, &hdatalen);
|
||||
CLIGetStrWithReturn(ctx, 9, hdata, &hdatalen);
|
||||
if (hdatalen > 16) {
|
||||
PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
CLIGetHexWithReturn(10, hdata, &hdatalen);
|
||||
CLIGetHexWithReturn(ctx, 10, hdata, &hdatalen);
|
||||
if (hdatalen && hdatalen != 32) {
|
||||
PrintAndLogEx(ERR, "ERROR: challenge parameter length must be 32 bytes only.");
|
||||
return 1;
|
||||
|
@ -482,13 +484,13 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
|||
|
||||
if (paramsPlain) {
|
||||
memset(hdata, 0x00, 32);
|
||||
CLIGetStrWithReturn(11, hdata, &hdatalen);
|
||||
CLIGetStrWithReturn(ctx, 11, hdata, &hdatalen);
|
||||
if (hdatalen > 16) {
|
||||
PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
CLIGetHexWithReturn(10, hdata, &hdatalen);
|
||||
CLIGetHexWithReturn(ctx, 10, hdata, &hdatalen);
|
||||
if (hdatalen && hdatalen != 32) {
|
||||
PrintAndLogEx(ERR, "ERROR: application parameter length must be 32 bytes only.");
|
||||
return 1;
|
||||
|
@ -497,7 +499,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
|||
if (hdatalen)
|
||||
memmove(&data[32], hdata, 32);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
@ -641,7 +643,8 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
|
|||
json_t *root = NULL;
|
||||
char fname[300] = {0};
|
||||
|
||||
CLIParserInit("hf fido make",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf fido make",
|
||||
"Execute a FIDO2 Make Credential command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.",
|
||||
"Usage:\n\thf fido make -> execute command with default parameters file `fido2.json`\n"
|
||||
"\thf fido make test.json -> execute command with parameters file `text.json`");
|
||||
|
@ -655,7 +658,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
|
|||
arg_str0(NULL, NULL, "<json file name>", "JSON input / output file name for parameters. Default `fido2.json`"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||
|
||||
bool APDULogging = arg_get_lit(1);
|
||||
bool verbose = arg_get_lit(2);
|
||||
|
@ -666,14 +669,14 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
|
|||
uint8_t jsonname[250] = {0};
|
||||
char *cjsonname = (char *)jsonname;
|
||||
int jsonnamelen = 0;
|
||||
CLIGetStrWithReturn(5, jsonname, &jsonnamelen);
|
||||
CLIGetStrWithReturn(ctx, 5, jsonname, &jsonnamelen);
|
||||
|
||||
if (!jsonnamelen) {
|
||||
strcat(cjsonname, "fido2");
|
||||
jsonnamelen = strlen(cjsonname);
|
||||
}
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
@ -767,7 +770,8 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
|
|||
json_t *root = NULL;
|
||||
char fname[300] = {0};
|
||||
|
||||
CLIParserInit("hf fido assert",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf fido assert",
|
||||
"Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.",
|
||||
"Usage:\n\thf fido assert -> execute command with default parameters file `fido2.json`\n"
|
||||
"\thf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId");
|
||||
|
@ -781,7 +785,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
|
|||
arg_str0(NULL, NULL, "<json file name>", "JSON input / output file name for parameters. Default `fido2.json`"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||
|
||||
bool APDULogging = arg_get_lit(1);
|
||||
bool verbose = arg_get_lit(2);
|
||||
|
@ -792,14 +796,14 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
|
|||
uint8_t jsonname[250] = {0};
|
||||
char *cjsonname = (char *)jsonname;
|
||||
int jsonnamelen = 0;
|
||||
CLIGetStrWithReturn(5, jsonname, &jsonnamelen);
|
||||
CLIGetStrWithReturn(ctx, 5, jsonname, &jsonnamelen);
|
||||
|
||||
if (!jsonnamelen) {
|
||||
strcat(cjsonname, "fido2");
|
||||
jsonnamelen = strlen(cjsonname);
|
||||
}
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
|
|
@ -4025,7 +4025,8 @@ static int CmdHF14AMfCWipe(const char *cmd) {
|
|||
uint8_t sak[1] = {0x00};
|
||||
int sakLen = 0;
|
||||
|
||||
CLIParserInit("hf mf cwipe",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mf cwipe",
|
||||
"Wipe gen1 magic chinese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.",
|
||||
"Usage:\n\thf mf cwipe -> wipe card.\n"
|
||||
"\thf mf cwipe -u 09080706 -a 0004 -s 18 -- set UID, ATQA and SAK and wipe card.");
|
||||
|
@ -4037,12 +4038,12 @@ static int CmdHF14AMfCWipe(const char *cmd) {
|
|||
arg_str0("sS", "sak", "<SAK (hex 1b)>", "SAK for card"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||
|
||||
CLIGetHexWithReturn(1, uid, &uidLen);
|
||||
CLIGetHexWithReturn(2, atqa, &atqaLen);
|
||||
CLIGetHexWithReturn(3, sak, &sakLen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 1, uid, &uidLen);
|
||||
CLIGetHexWithReturn(ctx, 2, atqa, &atqaLen);
|
||||
CLIGetHexWithReturn(ctx, 3, sak, &sakLen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (uidLen && uidLen != 4) {
|
||||
PrintAndLogEx(ERR, "UID length must be 4 bytes instead of: %d", uidLen);
|
||||
|
@ -4611,7 +4612,8 @@ static int CmdHF14AMfAuth4(const char *Cmd) {
|
|||
uint8_t key[16] = {0};
|
||||
int keylen = 0;
|
||||
|
||||
CLIParserInit("hf mf auth4",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mf auth4",
|
||||
"Executes AES authentication command in ISO14443-4",
|
||||
"Usage:\n\thf mf auth4 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n"
|
||||
"\thf mf auth4 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication\n");
|
||||
|
@ -4622,11 +4624,11 @@ static int CmdHF14AMfAuth4(const char *Cmd) {
|
|||
arg_str1(NULL, NULL, "<Key Value (HEX 16 bytes)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
CLIGetHexWithReturn(1, keyn, &keynlen);
|
||||
CLIGetHexWithReturn(2, key, &keylen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 1, keyn, &keynlen);
|
||||
CLIGetHexWithReturn(ctx, 2, key, &keylen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (keynlen != 2) {
|
||||
PrintAndLogEx(ERR, "<Key Num> must be 2 bytes long instead of: %d", keynlen);
|
||||
|
@ -4644,7 +4646,8 @@ static int CmdHF14AMfAuth4(const char *Cmd) {
|
|||
// https://www.nxp.com/docs/en/application-note/AN10787.pdf
|
||||
static int CmdHF14AMfMAD(const char *Cmd) {
|
||||
|
||||
CLIParserInit("hf mf mad",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mf mad",
|
||||
"Checks and prints Mifare Application Directory (MAD)",
|
||||
"Usage:\n\thf mf mad -> shows MAD if exists\n"
|
||||
"\thf mf mad -a 03e1 -k ffffffffffff -b -> shows NDEF data if exists. read card with custom key and key B\n");
|
||||
|
@ -4657,17 +4660,17 @@ static int CmdHF14AMfMAD(const char *Cmd) {
|
|||
arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool verbose = arg_get_lit(1);
|
||||
uint8_t aid[2] = {0};
|
||||
int aidlen;
|
||||
CLIGetHexWithReturn(2, aid, &aidlen);
|
||||
CLIGetHexWithReturn(ctx, 2, aid, &aidlen);
|
||||
uint8_t key[6] = {0};
|
||||
int keylen;
|
||||
CLIGetHexWithReturn(3, key, &keylen);
|
||||
CLIGetHexWithReturn(ctx, 3, key, &keylen);
|
||||
bool keyB = arg_get_lit(4);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (aidlen != 2 && keylen > 0) {
|
||||
PrintAndLogEx(WARNING, "do not need a key without aid.");
|
||||
|
@ -4734,7 +4737,8 @@ static int CmdHF14AMfMAD(const char *Cmd) {
|
|||
|
||||
static int CmdHFMFNDEF(const char *Cmd) {
|
||||
|
||||
CLIParserInit("hf mf ndef",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mf ndef",
|
||||
"Prints NFC Data Exchange Format (NDEF)",
|
||||
"Usage:\n\thf mf ndef -> shows NDEF data\n"
|
||||
"\thf mf ndef -a 03e1 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B\n");
|
||||
|
@ -4747,19 +4751,19 @@ static int CmdHFMFNDEF(const char *Cmd) {
|
|||
arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool verbose = arg_get_lit(1);
|
||||
bool verbose2 = arg_get_lit(1) > 1;
|
||||
uint8_t aid[2] = {0};
|
||||
int aidlen;
|
||||
CLIGetHexWithReturn(2, aid, &aidlen);
|
||||
CLIGetHexWithReturn(ctx, 2, aid, &aidlen);
|
||||
uint8_t key[6] = {0};
|
||||
int keylen;
|
||||
CLIGetHexWithReturn(3, key, &keylen);
|
||||
CLIGetHexWithReturn(ctx, 3, key, &keylen);
|
||||
bool keyB = arg_get_lit(4);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
uint16_t ndefAID = 0x03e1;
|
||||
if (aidlen == 2)
|
||||
|
@ -4838,7 +4842,8 @@ static int CmdHFMFNDEF(const char *Cmd) {
|
|||
|
||||
static int CmdHFMFPersonalize(const char *cmd) {
|
||||
|
||||
CLIParserInit("hf mf personalize",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mf personalize",
|
||||
"Personalize the UID of a Mifare Classic EV1 card. This is only possible if it is a 7Byte UID card and if it is not already personalized.",
|
||||
"Usage:\n\thf mf personalize UIDF0 -> double size UID according to ISO/IEC14443-3\n"
|
||||
"\thf mf personalize UIDF1 -> double size UID according to ISO/IEC14443-3, optional usage of selection process shortcut\n"
|
||||
|
@ -4853,7 +4858,7 @@ static int CmdHFMFPersonalize(const char *cmd) {
|
|||
arg_str1(NULL, NULL, "<UIDF0|UIDF1|UIDF2|UIDF3>", "Personalization Option"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||
|
||||
char keytypestr[2] = "a";
|
||||
uint8_t keytype = 0x00;
|
||||
|
@ -4863,7 +4868,7 @@ static int CmdHFMFPersonalize(const char *cmd) {
|
|||
|
||||
if (res || (keytypestr[0] != 'a' && keytypestr[0] != 'b')) {
|
||||
PrintAndLogEx(ERR, "ERROR: not a valid key type. Key type must be A or B");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (keytypestr[0] == 'b') {
|
||||
|
@ -4875,7 +4880,7 @@ static int CmdHFMFPersonalize(const char *cmd) {
|
|||
res = CLIParamHexToBuf(arg_get_str(2), key, 6, &key_len);
|
||||
if (res || (!res && key_len > 0 && key_len != 6)) {
|
||||
PrintAndLogEx(ERR, "ERROR: not a valid key. Key must be 12 hex digits");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
|
@ -4888,7 +4893,7 @@ static int CmdHFMFPersonalize(const char *cmd) {
|
|||
if (res || (!res && opt_len > 0 && opt_len != 5)
|
||||
|| (strncmp(pers_optionstr, "uidf0", 5) && strncmp(pers_optionstr, "uidf1", 5) && strncmp(pers_optionstr, "uidf2", 5) && strncmp(pers_optionstr, "uidf3", 5))) {
|
||||
PrintAndLogEx(ERR, "ERROR: invalid personalization option. Must be one of UIDF0, UIDF1, UIDF2, or UIDF3");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (!strncmp(pers_optionstr, "uidf0", 5)) {
|
||||
|
@ -4901,7 +4906,7 @@ static int CmdHFMFPersonalize(const char *cmd) {
|
|||
pers_option = MIFARE_EV1_UIDF3;
|
||||
}
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
clearCommandBuffer();
|
||||
|
||||
|
|
|
@ -1782,7 +1782,8 @@ static void swap16(uint8_t *data) {
|
|||
|
||||
|
||||
static int CmdHF14ADesCreateApp(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes createaid",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes createaid",
|
||||
"Create Application ID",
|
||||
"Usage:\n\thf mfdes createaid -a 123456 -f 1111 -k 0E -l 2E -n Test\n"
|
||||
);
|
||||
|
@ -1796,7 +1797,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) {
|
|||
arg_str0("nN", "name", "<name>", "App ISO-4 Name (optional)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
/* KeySetting 1 (AMK Setting):
|
||||
0: Allow change master key
|
||||
1: Free Directory list access without master key
|
||||
|
@ -1835,12 +1836,12 @@ static int CmdHF14ADesCreateApp(const char *Cmd) {
|
|||
int keylen1 = 1;
|
||||
int keylen2 = 1;
|
||||
int namelen = 16;
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(2, fid, &fidlength);
|
||||
CLIGetHexWithReturn(3, keysetting1, &keylen1);
|
||||
CLIGetHexWithReturn(4, keysetting2, &keylen2);
|
||||
CLIGetStrWithReturn(5, name, &namelen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 2, fid, &fidlength);
|
||||
CLIGetHexWithReturn(ctx, 3, keysetting1, &keylen1);
|
||||
CLIGetHexWithReturn(ctx, 4, keysetting2, &keylen2);
|
||||
CLIGetStrWithReturn(ctx, 5, name, &namelen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
swap24(aid);
|
||||
swap16(fid);
|
||||
|
@ -1908,7 +1909,8 @@ static int CmdHF14ADesCreateApp(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdHF14ADesDeleteApp(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes deleteaid",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes deleteaid",
|
||||
"Delete Application ID",
|
||||
"Usage:\n\t-a aid (3 hex bytes, big endian)\n\n"
|
||||
"Example:\n\thf mfdes deleteaid -a 123456\n"
|
||||
|
@ -1919,11 +1921,11 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) {
|
|||
arg_strx0("aA", "aid", "<aid>", "App ID to delete"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
int aidlength = 3;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
CLIParserFree(ctx);
|
||||
swap24(aid);
|
||||
if (aidlength != 3) {
|
||||
PrintAndLogEx(ERR, "AID must have 3 bytes length.");
|
||||
|
@ -1945,7 +1947,8 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) {
|
|||
|
||||
|
||||
static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes clearrecord",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes clearrecord",
|
||||
"Clear record file",
|
||||
"Usage:\n\t"
|
||||
"hf mfdes clearrecord -a 123456 -n 01\n"
|
||||
|
@ -1957,19 +1960,19 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
|||
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
|
||||
int filenolen = 0;
|
||||
uint8_t _fileno[1] = {0};
|
||||
CLIGetHexWithReturn(2, _fileno, &filenolen);
|
||||
CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen);
|
||||
|
||||
int fidlength = 0;
|
||||
uint8_t fid[2] = {0};
|
||||
CLIGetHexWithReturn(3, fid, &fidlength);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 3, fid, &fidlength);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (filenolen != 1) {
|
||||
PrintAndLogEx(ERR, "Fileno must have 1 bytes length.");
|
||||
|
@ -2005,7 +2008,8 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdHF14ADesDeleteFile(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes deletefile",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes deletefile",
|
||||
"Delete File",
|
||||
"Usage:\n\t"
|
||||
"hf mfdes deletefile -a 123456 -n 01\n"
|
||||
|
@ -2017,19 +2021,19 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) {
|
|||
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
|
||||
int filenolen = 0;
|
||||
uint8_t _fileno[1] = {0};
|
||||
CLIGetHexWithReturn(2, _fileno, &filenolen);
|
||||
CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen);
|
||||
|
||||
int fidlength = 0;
|
||||
uint8_t fid[2] = {0};
|
||||
CLIGetHexWithReturn(3, fid, &fidlength);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 3, fid, &fidlength);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (filenolen != 1) {
|
||||
PrintAndLogEx(ERR, "Fileno must have 1 bytes length.");
|
||||
|
@ -2065,7 +2069,8 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdHF14ADesCreateFile(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes createfile",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes createfile",
|
||||
"Create Standard/Backup File",
|
||||
"Usage:"
|
||||
"\n\thf mfdes createfile -a 123456 -f 1111 -n 01 -c 0 -r EEEE -s 000100\n"
|
||||
|
@ -2082,30 +2087,30 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
|
|||
arg_lit0("bB", "backup", "Create backupfile instead of standard file"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
|
||||
int filenolen = 0;
|
||||
uint8_t _fileno[1] = {0};
|
||||
CLIGetHexWithReturn(2, _fileno, &filenolen);
|
||||
CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen);
|
||||
|
||||
int fidlength = 0;
|
||||
uint8_t fid[2] = {0};
|
||||
CLIGetHexWithReturn(3, fid, &fidlength);
|
||||
CLIGetHexWithReturn(ctx, 3, fid, &fidlength);
|
||||
|
||||
uint8_t comset = arg_get_int(4);
|
||||
int arlength = 0;
|
||||
uint8_t ar[2] = {0};
|
||||
CLIGetHexWithReturn(5, ar, &arlength);
|
||||
CLIGetHexWithReturn(ctx, 5, ar, &arlength);
|
||||
|
||||
int fsizelen = 0;
|
||||
uint8_t filesize[3] = {0};
|
||||
CLIGetHexWithReturn(6, filesize, &fsizelen);
|
||||
CLIGetHexWithReturn(ctx, 6, filesize, &fsizelen);
|
||||
|
||||
bool isbackup = arg_get_lit(7);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
swap24(aid);
|
||||
swap16(fid);
|
||||
|
@ -2175,7 +2180,8 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdHF14ADesGetValueData(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes getvalue",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes getvalue",
|
||||
"Get value from value file",
|
||||
"Usage:"
|
||||
"\n\thf mfdes getvalue -a 123456 -n 03\n"
|
||||
|
@ -2187,16 +2193,16 @@ static int CmdHF14ADesGetValueData(const char *Cmd) {
|
|||
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
|
||||
int filenolen = 0;
|
||||
uint8_t _fileno[1] = {0};
|
||||
CLIGetHexWithReturn(2, _fileno, &filenolen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (filenolen != 1) {
|
||||
PrintAndLogEx(ERR, "File number is missing");
|
||||
|
@ -2242,7 +2248,8 @@ static int CmdHF14ADesGetValueData(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdHF14ADesReadData(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes readdata",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes readdata",
|
||||
"Read data from File",
|
||||
"Usage:"
|
||||
"\n\thf mfdes readdata -a 123456 -n 01 -t 0 -o 000000 -l 000000\n"
|
||||
|
@ -2257,25 +2264,25 @@ static int CmdHF14ADesReadData(const char *Cmd) {
|
|||
arg_int0("type", "type", "<type>", "File Type (0=Standard/Backup, 1=Record)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
|
||||
int filenolen = 0;
|
||||
uint8_t _fileno[1] = {0};
|
||||
CLIGetHexWithReturn(2, _fileno, &filenolen);
|
||||
CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen);
|
||||
|
||||
int offsetlength = 0;
|
||||
uint8_t offset[3] = {0};
|
||||
CLIGetHexWithReturn(3, offset, &offsetlength);
|
||||
CLIGetHexWithReturn(ctx, 3, offset, &offsetlength);
|
||||
|
||||
int flength = 0;
|
||||
uint8_t filesize[3] = {0};
|
||||
CLIGetHexWithReturn(4, filesize, &flength);
|
||||
CLIGetHexWithReturn(ctx, 4, filesize, &flength);
|
||||
|
||||
int type = arg_get_int(5);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (type > 1) {
|
||||
PrintAndLogEx(ERR, "Invalid file type (0=Standard/Backup, 1=Record)");
|
||||
|
@ -2347,7 +2354,8 @@ static int CmdHF14ADesReadData(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdHF14ADesChangeValue(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes changevalue",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes changevalue",
|
||||
"Change value (credit/limitedcredit/debit)",
|
||||
"Usage:"
|
||||
"\n\thf mfdes changevalue -a 123456 -n 03 -m 0 -d 00000001\n"
|
||||
|
@ -2363,22 +2371,22 @@ static int CmdHF14ADesChangeValue(const char *Cmd) {
|
|||
};
|
||||
|
||||
mfdes_value_t value;
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
|
||||
int filenolen = 0;
|
||||
uint8_t _fileno[1] = {0};
|
||||
CLIGetHexWithReturn(2, _fileno, &filenolen);
|
||||
CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen);
|
||||
value.fileno = _fileno[0];
|
||||
|
||||
int vlength = 0x0;
|
||||
CLIGetHexWithReturn(3, value.value, &vlength);
|
||||
CLIGetHexWithReturn(ctx, 3, value.value, &vlength);
|
||||
|
||||
int mode = arg_get_int(4);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
swap24(aid);
|
||||
|
||||
if (mode > 2) {
|
||||
|
@ -2439,7 +2447,8 @@ static int CmdHF14ADesChangeValue(const char *Cmd) {
|
|||
|
||||
static int CmdHF14ADesWriteData(const char *Cmd) {
|
||||
|
||||
CLIParserInit("hf mfdes writedata",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes writedata",
|
||||
"Write data to File",
|
||||
"Usage:"
|
||||
"\n\thf mfdes writedata -a 123456 -n 01 -t 0 -o 000000 -d 3132333435363738\n"
|
||||
|
@ -2455,19 +2464,19 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
|
|||
arg_param_end
|
||||
};
|
||||
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
|
||||
int filenolen = 0;
|
||||
uint8_t _fileno[1] = {0};
|
||||
CLIGetHexWithReturn(2, _fileno, &filenolen);
|
||||
CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen);
|
||||
|
||||
int offsetlength = 0;
|
||||
uint8_t offset[3] = {0};
|
||||
CLIGetHexWithReturn(3, offset, &offsetlength);
|
||||
CLIGetHexWithReturn(ctx, 3, offset, &offsetlength);
|
||||
|
||||
int dlength = 0xFFFF;
|
||||
uint8_t *data = (uint8_t *)calloc(dlength, sizeof(uint8_t));
|
||||
|
@ -2477,13 +2486,13 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
|
|||
}
|
||||
if (CLIParamHexToBuf(arg_get_str(4), data, dlength, &dlength)) {
|
||||
free(data);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
int type = arg_get_int(5);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
swap24(aid);
|
||||
swap24(offset);
|
||||
|
@ -2555,7 +2564,8 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
|
|||
|
||||
|
||||
static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes createrecordfile",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes createrecordfile",
|
||||
"Create Linear/Cyclic Record File",
|
||||
"Usage:"
|
||||
"\n\thf mfdes createrecordfile -a 123456 -f 1122 -n 02 -c 0 -r EEEE -s 000010 -m 000005\n"
|
||||
|
@ -2573,34 +2583,34 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
|
|||
arg_lit0("bB", "cyclic", "Create cyclic record file instead of linear record file"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
|
||||
int filenolen = 0;
|
||||
uint8_t _fileno[1] = {0};
|
||||
CLIGetHexWithReturn(2, _fileno, &filenolen);
|
||||
CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen);
|
||||
|
||||
int fidlength = 0;
|
||||
uint8_t fid[2] = {0};
|
||||
CLIGetHexWithReturn(3, fid, &fidlength);
|
||||
CLIGetHexWithReturn(ctx, 3, fid, &fidlength);
|
||||
|
||||
uint8_t comset = arg_get_int(4);
|
||||
int arlength = 0;
|
||||
uint8_t ar[2] = {0};
|
||||
CLIGetHexWithReturn(5, ar, &arlength);
|
||||
CLIGetHexWithReturn(ctx, 5, ar, &arlength);
|
||||
|
||||
int rsizelen = 0;
|
||||
uint8_t recordsize[3] = {0};
|
||||
CLIGetHexWithReturn(6, recordsize, &rsizelen);
|
||||
CLIGetHexWithReturn(ctx, 6, recordsize, &rsizelen);
|
||||
|
||||
int msizelen = 0;
|
||||
uint8_t maxnumrecords[3] = {0};
|
||||
CLIGetHexWithReturn(7, maxnumrecords, &msizelen);
|
||||
CLIGetHexWithReturn(ctx, 7, maxnumrecords, &msizelen);
|
||||
|
||||
bool cyclic = arg_get_lit(8);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
swap24(aid);
|
||||
swap16(fid);
|
||||
|
@ -2685,7 +2695,8 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdHF14ADesCreateValueFile(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes createvaluefile",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes createvaluefile",
|
||||
"Create Value File",
|
||||
"Usage:"
|
||||
"\n\thf mfdes createvaluefile -a 123456 -n 03 -c 0 -r EEEE -l 00000000 -u 00002000 -v 00000001 -m 02\n"
|
||||
|
@ -2703,37 +2714,37 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
|
|||
arg_strx0("mM", "limitcredit", "<limitcredit>", "Limited Credit enabled (1 hex byte [Bit 0=LimitedCredit, 1=FreeValue])"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
|
||||
int filenolen = 0;
|
||||
uint8_t _fileno[1] = {0};
|
||||
CLIGetHexWithReturn(2, _fileno, &filenolen);
|
||||
CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen);
|
||||
|
||||
uint8_t comset = arg_get_int(3);
|
||||
int arlength = 0;
|
||||
uint8_t ar[2] = {0};
|
||||
CLIGetHexWithReturn(4, ar, &arlength);
|
||||
CLIGetHexWithReturn(ctx, 4, ar, &arlength);
|
||||
|
||||
int lllen = 0;
|
||||
uint8_t lowerlimit[4] = {0};
|
||||
CLIGetHexWithReturn(5, lowerlimit, &lllen);
|
||||
CLIGetHexWithReturn(ctx, 5, lowerlimit, &lllen);
|
||||
|
||||
int ullen = 0;
|
||||
uint8_t upperlimit[4] = {0};
|
||||
CLIGetHexWithReturn(6, upperlimit, &ullen);
|
||||
CLIGetHexWithReturn(ctx, 6, upperlimit, &ullen);
|
||||
|
||||
int vllen = 0;
|
||||
uint8_t value[4] = {0};
|
||||
CLIGetHexWithReturn(7, value, &vllen);
|
||||
CLIGetHexWithReturn(ctx, 7, value, &vllen);
|
||||
|
||||
int limitedlen = 0;
|
||||
uint8_t limited[1] = {0};
|
||||
CLIGetHexWithReturn(8, limited, &limitedlen);
|
||||
CLIGetHexWithReturn(ctx, 8, limited, &limitedlen);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
swap24(aid);
|
||||
swap32(lowerlimit);
|
||||
|
@ -2813,7 +2824,8 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdHF14ADesFormatPICC(const char *Cmd) {
|
||||
CLIParserInit("hf mfdes formatpicc",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes formatpicc",
|
||||
"Formats MIFARE DESFire PICC to factory state",
|
||||
"Usage:\n\t-k PICC key (8 bytes)\n\n"
|
||||
"Example:\n\thf mfdes formatpicc -k 0000000000000000\n"
|
||||
|
@ -2824,12 +2836,12 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) {
|
|||
arg_str0("kK", "key", "<Key>", "Key for checking (HEX 16 bytes)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t key[8] = {0};
|
||||
int keylen = 8;
|
||||
CLIGetHexWithReturn(1, key, &keylen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 1, key, &keylen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if ((keylen < 8) || (keylen > 8)) {
|
||||
PrintAndLogEx(ERR, "Specified key must have 8 bytes length");
|
||||
|
@ -3419,7 +3431,8 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
|||
uint8_t keylength = 8;
|
||||
bool usedefaultkey = false;
|
||||
|
||||
CLIParserInit("hf mfdes auth",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes auth",
|
||||
"Authenticates Mifare DESFire using Key",
|
||||
"Usage:"
|
||||
"\n\thf mfdes auth -m 3 -t 4 -a 808301 -n 0 -k 00000000000000000000000000000000 (AES)"
|
||||
|
@ -3436,21 +3449,21 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
|||
arg_str0("kK", "key", "<Key>", "Key for checking (HEX 8-24 bytes)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t cmdAuthMode = arg_get_int_def(1, 0);
|
||||
uint8_t cmdAuthAlgo = arg_get_int_def(2, 0);
|
||||
|
||||
int aidlength = 3;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(3, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 3, aid, &aidlength);
|
||||
swap24(aid);
|
||||
uint8_t cmdKeyNo = arg_get_int_def(4, 0);
|
||||
|
||||
uint8_t key[24] = {0};
|
||||
int keylen = 0;
|
||||
CLIGetHexWithReturn(5, key, &keylen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 5, key, &keylen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (keylen == 0) {
|
||||
usedefaultkey = true;
|
||||
|
@ -3860,7 +3873,8 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
uint32_t k3kkeyListLen = 0;
|
||||
uint8_t foundKeys[4][0xE][24 + 1] = {{{0}}};
|
||||
|
||||
CLIParserInit("hf mfdes chk",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes chk",
|
||||
"Checks keys with Mifare Desfire card.",
|
||||
"Usage:\n"
|
||||
" hf mfdes chk -a 123456 -k 000102030405060708090a0b0c0d0e0f -> check key on aid 0x123456\n"
|
||||
|
@ -3881,15 +3895,15 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
arg_lit0("vV", "verbose", "Verbose mode."),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
swap24(aid);
|
||||
uint8_t vkey[16] = {0};
|
||||
int vkeylen = 0;
|
||||
CLIGetHexWithReturn(2, vkey, &vkeylen);
|
||||
CLIGetHexWithReturn(ctx, 2, vkey, &vkeylen);
|
||||
|
||||
if (vkeylen > 0) {
|
||||
if (vkeylen == 8) {
|
||||
|
@ -3903,7 +3917,7 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
k3kkeyListLen++;
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "Specified key must have 8, 16 or 24 bytes length.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
@ -3912,7 +3926,7 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
int dict_filenamelen = 0;
|
||||
if (CLIParamStrToBuf(arg_get_str(3), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) {
|
||||
PrintAndLogEx(FAILED, "File name too long or invalid.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
|
@ -3921,26 +3935,26 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
|
||||
if (pattern1b && pattern2b) {
|
||||
PrintAndLogEx(ERR, "Pattern search mode must be 2-byte or 1-byte only.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (dict_filenamelen && (pattern1b || pattern2b)) {
|
||||
PrintAndLogEx(ERR, "Pattern search mode and dictionary mode can't be used in one command.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint32_t startPattern = 0x0000;
|
||||
uint8_t vpattern[2];
|
||||
int vpatternlen = 0;
|
||||
CLIGetHexWithReturn(6, vpattern, &vpatternlen);
|
||||
CLIGetHexWithReturn(ctx, 6, vpattern, &vpatternlen);
|
||||
if (vpatternlen > 0) {
|
||||
if (vpatternlen > 0 && vpatternlen <= 2) {
|
||||
startPattern = (vpattern[0] << 8) + vpattern[1];
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "Pattern must be 2-byte length.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (!pattern2b)
|
||||
|
@ -3951,14 +3965,14 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
int jsonnamelen = 0;
|
||||
if (CLIParamStrToBuf(arg_get_str(7), jsonname, sizeof(jsonname), &jsonnamelen)) {
|
||||
PrintAndLogEx(ERR, "Invalid json name.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
jsonname[jsonnamelen] = 0;
|
||||
|
||||
bool verbose = arg_get_lit(8);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// 1-byte pattern search mode
|
||||
if (pattern1b) {
|
||||
|
|
|
@ -424,7 +424,8 @@ static int CmdHFMFPWritePerso(const char *Cmd) {
|
|||
uint8_t key[64] = {0};
|
||||
int keyLen = 0;
|
||||
|
||||
CLIParserInit("hf mfp wrp",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp wrp",
|
||||
"Executes Write Perso command. Can be used in SL0 mode only.",
|
||||
"Usage:\n\thf mfp wrp 4000 000102030405060708090a0b0c0d0e0f -> write key (00..0f) to key number 4000 \n"
|
||||
"\thf mfp wrp 4000 -> write default key(0xff..0xff) to key number 4000");
|
||||
|
@ -436,12 +437,12 @@ static int CmdHFMFPWritePerso(const char *Cmd) {
|
|||
arg_strx0(NULL, NULL, "<HEX key (16b)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool verbose = arg_get_lit(1);
|
||||
CLIGetHexWithReturn(2, keyNum, &keyNumLen);
|
||||
CLIGetHexWithReturn(3, key, &keyLen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 2, keyNum, &keyNumLen);
|
||||
CLIGetHexWithReturn(ctx, 3, key, &keyLen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
mfpSetVerboseMode(verbose);
|
||||
|
||||
|
@ -490,7 +491,8 @@ static int CmdHFMFPInitPerso(const char *Cmd) {
|
|||
uint8_t data[250] = {0};
|
||||
int datalen = 0;
|
||||
|
||||
CLIParserInit("hf mfp initp",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp initp",
|
||||
"Executes Write Perso command for all card's keys. Can be used in SL0 mode only.",
|
||||
"Usage:\n\thf mfp initp 000102030405060708090a0b0c0d0e0f -> fill all the keys with key (00..0f)\n"
|
||||
"\thf mfp initp -vv -> fill all the keys with default key(0xff..0xff) and show all the data exchange");
|
||||
|
@ -501,12 +503,12 @@ static int CmdHFMFPInitPerso(const char *Cmd) {
|
|||
arg_strx0(NULL, NULL, "<HEX key (16b)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool verbose = arg_get_lit(1);
|
||||
bool verbose2 = arg_get_lit(1) > 1;
|
||||
CLIGetHexWithReturn(2, key, &keyLen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 2, key, &keyLen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (keyLen && keyLen != 16) {
|
||||
PrintAndLogEx(ERR, "Key length must be 16 bytes instead of: %d", keyLen);
|
||||
|
@ -557,7 +559,8 @@ static int CmdHFMFPInitPerso(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdHFMFPCommitPerso(const char *Cmd) {
|
||||
CLIParserInit("hf mfp commitp",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp commitp",
|
||||
"Executes Commit Perso command. Can be used in SL0 mode only.",
|
||||
"Usage:\n\thf mfp commitp -> \n");
|
||||
|
||||
|
@ -567,10 +570,10 @@ static int CmdHFMFPCommitPerso(const char *Cmd) {
|
|||
arg_int0(NULL, NULL, "SL mode", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool verbose = arg_get_lit(1);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
mfpSetVerboseMode(verbose);
|
||||
|
||||
|
@ -603,7 +606,8 @@ static int CmdHFMFPAuth(const char *Cmd) {
|
|||
uint8_t key[250] = {0};
|
||||
int keylen = 0;
|
||||
|
||||
CLIParserInit("hf mfp auth",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp auth",
|
||||
"Executes AES authentication command for Mifare Plus card",
|
||||
"Usage:\n\thf mfp auth 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n"
|
||||
"\thf mfp auth 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -v -> executes authentication and shows all the system data\n");
|
||||
|
@ -615,12 +619,12 @@ static int CmdHFMFPAuth(const char *Cmd) {
|
|||
arg_str1(NULL, NULL, "<Key Value (HEX 16 bytes)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool verbose = arg_get_lit(1);
|
||||
CLIGetHexWithReturn(2, keyn, &keynlen);
|
||||
CLIGetHexWithReturn(3, key, &keylen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 2, keyn, &keynlen);
|
||||
CLIGetHexWithReturn(ctx, 3, key, &keylen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (keynlen != 2) {
|
||||
PrintAndLogEx(ERR, "ERROR: <Key Num> must be 2 bytes long instead of: %d", keynlen);
|
||||
|
@ -640,7 +644,8 @@ static int CmdHFMFPRdbl(const char *Cmd) {
|
|||
uint8_t key[250] = {0};
|
||||
int keylen = 0;
|
||||
|
||||
CLIParserInit("hf mfp rdbl",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp rdbl",
|
||||
"Reads several blocks from Mifare Plus card.",
|
||||
"Usage:\n\thf mfp rdbl 0 000102030405060708090a0b0c0d0e0f -> executes authentication and read block 0 data\n"
|
||||
"\thf mfp rdbl 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF and some additional data\n");
|
||||
|
@ -655,15 +660,15 @@ static int CmdHFMFPRdbl(const char *Cmd) {
|
|||
arg_str0(NULL, NULL, "<Key Value (HEX 16 bytes)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
bool verbose = arg_get_lit(1);
|
||||
int blocksCount = arg_get_int_def(2, 1);
|
||||
bool keyB = arg_get_lit(3);
|
||||
int plain = arg_get_lit(4);
|
||||
uint32_t blockn = arg_get_int(5);
|
||||
CLIGetHexWithReturn(6, key, &keylen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 6, key, &keylen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
mfpSetVerboseMode(verbose);
|
||||
|
||||
|
@ -752,7 +757,8 @@ static int CmdHFMFPRdsc(const char *Cmd) {
|
|||
uint8_t key[250] = {0};
|
||||
int keylen = 0;
|
||||
|
||||
CLIParserInit("hf mfp rdsc",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp rdsc",
|
||||
"Reads one sector from Mifare Plus card.",
|
||||
"Usage:\n\thf mfp rdsc 0 000102030405060708090a0b0c0d0e0f -> executes authentication and read sector 0 data\n"
|
||||
"\thf mfp rdsc 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF and some additional data\n");
|
||||
|
@ -766,14 +772,14 @@ static int CmdHFMFPRdsc(const char *Cmd) {
|
|||
arg_str0(NULL, NULL, "<Key Value (HEX 16 bytes)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
bool verbose = arg_get_lit(1);
|
||||
bool keyB = arg_get_lit(2);
|
||||
bool plain = arg_get_lit(3);
|
||||
uint32_t sectorNum = arg_get_int(4);
|
||||
CLIGetHexWithReturn(5, key, &keylen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 5, key, &keylen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
mfpSetVerboseMode(verbose);
|
||||
|
||||
|
@ -850,7 +856,8 @@ static int CmdHFMFPWrbl(const char *Cmd) {
|
|||
uint8_t datain[250] = {0};
|
||||
int datainlen = 0;
|
||||
|
||||
CLIParserInit("hf mfp wrbl",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp wrbl",
|
||||
"Writes one block to Mifare Plus card.",
|
||||
"Usage:\n\thf mfp wrbl 1 ff0000000000000000000000000000ff 000102030405060708090a0b0c0d0e0f -> writes block 1 data\n"
|
||||
"\thf mfp wrbl 2 ff0000000000000000000000000000ff -v -> writes block 2 data with default key 0xFF..0xFF and some additional data\n");
|
||||
|
@ -864,14 +871,14 @@ static int CmdHFMFPWrbl(const char *Cmd) {
|
|||
arg_str0(NULL, NULL, "<Key (HEX 16 bytes)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
bool verbose = arg_get_lit(1);
|
||||
bool keyB = arg_get_lit(2);
|
||||
uint32_t blockNum = arg_get_int(3);
|
||||
CLIGetHexWithReturn(4, datain, &datainlen);
|
||||
CLIGetHexWithReturn(5, key, &keylen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 4, datain, &datainlen);
|
||||
CLIGetHexWithReturn(ctx, 5, key, &keylen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
mfpSetVerboseMode(verbose);
|
||||
|
||||
|
@ -1047,7 +1054,8 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
uint32_t keyListLen = 0;
|
||||
uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {{{0}}};
|
||||
|
||||
CLIParserInit("hf mfp chk",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp chk",
|
||||
"Checks keys with Mifare Plus card.",
|
||||
"Usage:\n"
|
||||
" hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n"
|
||||
|
@ -1071,7 +1079,7 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
arg_lit0("vV", "verbose", "verbose mode."),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool keyA = arg_get_lit(1);
|
||||
bool keyB = arg_get_lit(2);
|
||||
|
@ -1080,14 +1088,14 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
|
||||
uint8_t vkey[16] = {0};
|
||||
int vkeylen = 0;
|
||||
CLIGetHexWithReturn(5, vkey, &vkeylen);
|
||||
CLIGetHexWithReturn(ctx, 5, vkey, &vkeylen);
|
||||
if (vkeylen > 0) {
|
||||
if (vkeylen == 16) {
|
||||
memcpy(&keyList[keyListLen], vkey, 16);
|
||||
keyListLen++;
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "Specified key must have 16 bytes length.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
@ -1096,7 +1104,7 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
int dict_filenamelen = 0;
|
||||
if (CLIParamStrToBuf(arg_get_str(6), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) {
|
||||
PrintAndLogEx(FAILED, "File name too long or invalid.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
|
@ -1105,26 +1113,26 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
|
||||
if (pattern1b && pattern2b) {
|
||||
PrintAndLogEx(ERR, "Pattern search mode must be 2-byte or 1-byte only.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (dict_filenamelen && (pattern1b || pattern2b)) {
|
||||
PrintAndLogEx(ERR, "Pattern search mode and dictionary mode can't be used in one command.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint32_t startPattern = 0x0000;
|
||||
uint8_t vpattern[2];
|
||||
int vpatternlen = 0;
|
||||
CLIGetHexWithReturn(9, vpattern, &vpatternlen);
|
||||
CLIGetHexWithReturn(ctx, 9, vpattern, &vpatternlen);
|
||||
if (vpatternlen > 0) {
|
||||
if (vpatternlen > 0 && vpatternlen <= 2) {
|
||||
startPattern = (vpattern[0] << 8) + vpattern[1];
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "Pattern must be 2-byte length.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (!pattern2b)
|
||||
|
@ -1135,14 +1143,14 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
int jsonnamelen = 0;
|
||||
if (CLIParamStrToBuf(arg_get_str(10), jsonname, sizeof(jsonname), &jsonnamelen)) {
|
||||
PrintAndLogEx(ERR, "Invalid json name.");
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
jsonname[jsonnamelen] = 0;
|
||||
|
||||
bool verbose = arg_get_lit(11);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
uint8_t startKeyAB = 0;
|
||||
uint8_t endKeyAB = 1;
|
||||
|
@ -1277,7 +1285,8 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
|
||||
static int CmdHFMFPMAD(const char *Cmd) {
|
||||
|
||||
CLIParserInit("hf mfp mad",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp mad",
|
||||
"Checks and prints Mifare Application Directory (MAD)",
|
||||
"Usage:\n\thf mfp mad -> shows MAD if exists\n"
|
||||
"\thf mfp mad -a 03e1 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data if exists\n");
|
||||
|
@ -1290,18 +1299,18 @@ static int CmdHFMFPMAD(const char *Cmd) {
|
|||
arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool verbose = arg_get_lit(1);
|
||||
uint8_t aid[2] = {0};
|
||||
int aidlen;
|
||||
CLIGetHexWithReturn(2, aid, &aidlen);
|
||||
CLIGetHexWithReturn(ctx, 2, aid, &aidlen);
|
||||
uint8_t key[16] = {0};
|
||||
int keylen;
|
||||
CLIGetHexWithReturn(3, key, &keylen);
|
||||
CLIGetHexWithReturn(ctx, 3, key, &keylen);
|
||||
bool keyB = arg_get_lit(4);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (aidlen != 2 && keylen > 0) {
|
||||
PrintAndLogEx(WARNING, "do not need a key without aid.");
|
||||
|
@ -1371,7 +1380,8 @@ static int CmdHFMFPMAD(const char *Cmd) {
|
|||
|
||||
static int CmdHFMFPNDEF(const char *Cmd) {
|
||||
|
||||
CLIParserInit("hf mfp ndef",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp ndef",
|
||||
"Prints NFC Data Exchange Format (NDEF)",
|
||||
"Usage:\n\thf mfp ndef -> shows NDEF data\n"
|
||||
"\thf mfp ndef -a 03e1 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key\n");
|
||||
|
@ -1384,19 +1394,19 @@ static int CmdHFMFPNDEF(const char *Cmd) {
|
|||
arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool verbose = arg_get_lit(1);
|
||||
bool verbose2 = arg_get_lit(1) > 1;
|
||||
uint8_t aid[2] = {0};
|
||||
int aidlen;
|
||||
CLIGetHexWithReturn(2, aid, &aidlen);
|
||||
CLIGetHexWithReturn(ctx, 2, aid, &aidlen);
|
||||
uint8_t key[16] = {0};
|
||||
int keylen;
|
||||
CLIGetHexWithReturn(3, key, &keylen);
|
||||
CLIGetHexWithReturn(ctx, 3, key, &keylen);
|
||||
bool keyB = arg_get_lit(4);
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
uint16_t ndefAID = 0x03e1;
|
||||
if (aidlen == 2)
|
||||
|
|
|
@ -2915,7 +2915,8 @@ static int CmdHF14MfuNDEF(const char *Cmd) {
|
|||
uint8_t *p_key = key;
|
||||
uint8_t pack[4] = {0, 0, 0, 0};
|
||||
|
||||
CLIParserInit("hf mfu ndef",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfu ndef",
|
||||
"Prints NFC Data Exchange Format (NDEF)",
|
||||
"Usage:\n\thf mfu ndef -> shows NDEF data\n"
|
||||
"\thf mfu ndef -k ffffffff -> shows NDEF data with key\n");
|
||||
|
@ -2926,10 +2927,10 @@ static int CmdHF14MfuNDEF(const char *Cmd) {
|
|||
arg_lit0("lL", "key", "(optional) swap entered key's endianness"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIGetHexWithReturn(1, key, &keylen);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIGetHexWithReturn(ctx, 1, key, &keylen);
|
||||
swapEndian = arg_get_lit(2);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
switch (keylen) {
|
||||
case 0:
|
||||
|
|
|
@ -560,7 +560,8 @@ static int CmdIndalaClone(const char *Cmd) {
|
|||
uint8_t fc = 0;
|
||||
uint16_t cn = 0;
|
||||
|
||||
CLIParserInit("lf indala clone",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf indala clone",
|
||||
"clone INDALA tag to T55x7 (or to q5/T5555)",
|
||||
"Examples:\n"
|
||||
"\tlf indala clone --heden 888\n"
|
||||
|
@ -578,12 +579,12 @@ static int CmdIndalaClone(const char *Cmd) {
|
|||
arg_int0("", "cn", "<decimal>", "Cardnumber (26 bit format)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
is_long_uid = arg_get_lit(1);
|
||||
|
||||
// raw param
|
||||
CLIGetHexWithReturn(3, data, &datalen);
|
||||
CLIGetHexWithReturn(ctx, 3, data, &datalen);
|
||||
|
||||
is_t5555 = arg_get_lit(4);
|
||||
|
||||
|
@ -599,7 +600,7 @@ static int CmdIndalaClone(const char *Cmd) {
|
|||
got_26 = (fc != 0 && cn != 0);
|
||||
}
|
||||
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (is_long_uid) {
|
||||
// 224 BIT UID
|
||||
|
|
|
@ -150,7 +150,8 @@ static int CmdMotorolaClone(const char *Cmd) {
|
|||
uint8_t data[8];
|
||||
int datalen = 0;
|
||||
|
||||
CLIParserInit("lf indala clone",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf indala clone",
|
||||
"Enables cloning of Motorola card with specified uid onto T55x7\n"
|
||||
"defaults to 64.\n",
|
||||
"\n"
|
||||
|
@ -163,9 +164,9 @@ static int CmdMotorolaClone(const char *Cmd) {
|
|||
arg_strx1(NULL, NULL, "<uid (hex)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIGetHexWithReturn(1, data, &datalen);
|
||||
CLIParserFree();
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
CLIGetHexWithReturn(ctx, 1, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
//TODO add selection of chip for Q5 or T55x7
|
||||
// data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT;
|
||||
|
|
|
@ -68,7 +68,8 @@ static int CmdEMVSelect(const char *Cmd) {
|
|||
uint8_t data[APDU_AID_LEN] = {0};
|
||||
int datalen = 0;
|
||||
|
||||
CLIParserInit("emv select",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv select",
|
||||
"Executes select applet command",
|
||||
"Usage:\n\temv select -s a00000000101 -> select card, select applet\n\temv select -st a00000000101 -> select card, select applet, show result in TLV\n");
|
||||
|
||||
|
@ -82,7 +83,7 @@ static int CmdEMVSelect(const char *Cmd) {
|
|||
arg_strx0(NULL, NULL, "<HEX applet AID>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool activateField = arg_get_lit(1);
|
||||
bool leaveSignalON = arg_get_lit(2);
|
||||
|
@ -92,8 +93,8 @@ static int CmdEMVSelect(const char *Cmd) {
|
|||
if (arg_get_lit(5))
|
||||
channel = ECC_CONTACT;
|
||||
PrintChannel(channel);
|
||||
CLIGetHexWithReturn(6, data, &datalen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 6, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
@ -117,7 +118,8 @@ static int CmdEMVSelect(const char *Cmd) {
|
|||
|
||||
static int CmdEMVSearch(const char *Cmd) {
|
||||
|
||||
CLIParserInit("emv search",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv search",
|
||||
"Tries to select all applets from applet list:\n",
|
||||
"Usage:\n\temv search -s -> select card and search\n\temv search -st -> select card, search and show result in TLV\n");
|
||||
|
||||
|
@ -130,7 +132,7 @@ static int CmdEMVSearch(const char *Cmd) {
|
|||
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool activateField = arg_get_lit(1);
|
||||
bool leaveSignalON = arg_get_lit(2);
|
||||
|
@ -140,7 +142,7 @@ static int CmdEMVSearch(const char *Cmd) {
|
|||
if (arg_get_lit(5))
|
||||
channel = ECC_CONTACT;
|
||||
PrintChannel(channel);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
@ -167,7 +169,8 @@ static int CmdEMVSearch(const char *Cmd) {
|
|||
|
||||
static int CmdEMVPPSE(const char *Cmd) {
|
||||
|
||||
CLIParserInit("emv pse",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv pse",
|
||||
"Executes PSE/PPSE select command. It returns list of applet on the card:\n",
|
||||
"Usage:\n\temv pse -s1 -> select, get pse\n\temv pse -st2 -> select, get ppse, show result in TLV\n");
|
||||
|
||||
|
@ -182,7 +185,7 @@ static int CmdEMVPPSE(const char *Cmd) {
|
|||
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool activateField = arg_get_lit(1);
|
||||
bool leaveSignalON = arg_get_lit(2);
|
||||
|
@ -197,7 +200,7 @@ static int CmdEMVPPSE(const char *Cmd) {
|
|||
if (arg_get_lit(7))
|
||||
channel = ECC_CONTACT;
|
||||
PrintChannel(channel);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
@ -223,7 +226,8 @@ static int CmdEMVGPO(const char *Cmd) {
|
|||
uint8_t data[APDU_RES_LEN] = {0};
|
||||
int datalen = 0;
|
||||
|
||||
CLIParserInit("emv gpo",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv gpo",
|
||||
"Executes Get Processing Options command. It returns data in TLV format (0x77 - format2) or plain format (0x80 - format1).\nNeeds a EMV applet to be selected.",
|
||||
"Usage:\n\temv gpo -k -> execute GPO\n"
|
||||
"\temv gpo -t 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n"
|
||||
|
@ -240,7 +244,7 @@ static int CmdEMVGPO(const char *Cmd) {
|
|||
arg_strx0(NULL, NULL, "<HEX PDOLdata/PDOL>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool leaveSignalON = arg_get_lit(1);
|
||||
bool paramsLoadFromFile = arg_get_lit(2);
|
||||
|
@ -251,8 +255,8 @@ static int CmdEMVGPO(const char *Cmd) {
|
|||
if (arg_get_lit(6))
|
||||
channel = ECC_CONTACT;
|
||||
PrintChannel(channel);
|
||||
CLIGetHexWithReturn(7, data, &datalen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 7, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
@ -331,7 +335,8 @@ static int CmdEMVReadRecord(const char *Cmd) {
|
|||
uint8_t data[APDU_RES_LEN] = {0};
|
||||
int datalen = 0;
|
||||
|
||||
CLIParserInit("emv readrec",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv readrec",
|
||||
"Executes Read Record command. It returns data in TLV format.\nNeeds a bank applet to be selected and sometimes needs GPO to be executed.",
|
||||
"Usage:\n\temv readrec -k 0101 -> read file SFI=01, SFIrec=01\n\temv readrec -kt 0201-> read file 0201 and show result in TLV\n");
|
||||
|
||||
|
@ -344,7 +349,7 @@ static int CmdEMVReadRecord(const char *Cmd) {
|
|||
arg_strx1(NULL, NULL, "<SFI 1byte HEX><SFIrecord 1byte HEX>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool leaveSignalON = arg_get_lit(1);
|
||||
bool APDULogging = arg_get_lit(2);
|
||||
|
@ -353,8 +358,8 @@ static int CmdEMVReadRecord(const char *Cmd) {
|
|||
if (arg_get_lit(4))
|
||||
channel = ECC_CONTACT;
|
||||
PrintChannel(channel);
|
||||
CLIGetHexWithReturn(5, data, &datalen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 5, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (datalen != 2) {
|
||||
PrintAndLogEx(ERR, "Command needs to have 2 bytes of data");
|
||||
|
@ -386,7 +391,8 @@ static int CmdEMVAC(const char *Cmd) {
|
|||
uint8_t data[APDU_RES_LEN] = {0};
|
||||
int datalen = 0;
|
||||
|
||||
CLIParserInit("emv genac",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv genac",
|
||||
"Generate Application Cryptogram command. It returns data in TLV format .\nNeeds a EMV applet to be selected and GPO to be executed.",
|
||||
"Usage:\n\temv genac -k 0102 -> generate AC with 2-byte CDOLdata and keep field ON after command\n"
|
||||
"\temv genac -t 01020304 -> generate AC with 4-byte CDOL data, show result in TLV\n"
|
||||
|
@ -406,7 +412,7 @@ static int CmdEMVAC(const char *Cmd) {
|
|||
arg_strx1(NULL, NULL, "<HEX CDOLdata/CDOL>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
bool leaveSignalON = arg_get_lit(1);
|
||||
bool trTypeCDA = arg_get_lit(2);
|
||||
|
@ -436,8 +442,8 @@ static int CmdEMVAC(const char *Cmd) {
|
|||
if (arg_get_lit(8))
|
||||
channel = ECC_CONTACT;
|
||||
PrintChannel(channel);
|
||||
CLIGetHexWithReturn(9, data, &datalen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 9, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
@ -505,7 +511,8 @@ static int CmdEMVAC(const char *Cmd) {
|
|||
|
||||
static int CmdEMVGenerateChallenge(const char *Cmd) {
|
||||
|
||||
CLIParserInit("emv challenge",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv challenge",
|
||||
"Executes Generate Challenge command. It returns 4 or 8-byte random number from card.\nNeeds a EMV applet to be selected and GPO to be executed.",
|
||||
"Usage:\n\temv challenge -> get challenge\n\temv challenge -k -> get challenge, keep fileld ON\n");
|
||||
|
||||
|
@ -516,7 +523,7 @@ static int CmdEMVGenerateChallenge(const char *Cmd) {
|
|||
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool leaveSignalON = arg_get_lit(1);
|
||||
bool APDULogging = arg_get_lit(2);
|
||||
|
@ -524,7 +531,7 @@ static int CmdEMVGenerateChallenge(const char *Cmd) {
|
|||
if (arg_get_lit(3))
|
||||
channel = ECC_CONTACT;
|
||||
PrintChannel(channel);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
@ -552,7 +559,8 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) {
|
|||
uint8_t data[APDU_RES_LEN] = {0};
|
||||
int datalen = 0;
|
||||
|
||||
CLIParserInit("emv intauth",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv intauth",
|
||||
"Generate Internal Authenticate command. Usually needs 4-byte random number. It returns data in TLV format .\n"
|
||||
"Needs a EMV applet to be selected and GPO to be executed.",
|
||||
|
||||
|
@ -572,7 +580,7 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) {
|
|||
arg_strx1(NULL, NULL, "<HEX DDOLdata/DDOL>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, false);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
bool leaveSignalON = arg_get_lit(1);
|
||||
bool paramsLoadFromFile = arg_get_lit(2);
|
||||
|
@ -583,8 +591,8 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) {
|
|||
if (arg_get_lit(6))
|
||||
channel = ECC_CONTACT;
|
||||
PrintChannel(channel);
|
||||
CLIGetHexWithReturn(7, data, &datalen);
|
||||
CLIParserFree();
|
||||
CLIGetHexWithReturn(ctx, 7, data, &datalen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
|
@ -782,7 +790,8 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
struct tlvdb *tlvRoot = NULL;
|
||||
struct tlv *pdol_data_tlv = NULL;
|
||||
|
||||
CLIParserInit("emv exec",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv exec",
|
||||
"Executes EMV contactless transaction",
|
||||
"Usage:\n"
|
||||
"\temv exec -sat -> select card, execute MSD transaction, show APDU and TLV\n"
|
||||
|
@ -803,7 +812,7 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool activateField = arg_get_lit(1);
|
||||
bool showAPDU = arg_get_lit(2);
|
||||
|
@ -825,7 +834,7 @@ static int CmdEMVExec(const char *Cmd) {
|
|||
channel = ECC_CONTACT;
|
||||
PrintChannel(channel);
|
||||
uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2;
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (!IfPm3Smartcard()) {
|
||||
if (channel == ECC_CONTACT) {
|
||||
|
@ -1375,7 +1384,8 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
json_t *root;
|
||||
json_error_t error;
|
||||
|
||||
CLIParserInit("emv scan",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv scan",
|
||||
"Scan EMV card and save it contents to a file.",
|
||||
"It executes EMV contactless transaction and saves result to a file which can be used for emulation\n"
|
||||
"Usage:\n\temv scan -at -> scan MSD transaction mode and show APDU and TLV\n"
|
||||
|
@ -1397,7 +1407,7 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
arg_str1(NULL, NULL, "output.json", "JSON output file name"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool showAPDU = arg_get_lit(1);
|
||||
bool decodeTLV = arg_get_lit(2);
|
||||
|
@ -1422,8 +1432,8 @@ static int CmdEMVScan(const char *Cmd) {
|
|||
uint8_t relfname[250] = {0};
|
||||
char *crelfname = (char *)relfname;
|
||||
int relfnamelen = 0;
|
||||
CLIGetStrWithReturn(12, relfname, &relfnamelen);
|
||||
CLIParserFree();
|
||||
CLIGetStrWithReturn(ctx, 12, relfname, &relfnamelen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (!IfPm3Smartcard()) {
|
||||
if (channel == ECC_CONTACT) {
|
||||
|
@ -1752,7 +1762,8 @@ static int CmdEMVList(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdEMVTest(const char *Cmd) {
|
||||
CLIParserInit("emv test",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv test",
|
||||
"Executes tests\n",
|
||||
"Usage:\n\temv test [l]\n");
|
||||
|
||||
|
@ -1762,11 +1773,11 @@ static int CmdEMVTest(const char *Cmd) {
|
|||
arg_lit0("lL", "long", "run long tests too"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool ignoreTimeTest = arg_get_lit(1);
|
||||
bool runSlowTests = arg_get_lit(2);
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
|
||||
return ExecuteCryptoTests(true, ignoreTimeTest, runSlowTests);
|
||||
}
|
||||
|
@ -1781,7 +1792,8 @@ static int CmdEMVRoca(const char *Cmd) {
|
|||
size_t ODAI_listlen = 0;
|
||||
int res;
|
||||
|
||||
CLIParserInit("emv roca",
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv roca",
|
||||
"Tries to extract public keys and run the ROCA test against them.\n",
|
||||
"Usage:\n"
|
||||
"\temv roca -w -> select --CONTACT-- card and run test\n"
|
||||
|
@ -1795,11 +1807,11 @@ static int CmdEMVRoca(const char *Cmd) {
|
|||
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(Cmd, argtable, true);
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
EMVCommandChannel channel = ECC_CONTACTLESS;
|
||||
if (arg_get_lit(1)) {
|
||||
CLIParserFree();
|
||||
CLIParserFree(ctx);
|
||||
return roca_self_test();
|
||||
}
|
||||
|
||||
|
@ -1807,9 +1819,8 @@ static int CmdEMVRoca(const char *Cmd) {
|
|||
|
||||
if (arg_get_lit(3))
|
||||
channel = ECC_CONTACT;
|
||||
|
||||
CLIParserFree();
|
||||
|
||||
|
||||
CLIParserFree(ctx);
|
||||
PrintChannel(channel);
|
||||
|
||||
if (!IfPm3Smartcard()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue