diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 40646fb7..85ab0857 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -292,6 +292,14 @@ Files are found by selecting all file identifiers in the range from start-fid to end-fid (by default from 0000 to FFFF). + + + find_tags [start-tag [end-tag]] + + Find all tags of data objects in the current context. + Tags are found by using GET DATA in the range from start-tag to end-tag (by default from 0000 to FFFF). + + mkdir file-id size diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index b6b208ae..1a716030 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -1217,35 +1217,6 @@ cardos_logout(sc_card_t *card) return SC_ERROR_NOT_SUPPORTED; } -static int cardos_get_data(struct sc_card *card, unsigned int tag, u8 *buf, size_t len) -{ - int r; - struct sc_apdu apdu; - - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, - (tag >> 8) & 0xff, tag & 0xff); - apdu.lc = 0; - apdu.datalen = 0; - apdu.le = len; - apdu.resp = buf; - apdu.resplen = len; - r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "GET_DATA returned error"); - - if (apdu.resplen > len) - r = SC_ERROR_WRONG_LENGTH; - else - r = apdu.resplen; - - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); -} - - /* eToken R2 supports WRITE_BINARY, PRO Tokens support UPDATE_BINARY */ static struct sc_card_driver * sc_get_driver(void) @@ -1266,7 +1237,6 @@ static struct sc_card_driver * sc_get_driver(void) cardos_ops.card_ctl = cardos_card_ctl; cardos_ops.pin_cmd = cardos_pin_cmd; cardos_ops.logout = cardos_logout; - cardos_ops.get_data = cardos_get_data; return &cardos_drv; } diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 19f9e7e3..baa15814 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1128,6 +1128,38 @@ iso7816_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_l } +static int iso7816_get_data(struct sc_card *card, unsigned int tag, u8 *buf, size_t len) +{ + int r, cse; + struct sc_apdu apdu; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (buf && len) + cse = SC_APDU_CASE_2; + else + cse = SC_APDU_CASE_1; + + sc_format_apdu(card, &apdu, cse, 0xCA, (tag >> 8) & 0xff, tag & 0xff); + apdu.le = len; + apdu.resp = buf; + apdu.resplen = len; + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "GET_DATA returned error"); + + if (apdu.resplen > len) + r = SC_ERROR_WRONG_LENGTH; + else + r = apdu.resplen; + + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); +} + + + static int iso7816_init(struct sc_card *card) { @@ -1175,7 +1207,7 @@ static struct sc_card_operations iso_ops = { iso7816_process_fci, iso7816_construct_fci, iso7816_pin_cmd, - NULL, /* get_data */ + iso7816_get_data, NULL, /* put_data */ NULL, /* delete_record */ NULL /* read_public_key */ diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 75588df7..22943596 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -85,6 +85,7 @@ static const char *option_help[] = { static int do_echo(int argc, char **argv); static int do_ls(int argc, char **argv); static int do_find(int argc, char **argv); +static int do_find_tags(int argc, char **argv); static int do_cd(int argc, char **argv); static int do_cat(int argc, char **argv); static int do_info(int argc, char **argv); @@ -127,6 +128,9 @@ static struct command cmds[] = { { do_find, "find", "[ []]", "find all files in the current DF" }, + { do_find_tags, + "find_tags", "[ []]", + "find all tags of data objects in the current context" }, { do_cd, "cd", "{.. | | aid:}", "change to another DF" }, @@ -579,6 +583,73 @@ static int do_find(int argc, char **argv) return 0; } +static int do_find_tags(int argc, char **argv) +{ + u8 start[2], end[2], rbuf[256]; + int r; + unsigned int tag, tag_end; + + start[0] = 0x00; + start[1] = 0x00; + end[0] = 0xFF; + end[1] = 0xFF; + switch (argc) { + case 2: + if (arg_to_fid(argv[1], end) != 0) + return usage(do_find_tags); + /* fall through */ + case 1: + if (arg_to_fid(argv[0], start) != 0) + return usage(do_find_tags); + /* fall through */ + case 0: + break; + default: + return usage(do_find_tags); + } + tag = (start[0] << 8) | start[1]; + tag_end = (end[0] << 8) | end[1]; + + printf("Tag\tType\n"); + while (1) { + printf("(%04X)\r", tag); + fflush(stdout); + + r = sc_get_data(card, tag, rbuf, sizeof rbuf); + if (r >= 0) { + printf(" %04X ", tag); + if (tag == 0) + printf("\tdump file"); + if ((0x0001 <= tag && tag <= 0x00FE) + || (0x1F1F <= tag && tag <= 0xFFFF)) + printf("\tBER-TLV"); + if (tag == 0x00FF || tag == 0x02FF) + printf("\tspecial function"); + if (0x0100 <= tag && tag <= 0x01FF) + printf("\tproprietary"); + if (tag == 0x0200) + printf("\tRFU"); + if (0x0201 <= tag && tag <= 0x02FE) + printf("\tSIMPLE-TLV"); + printf("\n"); + if (r > 0) + util_hex_dump_asc(stdout, rbuf, r, -1); + } else { + switch (r) { + case SC_ERROR_NOT_ALLOWED: + case SC_ERROR_SECURITY_STATUS_NOT_SATISFIED: + printf("(%04X)\t%s\n", tag, sc_strerror(r)); + break; + } + } + + if (tag >= tag_end) + break; + tag++; + } + return 0; +} + static int do_cd(int argc, char **argv) { sc_path_t path;