FreeCalypso > hg > fc-pcsc-tools
view uicc/bfsearch.c @ 155:cb3c40ff443e
fc-uicc-tool bfsearch: handle more weird SW response cases
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 25 Feb 2021 20:17:10 +0000 |
parents | 2ef31306be22 |
children | 5f1f3f6fd865 |
line wrap: on
line source
/* * This module implements a brute force search of file ID space, * both MF and ADF trees. */ #include <sys/types.h> #include <stdio.h> #include "simresp.h" #include "file_id.h" extern u_char *extract_select_resp_tag(); static bfsearch_dir(path, pathlen, siblings, nsiblings, outf) unsigned *path, pathlen, *siblings, nsiblings; FILE *outf; { unsigned bfs, n; unsigned df_children[255], ndfc; unsigned childpath[8]; u_char *tlv_file_desc, *tlv_file_size; int rc; for (n = 0; n < pathlen; n++) { rc = elem_select_op(path[n]); if (rc < 0) return(rc); if ((sim_resp_sw & 0xFF00) != 0x6100) { fprintf(stderr, "error selecting 0x%04X: SW resp 0x%04X\n", path[n], sim_resp_sw); return(-1); } } ndfc = 0; for (bfs = 0; bfs <= 0xFFFF; bfs++) { if (bfs == FILEID_MF || bfs == FILEID_ADF) continue; for (n = 0; n < pathlen; n++) { if (bfs == path[n]) break; } if (n < pathlen) continue; for (n = 0; n < nsiblings; n++) { if (bfs == siblings[n]) break; } if (n < nsiblings) continue; rc = elem_select_op(bfs); if (rc < 0) return(rc); if (sim_resp_sw == 0x6A82) continue; if ((sim_resp_sw & 0xFF00) != 0x6100) { for (n = 0; n < pathlen; n++) fprintf(outf, "%04X/", path[n]); fprintf(outf, "%04X: SW response 0x%04X", bfs, sim_resp_sw); continue; } rc = get_response_op(); if (rc < 0) return(rc); tlv_file_desc = extract_select_resp_tag(0x82); if (!tlv_file_desc) return(-1); if (tlv_file_desc[1] < 1) { fprintf(stderr, "error: file desc TLV object is too short\n"); return(-1); } for (n = 0; n < pathlen; n++) fprintf(outf, "%04X/", path[n]); fprintf(outf, "%04X: file desc 0x%02X", bfs, tlv_file_desc[2]); if ((tlv_file_desc[2] & 0xBF) == 0x38) { fprintf(outf, ", DF\n"); if (ndfc < 255) df_children[ndfc++] = bfs; } else { tlv_file_size = extract_select_resp_tag(0x80); if (tlv_file_size && tlv_file_size[1] == 2) fprintf(outf, ", total size %u", (tlv_file_size[2] << 8) | tlv_file_size[3]); if (tlv_file_desc[1] == 5) fprintf(outf, ", %u records of %u bytes", tlv_file_desc[6], (tlv_file_desc[4] << 8) | tlv_file_desc[5]); putc('\n', outf); } rc = elem_select_op(path[pathlen-1]); if (rc < 0) return(rc); if ((sim_resp_sw & 0xFF00) != 0x6100) { fprintf(stderr, "reselecting starting file ID 0x%04X: SW resp 0x%04X\n", path[pathlen-1], sim_resp_sw); return(-1); } } if (pathlen >= 8) return(0); for (n = 0; n < pathlen; n++) childpath[n] = path[n]; for (n = 0; n < ndfc; n++) { childpath[pathlen] = df_children[n]; rc = bfsearch_dir(childpath, pathlen + 1, df_children, ndfc, outf); if (rc < 0) return(rc); } return(0); } cmd_bfsearch_mf(argc, argv, outf) char **argv; FILE *outf; { unsigned initpath; initpath = FILEID_MF; return bfsearch_dir(&initpath, 1, &initpath, 1, outf); } cmd_bfsearch_adf(argc, argv, outf) char **argv; FILE *outf; { unsigned initpath; initpath = FILEID_ADF; return bfsearch_dir(&initpath, 1, &initpath, 1, outf); }