# HG changeset patch # User Mychaela Falconia # Date 1612402614 0 # Node ID 5af88fa11b54261cd9dcfc104c3999d8756e3319 # Parent d0929cb42e1c93ce1459ecf6850e01d0c947d58d fc-uicc-tool: SELECT response parsing implemented (basic) diff -r d0929cb42e1c -r 5af88fa11b54 uicc/select.c --- a/uicc/select.c Thu Feb 04 00:23:33 2021 +0000 +++ b/uicc/select.c Thu Feb 04 01:36:54 2021 +0000 @@ -56,10 +56,85 @@ return(0); } +select_resp_header_check(ret_offset, ret_length) + unsigned *ret_offset, *ret_length; +{ + unsigned offset, len; + + if (sim_resp_data_len < 2) { +tooshort: fprintf(stderr, "error: SELECT response is too short\n"); + return(-1); + } + if (sim_resp_data[0] != 0x62) { + fprintf(stderr, "error: SELECT response first byte != 0x62\n"); + return(-1); + } + len = sim_resp_data[1]; + if (len <= 0x7F) { + offset = 2; +return_check: if (offset + len > sim_resp_data_len) + goto tooshort; + if (ret_offset) + *ret_offset = offset; + if (ret_length) + *ret_length = len; + return(0); + } + if (len != 0x81) { + fprintf(stderr, "SELECT response: first length byte is bad\n"); + return(-1); + } + if (sim_resp_data_len < 3) + goto tooshort; + len = sim_resp_data[2]; + offset = 3; + goto return_check; +} + +parse_and_display_select_response() +{ + unsigned offset, totlen, reclen, n; + u_char *dp, *endp; + int rc; + + rc = select_resp_header_check(&offset, &totlen); + if (rc < 0) + return(rc); + dp = sim_resp_data + offset; + endp = sim_resp_data + offset + totlen; + while (dp < endp) { + if (endp - dp < 2) { +trunc_error: fprintf(stderr, + "error: truncated TLV record in SELECT response\n"); + return(-1); + } + if ((dp[0] & 0x1F) == 0x1F) { + fprintf(stderr, + "error: extended tag not supported in SELECT response\n"); + return(-1); + } + if (dp[1] & 0x80) { + fprintf(stderr, + "error: extended length not supported in SELECT response\n"); + return(-1); + } + reclen = dp[1] + 2; + if (endp - dp < reclen) + goto trunc_error; + for (n = 0; n < reclen; n++) { + if (n) + putchar(' '); + printf("%02X", *dp++); + } + putchar('\n'); + } + return(0); +} + cmd_select(argc, argv) char **argv; { - int file_id; + int file_id, rc; if (isxdigit(argv[1][0]) && isxdigit(argv[1][1]) && isxdigit(argv[1][2]) && isxdigit(argv[1][3]) && !argv[1][4]) @@ -71,5 +146,8 @@ "error: file ID argument is not a hex value or a recognized symbolic name\n"); return(-1); } - return select_op(file_id); + rc = select_op(file_id); + if (rc < 0) + return(rc); + return parse_and_display_select_response(); }