mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-21 05:43:23 -07:00
works
This commit is contained in:
parent
7aac07be8e
commit
9b4edaab6a
1 changed files with 123 additions and 24 deletions
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue