mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 22:03:42 -07:00
Merge branch 'merlokk-fido_fix' into future
* merlokk-fido_fix: fix config files fix help fido U2F auth command works fix working with config files add saveFileJSONrootEx with overwrite function
This commit is contained in:
commit
d763187ed7
3 changed files with 52 additions and 39 deletions
|
@ -127,11 +127,12 @@ static int CmdHFFidoRegister(const char *cmd) {
|
||||||
CLIParserInit(&ctx, "hf fido reg",
|
CLIParserInit(&ctx, "hf fido reg",
|
||||||
"Initiate a U2F token registration. Needs two 32-byte hash numbers.\n"
|
"Initiate a U2F token registration. Needs two 32-byte hash numbers.\n"
|
||||||
"challenge parameter (32b) and application parameter (32b).\n"
|
"challenge parameter (32b) and application parameter (32b).\n"
|
||||||
"The output template filename is `hf-fido2-params.json`\n"
|
"The default config filename is `fido2_defparams.json`\n"
|
||||||
"\n",
|
"\n",
|
||||||
"hf fido reg -> execute command with 2 parameters, filled 0x00\n"
|
"hf fido reg -> execute command with 2 parameters, filled 0x00\n"
|
||||||
"hf fido reg --cp s0 --ap s1 -> execute command with plain parameters\n"
|
"hf fido reg --cp s0 --ap s1 -> execute command with plain parameters\n"
|
||||||
"hf fido reg --cpx 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f --apx 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f\n"
|
"hf fido reg --cpx 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f --apx 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f\n"
|
||||||
|
"hf fido reg -f fido2-params -> execute command with custom config file\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -378,8 +379,7 @@ static int CmdHFFidoRegister(const char *cmd) {
|
||||||
JsonSaveBufAsHexCompact(root, "KeyHandle", &buf[67], keyHandleLen);
|
JsonSaveBufAsHexCompact(root, "KeyHandle", &buf[67], keyHandleLen);
|
||||||
JsonSaveBufAsHexCompact(root, "DER", &buf[67 + keyHandleLen], derLen);
|
JsonSaveBufAsHexCompact(root, "DER", &buf[67 + keyHandleLen], derLen);
|
||||||
|
|
||||||
//sprintf(filename, "hf-fido2-params");
|
res = saveFileJSONrootEx(filename, root, JSON_INDENT(2), verbose, true);
|
||||||
res = saveFileJSONroot(filename, root, JSON_INDENT(2), verbose);
|
|
||||||
(void)res;
|
(void)res;
|
||||||
}
|
}
|
||||||
json_decref(root);
|
json_decref(root);
|
||||||
|
@ -391,7 +391,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
||||||
CLIParserInit(&ctx, "hf fido auth",
|
CLIParserInit(&ctx, "hf fido auth",
|
||||||
"Initiate a U2F token authentication. Needs key handle and two 32-byte hash numbers.\n"
|
"Initiate a U2F token authentication. Needs key handle and two 32-byte hash numbers.\n"
|
||||||
"key handle(var 0..255), challenge parameter (32b) and application parameter (32b)\n"
|
"key handle(var 0..255), challenge parameter (32b) and application parameter (32b)\n"
|
||||||
"The output template filename is `hf-fido2-params.json`\n"
|
"The default config filename is `fido2_defparams.json`\n"
|
||||||
"\n",
|
"\n",
|
||||||
"hf fido auth --kh 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n"
|
"hf fido auth --kh 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n"
|
||||||
"hf fido auth \n"
|
"hf fido auth \n"
|
||||||
|
@ -403,30 +403,28 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0("a", "apdu", "show APDU reqests and responses"),
|
arg_lit0("a", "apdu", "show APDU reqests and responses"),
|
||||||
arg_lit0("v", "verbose", "show technical data"),
|
arg_lit0("v", "verbose", "show technical data"),
|
||||||
arg_lit0("p", "plain", "send plain ASCII to challenge and application parameters instead of HEX"),
|
|
||||||
arg_rem("default mode:", "dont-enforce-user-presence-and-sign"),
|
arg_rem("default mode:", "dont-enforce-user-presence-and-sign"),
|
||||||
arg_lit0("u", "user", "mode: enforce-user-presence-and-sign"),
|
arg_lit0("u", "user", "mode: enforce-user-presence-and-sign"),
|
||||||
arg_lit0("c", "check", "mode: check-only"),
|
arg_lit0("c", "check", "mode: check-only"),
|
||||||
arg_str0("f", "file", "<fn>", "JSON input file name for parameters"),
|
arg_str0("f", "file", "<fn>", "JSON input file name for parameters"),
|
||||||
arg_str0("k", "key", "<hex>", "public key to verify signature"),
|
arg_str0("k", "key", "<hex>", "public key to verify signature"),
|
||||||
arg_str0(NULL, "kh", "<hex>", "key handle (var 0..255b)"),
|
arg_str0(NULL, "kh", "<hex>", "key handle (var 0..255b)"),
|
||||||
arg_str0(NULL, "cp", "<ascii>", "challenge parameter (1..16 chars)"),
|
arg_str0(NULL, "cp", "<ascii>", "challenge parameter (1..16 chars)"),
|
||||||
arg_str0(NULL, "ap", "<ascii>", "application parameter (1..16 chars)"),
|
arg_str0(NULL, "ap", "<ascii>", "application parameter (1..16 chars)"),
|
||||||
arg_str0(NULL, "cpx", "<hex>", "challenge parameter (32 bytes hex)"),
|
arg_str0(NULL, "cpx", "<hex>", "challenge parameter (32 bytes hex)"),
|
||||||
arg_str0(NULL, "apx", "<hex>", "application parameter (32 bytes hex)"),
|
arg_str0(NULL, "apx", "<hex>", "application parameter (32 bytes hex)"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||||
|
|
||||||
bool APDULogging = arg_get_lit(ctx, 1);
|
bool APDULogging = arg_get_lit(ctx, 1);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
bool paramsPlain = arg_get_lit(ctx, 3);
|
|
||||||
|
|
||||||
uint8_t controlByte = 0x08;
|
uint8_t controlByte = 0x08;
|
||||||
if (arg_get_lit(ctx, 5))
|
if (arg_get_lit(ctx, 4))
|
||||||
controlByte = 0x03;
|
controlByte = 0x03;
|
||||||
|
|
||||||
if (arg_get_lit(ctx, 6))
|
if (arg_get_lit(ctx, 5))
|
||||||
controlByte = 0x07;
|
controlByte = 0x07;
|
||||||
|
|
||||||
uint8_t data[512] = {0};
|
uint8_t data[512] = {0};
|
||||||
|
@ -438,7 +436,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
||||||
|
|
||||||
int fnlen = 0;
|
int fnlen = 0;
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||||
|
|
||||||
// deafault name
|
// deafault name
|
||||||
if (fnlen == 0) {
|
if (fnlen == 0) {
|
||||||
|
@ -463,7 +461,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
||||||
public_key_loaded = (jlen > 0);
|
public_key_loaded = (jlen > 0);
|
||||||
|
|
||||||
// public key
|
// public key
|
||||||
CLIGetHexWithReturn(ctx, 8, hdata, &hdatalen);
|
CLIGetHexWithReturn(ctx, 7, hdata, &hdatalen);
|
||||||
if (hdatalen && hdatalen != 65) {
|
if (hdatalen && hdatalen != 65) {
|
||||||
PrintAndLogEx(ERR, "ERROR: public key length must be 65 bytes only.");
|
PrintAndLogEx(ERR, "ERROR: public key length must be 65 bytes only.");
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
@ -476,33 +474,41 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
||||||
public_key_loaded = true;
|
public_key_loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLIGetHexWithReturn(ctx, 9, hdata, &hdatalen);
|
CLIGetHexWithReturn(ctx, 8, hdata, &hdatalen);
|
||||||
if (hdatalen > 255) {
|
if (hdatalen > 255) {
|
||||||
PrintAndLogEx(ERR, "ERROR: application parameter length must be less than 255.");
|
PrintAndLogEx(ERR, "ERROR: key handle length must be less than 255.");
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
json_decref(root);
|
json_decref(root);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("-- hlen=%d\n", hdatalen);
|
||||||
if (hdatalen) {
|
if (hdatalen) {
|
||||||
keyHandleLen = hdatalen;
|
keyHandleLen = hdatalen;
|
||||||
data[64] = keyHandleLen;
|
data[64] = keyHandleLen;
|
||||||
memmove(&data[65], hdata, keyHandleLen);
|
memmove(&data[65], hdata, keyHandleLen);
|
||||||
|
hdatalen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paramsPlain) {
|
bool cpplain = arg_get_str_len(ctx, 9);
|
||||||
|
bool applain = arg_get_str_len(ctx, 10);
|
||||||
|
bool cphex = arg_get_str_len(ctx, 11);
|
||||||
|
bool aphex = arg_get_str_len(ctx, 12);
|
||||||
|
|
||||||
|
if (cpplain) {
|
||||||
memset(hdata, 0x00, 32);
|
memset(hdata, 0x00, 32);
|
||||||
hdatalen = sizeof(hdata);
|
hdatalen = sizeof(hdata);
|
||||||
CLIGetStrWithReturn(ctx, 10, hdata, &hdatalen);
|
CLIGetStrWithReturn(ctx, 9, hdata, &hdatalen);
|
||||||
if (hdatalen > 16) {
|
if (hdatalen > 16) {
|
||||||
PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen);
|
PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
json_decref(root);
|
json_decref(root);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
if (cphex && cpplain == false) {
|
||||||
hdatalen = sizeof(hdata);
|
hdatalen = sizeof(hdata);
|
||||||
CLIGetHexWithReturn(ctx, 12, hdata, &hdatalen);
|
CLIGetHexWithReturn(ctx, 11, hdata, &hdatalen);
|
||||||
if (hdatalen && hdatalen != 32) {
|
if (hdatalen && hdatalen != 32) {
|
||||||
PrintAndLogEx(ERR, "ERROR: challenge parameter length must be 32 bytes only.");
|
PrintAndLogEx(ERR, "ERROR: challenge parameter length must be 32 bytes only.");
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
@ -510,23 +516,25 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (hdatalen) {
|
||||||
if (hdatalen)
|
|
||||||
memmove(data, hdata, 32);
|
memmove(data, hdata, 32);
|
||||||
|
hdatalen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (paramsPlain) {
|
if (applain) {
|
||||||
memset(hdata, 0x00, 32);
|
memset(hdata, 0x00, 32);
|
||||||
hdatalen = sizeof(hdata);
|
hdatalen = sizeof(hdata);
|
||||||
CLIGetStrWithReturn(ctx, 11, hdata, &hdatalen);
|
CLIGetStrWithReturn(ctx, 10, hdata, &hdatalen);
|
||||||
if (hdatalen > 16) {
|
if (hdatalen > 16) {
|
||||||
PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen);
|
PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
json_decref(root);
|
json_decref(root);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
if (aphex && applain == false) {
|
||||||
hdatalen = sizeof(hdata);
|
hdatalen = sizeof(hdata);
|
||||||
CLIGetHexWithReturn(ctx, 13, hdata, &hdatalen);
|
CLIGetHexWithReturn(ctx, 12, hdata, &hdatalen);
|
||||||
if (hdatalen && hdatalen != 32) {
|
if (hdatalen && hdatalen != 32) {
|
||||||
PrintAndLogEx(ERR, "ERROR: application parameter length must be 32 bytes only.");
|
PrintAndLogEx(ERR, "ERROR: application parameter length must be 32 bytes only.");
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
@ -534,9 +542,10 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (hdatalen) {
|
||||||
if (hdatalen)
|
|
||||||
memmove(&data[32], hdata, 32);
|
memmove(&data[32], hdata, 32);
|
||||||
|
hdatalen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
@ -613,7 +622,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
||||||
res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, public_key, xbuf, xbuflen, &buf[5], len - 5, true);
|
res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, public_key, xbuf, xbuflen, &buf[5], len - 5, true);
|
||||||
if (res) {
|
if (res) {
|
||||||
if (res == MBEDTLS_ERR_ECP_VERIFY_FAILED) {
|
if (res == MBEDTLS_ERR_ECP_VERIFY_FAILED) {
|
||||||
PrintAndLogEx(WARNING, "Signature is" _RED_("NOT VALID."));
|
PrintAndLogEx(WARNING, "Signature is ( " _RED_("not valid") " )");
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res));
|
PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res));
|
||||||
}
|
}
|
||||||
|
@ -634,8 +643,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
||||||
JsonSaveBufAsHexCompact(root, "KeyHandle", &data[65], keyHandleLen);
|
JsonSaveBufAsHexCompact(root, "KeyHandle", &data[65], keyHandleLen);
|
||||||
JsonSaveInt(root, "Counter", cntr);
|
JsonSaveInt(root, "Counter", cntr);
|
||||||
|
|
||||||
sprintf(filename, "hf-fido2-params");
|
res = saveFileJSONrootEx(filename, root, JSON_INDENT(2), verbose, true);
|
||||||
res = saveFileJSONroot(filename, root, JSON_INDENT(2), verbose);
|
|
||||||
(void)res;
|
(void)res;
|
||||||
}
|
}
|
||||||
json_decref(root);
|
json_decref(root);
|
||||||
|
@ -753,9 +761,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
|
||||||
// parse returned cbor
|
// parse returned cbor
|
||||||
FIDO2MakeCredentionalParseRes(root, &buf[1], len - 1, verbose, verbose2, showCBOR, showDERTLV);
|
FIDO2MakeCredentionalParseRes(root, &buf[1], len - 1, verbose, verbose2, showCBOR, showDERTLV);
|
||||||
|
|
||||||
// new file name..
|
res = saveFileJSONrootEx(filename, root, JSON_INDENT(2), verbose, true);
|
||||||
sprintf(filename, "hf-fido2");
|
|
||||||
res = saveFileJSONroot(filename, root, JSON_INDENT(2), verbose);
|
|
||||||
(void)res;
|
(void)res;
|
||||||
json_decref(root);
|
json_decref(root);
|
||||||
return res;
|
return res;
|
||||||
|
@ -873,9 +879,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
|
||||||
// parse returned cbor
|
// parse returned cbor
|
||||||
FIDO2GetAssertionParseRes(root, &buf[1], len - 1, verbose, verbose2, showCBOR);
|
FIDO2GetAssertionParseRes(root, &buf[1], len - 1, verbose, verbose2, showCBOR);
|
||||||
|
|
||||||
// new file name..
|
res = saveFileJSONrootEx(filename, root, JSON_INDENT(2), verbose, true);
|
||||||
sprintf(filename, "hf-fido2");
|
|
||||||
res = saveFileJSONroot(filename, root, JSON_INDENT(2), verbose);
|
|
||||||
(void)res;
|
(void)res;
|
||||||
json_decref(root);
|
json_decref(root);
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -667,10 +667,18 @@ out:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
int saveFileJSONroot(const char *preferredName, void *root, size_t flags, bool verbose) {
|
int saveFileJSONroot(const char *preferredName, void *root, size_t flags, bool verbose) {
|
||||||
|
return saveFileJSONrootEx(preferredName, root, flags, verbose, false);
|
||||||
|
}
|
||||||
|
int saveFileJSONrootEx(const char *preferredName, void *root, size_t flags, bool verbose, bool overwrite) {
|
||||||
if (root == NULL)
|
if (root == NULL)
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
|
||||||
char *filename = newfilenamemcopy(preferredName, ".json");
|
char *filename = NULL;
|
||||||
|
if (overwrite)
|
||||||
|
filename = filenamemcopy(preferredName, ".json");
|
||||||
|
else
|
||||||
|
filename = newfilenamemcopy(preferredName, ".json");
|
||||||
|
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,7 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t
|
||||||
int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, void (*callback)(json_t *));
|
int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, void (*callback)(json_t *));
|
||||||
int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, bool verbose, void (*callback)(json_t *));
|
int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, bool verbose, void (*callback)(json_t *));
|
||||||
int saveFileJSONroot(const char *preferredName, void *root, size_t flags, bool verbose);
|
int saveFileJSONroot(const char *preferredName, void *root, size_t flags, bool verbose);
|
||||||
|
int saveFileJSONrootEx(const char *preferredName, void *root, size_t flags, bool verbose, bool overwrite);
|
||||||
/** STUB
|
/** STUB
|
||||||
* @brief Utility function to save WAVE data to a file. This method takes a preferred name, but if that
|
* @brief Utility function to save WAVE data to a file. This method takes a preferred name, but if that
|
||||||
* file already exists, it tries with another name until it finds something suitable.
|
* file already exists, it tries with another name until it finds something suitable.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue