Merge pull request #3296 from kormax/calypso-maintenance

Calypso maintenance
This commit is contained in:
Iceman
2026-05-08 21:23:59 +02:00
committed by GitHub
3 changed files with 85 additions and 12 deletions
+52 -12
View File
@@ -56,6 +56,9 @@
#define CALYPSO_DUMP_FILENAME_MAX_SERIALS 8
#define CALYPSO_MAX_EF_LIST_LIDS 128
#define CALYPSO_MAX_LID_CANDIDATES 384
#define CALYPSO_GET_DATA_INLINE_MAX 32
#define CALYPSO_GET_DATA_HEX_BREAK 32
#define CALYPSO_GET_DATA_HEX_INDENT " "
#define CALYPSO_MANUFACTURERS_RESOURCE "calypso/manufacturers"
#define CALYPSO_IC_FAMILIES_RESOURCE "calypso/ic_families"
@@ -1736,22 +1739,51 @@ static bool calypso_ef_list_contains_lid(const calypso_ef_list_t *ef_list, uint1
return false;
}
static void calypso_print_ef_list_lids(const calypso_ef_list_t *ef_list) {
if (ef_list == NULL || ef_list->count == 0) {
static void calypso_print_get_data_object(const calypso_get_data_probe_t *probe, const uint8_t *data, size_t data_len) {
if (data_len <= CALYPSO_GET_DATA_INLINE_MAX) {
PrintAndLogEx(SUCCESS, " %04X %-24s : " _YELLOW_("%s"), probe->tag, probe->name, sprint_hex(data, data_len));
return;
}
char lids[CALYPSO_MAX_EF_LIST_LIDS * 6 + 1] = {0};
size_t pos = 0;
for (size_t i = 0; i < ef_list->count && pos < sizeof(lids); i++) {
int written = snprintf(lids + pos, sizeof(lids) - pos, "%s%04X", i == 0 ? "" : " ", ef_list->lids[i]);
if (written < 0 || (size_t)written >= sizeof(lids) - pos) {
PrintAndLogEx(SUCCESS, " %04X %-24s : " _YELLOW_("%zu bytes"), probe->tag, probe->name, data_len);
print_hex_noascii_break_ex(data, data_len, CALYPSO_GET_DATA_HEX_BREAK, CALYPSO_GET_DATA_HEX_INDENT "\x1b[33m", ' ', AEND);
}
static void calypso_print_info_data_objects(void) {
bool printed_header = false;
for (size_t i = 0; i < ARRAYLEN(calypso_get_data_probes); i++) {
const calypso_get_data_probe_t *probe = &calypso_get_data_probes[i];
if (probe->tag != 0x0185 && probe->tag != 0x5F52) {
continue;
}
uint8_t response[APDU_RES_LEN] = {0};
size_t response_len = 0;
uint16_t sw = 0;
int res = calypso_get_data_object(probe->tag, response, sizeof(response), &response_len, &sw);
bool has_data = res == PM3_SUCCESS && calypso_read_sw_has_data(sw, response_len);
if (printed_header == false && has_data) {
PrintAndLogEx(INFO, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Get Data Objects") " ----------------------");
printed_header = true;
}
if (res != PM3_SUCCESS) {
continue;
}
if (sw == ISO7816_INS_NOT_SUPPORTED) {
break;
}
pos += (size_t)written;
}
PrintAndLogEx(SUCCESS, " EF List LIDs : " _YELLOW_("%s") "%s", lids, ef_list->truncated ? " (truncated)" : "");
if (has_data == false) {
continue;
}
calypso_print_get_data_object(probe, response, response_len);
}
}
static size_t calypso_probe_get_data_objects(json_t *entries, bool print_results, bool verbose, calypso_ef_list_t *ef_list) {
@@ -1776,9 +1808,16 @@ static size_t calypso_probe_get_data_objects(json_t *entries, bool print_results
continue;
}
if (sw == ISO7816_INS_NOT_SUPPORTED) {
if (verbose) {
PrintAndLogEx(INFO, " %04X %-24s : " _YELLOW_("%04X") " - %s", probe->tag, probe->name, sw, GetAPDUCodeDescription(sw >> 8, sw & 0xFF));
}
break;
}
if (calypso_read_sw_has_data(sw, response_len)) {
if (print_results || verbose) {
PrintAndLogEx(SUCCESS, " %04X %-24s : " _YELLOW_("%s"), probe->tag, probe->name, sprint_hex(response, response_len));
calypso_print_get_data_object(probe, response, response_len);
if (verbose && probe->tlv) {
TLVPrintFromBuffer(response, (int)response_len);
}
@@ -1788,7 +1827,6 @@ static size_t calypso_probe_get_data_objects(json_t *entries, bool print_results
}
if (probe->tag == 0x00C0) {
calypso_parse_ef_list_object(response, response_len, ef_list);
calypso_print_ef_list_lids(ef_list);
}
found++;
continue;
@@ -2924,6 +2962,8 @@ static int CmdHFCalypsoInfo(const char *Cmd) {
calypso_print_select_info(&selected, verbose);
calypso_reselect_exact_df_name(&selected, verbose);
calypso_print_info_data_objects();
calypso_reselect_exact_df_name(&selected, verbose);
uint8_t icc[CALYPSO_ICC_RECORD_LEN] = {0};
size_t icc_len = 0;
+32
View File
@@ -339,6 +339,38 @@ void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t brea
}
}
void print_hex_noascii_break_ex(const uint8_t *data, const size_t len, uint8_t breaks, const char *prefix, char separator, const char *suffix) {
if (data == NULL || len == 0 || breaks == 0) return;
if (prefix == NULL) {
prefix = "";
}
if (suffix == NULL) {
suffix = "";
}
char sep[2] = {separator, '\0'};
for (size_t pos = 0; pos < len; pos += breaks) {
char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0};
size_t chunk_len = len - pos;
if (chunk_len > breaks) {
chunk_len = breaks;
}
char *p = buf;
size_t remaining = sizeof(buf);
for (size_t i = 0; i < chunk_len; i++) {
int written = snprintf(p, remaining, "%s%02X", (i > 0 && separator != '\0') ? sep : "", data[pos + i]);
if (written < 0 || (size_t)written >= remaining) {
break;
}
p += written;
remaining -= (size_t)written;
}
PrintAndLogEx(INFO, "%s%s%s", prefix, buf, suffix);
}
}
static void print_buffer_ex(const uint8_t *data, const size_t len, int level, uint8_t breaks) {
// sanity checks
+1
View File
@@ -84,6 +84,7 @@ void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len,
void print_hex(const uint8_t *data, const size_t len);
void print_hex_break(const uint8_t *data, const size_t len, const uint8_t breaks);
void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t breaks);
void print_hex_noascii_break_ex(const uint8_t *data, const size_t len, uint8_t breaks, const char *prefix, char separator, const char *suffix);
char *sprint_hex(const uint8_t *data, const size_t len);
char *sprint_hex_inrow(const uint8_t *data, const size_t len);