mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-25 01:36:12 +08:00
134 lines
4.1 KiB
C
134 lines
4.1 KiB
C
//-----------------------------------------------------------------------------
|
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
|
// the license.
|
|
//-----------------------------------------------------------------------------
|
|
// AID DESFire functions
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "aiddesfire.h"
|
|
#include "pm3_cmd.h"
|
|
#include "fileutils.h"
|
|
#include "jansson.h"
|
|
|
|
static json_t *df_known_aids = NULL;
|
|
|
|
static int open_aiddf_file(json_t **root, bool verbose) {
|
|
|
|
char *path;
|
|
int res = searchFile(&path, RESOURCES_SUBDIR, "aid_desfire", ".json", true);
|
|
if (res != PM3_SUCCESS) {
|
|
return PM3_EFILE;
|
|
}
|
|
|
|
int retval = PM3_SUCCESS;
|
|
json_error_t error;
|
|
|
|
*root = json_load_file(path, 0, &error);
|
|
if (!*root) {
|
|
PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text);
|
|
retval = PM3_ESOFT;
|
|
goto out;
|
|
}
|
|
|
|
if (!json_is_array(*root)) {
|
|
PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path);
|
|
retval = PM3_ESOFT;
|
|
goto out;
|
|
}
|
|
|
|
if (verbose)
|
|
PrintAndLogEx(SUCCESS, "Loaded file " _YELLOW_("`%s`") " (%s) %zu records.", path, _GREEN_("ok"), json_array_size(*root));
|
|
out:
|
|
free(path);
|
|
return retval;
|
|
}
|
|
|
|
static int close_aiddf_file(json_t *root) {
|
|
json_decref(root);
|
|
return PM3_SUCCESS;
|
|
}
|
|
|
|
static const char *aiddf_json_get_str(json_t *data, const char *name) {
|
|
|
|
json_t *jstr = json_object_get(data, name);
|
|
if (jstr == NULL)
|
|
return NULL;
|
|
|
|
if (!json_is_string(jstr)) {
|
|
PrintAndLogEx(WARNING, _YELLOW_("`%s`") " is not a string", name);
|
|
return NULL;
|
|
}
|
|
|
|
const char *cstr = json_string_value(jstr);
|
|
if (strlen(cstr) == 0)
|
|
return NULL;
|
|
|
|
return cstr;
|
|
}
|
|
|
|
static int print_aiddf_description(json_t *root, uint8_t aid[3], char *fmt, bool verbose) {
|
|
char laid[7] = {0};
|
|
sprintf(laid, "%02x%02x%02x", aid[2], aid[1], aid[0]); // must be lowercase
|
|
|
|
json_t *elm = NULL;
|
|
|
|
for (uint32_t idx = 0; idx < json_array_size(root); idx++) {
|
|
json_t *data = json_array_get(root, idx);
|
|
if (!json_is_object(data)) {
|
|
PrintAndLogEx(ERR, "data [%d] is not an object\n", idx);
|
|
continue;
|
|
}
|
|
const char *faid = aiddf_json_get_str(data, "AID");
|
|
char lfaid[strlen(faid) + 1];
|
|
strcpy(lfaid, faid);
|
|
str_lower(lfaid);
|
|
if (strcmp(laid, lfaid) == 0) {
|
|
elm = data;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (elm == NULL) {
|
|
PrintAndLogEx(INFO, fmt, " (unknown)");
|
|
return PM3_ENODATA;
|
|
}
|
|
const char *vaid = aiddf_json_get_str(elm, "AID");
|
|
const char *vendor = aiddf_json_get_str(elm, "Vendor");
|
|
const char *country = aiddf_json_get_str(elm, "Country");
|
|
const char *name = aiddf_json_get_str(elm, "Name");
|
|
const char *description = aiddf_json_get_str(elm, "Description");
|
|
const char *type = aiddf_json_get_str(elm, "Type");
|
|
|
|
if (name && vendor) {
|
|
char result[4 + strlen(name) + strlen(vendor)];
|
|
sprintf(result, " %s [%s]", name, vendor);
|
|
PrintAndLogEx(INFO, fmt, result);
|
|
}
|
|
|
|
if (verbose) {
|
|
PrintAndLogEx(SUCCESS, " AID: %s", vaid);
|
|
if (name)
|
|
PrintAndLogEx(SUCCESS, " Name: %s", name);
|
|
if (description)
|
|
PrintAndLogEx(SUCCESS, " Description: %s", description);
|
|
if (type)
|
|
PrintAndLogEx(SUCCESS, " Type: %s", type);
|
|
if (vendor)
|
|
PrintAndLogEx(SUCCESS, " Vendor: %s", vendor);
|
|
if (country)
|
|
PrintAndLogEx(SUCCESS, " Country: %s", country);
|
|
}
|
|
return PM3_SUCCESS;
|
|
}
|
|
|
|
int AIDDFDecodeAndPrint(uint8_t aid[3]) {
|
|
open_aiddf_file(&df_known_aids, false);
|
|
|
|
char fmt[50];
|
|
sprintf(fmt, " DF AID Function %02X%02X%02X :" _YELLOW_("%s"), aid[2], aid[1], aid[0], "%s");
|
|
print_aiddf_description(df_known_aids, aid, fmt, false);
|
|
close_aiddf_file(df_known_aids);
|
|
return PM3_SUCCESS;
|
|
}
|