static void print_file(const sc_file_t *file) { const char *format = " %02X%02X "; const char *st = "???"; switch (file->type) { case SC_FILE_TYPE_WORKING_EF: st = "wEF"; break; case SC_FILE_TYPE_INTERNAL_EF: st = "iEF"; break; case SC_FILE_TYPE_DF: format = "[%02X%02X]"; st = "DF"; break; } printf(format, file->id >> 8, file->id & 0xFF); printf("\t%4s", st); printf(" %5lu", (unsigned long)file->size); if (file->namelen) { printf("\tName: "); util_print_binary(stdout, file->name, file->namelen); } printf("\n"); return; }
static int write_output(const u8 *buf, int len) { FILE *outf; int output_binary = (opt_output == NULL && opt_raw == 0 ? 0 : 1); if (opt_output != NULL) { outf = fopen(opt_output, "wb"); if (outf == NULL) { fprintf(stderr, "Unable to open '%s' for writing.\n", opt_output); return -1; } } else { outf = stdout; } if (output_binary == 0) util_print_binary(outf, buf, len); else fwrite(buf, len, 1, outf); if (outf != stdout) fclose(outf); return 0; }
static int do_info(int argc, char **argv) { sc_file_t *file; sc_path_t path; size_t i; const char *st; int r, not_current = 1; const id2str_t *ac_ops = NULL; if (!argc) { path = current_path; file = current_file; not_current = 0; } else if (argc == 1) { if (arg_to_path(argv[0], &path, 0) != 0) return usage(do_info); r = sc_select_file(card, &path, &file); if (r) { printf("unable to select file: %s\n", sc_strerror(r)); return -1; } } else return usage(do_info); switch (file->type) { case SC_FILE_TYPE_WORKING_EF: case SC_FILE_TYPE_INTERNAL_EF: st = "Elementary File"; break; case SC_FILE_TYPE_DF: st = "Dedicated File"; break; default: st = "Unknown File"; break; } printf("\n%s ID %04X\n\n", st, file->id); printf("%-15s%s\n", "File path:", path_to_filename(&path, '/')); printf("%-15s%lu bytes\n", "File size:", (unsigned long) file->size); if (file->type == SC_FILE_TYPE_DF) { static const id2str_t ac_ops_df[] = { { SC_AC_OP_SELECT, "SELECT" }, { SC_AC_OP_LOCK, "LOCK" }, { SC_AC_OP_DELETE, "DELETE" }, { SC_AC_OP_CREATE, "CREATE" }, { SC_AC_OP_REHABILITATE, "REHABILITATE" }, { SC_AC_OP_INVALIDATE, "INVALIDATE" }, { SC_AC_OP_LIST_FILES, "LIST FILES" }, { SC_AC_OP_CRYPTO, "CRYPTO" }, { SC_AC_OP_DELETE_SELF, "DELETE SELF" }, { 0, NULL } }; if (file->namelen) { printf("%-15s", "DF name:"); util_print_binary(stdout, file->name, file->namelen); printf("\n"); } ac_ops = ac_ops_df; } else { static const id2str_t ac_ops_ef[] = { { SC_AC_OP_READ, "READ" }, { SC_AC_OP_UPDATE, "UPDATE" }, { SC_AC_OP_DELETE, "DELETE" }, { SC_AC_OP_WRITE, "WRITE" }, { SC_AC_OP_REHABILITATE, "REHABILITATE" }, { SC_AC_OP_INVALIDATE, "INVALIDATE" }, { SC_AC_OP_LIST_FILES, "LIST FILES" }, { SC_AC_OP_CRYPTO, "CRYPTO" }, { 0, NULL } }; const id2str_t ef_type_name[] = { { SC_FILE_EF_TRANSPARENT, "Transparent" }, { SC_FILE_EF_LINEAR_FIXED, "Linear fixed" }, { SC_FILE_EF_LINEAR_FIXED_TLV, "Linear fixed, SIMPLE-TLV" }, { SC_FILE_EF_LINEAR_VARIABLE, "Linear variable" }, { SC_FILE_EF_LINEAR_VARIABLE_TLV, "Linear variable, SIMPLE-TLV" }, { SC_FILE_EF_CYCLIC, "Cyclic" }, { SC_FILE_EF_CYCLIC_TLV, "Cyclic, SIMPLE-TLV" }, { 0, NULL } }; const char *ef_type = "Unknown"; for (i = 0; ef_type_name[i].str != NULL; i++) if (file->ef_structure == ef_type_name[i].id) ef_type = ef_type_name[i].str; printf("%-15s%s\n", "EF structure:", ef_type); ac_ops = ac_ops_ef; } for (i = 0; ac_ops != NULL && ac_ops[i].str != NULL; i++) { int len = strlen(ac_ops[i].str); printf("ACL for %s:%*s %s\n", ac_ops[i].str, (12 > len) ? (12 - len) : 0, "", util_acl_to_str(sc_file_get_acl_entry(file, ac_ops[i].id))); } if (file->prop_attr_len) { printf("%-25s", "Proprietary attributes:"); util_hex_dump(stdout, file->prop_attr, file->prop_attr_len, " "); printf("\n"); } if (file->sec_attr_len) { printf("%-25s", "Security attributes:"); util_hex_dump(stdout, file->sec_attr, file->sec_attr_len, " "); printf("\n"); } printf("\n"); if (not_current) { sc_file_free(file); select_current_path_or_die(); } return 0; }
static int do_info(int argc, char **argv) { sc_file_t *file; sc_path_t path; size_t i; const char *st; int r, not_current = 1; if (!argc) { path = current_path; file = current_file; not_current = 0; } else if (argc == 1) { if (arg_to_path(argv[0], &path, 0) != 0) goto usage; r = sc_select_file(card, &path, &file); if (r) { printf("unable to select file: %s\n", sc_strerror(r)); return -1; } } else goto usage; switch (file->type) { case SC_FILE_TYPE_WORKING_EF: case SC_FILE_TYPE_INTERNAL_EF: st = "Elementary File"; break; case SC_FILE_TYPE_DF: st = "Dedicated File"; break; default: st = "Unknown File"; break; } printf("\n%s ID %04X\n\n", st, file->id); printf("%-15s", "File path:"); for (i = 0; i < path.len; i++) { for (i = 0; i < path.len; i++) { if ((i & 1) == 0 && i) printf("/"); printf("%02X", path.value[i]); } } printf("\n%-15s%lu bytes\n", "File size:", (unsigned long) file->size); if (file->type == SC_FILE_TYPE_DF) { const char *ops[] = { "SELECT", "LOCK", "DELETE", "CREATE", "REHABILITATE", "INVALIDATE", "LIST FILES", "CRYPTO", "DELETE SELF" }; if (file->namelen) { printf("%-15s", "DF name:"); util_print_binary(stdout, file->name, file->namelen); printf("\n"); } for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) { char buf[80]; sprintf(buf, "ACL for %s:", ops[i]); printf("%-25s%s\n", buf, util_acl_to_str(sc_file_get_acl_entry(file, i))); } } else { const char *structs[] = { "Unknown", "Transparent", "Linear fixed", "Linear fixed, SIMPLE-TLV", "Linear variable", "Linear variable TLV", "Cyclic, SIMPLE-TLV", }; const struct { const char * label; int op; } ops[] = { { "READ", SC_AC_OP_READ }, { "UPDATE", SC_AC_OP_UPDATE }, { "DELETE", SC_AC_OP_DELETE }, { "WRITE", SC_AC_OP_WRITE }, { "REHABILITATE", SC_AC_OP_REHABILITATE }, { "INVALIDATE", SC_AC_OP_INVALIDATE }, { "LIST_FILES", SC_AC_OP_LIST_FILES }, { "CRYPTO", SC_AC_OP_CRYPTO }, }; printf("%-15s%s\n", "EF structure:", structs[file->ef_structure]); for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) { char buf[80]; sprintf(buf, "ACL for %s:", ops[i].label); printf("%-25s%s\n", buf, util_acl_to_str(sc_file_get_acl_entry(file, ops[i].op))); } } if (file->prop_attr_len) { printf("%-25s", "Proprietary attributes:"); for (i = 0; i < file->prop_attr_len; i++) printf("%02X ", file->prop_attr[i]); printf("\n"); } if (file->sec_attr_len) { printf("%-25s", "Security attributes:"); for (i = 0; i < file->sec_attr_len; i++) printf("%02X ", file->sec_attr[i]); printf("\n"); } printf("\n"); if (not_current) { sc_file_free(file); select_current_path_or_die(); } return 0; usage: puts("Usage: info [file_id]"); return -1; }