changeset 145:c2889812788e

fc-simtool bfsearch implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 25 Feb 2021 06:03:13 +0000
parents 60411fd4b803
children 8d55571c8118
files simtool/Makefile simtool/bfsearch.c simtool/dispatch.c simtool/getresp.c
diffstat 4 files changed, 135 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/simtool/Makefile	Thu Feb 25 05:44:27 2021 +0000
+++ b/simtool/Makefile	Thu Feb 25 06:03:13 2021 +0000
@@ -1,13 +1,13 @@
 CC=	gcc
 CFLAGS=	-O2 -I/usr/include/PCSC -I../libcommon
 PROG=	fc-simtool
-OBJS=	a38.o chv.o chvext.o curfile.o dispatch.o dumpdir.o fplmn.o getresp.o \
-	grcard1.o grcard2.o hlread.o inval_rehab.o lndwrite.o main.o miscadm.o \
-	opldump.o pbcommon.o pbdump.o pberase.o pbrestore.o pbupd_imm.o \
-	pbupd_immhex.o plmnsel.o pnndump.o readcmd.o readops.o restorebin.o \
-	savebin.o script.o select.o smserase.o smsp_common.o smsp_dump.o \
-	smsp_erase.o smsp_restore.o smsp_set.o sstlist.o stktest.o sysmo.o \
-	telsum.o usersum.o writecmd.o writeops.o
+OBJS=	a38.o bfsearch.o chv.o chvext.o curfile.o dispatch.o dumpdir.o fplmn.o \
+	getresp.o grcard1.o grcard2.o hlread.o inval_rehab.o lndwrite.o main.o \
+	miscadm.o opldump.o pbcommon.o pbdump.o pberase.o pbrestore.o \
+	pbupd_imm.o pbupd_immhex.o plmnsel.o pnndump.o readcmd.o readops.o \
+	restorebin.o savebin.o script.o select.o smserase.o smsp_common.o \
+	smsp_dump.o smsp_erase.o smsp_restore.o smsp_set.o sstlist.o stktest.o \
+	sysmo.o telsum.o usersum.o writecmd.o writeops.o
 LIBS=	../libcommon/libcommon.a
 INSTBIN=/opt/freecalypso/bin
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/simtool/bfsearch.c	Thu Feb 25 06:03:13 2021 +0000
@@ -0,0 +1,96 @@
+/*
+ * This module implements a brute force search of file ID space at a given
+ * file system directory level.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "simresp.h"
+
+static
+parse_skip_ids(argv, array, total)
+	char **argv;
+	unsigned *array, total;
+{
+	unsigned n;
+
+	for (n = 0; n < total; n++) {
+		if (!isxdigit(argv[n][0]) || !isxdigit(argv[n][1]) ||
+		    !isxdigit(argv[n][2]) || !isxdigit(argv[n][3]) ||
+		    argv[n][4]) {
+			fprintf(stderr, "error: argument is not 4-digit hex\n");
+			return(-1);
+		}
+		array[n] = strtoul(argv[n], 0, 16);
+	}
+	return(0);
+}
+
+cmd_bfsearch(argc, argv, outf)
+	char **argv;
+	FILE *outf;
+{
+	unsigned skip_ids[8], num_skip_ids;
+	unsigned bfs, n;
+	int rc;
+
+	num_skip_ids = argc - 1;
+	rc = parse_skip_ids(argv + 1, skip_ids, num_skip_ids);
+	if (rc < 0)
+		return(rc);
+	rc = elem_select_op(skip_ids[0]);
+	if (rc < 0)
+		return(rc);
+	if (!rc) {
+		fprintf(stderr, "error: starting file ID 0x%04X not found\n",
+			skip_ids[0]);
+		return(-1);
+	}
+	for (bfs = 0; bfs <= 0xFFFF; bfs++) {
+		for (n = 0; n < num_skip_ids; n++) {
+			if (bfs == skip_ids[n])
+				break;
+		}
+		if (n < num_skip_ids)
+			continue;
+		rc = elem_select_op(bfs);
+		if (rc < 0)
+			return(rc);
+		if (!rc)
+			continue;
+		rc = get_response_op();
+		if (rc < 0)
+			return(rc);
+		if (sim_resp_data_len < 14)
+			printf("%04X: too-short response struct\n", bfs);
+		else {
+			switch (sim_resp_data[6]) {
+			case 0x01:
+				printf("%04X: MF\n", bfs);
+				break;
+			case 0x02:
+				printf("%04X: DF\n", bfs);
+				break;
+			case 0x04:
+				printf("%04X: EF (struct %02X)\n", bfs,
+					sim_resp_data[13]);
+				break;
+			default:
+				printf("%04X: unknown file type %02X\n", bfs,
+					sim_resp_data[6]);
+			}
+		}
+		rc = elem_select_op(skip_ids[0]);
+		if (rc < 0)
+			return(rc);
+		if (!rc) {
+			fprintf(stderr,
+			"reselecting starting file ID 0x%04X not-found error\n",
+				skip_ids[0]);
+			return(-1);
+		}
+	}
+	return(0);
+}
--- a/simtool/dispatch.c	Thu Feb 25 05:44:27 2021 +0000
+++ b/simtool/dispatch.c	Thu Feb 25 06:03:13 2021 +0000
@@ -10,6 +10,7 @@
 
 extern int cmd_a38();
 extern int cmd_apdu();
+extern int cmd_bfsearch();
 extern int cmd_cd();
 extern int cmd_change_chv();
 extern int cmd_disable_chv();
@@ -108,6 +109,7 @@
 	{"a38", 1, 1, 1, cmd_a38},
 	{"apdu", 1, 1, 0, cmd_apdu},
 	{"atr", 0, 0, 0, retrieve_atr},
+	{"bfsearch", 1, 8, 1, cmd_bfsearch},
 	{"cd", 1, 1, 0, cmd_cd},
 	{"change-chv1", 2, 2, 0, cmd_change_chv},
 	{"change-chv2", 2, 2, 0, cmd_change_chv},
--- a/simtool/getresp.c	Thu Feb 25 05:44:27 2021 +0000
+++ b/simtool/getresp.c	Thu Feb 25 06:03:13 2021 +0000
@@ -37,3 +37,33 @@
 	display_sim_resp_in_hex(outf);
 	return(0);
 }
+
+get_response_op()
+{
+	u_char cmd[5];
+	int rc;
+	unsigned expect_resp_len;
+
+	expect_resp_len = sim_resp_sw & 0xFF;
+	/* GET RESPONSE command APDU */
+	cmd[0] = 0xA0;
+	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: %04X\n",
+			sim_resp_sw);
+		return(-1);
+	}
+	if (sim_resp_data_len != expect_resp_len) {
+		fprintf(stderr,
+			"error: GET RESPONSE returned %u bytes, expected %u\n",
+			sim_resp_data_len, expect_resp_len);
+		return(-1);
+	}
+	return(0);
+}