fix little endian vs big endian in the macros... again... but this time correct
[RRG-proxmark3.git] / client / src / aiddesfire.c
blobb628ea07254b47be292c6e88c938439daeb9f996
1 //-----------------------------------------------------------------------------
2 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
3 // at your option, any later version. See the LICENSE.txt file for the text of
4 // the license.
5 //-----------------------------------------------------------------------------
6 // AID DESFire functions
7 //-----------------------------------------------------------------------------
9 #include "aiddesfire.h"
10 #include "pm3_cmd.h"
11 #include "fileutils.h"
12 #include "jansson.h"
14 static json_t *df_known_aids = NULL;
16 static int open_aiddf_file(json_t **root, bool verbose) {
18 char *path;
19 int res = searchFile(&path, RESOURCES_SUBDIR, "aid_desfire", ".json", true);
20 if (res != PM3_SUCCESS) {
21 return PM3_EFILE;
24 int retval = PM3_SUCCESS;
25 json_error_t error;
27 *root = json_load_file(path, 0, &error);
28 if (!*root) {
29 PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text);
30 retval = PM3_ESOFT;
31 goto out;
34 if (!json_is_array(*root)) {
35 PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path);
36 retval = PM3_ESOFT;
37 goto out;
40 if (verbose)
41 PrintAndLogEx(SUCCESS, "Loaded file " _YELLOW_("`%s`") " (%s) %zu records.", path, _GREEN_("ok"), json_array_size(*root));
42 out:
43 free(path);
44 return retval;
47 static int close_aiddf_file(json_t *root) {
48 json_decref(root);
49 return PM3_SUCCESS;
52 static const char *aiddf_json_get_str(json_t *data, const char *name) {
54 json_t *jstr = json_object_get(data, name);
55 if (jstr == NULL)
56 return NULL;
58 if (!json_is_string(jstr)) {
59 PrintAndLogEx(WARNING, _YELLOW_("`%s`") " is not a string", name);
60 return NULL;
63 const char *cstr = json_string_value(jstr);
64 if (strlen(cstr) == 0)
65 return NULL;
67 return cstr;
70 static int print_aiddf_description(json_t *root, uint8_t aid[3], char *fmt, bool verbose) {
71 char laid[7] = {0};
72 sprintf(laid, "%02x%02x%02x", aid[2], aid[1], aid[0]); // must be lowercase
74 json_t *elm = NULL;
76 for (uint32_t idx = 0; idx < json_array_size(root); idx++) {
77 json_t *data = json_array_get(root, idx);
78 if (!json_is_object(data)) {
79 PrintAndLogEx(ERR, "data [%d] is not an object\n", idx);
80 continue;
82 const char *faid = aiddf_json_get_str(data, "AID");
83 char lfaid[strlen(faid) + 1];
84 strcpy(lfaid, faid);
85 str_lower(lfaid);
86 if (strcmp(laid, lfaid) == 0) {
87 elm = data;
88 break;
92 if (elm == NULL) {
93 PrintAndLogEx(INFO, fmt, " (unknown)");
94 return PM3_ENODATA;
96 const char *vaid = aiddf_json_get_str(elm, "AID");
97 const char *vendor = aiddf_json_get_str(elm, "Vendor");
98 const char *country = aiddf_json_get_str(elm, "Country");
99 const char *name = aiddf_json_get_str(elm, "Name");
100 const char *description = aiddf_json_get_str(elm, "Description");
101 const char *type = aiddf_json_get_str(elm, "Type");
103 if (name && vendor) {
104 char result[5 + strlen(name) + strlen(vendor)];
105 sprintf(result, " %s [%s]", name, vendor);
106 PrintAndLogEx(INFO, fmt, result);
109 if (verbose) {
110 PrintAndLogEx(SUCCESS, " AID: %s", vaid);
111 if (name)
112 PrintAndLogEx(SUCCESS, " Name: %s", name);
113 if (description)
114 PrintAndLogEx(SUCCESS, " Description: %s", description);
115 if (type)
116 PrintAndLogEx(SUCCESS, " Type: %s", type);
117 if (vendor)
118 PrintAndLogEx(SUCCESS, " Vendor: %s", vendor);
119 if (country)
120 PrintAndLogEx(SUCCESS, " Country: %s", country);
122 return PM3_SUCCESS;
125 int AIDDFDecodeAndPrint(uint8_t aid[3]) {
126 open_aiddf_file(&df_known_aids, false);
128 char fmt[80];
129 sprintf(fmt, " DF AID Function %02X%02X%02X :" _YELLOW_("%s"), aid[2], aid[1], aid[0], "%s");
130 print_aiddf_description(df_known_aids, aid, fmt, false);
131 close_aiddf_file(df_known_aids);
132 return PM3_SUCCESS;