mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-04-02 10:30:16 +08:00
make credentional command works. and refactoring
This commit is contained in:
parent
da45b1db39
commit
f705402b7a
3 changed files with 182 additions and 56 deletions
client
|
@ -36,7 +36,6 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "cmdhf14a.h"
|
|
||||||
#include "mifare.h"
|
#include "mifare.h"
|
||||||
#include "emv/emvcore.h"
|
#include "emv/emvcore.h"
|
||||||
#include "emv/emvjson.h"
|
#include "emv/emvjson.h"
|
||||||
|
@ -50,57 +49,6 @@
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
int FIDOSelect(bool ActivateField, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
|
||||||
uint8_t data[] = {0xA0, 0x00, 0x00, 0x06, 0x47, 0x2F, 0x00, 0x01};
|
|
||||||
|
|
||||||
return EMVSelect(ActivateField, LeaveFieldON, data, sizeof(data), Result, MaxResultLen, ResultLen, sw, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FIDOExchange(sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
|
||||||
int res = EMVExchange(true, apdu, Result, MaxResultLen, ResultLen, sw, NULL);
|
|
||||||
if (res == 5) // apdu result (sw) not a 0x9000
|
|
||||||
res = 0;
|
|
||||||
// software chaining
|
|
||||||
while (!res && (*sw >> 8) == 0x61) {
|
|
||||||
size_t oldlen = *ResultLen;
|
|
||||||
res = EMVExchange(true, (sAPDU){0x00, 0xC0, 0x00, 0x00, 0x00, NULL}, &Result[oldlen], MaxResultLen - oldlen, ResultLen, sw, NULL);
|
|
||||||
if (res == 5) // apdu result (sw) not a 0x9000
|
|
||||||
res = 0;
|
|
||||||
|
|
||||||
*ResultLen += oldlen;
|
|
||||||
if (*ResultLen > MaxResultLen)
|
|
||||||
return 100;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FIDORegister(uint8_t *params, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
|
||||||
return FIDOExchange((sAPDU){0x00, 0x01, 0x03, 0x00, 64, params}, Result, MaxResultLen, ResultLen, sw);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FIDOAuthentication(uint8_t *params, uint8_t paramslen, uint8_t controlb, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
|
||||||
return FIDOExchange((sAPDU){0x00, 0x02, controlb, 0x00, paramslen, params}, Result, MaxResultLen, ResultLen, sw);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FIDO2GetInfo(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
|
||||||
uint8_t data[] = {fido2CmdGetInfo};
|
|
||||||
return FIDOExchange((sAPDU){0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FIDO2MakeCredential(uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
|
||||||
uint8_t data[paramslen + 1];
|
|
||||||
data[0] = fido2CmdMakeCredential;
|
|
||||||
memcpy(&data[1], params, paramslen);
|
|
||||||
return FIDOExchange((sAPDU){0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FIDO2GetAssertion(uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
|
||||||
uint8_t data[paramslen + 1];
|
|
||||||
data[0] = fido2CmdGetAssertion;
|
|
||||||
memcpy(&data[1], params, paramslen);
|
|
||||||
return FIDOExchange((sAPDU){0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CmdHFFidoInfo(const char *cmd) {
|
int CmdHFFidoInfo(const char *cmd) {
|
||||||
|
|
||||||
if (cmd && strlen(cmd) > 0)
|
if (cmd && strlen(cmd) > 0)
|
||||||
|
@ -754,15 +702,13 @@ int GetExistsFileNameJson(char *prefixDir, char *reqestedFileName, char *fileNam
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHFFido2MakeCredential(const char *cmd) {
|
int CmdHFFido2MakeCredential(const char *cmd) {
|
||||||
|
|
||||||
|
|
||||||
json_error_t error;
|
json_error_t error;
|
||||||
json_t *root = NULL;
|
json_t *root = NULL;
|
||||||
char fname[300] = {0};
|
char fname[300] = {0};
|
||||||
|
|
||||||
int res = GetExistsFileNameJson("fido", "fido2", fname);
|
int res = GetExistsFileNameJson("fido", "fido2", fname);
|
||||||
if(res) {
|
if(res) {
|
||||||
PrintAndLog("ERROR: Can't found json file.");
|
PrintAndLog("ERROR: Can't found the json file.");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
PrintAndLog("fname: %s\n", fname);
|
PrintAndLog("fname: %s\n", fname);
|
||||||
|
@ -793,6 +739,13 @@ int CmdHFFido2MakeCredential(const char *cmd) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res = FIDO2CreateMakeCredentionalReq(root, data, sizeof(data), &datalen);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
PrintAndLog("CBOR make credentional request:");
|
||||||
|
TinyCborPrintFIDOPackage(fido2CmdMakeCredential, data, datalen);
|
||||||
|
|
||||||
res = FIDO2MakeCredential(data, datalen, buf, sizeof(buf), &len, &sw);
|
res = FIDO2MakeCredential(data, datalen, buf, sizeof(buf), &len, &sw);
|
||||||
DropField();
|
DropField();
|
||||||
if (res) {
|
if (res) {
|
||||||
|
@ -810,7 +763,11 @@ int CmdHFFido2MakeCredential(const char *cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("res[%d]: %s", len, sprint_hex(buf, len));
|
PrintAndLog("MakeCredential result (%d) OK.", len);
|
||||||
|
PrintAndLog("CBOR make credentional response:");
|
||||||
|
TinyCborPrintFIDOPackage(fido2CmdMakeCredential, &buf[1], len - 1);
|
||||||
|
|
||||||
|
json_decref(root);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "fidocore.h"
|
#include "fidocore.h"
|
||||||
|
#include "emv/emvcore.h"
|
||||||
|
#include "emv/emvjson.h"
|
||||||
|
#include <cbor.h>
|
||||||
|
#include "cbortools.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t ErrorCode;
|
uint8_t ErrorCode;
|
||||||
|
@ -122,3 +126,156 @@ char *fido2GetCmdMemberDescription(uint8_t cmdCode, uint8_t memberNum) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FIDOSelect(bool ActivateField, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
|
uint8_t data[] = {0xA0, 0x00, 0x00, 0x06, 0x47, 0x2F, 0x00, 0x01};
|
||||||
|
|
||||||
|
return EMVSelect(ActivateField, LeaveFieldON, data, sizeof(data), Result, MaxResultLen, ResultLen, sw, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FIDOExchange(sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
|
int res = EMVExchange(true, apdu, Result, MaxResultLen, ResultLen, sw, NULL);
|
||||||
|
if (res == 5) // apdu result (sw) not a 0x9000
|
||||||
|
res = 0;
|
||||||
|
// software chaining
|
||||||
|
while (!res && (*sw >> 8) == 0x61) {
|
||||||
|
size_t oldlen = *ResultLen;
|
||||||
|
res = EMVExchange(true, (sAPDU){0x00, 0xC0, 0x00, 0x00, 0x00, NULL}, &Result[oldlen], MaxResultLen - oldlen, ResultLen, sw, NULL);
|
||||||
|
if (res == 5) // apdu result (sw) not a 0x9000
|
||||||
|
res = 0;
|
||||||
|
|
||||||
|
*ResultLen += oldlen;
|
||||||
|
if (*ResultLen > MaxResultLen)
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FIDORegister(uint8_t *params, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
|
return FIDOExchange((sAPDU){0x00, 0x01, 0x03, 0x00, 64, params}, Result, MaxResultLen, ResultLen, sw);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FIDOAuthentication(uint8_t *params, uint8_t paramslen, uint8_t controlb, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
|
return FIDOExchange((sAPDU){0x00, 0x02, controlb, 0x00, paramslen, params}, Result, MaxResultLen, ResultLen, sw);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FIDO2GetInfo(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
|
uint8_t data[] = {fido2CmdGetInfo};
|
||||||
|
return FIDOExchange((sAPDU){0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FIDO2MakeCredential(uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
|
uint8_t data[paramslen + 1];
|
||||||
|
data[0] = fido2CmdMakeCredential;
|
||||||
|
memcpy(&data[1], params, paramslen);
|
||||||
|
return FIDOExchange((sAPDU){0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FIDO2GetAssertion(uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
|
uint8_t data[paramslen + 1];
|
||||||
|
data[0] = fido2CmdGetAssertion;
|
||||||
|
memcpy(&data[1], params, paramslen);
|
||||||
|
return FIDOExchange((sAPDU){0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define fido_check_if(r) if ((r) != CborNoError) {return r;} else
|
||||||
|
#define fido_check(r) if ((r) != CborNoError) return r;
|
||||||
|
|
||||||
|
int CBOREncodeClientDataHash(json_t *root, CborEncoder *encoder) {
|
||||||
|
uint8_t buf[100] = {0};
|
||||||
|
size_t jlen;
|
||||||
|
|
||||||
|
JsonLoadBufAsHex(root, "$.ClientDataHash", buf, sizeof(buf), &jlen);
|
||||||
|
|
||||||
|
// fill with 0x00 if not found
|
||||||
|
if (!jlen)
|
||||||
|
jlen = 32;
|
||||||
|
|
||||||
|
int res = cbor_encode_byte_string(encoder, buf, jlen);
|
||||||
|
fido_check(res);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CBOREncodeRp(json_t *root, CborEncoder *encoder) {
|
||||||
|
json_t *elm = json_object_get(root, "RelyingPartyEntity");
|
||||||
|
if (!elm)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
JsonToCbor(elm, encoder);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CBOREncodeUser(json_t *root, CborEncoder *encoder) {
|
||||||
|
json_t *elm = json_object_get(root, "UserEntity");
|
||||||
|
if (!elm)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
JsonToCbor(elm, encoder);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CBOREncodePubKeyParams(json_t *root, CborEncoder *encoder) {
|
||||||
|
json_t *elm = json_object_get(root, "pubKeyCredParams");
|
||||||
|
if (!elm)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
JsonToCbor(elm, encoder);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FIDO2CreateMakeCredentionalReq(json_t *root, uint8_t *data, size_t maxdatalen, size_t *datalen) {
|
||||||
|
if (datalen)
|
||||||
|
*datalen = 0;
|
||||||
|
if (!root || !data || !maxdatalen)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int res;
|
||||||
|
CborEncoder encoder;
|
||||||
|
CborEncoder map;
|
||||||
|
|
||||||
|
cbor_encoder_init(&encoder, data, maxdatalen, 0);
|
||||||
|
|
||||||
|
// create main map
|
||||||
|
res = cbor_encoder_create_map(&encoder, &map, 4);
|
||||||
|
fido_check_if(res) {
|
||||||
|
// clientDataHash
|
||||||
|
res = cbor_encode_uint(&map, 1);
|
||||||
|
fido_check_if(res) {
|
||||||
|
res = CBOREncodeClientDataHash(root, &map);
|
||||||
|
fido_check(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rp
|
||||||
|
res = cbor_encode_uint(&map, 2);
|
||||||
|
fido_check_if(res) {
|
||||||
|
res = CBOREncodeRp(root, &map);
|
||||||
|
fido_check(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// user
|
||||||
|
res = cbor_encode_uint(&map, 3);
|
||||||
|
fido_check_if(res) {
|
||||||
|
res = CBOREncodeUser(root, &map);
|
||||||
|
fido_check(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pubKeyCredParams
|
||||||
|
res = cbor_encode_uint(&map, 4);
|
||||||
|
fido_check_if(res) {
|
||||||
|
res = CBOREncodePubKeyParams(root, &map);
|
||||||
|
fido_check(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
res = cbor_encoder_close_container(&encoder, &map);
|
||||||
|
fido_check(res);
|
||||||
|
|
||||||
|
size_t len = cbor_encoder_get_buffer_size(&encoder, data);
|
||||||
|
if (datalen)
|
||||||
|
*datalen = len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <jansson.h>
|
||||||
|
#include "cmdhf14a.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
fido2CmdMakeCredential = 0x01,
|
fido2CmdMakeCredential = 0x01,
|
||||||
|
@ -30,7 +32,17 @@ typedef enum {
|
||||||
ptResponse,
|
ptResponse,
|
||||||
} fido2PacketType;
|
} fido2PacketType;
|
||||||
|
|
||||||
|
extern int FIDOSelect(bool ActivateField, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
|
extern int FIDOExchange(sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
|
extern int FIDORegister(uint8_t *params, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
|
extern int FIDOAuthentication(uint8_t *params, uint8_t paramslen, uint8_t controlb, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
|
extern int FIDO2GetInfo(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
|
extern int FIDO2MakeCredential(uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
|
extern int FIDO2GetAssertion(uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
|
|
||||||
extern char *fido2GetCmdMemberDescription(uint8_t cmdCode, uint8_t memberNum);
|
extern char *fido2GetCmdMemberDescription(uint8_t cmdCode, uint8_t memberNum);
|
||||||
extern char *fido2GetCmdErrorDescription(uint8_t errorCode);
|
extern char *fido2GetCmdErrorDescription(uint8_t errorCode);
|
||||||
|
|
||||||
|
extern int FIDO2CreateMakeCredentionalReq(json_t *root, uint8_t *data, size_t maxdatalen, size_t *datalen);
|
||||||
|
|
||||||
#endif /* __FIDOCORE_H__ */
|
#endif /* __FIDOCORE_H__ */
|
||||||
|
|
Loading…
Add table
Reference in a new issue