save to json

This commit is contained in:
merlokk 2018-10-26 19:25:13 +03:00
commit c1a23412ba
4 changed files with 90 additions and 9 deletions

View file

@ -26,13 +26,17 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <unistd.h>
#include <jansson.h>
#include "comms.h" #include "comms.h"
#include "cmdmain.h" #include "cmdmain.h"
#include "util.h" #include "util.h"
#include "ui.h" #include "ui.h"
#include "proxmark3.h"
#include "cmdhf14a.h" #include "cmdhf14a.h"
#include "mifare.h" #include "mifare.h"
#include "emv/emvcore.h" #include "emv/emvcore.h"
#include "emv/emvjson.h"
#include "emv/dump.h" #include "emv/dump.h"
#include "cliparser/cliparser.h" #include "cliparser/cliparser.h"
@ -142,6 +146,8 @@ int CmdHFFidoRegister(const char *cmd) {
uint8_t cdata[250] = {0}; uint8_t cdata[250] = {0};
int applen = 0; int applen = 0;
uint8_t adata[250] = {0}; uint8_t adata[250] = {0};
json_t *root = NULL;
json_error_t error;
CLIParserInit("hf fido reg", CLIParserInit("hf fido reg",
"Initiate a U2F token registration. Needs two 32-byte hash number. \nchallenge parameter (32b) and application parameter (32b).", "Initiate a U2F token registration. Needs two 32-byte hash number. \nchallenge parameter (32b) and application parameter (32b).",
@ -154,6 +160,7 @@ int CmdHFFidoRegister(const char *cmd) {
arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("vV", "verbose", "show technical data"), arg_lit0("vV", "verbose", "show technical data"),
arg_lit0("pP", "plain", "send plain ASCII to challenge and application parameters instead of HEX"), arg_lit0("pP", "plain", "send plain ASCII to challenge and application parameters instead of HEX"),
arg_str0("jJ", "json", "fido.json", "JSON input / output file name for parameters."),
arg_str0(NULL, NULL, "<HEX/ASCII challenge parameter (32b HEX/1..16 chars)>", NULL), arg_str0(NULL, NULL, "<HEX/ASCII challenge parameter (32b HEX/1..16 chars)>", NULL),
arg_str0(NULL, NULL, "<HEX/ASCII application parameter (32b HEX/1..16 chars)>", NULL), arg_str0(NULL, NULL, "<HEX/ASCII application parameter (32b HEX/1..16 chars)>", NULL),
arg_param_end arg_param_end
@ -163,15 +170,45 @@ int CmdHFFidoRegister(const char *cmd) {
bool APDULogging = arg_get_lit(1); bool APDULogging = arg_get_lit(1);
bool verbose = arg_get_lit(2); bool verbose = arg_get_lit(2);
bool paramsPlain = arg_get_lit(3); bool paramsPlain = arg_get_lit(3);
uint8_t jsonname[250] ={0};
char *cjsonname = (char *)jsonname;
int jsonnamelen = 0;
CLIGetStrWithReturn(4, jsonname, &jsonnamelen);
// current path + file name
if (!strstr(cjsonname, ".json"))
strcat(cjsonname, ".json");
char fname[strlen(get_my_executable_directory()) + strlen(cjsonname) + 1];
if (jsonnamelen) {
strcpy(fname, get_my_executable_directory());
strcat(fname, cjsonname);
if (access(fname, F_OK) != -1) {
root = json_load_file(fname, 0, &error);
if (!root) {
PrintAndLog("ERROR: json error on line %d: %s", error.line, error.text);
return 1;
}
if (!json_is_object(root)) {
PrintAndLog("ERROR: Invalid json format. root must be an object.");
return 1;
}
} else {
root = json_object();
}
}
if (paramsPlain) { if (paramsPlain) {
memset(cdata, 0x00, 32); memset(cdata, 0x00, 32);
CLIGetStrWithReturn(4, cdata, &chlen); CLIGetStrWithReturn(5, cdata, &chlen);
if (chlen && chlen > 16) { if (chlen && chlen > 16) {
PrintAndLog("ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", chlen); PrintAndLog("ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", chlen);
return 1; return 1;
} }
} else { } else {
CLIGetHexWithReturn(4, cdata, &chlen); CLIGetHexWithReturn(5, cdata, &chlen);
if (chlen && chlen != 32) { if (chlen && chlen != 32) {
PrintAndLog("ERROR: challenge parameter length must be 32 bytes only."); PrintAndLog("ERROR: challenge parameter length must be 32 bytes only.");
return 1; return 1;
@ -183,13 +220,13 @@ int CmdHFFidoRegister(const char *cmd) {
if (paramsPlain) { if (paramsPlain) {
memset(adata, 0x00, 32); memset(adata, 0x00, 32);
CLIGetStrWithReturn(5, adata, &applen); CLIGetStrWithReturn(6, adata, &applen);
if (applen && applen > 16) { if (applen && applen > 16) {
PrintAndLog("ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", applen); PrintAndLog("ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", applen);
return 1; return 1;
} }
} else { } else {
CLIGetHexWithReturn(5, adata, &applen); CLIGetHexWithReturn(6, adata, &applen);
if (applen && applen != 32) { if (applen && applen != 32) {
PrintAndLog("ERROR: application parameter length must be 32 bytes only."); PrintAndLog("ERROR: application parameter length must be 32 bytes only.");
return 1; return 1;
@ -280,6 +317,24 @@ int CmdHFFidoRegister(const char *cmd) {
printf(" %s", paramsPlain?(char *)adata:sprint_hex_inrow(adata, 32)); printf(" %s", paramsPlain?(char *)adata:sprint_hex_inrow(adata, 32));
printf("\n"); printf("\n");
if (root) {
JsonSaveBufAsHex(root, "ChallengeParam", data, 32);
JsonSaveBufAsHex(root, "ApplicationParam", &data[32], 32);
JsonSaveInt(root, "KeyHandleLen", keyHandleLen);
JsonSaveBufAsHexCompact(root, "KeyHandle", &buf[67], keyHandleLen);
JsonSaveBufAsHexCompact(root, "DER", &buf[67 + keyHandleLen], derLen);
res = json_dump_file(root, fname, JSON_INDENT(2));
if (res) {
PrintAndLog("ERROR: can't save the file: %s", fname);
return 200;
}
PrintAndLog("File `%s` saved.", fname);
// free json object
json_decref(root);
}
return 0; return 0;
}; };

View file

@ -68,24 +68,40 @@ char* GetApplicationDataName(tlv_tag_t tag) {
return NULL; return NULL;
} }
int JsonSaveStr(json_t *root, char *path, char *value) { int JsonSaveJsonObject(json_t *root, char *path, json_t *value) {
json_error_t error; json_error_t error;
if (strlen(path) < 1) if (strlen(path) < 1)
return 1; return 1;
if (path[0] == '$') { if (path[0] == '$') {
if (json_path_set(root, path, json_string(value), 0, &error)) { if (json_path_set(root, path, value, 0, &error)) {
PrintAndLog("ERROR: can't set json path: ", error.text); PrintAndLog("ERROR: can't set json path: ", error.text);
return 2; return 2;
} else { } else {
return 0; return 0;
} }
} else { } else {
return json_object_set_new(root, path, json_string(value)); return json_object_set_new(root, path, value);
} }
}
int JsonSaveInt(json_t *root, char *path, int value) {
return JsonSaveJsonObject(root, path, json_integer(value));
}
int JsonSaveStr(json_t *root, char *path, char *value) {
return JsonSaveJsonObject(root, path, json_string(value));
}; };
int JsonSaveBufAsHexCompact(json_t *elm, char *path, uint8_t *data, size_t datalen) {
char * msg = sprint_hex_inrow(data, datalen);
if (msg && strlen(msg) && msg[strlen(msg) - 1] == ' ')
msg[strlen(msg) - 1] = '\0';
return JsonSaveStr(elm, path, msg);
}
int JsonSaveBufAsHex(json_t *elm, char *path, uint8_t *data, size_t datalen) { int JsonSaveBufAsHex(json_t *elm, char *path, uint8_t *data, size_t datalen) {
char * msg = sprint_hex(data, datalen); char * msg = sprint_hex(data, datalen);
if (msg && strlen(msg) && msg[strlen(msg) - 1] == ' ') if (msg && strlen(msg) && msg[strlen(msg) - 1] == ' ')
@ -248,6 +264,11 @@ bool HexToBuffer(const char *errormsg, const char *hexvalue, uint8_t * buffer, s
return true; return true;
} }
int JsonLoadBufAsHex(json_t *elm, char *path, uint8_t *data, size_t *datalen) {
return 0;
};
bool ParamLoadFromJson(struct tlvdb *tlv) { bool ParamLoadFromJson(struct tlvdb *tlv) {
json_t *root; json_t *root;
json_error_t error; json_error_t error;

View file

@ -20,7 +20,10 @@ typedef struct {
extern char* GetApplicationDataName(tlv_tag_t tag); extern char* GetApplicationDataName(tlv_tag_t tag);
extern int JsonSaveJsonObject(json_t *root, char *path, json_t *value);
extern int JsonSaveStr(json_t *root, char *path, char *value); extern int JsonSaveStr(json_t *root, char *path, char *value);
extern int JsonSaveInt(json_t *root, char *path, int value);
extern int JsonSaveBufAsHexCompact(json_t *elm, char *path, uint8_t *data, size_t datalen);
extern int JsonSaveBufAsHex(json_t *elm, char *path, uint8_t *data, size_t datalen); extern int JsonSaveBufAsHex(json_t *elm, char *path, uint8_t *data, size_t datalen);
extern int JsonSaveHex(json_t *elm, char *path, uint64_t data, int datalen); extern int JsonSaveHex(json_t *elm, char *path, uint64_t data, int datalen);
@ -30,6 +33,8 @@ extern int JsonSaveTLVTreeElm(json_t *elm, char *path, struct tlvdb *tlvdbelm, b
extern int JsonSaveTLVTree(json_t *root, json_t *elm, char *path, struct tlvdb *tlvdbelm); extern int JsonSaveTLVTree(json_t *root, json_t *elm, char *path, struct tlvdb *tlvdbelm);
extern int JsonLoadBufAsHex(json_t *elm, char *path, uint8_t *data, size_t *datalen);
extern bool ParamLoadFromJson(struct tlvdb *tlv); extern bool ParamLoadFromJson(struct tlvdb *tlv);
#endif #endif

View file

@ -139,7 +139,7 @@ void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex
// printing and converting functions // printing and converting functions
char *sprint_hex(const uint8_t *data, const size_t len) { char *sprint_hex(const uint8_t *data, const size_t len) {
static char buf[1025] = {0}; static char buf[4097] = {0};
hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, 1, false); hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, 1, false);
@ -147,7 +147,7 @@ char *sprint_hex(const uint8_t *data, const size_t len) {
} }
char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const size_t min_str_len) { char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const size_t min_str_len) {
static char buf[1025] = {0}; static char buf[4097] = {0};
hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, min_str_len, 0, false); hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, min_str_len, 0, false);