# HG changeset patch # User Mychaela Falconia # Date 1612414268 0 # Node ID baf5bd69876499b80ea342162b2f7f905c7714ea # Parent c331560c15a41bb6e16c693927e4ed50d4301afd fc-uicc-tool: select-aid command implemented diff -r c331560c15a4 -r baf5bd698764 uicc/Makefile --- a/uicc/Makefile Thu Feb 04 04:27:09 2021 +0000 +++ b/uicc/Makefile Thu Feb 04 04:51:08 2021 +0000 @@ -2,8 +2,8 @@ CFLAGS= -O2 -I/usr/include/PCSC PROG= fc-uicc-tool OBJS= alpha_decode.o alpha_valid.o apdu.o atr.o cardconnect.o dispatch.o \ - dumpdir.o exit.o globals.o hexdump.o hlread.o main.o names.o pbcommon.o\ - pbdump.o readcmd.o readops.o script.o select.o telsum.o + dumpdir.o exit.o globals.o hexdump.o hexstr.o hlread.o main.o names.o \ + pbcommon.o pbdump.o readcmd.o readops.o script.o select.o telsum.o all: ${PROG} diff -r c331560c15a4 -r baf5bd698764 uicc/dispatch.c --- a/uicc/dispatch.c Thu Feb 04 04:27:09 2021 +0000 +++ b/uicc/dispatch.c Thu Feb 04 04:51:08 2021 +0000 @@ -16,6 +16,7 @@ extern int cmd_readbin(); extern int cmd_readrec(); extern int cmd_select(); +extern int cmd_select_aid(); extern int cmd_telecom_sum(); extern int display_sim_resp_in_hex(); @@ -37,6 +38,7 @@ {"readbin", 2, 2, cmd_readbin}, {"readrec", 2, 2, cmd_readrec}, {"select", 1, 1, cmd_select}, + {"select-aid", 1, 1, cmd_select_aid}, {"sim-resp", 0, 0, display_sim_resp_in_hex}, {"telecom-sum", 0, 0, cmd_telecom_sum}, {0, 0, 0, 0} diff -r c331560c15a4 -r baf5bd698764 uicc/hexstr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uicc/hexstr.c Thu Feb 04 04:51:08 2021 +0000 @@ -0,0 +1,52 @@ +/* + * This module contains the function for decoding hex strings. + */ + +#include +#include +#include +#include +#include +#include + +decode_hex_digit(c) +{ + if (c >= '0' && c <= '9') + return(c - '0'); + if (c >= 'A' && c <= 'F') + return(c - 'A' + 10); + if (c >= 'a' && c <= 'f') + return(c - 'a' + 10); + return(-1); +} + +decode_hex_data_from_string(arg, databuf, maxlen) + char *arg; + u_char *databuf; + unsigned maxlen; +{ + unsigned count; + + for (count = 0; ; count++) { + while (isspace(*arg)) + arg++; + if (!*arg) + break; + if (!isxdigit(arg[0]) || !isxdigit(arg[1])) { + fprintf(stderr, "error: invalid hex string input\n"); + return(-1); + } + if (count >= maxlen) { + fprintf(stderr, "error: hex input data is too long\n"); + return(-1); + } + databuf[count] = (decode_hex_digit(arg[0]) << 4) | + decode_hex_digit(arg[1]); + arg += 2; + } + if (!count) { + fprintf(stderr, "error: empty hex string argument\n"); + return(-1); + } + return(count); +} diff -r c331560c15a4 -r baf5bd698764 uicc/select.c --- a/uicc/select.c Thu Feb 04 04:27:09 2021 +0000 +++ b/uicc/select.c Thu Feb 04 04:51:08 2021 +0000 @@ -56,6 +56,54 @@ return(0); } +select_aid_op(aid, aid_len) + u_char *aid; + unsigned aid_len; +{ + u_char cmd[21]; + int rc; + unsigned expect_resp_len; + + /* SELECT command APDU */ + cmd[0] = 0x00; + cmd[1] = 0xA4; + cmd[2] = 0x04; + cmd[3] = 0x04; + cmd[4] = aid_len; + bcopy(aid, cmd + 5, aid_len); + rc = apdu_exchange(cmd, aid_len + 5); + if (rc < 0) + return(rc); + if ((sim_resp_sw & 0xFF00) != 0x6100) { + fprintf(stderr, + "error or unexpected SW response to SELECT by AID: %04X\n", + sim_resp_sw); + return(-1); + } + expect_resp_len = sim_resp_sw & 0xFF; + /* GET RESPONSE follow-up */ + cmd[1] = 0xC0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = expect_resp_len; + rc = apdu_exchange(cmd, 5); + if (rc < 0) + return(rc); + if (sim_resp_sw != 0x9000) { + fprintf(stderr, + "bad SW resp to GET RESPONSE after SELECT: %04X\n", + sim_resp_sw); + return(-1); + } + if (sim_resp_data_len != expect_resp_len) { + fprintf(stderr, + "error: GET RESPONSE after SELECT returned %u bytes, expected %u\n", + sim_resp_data_len, expect_resp_len); + return(-1); + } + return(0); +} + select_resp_header_check(ret_offset, ret_length) unsigned *ret_offset, *ret_length; { @@ -152,6 +200,23 @@ return parse_and_display_select_response(); } +cmd_select_aid(argc, argv) + char **argv; +{ + u_char aid[16]; + unsigned aid_len; + int rc; + + rc = decode_hex_data_from_string(argv[1], aid, 16); + if (rc < 0) + return(rc); + aid_len = rc; + rc = select_aid_op(aid, aid_len); + if (rc < 0) + return(rc); + return parse_and_display_select_response(); +} + u_char * extract_select_resp_tag(sought_tag) unsigned sought_tag;