changeset 153:2ef31306be22

fc-uicc-tool bfsearch-{adf,mf} implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 25 Feb 2021 17:46:53 +0000
parents 77832c9f2001
children 6d93a51f01dc
files uicc/Makefile uicc/bfsearch.c uicc/dispatch.c
diffstat 3 files changed, 135 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/uicc/Makefile	Thu Feb 25 17:22:20 2021 +0000
+++ b/uicc/Makefile	Thu Feb 25 17:46:53 2021 +0000
@@ -1,8 +1,8 @@
 CC=	gcc
 CFLAGS=	-O2 -I/usr/include/PCSC -I../libcommon
 PROG=	fc-uicc-tool
-OBJS=	createfile.o dispatch.o dumpdir.o getresp.o hlread.o main.o pins.o \
-	readcmd.o readops.o script.o select.o writecmd.o writeops.o
+OBJS=	bfsearch.o createfile.o dispatch.o dumpdir.o getresp.o hlread.o main.o \
+	pins.o readcmd.o readops.o script.o select.o writecmd.o writeops.o
 LIBS=	../libcommon/libcommon.a
 INSTBIN=/opt/freecalypso/bin
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uicc/bfsearch.c	Thu Feb 25 17:46:53 2021 +0000
@@ -0,0 +1,129 @@
+/*
+ * 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 (!rc) {
+			fprintf(stderr,
+				"error selecting 0x%04X: file not found\n",
+				path[n]);
+			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 (!rc)
+			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 (!rc) {
+			fprintf(stderr,
+			"reselecting starting file ID 0x%04X not-found error\n",
+				path[pathlen-1]);
+			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);
+}
--- a/uicc/dispatch.c	Thu Feb 25 17:22:20 2021 +0000
+++ b/uicc/dispatch.c	Thu Feb 25 17:46:53 2021 +0000
@@ -9,6 +9,8 @@
 #include <stdlib.h>
 
 extern int cmd_apdu();
+extern int cmd_bfsearch_adf();
+extern int cmd_bfsearch_mf();
 extern int cmd_cd();
 extern int cmd_change_pin();
 extern int cmd_create_file();
@@ -48,6 +50,8 @@
 } cmdtab[] = {
 	{"apdu", 1, 1, 0, cmd_apdu},
 	{"atr", 0, 0, 0, retrieve_atr},
+	{"bfsearch-adf", 0, 0, 1, cmd_bfsearch_adf},
+	{"bfsearch-mf", 0, 0, 1, cmd_bfsearch_mf},
 	{"cd", 1, 1, 0, cmd_cd},
 	{"change-pin", 3, 3, 0, cmd_change_pin},
 	{"create-file", 1, 1, 0, cmd_create_file},