This commit is contained in:
merlokk 2018-10-18 18:34:38 +03:00
commit 9b4edaab6a

View file

@ -34,6 +34,7 @@
#include "mifare.h" #include "mifare.h"
#include "emv/emvcore.h" #include "emv/emvcore.h"
#include "emv/dump.h" #include "emv/dump.h"
#include "cliparser/cliparser.h"
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
@ -112,23 +113,54 @@ int CmdHFFidoInfo(const char *cmd) {
return 0; return 0;
} }
// test only!!!
static uint8_t GkeyHandle[512] = {0};
int CmdHFFidoRegister(const char *cmd) { int CmdHFFidoRegister(const char *cmd) {
uint8_t data[64] = {0};
uint8_t hdata[32] = {0};
int datalen = 0;
CLIParserInit("hf fido reg",
"Initiate a U2F token registration. Needs two 32-byte hash number. \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");
void* argtable[] = {
arg_param_begin,
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("vV", "verbose", "show technical data"),
arg_str0(NULL, NULL, "<HEX challenge parameter (32b)>", NULL),
arg_str0(NULL, NULL, "<HEX application parameter (32b)>", NULL),
arg_param_end
};
CLIExecWithReturn(cmd, argtable, true);
bool APDULogging = arg_get_lit(1);
bool verbose = arg_get_lit(2);
CLIGetStrWithReturn(3, hdata, &datalen);
if (datalen && datalen != 32) {
PrintAndLog("ERROR: challenge parameter length must be 32 bytes only.");
return 1;
}
if (datalen)
memmove(data, hdata, 32);
CLIGetStrWithReturn(4, hdata, &datalen);
if (datalen && datalen != 32) {
PrintAndLog("ERROR: application parameter length must be 32 bytes only.");
return 1;
}
if (datalen)
memmove(&data[32], hdata, 32);
CLIParserFree();
SetAPDULogging(APDULogging);
// here will be command extraction
// challenge parameter [32 bytes] - The challenge parameter is the SHA-256 hash of the Client Data, a stringified JSON data structure that the FIDO Client prepares // challenge parameter [32 bytes] - The challenge parameter is the SHA-256 hash of the Client Data, a stringified JSON data structure that the FIDO Client prepares
// application parameter [32 bytes] - The application parameter is the SHA-256 hash of the UTF-8 encoding of the application identity // application parameter [32 bytes] - The application parameter is the SHA-256 hash of the UTF-8 encoding of the application identity
uint8_t data[64] = {0};
SetAPDULogging(true);
DropField();
uint8_t buf[2048] = {0}; uint8_t buf[2048] = {0};
size_t len = 0; size_t len = 0;
uint16_t sw = 0; uint16_t sw = 0;
DropField();
int res = FIDOSelect(true, true, buf, sizeof(buf), &len, &sw); int res = FIDOSelect(true, true, buf, sizeof(buf), &len, &sw);
if (res) { if (res) {
@ -152,9 +184,15 @@ int CmdHFFidoRegister(const char *cmd) {
return 3; return 3;
} }
PrintAndLog("");
if (APDULogging)
PrintAndLog("---------------------------------------------------------------"); PrintAndLog("---------------------------------------------------------------");
PrintAndLog("data len: %d", len); PrintAndLog("data len: %d", len);
if (verbose) {
PrintAndLog("--------------data----------------------");
dump_buffer((const unsigned char *)buf, len, NULL, 0); dump_buffer((const unsigned char *)buf, len, NULL, 0);
PrintAndLog("--------------data----------------------");
}
if (buf[0] != 0x05) { if (buf[0] != 0x05) {
PrintAndLog("ERROR: First byte must be 0x05, but it %2x", buf[0]); PrintAndLog("ERROR: First byte must be 0x05, but it %2x", buf[0]);
@ -164,14 +202,17 @@ int CmdHFFidoRegister(const char *cmd) {
uint8_t keyHandleLen = buf[66]; uint8_t keyHandleLen = buf[66];
PrintAndLog("Key handle[%d]: %s", keyHandleLen, sprint_hex(&buf[67], keyHandleLen)); PrintAndLog("Key handle[%d]: %s", keyHandleLen, sprint_hex(&buf[67], keyHandleLen));
memmove(GkeyHandle, &buf[67], keyHandleLen);
int derp = 67 + keyHandleLen; int derp = 67 + keyHandleLen;
int derLen = (buf[derp + 2] << 8) + buf[derp + 3] + 4; int derLen = (buf[derp + 2] << 8) + buf[derp + 3] + 4;
// needs to decode DER certificate // needs to decode DER certificate
PrintAndLog("DER certificate[%d]: %s...", derLen, sprint_hex(&buf[derp], 20)); if (verbose) {
PrintAndLog("DER certificate[%d]:------------------DER-------------------", derLen);
dump_buffer_simple((const unsigned char *)&buf[67 + keyHandleLen], derLen, NULL); dump_buffer_simple((const unsigned char *)&buf[67 + keyHandleLen], derLen, NULL);
PrintAndLog("---------------------------------------------------------------"); PrintAndLog("\n----------------DER---------------------");
} else {
PrintAndLog("DER certificate[%d]: %s...", derLen, sprint_hex(&buf[derp], 20));
}
int hashp = 1 + 65 + 1 + keyHandleLen + derLen; int hashp = 1 + 65 + 1 + keyHandleLen + derLen;
@ -179,32 +220,90 @@ int CmdHFFidoRegister(const char *cmd) {
// check ANSI X9.62 format ECDSA signature (on P-256) // check ANSI X9.62 format ECDSA signature (on P-256)
PrintAndLog("\nauth command: hf fido auth %s", sprint_hex_inrow(&buf[67], keyHandleLen));
DropField(); DropField();
return 0; return 0;
}; };
int CmdHFFidoAuthenticate(const char *cmd) { int CmdHFFidoAuthenticate(const char *cmd) {
uint8_t data[512] = {0};
uint8_t hdata[128] = {0};
int hdatalen = 0;
uint8_t keyHandleLen = 0;
CLIParserInit("hf fido auth",
"Initiate a U2F token authentication. Needs key handle and two 32-byte hash number. \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 "
"000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters");
void* argtable[] = {
arg_param_begin,
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("vV", "verbose", "show technical data"),
arg_rem("default mode:", "dont-enforce-user-presence-and-sign"),
arg_lit0("pP", "presence", "mode: enforce-user-presence-and-sign"),
arg_lit0("cC", "check", "mode: check-only"),
arg_str1(NULL, NULL, "<HEX key handle (var 0..255b)>", NULL),
arg_str0(NULL, NULL, "<HEX challenge parameter (32b)>", NULL),
arg_str0(NULL, NULL, "<HEX application parameter (32b)>", NULL),
arg_param_end
};
CLIExecWithReturn(cmd, argtable, true);
bool APDULogging = arg_get_lit(1);
//bool verbose = arg_get_lit(2);
uint8_t controlByte = 0x08;
if (arg_get_lit(4))
controlByte = 0x03;
if (arg_get_lit(5))
controlByte = 0x07;
CLIGetStrWithReturn(6, hdata, &hdatalen);
if (hdatalen > 255) {
PrintAndLog("ERROR: application parameter length must be less than 255.");
return 1;
}
if (hdatalen) {
keyHandleLen = hdatalen;
data[64] = keyHandleLen;
memmove(&data[65], hdata, keyHandleLen);
}
CLIGetStrWithReturn(7, hdata, &hdatalen);
if (hdatalen && hdatalen != 32) {
PrintAndLog("ERROR: challenge parameter length must be 32 bytes only.");
return 1;
}
if (hdatalen)
memmove(data, hdata, 32);
CLIGetStrWithReturn(8, hdata, &hdatalen);
if (hdatalen && hdatalen != 32) {
PrintAndLog("ERROR: application parameter length must be 32 bytes only.");
return 1;
}
if (hdatalen)
memmove(&data[32], hdata, 32);
CLIParserFree();
SetAPDULogging(APDULogging);
// here will be command extraction
// (in parameter) conrtol byte 0x07 - check only, 0x03 - user presense + cign. 0x08 - sign only // (in parameter) conrtol byte 0x07 - check only, 0x03 - user presense + cign. 0x08 - sign only
// challenge parameter [32 bytes] // challenge parameter [32 bytes]
// application parameter [32 bytes] // application parameter [32 bytes]
// key handle length [1b] = N // key handle length [1b] = N
// key handle [N] // key handle [N]
uint8_t keyHandleLen = 64;
uint8_t data[512] = {0};
uint8_t datalen = 32 + 32 + 1 + keyHandleLen; uint8_t datalen = 32 + 32 + 1 + keyHandleLen;
uint8_t controlByte = 0x08;
data[64] = keyHandleLen;
memmove(&data[65], GkeyHandle, keyHandleLen);
SetAPDULogging(true);
DropField();
uint8_t buf[2048] = {0}; uint8_t buf[2048] = {0};
size_t len = 0; size_t len = 0;
uint16_t sw = 0; uint16_t sw = 0;
DropField();
int res = FIDOSelect(true, true, buf, sizeof(buf), &len, &sw); int res = FIDOSelect(true, true, buf, sizeof(buf), &len, &sw);
if (res) { if (res) {