1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // AID DESFire functions
17 //-----------------------------------------------------------------------------
19 #include "aiddesfire.h"
21 #include "fileutils.h"
24 // NXP Appnote AN10787 - Application Directory (MAD)
40 CL_CITYTRAFFIC
= 0x18,
47 CL_COMPANY_SERVICES
= 0x38,
49 CL_ACCESS_CONTROL_1
= 0x47,
52 CL_NED_DEFENCE
= 0x4A,
53 CL_BOSCH_TELECOM
= 0x4B,
94 const char *nxp_cluster_to_text(uint8_t cluster
) {
97 return "card administration";
105 return "miscellaneous applications";
109 return "ferry traffic";
111 return "railway services";
113 return "miscellaneous applications";
117 return "security solutions";
119 return "city traffic";
121 return "Czech Railways";
123 return "bus services";
125 return "multi modal transit";
130 case CL_GENERIC_TRANS
:
131 return "generic transport";
132 case CL_COMPANY_SERVICES
:
133 return "company services";
135 return "city card services";
136 case CL_ACCESS_CONTROL_1
:
137 case CL_ACCESS_CONTROL_2
:
138 return "access control & security";
142 return "Ministry of Defence, Netherlands";
143 case CL_BOSCH_TELECOM
:
144 return "Bosch Telecom, Germany";
146 return "European Union Institutions";
148 return "ski ticketing";
150 return "SOAA standard for offline access standard";
152 return "access control & security";
156 return "non-food trade";
162 return "airport services";
166 return "Dutch government";
168 return "administration services";
170 return "electronic purse";
174 return "cruise ship";
182 return "health services";
188 return "entertainment & sports";
190 return "car parking";
192 return "fleet management";
194 return "fuel, gasoline";
196 return "info services";
213 return "miscellaneous applications";
220 static json_t
*df_known_aids
= NULL
;
222 static int open_aiddf_file(json_t
**root
, bool verbose
) {
225 int res
= searchFile(&path
, RESOURCES_SUBDIR
, "aid_desfire", ".json", true);
226 if (res
!= PM3_SUCCESS
) {
230 int retval
= PM3_SUCCESS
;
233 *root
= json_load_file(path
, 0, &error
);
235 PrintAndLogEx(ERR
, "json (%s) error on line %d: %s", path
, error
.line
, error
.text
);
240 if (!json_is_array(*root
)) {
241 PrintAndLogEx(ERR
, "Invalid json (%s) format. root must be an array.", path
);
247 PrintAndLogEx(SUCCESS
, "Loaded file `" _YELLOW_("%s") "` " _GREEN_("%zu") " records ( " _GREEN_("ok") " )"
249 , json_array_size(*root
)
258 static int close_aiddf_file(json_t
*root
) {
263 static const char *aiddf_json_get_str(json_t
*data
, const char *name
) {
265 json_t
*jstr
= json_object_get(data
, name
);
269 if (!json_is_string(jstr
)) {
270 PrintAndLogEx(WARNING
, _YELLOW_("`%s`") " is not a string", name
);
274 const char *cstr
= json_string_value(jstr
);
275 if (strlen(cstr
) == 0)
281 static int print_aiddf_description(json_t
*root
, uint8_t aid
[3], char *fmt
, bool verbose
) {
283 snprintf(laid
, sizeof(laid
), "%02x%02x%02x", aid
[2], aid
[1], aid
[0]); // must be lowercase
287 for (uint32_t idx
= 0; idx
< json_array_size(root
); idx
++) {
288 json_t
*data
= json_array_get(root
, idx
);
289 if (!json_is_object(data
)) {
290 PrintAndLogEx(ERR
, "data [%d] is not an object\n", idx
);
293 const char *faid
= aiddf_json_get_str(data
, "AID");
294 char lfaid
[strlen(faid
) + 1];
297 if (strcmp(laid
, lfaid
) == 0) {
304 PrintAndLogEx(INFO
, fmt
, " (unknown)");
307 const char *vaid
= aiddf_json_get_str(elm
, "AID");
308 const char *vendor
= aiddf_json_get_str(elm
, "Vendor");
309 const char *country
= aiddf_json_get_str(elm
, "Country");
310 const char *name
= aiddf_json_get_str(elm
, "Name");
311 const char *description
= aiddf_json_get_str(elm
, "Description");
312 const char *type
= aiddf_json_get_str(elm
, "Type");
314 if (name
&& vendor
) {
315 size_t result_len
= 5 + strlen(name
) + strlen(vendor
);
316 char result
[result_len
];
317 snprintf(result
, result_len
, " %s [%s]", name
, vendor
);
318 PrintAndLogEx(INFO
, fmt
, result
);
322 PrintAndLogEx(SUCCESS
, " AID: %s", vaid
);
324 PrintAndLogEx(SUCCESS
, " Name: %s", name
);
326 PrintAndLogEx(SUCCESS
, " Description: %s", description
);
328 PrintAndLogEx(SUCCESS
, " Type: %s", type
);
330 PrintAndLogEx(SUCCESS
, " Vendor: %s", vendor
);
332 PrintAndLogEx(SUCCESS
, " Country: %s", country
);
337 int AIDDFDecodeAndPrint(uint8_t aid
[3]) {
338 open_aiddf_file(&df_known_aids
, false);
341 snprintf(fmt
, sizeof(fmt
), " DF AID Function... %02X%02X%02X :" _YELLOW_("%s"), aid
[2], aid
[1], aid
[0], "%s");
342 print_aiddf_description(df_known_aids
, aid
, fmt
, false);
343 close_aiddf_file(df_known_aids
);