fido U2F auth command works

This commit is contained in:
merlokk 2021-05-28 15:19:49 +03:00
commit 6ab2d98644

View file

@ -132,6 +132,7 @@ static int CmdHFFidoRegister(const char *cmd) {
"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[] = {
@ -402,7 +403,6 @@ 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"),
@ -419,13 +419,12 @@ static int CmdHFFidoAuthenticate(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 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};
@ -437,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) {
@ -462,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);
@ -475,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);
@ -509,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);
@ -533,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);
@ -612,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));
} }
@ -633,7 +643,6 @@ 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 = saveFileJSONrootEx(filename, root, JSON_INDENT(2), verbose, true);
(void)res; (void)res;
} }