diff --git a/doc/tools/opensc-explorer.xml b/doc/tools/opensc-explorer.xml index dae38427..f53e16f2 100644 --- a/doc/tools/opensc-explorer.xml +++ b/doc/tools/opensc-explorer.xml @@ -104,8 +104,10 @@ [file-id] + sfi:sfi-id print the contents of the currently selected EF or the contents of a file - specified by file-id. + specified by file-id + or sfi-id. diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 84b0ff8c..0f9b2bd2 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -323,13 +323,14 @@ static int read_and_util_print_binary_file(sc_file_t *file) return 0; } -static int read_and_print_record_file(sc_file_t *file) +static int read_and_print_record_file(sc_file_t *file, unsigned long sfi) { u8 buf[256]; int rec, r; for (rec = 1; ; rec++) { - r = sc_read_record(card, rec, buf, sizeof(buf), SC_RECORD_BY_REC_NR); + r = sc_read_record(card, rec, buf, sizeof(buf), + SC_RECORD_BY_REC_NR | sfi); if (r == SC_ERROR_RECORD_NOT_FOUND) return 0; if (r < 0) { @@ -347,6 +348,8 @@ static int do_cat(int argc, char **argv) sc_path_t path; sc_file_t *file = NULL; int not_current = 1; + int sfi = 0; + const char sfi_prefix[] = "sfi:"; if (argc > 1) goto usage; @@ -355,23 +358,40 @@ static int do_cat(int argc, char **argv) file = current_file; not_current = 0; } else { - if (arg_to_path(argv[0], &path, 1) != 0) - goto usage; - - r = sc_select_file(card, &path, &file); - if (r) { - check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file); - goto err; + if (strncmp(argv[0], sfi_prefix, sizeof(sfi_prefix)-1)) { + if (arg_to_path(argv[0], &path, 1) != 0) + goto usage; + r = sc_select_file(card, &path, &file); + if (r) { + check_ret(r, SC_AC_OP_SELECT, "unable to select file", + current_file); + goto err; + } + } else { + if(!current_file) { + printf("A DF must be selected to read by SFI\n"); + goto err; + } + path = current_path; + file = current_file; + not_current = 0; + const char *sfi_n = &argv[0][sizeof(sfi_prefix)-1]; + sfi = atoi(sfi_n); + if ((sfi < 1) || (sfi > 30)) { + printf("Invalid SFI: %s\n", sfi_n); + goto usage; + } } } - if (file->type != SC_FILE_TYPE_WORKING_EF) { + if (file->type != SC_FILE_TYPE_WORKING_EF && + !(file->type == SC_FILE_TYPE_DF && sfi)) { printf("only working EFs may be read\n"); goto err; } - if (file->ef_structure == SC_FILE_EF_TRANSPARENT) + if (file->ef_structure == SC_FILE_EF_TRANSPARENT && !sfi) read_and_util_print_binary_file(file); else - read_and_print_record_file(file); + read_and_print_record_file(file, sfi); err = 0; @@ -385,7 +405,8 @@ err: return -err; usage: - puts("Usage: cat [file_id]"); + puts("Usage: cat [file_id] or"); + puts(" cat sfi:"); return -1; }