Merge pull request #1269 from merlokk/fix_fido

FIDO fixing
This commit is contained in:
Oleg Moiseenko 2021-05-10 16:14:06 +03:00 committed by GitHub
commit 0d3c2978a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 45 deletions

View file

@ -1049,7 +1049,7 @@ int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool lea
while (chaining) { while (chaining) {
// I-block with chaining // I-block with chaining
res = CmdExchangeAPDU(false, NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining); res = CmdExchangeAPDU(false, NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining);
if (res == PM3_SUCCESS) { if (res != PM3_SUCCESS) {
if (leaveSignalON == false) if (leaveSignalON == false)
DropField(); DropField();

View file

@ -130,19 +130,20 @@ static int CmdHFFidoRegister(const char *cmd) {
"The output template filename is `hf-fido2-params.json`\n" "The output template filename is `hf-fido2-params.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 -p s0 s1 -> execute command with plain parameters\n" "hf fido reg --cp s0 --ap s1 -> execute command with plain parameters\n"
"hf fido reg --cp 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f --ap 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f\n" "hf fido reg --cpx 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f --apx 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f\n"
); );
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"), arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_litn("v", "verbose", 0, 2, "show technical data. vv - show full certificates data"), arg_litn("v", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("p", "plain", "send plain ASCII to challenge and application parameters instead of HEX"),
arg_lit0("t", "tlv", "Show DER certificate contents in TLV representation"), arg_lit0("t", "tlv", "Show DER certificate contents in TLV representation"),
arg_str0("f", "file", "<fn>", "JSON input file name for parameters"), arg_str0("f", "file", "<fn>", "JSON input file name for parameters"),
arg_str0(NULL, "cp", "<hex/ascii>", "challenge parameter (32 bytes hex / 1..16 chars)"), arg_str0(NULL, "cp", "<ascii>", "challenge parameter (1..16 chars)"),
arg_str0(NULL, "ap", "<hex/ascii>", "application parameter (32 bytes hex / 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, "apx", "<hex>", "application parameter (32 bytes hex)"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, cmd, argtable, true); CLIExecWithReturn(ctx, cmd, argtable, true);
@ -150,9 +151,11 @@ static int CmdHFFidoRegister(const char *cmd) {
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 verbose2 = arg_get_lit(ctx, 2) > 1; bool verbose2 = arg_get_lit(ctx, 2) > 1;
bool paramsPlain = arg_get_lit(ctx, 3); bool showDERTLV = arg_get_lit(ctx, 3);
bool showDERTLV = arg_get_lit(ctx, 4); bool cpplain = arg_get_str_len(ctx, 5);
bool applain = arg_get_str_len(ctx, 6);
bool cphex = arg_get_str_len(ctx, 7);
bool aphex = arg_get_str_len(ctx, 8);
uint8_t data[64] = {0}; uint8_t data[64] = {0};
int chlen = 0; int chlen = 0;
@ -162,7 +165,7 @@ static int CmdHFFidoRegister(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, 5), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParamStrToBuf(arg_get_str(ctx, 4), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
// deafault name // deafault name
if (fnlen == 0) { if (fnlen == 0) {
@ -170,13 +173,6 @@ static int CmdHFFidoRegister(const char *cmd) {
fnlen = strlen(filename); fnlen = strlen(filename);
} }
/*
json_t *root = calloc(1, sizeof(json_t));
if (root == NULL) {
PrintAndLogEx(ERR, "error, cannot allocate memory ");
return PM3_EMALLOC;
}
*/
json_t *root = NULL; json_t *root = NULL;
int res = loadFileJSONroot(filename, (void**)&root, verbose); int res = loadFileJSONroot(filename, (void**)&root, verbose);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
@ -188,19 +184,20 @@ static int CmdHFFidoRegister(const char *cmd) {
JsonLoadBufAsHex(root, "$.ChallengeParam", data, 32, &jlen); JsonLoadBufAsHex(root, "$.ChallengeParam", data, 32, &jlen);
JsonLoadBufAsHex(root, "$.ApplicationParam", &data[32], 32, &jlen); JsonLoadBufAsHex(root, "$.ApplicationParam", &data[32], 32, &jlen);
if (paramsPlain) { if (cpplain) {
memset(cdata, 0x00, 32); memset(cdata, 0x00, 32);
chlen = sizeof(cdata); chlen = sizeof(cdata);
CLIGetStrWithReturn(ctx, 6, cdata, &chlen); CLIGetStrWithReturn(ctx, 5, cdata, &chlen);
if (chlen > 16) { if (chlen > 16) {
PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", chlen); PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", chlen);
CLIParserFree(ctx); CLIParserFree(ctx);
json_decref(root); json_decref(root);
return PM3_EINVARG; return PM3_EINVARG;
} }
} else { }
if (cphex & !cpplain) {
chlen = sizeof(cdata); chlen = sizeof(cdata);
CLIGetHexWithReturn(ctx, 6, cdata, &chlen); CLIGetHexWithReturn(ctx, 7, cdata, &chlen);
if (chlen && chlen != 32) { if (chlen && chlen != 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);
@ -211,20 +208,20 @@ static int CmdHFFidoRegister(const char *cmd) {
if (chlen) if (chlen)
memmove(data, cdata, 32); memmove(data, cdata, 32);
if (applain) {
if (paramsPlain) {
memset(adata, 0x00, 32); memset(adata, 0x00, 32);
applen = sizeof(adata); applen = sizeof(adata);
CLIGetStrWithReturn(ctx, 7, adata, &applen); CLIGetStrWithReturn(ctx, 6, adata, &applen);
if (applen > 16) { if (applen > 16) {
PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", applen); PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", applen);
CLIParserFree(ctx); CLIParserFree(ctx);
json_decref(root); json_decref(root);
return PM3_EINVARG; return PM3_EINVARG;
} }
} else { }
if (aphex & !applain) {
applen = sizeof(adata); applen = sizeof(adata);
CLIGetHexWithReturn(ctx, 7, adata, &applen); CLIGetHexWithReturn(ctx, 8, adata, &applen);
if (applen && applen != 32) { if (applen && applen != 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);
@ -363,12 +360,15 @@ static int CmdHFFidoRegister(const char *cmd) {
PrintAndLogEx(WARNING, "Invalid signature. res = %d. ( " _RED_("fail") " )" , res); PrintAndLogEx(WARNING, "Invalid signature. res = %d. ( " _RED_("fail") " )" , res);
} }
PrintAndLogEx(INFO, "\nauth command: "); PrintAndLogEx(INFO, "");
PrintAndLogEx(INFO, "hf fido auth %s%s", paramsPlain ? "-p " : "", sprint_hex_inrow(&buf[67], keyHandleLen)); PrintAndLogEx(INFO, "auth command: ");
if (chlen || applen) char command[500] = {0};
PrintAndLogEx(INFO, " %s", paramsPlain ? (char *)cdata : sprint_hex_inrow(cdata, 32)); sprintf(command, "hf fido auth --kh %s", sprint_hex_inrow(&buf[67], keyHandleLen));
if (chlen)
sprintf(command + strlen(command), " --%s %s", cpplain ? "cp" : "cpx", cpplain ? (char *)cdata : sprint_hex_inrow(cdata, 32));
if (applen) if (applen)
PrintAndLogEx(INFO, " %s", paramsPlain ? (char *)adata : sprint_hex_inrow(adata, 32)); sprintf(command + strlen(command), " --%s %s", applain ? "cp" : "cpx", applain ? (char *)adata : sprint_hex_inrow(adata, 32));
PrintAndLogEx(INFO, "%s", command);
if (root) { if (root) {
JsonSaveBufAsHex(root, "ChallengeParam", data, 32); JsonSaveBufAsHex(root, "ChallengeParam", data, 32);
@ -378,7 +378,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"); //sprintf(filename, "hf-fido2-params");
res = saveFileJSONroot(filename, root, JSON_INDENT(2), verbose); res = saveFileJSONroot(filename, root, JSON_INDENT(2), verbose);
} }
json_decref(root); json_decref(root);
@ -400,17 +400,19 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
void *argtable[] = { void *argtable[] = {
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_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", "<hex/ascii>", "challenge parameter (32 bytes hex / 1..16 chars)"), arg_str0(NULL, "cp", "<ascii>", "challenge parameter (1..16 chars)"),
arg_str0(NULL, "ap", "<hex/ascii>", "application parameter (32 bytes hex / 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, "apx", "<hex>", "application parameter (32 bytes hex)"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, cmd, argtable, true); CLIExecWithReturn(ctx, cmd, argtable, true);
@ -490,7 +492,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
if (paramsPlain) { if (paramsPlain) {
memset(hdata, 0x00, 32); memset(hdata, 0x00, 32);
hdatalen = sizeof(hdata); hdatalen = sizeof(hdata);
CLIGetStrWithReturn(ctx, 9, hdata, &hdatalen); CLIGetStrWithReturn(ctx, 10, 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);
@ -499,7 +501,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
} }
} else { } else {
hdatalen = sizeof(hdata); hdatalen = sizeof(hdata);
CLIGetHexWithReturn(ctx, 10, hdata, &hdatalen); CLIGetHexWithReturn(ctx, 12, 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);
@ -523,7 +525,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
} }
} else { } else {
hdatalen = sizeof(hdata); hdatalen = sizeof(hdata);
CLIGetHexWithReturn(ctx, 10, hdata, &hdatalen); CLIGetHexWithReturn(ctx, 13, 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);