changeset 144:429a8f80426e

fc-uicc-tool: catch record length from manual select
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 06 Feb 2021 02:03:11 +0000
parents 431194b772e1
children 14dee03e9675
files uicc/dispatch.c uicc/globals.c uicc/globals.h uicc/readcmd.c uicc/select.c
diffstat 5 files changed, 41 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/uicc/dispatch.c	Thu Feb 04 05:12:24 2021 +0000
+++ b/uicc/dispatch.c	Sat Feb 06 02:03:11 2021 +0000
@@ -38,7 +38,7 @@
 	{"pb-dump-rec", 2, 3, cmd_pb_dump_rec},
 	{"quit", 0, 0, good_exit},
 	{"readbin", 2, 2, cmd_readbin},
-	{"readrec", 2, 2, cmd_readrec},
+	{"readrec", 1, 2, cmd_readrec},
 	{"select", 1, 1, cmd_select},
 	{"select-aid", 1, 1, cmd_select_aid},
 	{"select-isim", 0, 0, cmd_select_isim},
--- a/uicc/globals.c	Thu Feb 04 05:12:24 2021 +0000
+++ b/uicc/globals.c	Sat Feb 06 02:03:11 2021 +0000
@@ -7,3 +7,4 @@
 char *reader_name_buf;
 u_char sim_resp_data[258];
 unsigned sim_resp_data_len, sim_resp_sw;
+unsigned last_sel_file_record_len;
--- a/uicc/globals.h	Thu Feb 04 05:12:24 2021 +0000
+++ b/uicc/globals.h	Sat Feb 06 02:03:11 2021 +0000
@@ -5,3 +5,4 @@
 extern char *reader_name_buf;
 extern u_char sim_resp_data[];
 extern unsigned sim_resp_data_len, sim_resp_sw;
+extern unsigned last_sel_file_record_len;
--- a/uicc/readcmd.c	Thu Feb 04 05:12:24 2021 +0000
+++ b/uicc/readcmd.c	Sat Feb 06 02:03:11 2021 +0000
@@ -40,10 +40,20 @@
 			"error: record number argument is out of range\n");
 		return(-1);
 	}
-	len = strtoul(argv[2], 0, 0);
-	if (len < 1 || len > 255) {
-		fprintf(stderr, "error: length argument is out of range\n");
-		return(-1);
+	if (argv[2]) {
+		len = strtoul(argv[2], 0, 0);
+		if (len < 1 || len > 255) {
+			fprintf(stderr,
+				"error: length argument is out of range\n");
+			return(-1);
+		}
+	} else {
+		if (!last_sel_file_record_len) {
+			fprintf(stderr,
+			"error: no current file record length is available\n");
+			return(-1);
+		}
+		len = last_sel_file_record_len;
 	}
 	rc = readrec_op(recno, 0x04, len);
 	if (rc < 0)
--- a/uicc/select.c	Thu Feb 04 05:12:24 2021 +0000
+++ b/uicc/select.c	Sat Feb 06 02:03:11 2021 +0000
@@ -18,6 +18,7 @@
 	int rc;
 	unsigned expect_resp_len;
 
+	last_sel_file_record_len = 0;
 	/* SELECT command APDU */
 	cmd[0] = 0x00;
 	cmd[1] = 0xA4;
@@ -67,6 +68,7 @@
 	int rc;
 	unsigned expect_resp_len;
 
+	last_sel_file_record_len = 0;
 	/* SELECT command APDU */
 	cmd[0] = 0x00;
 	cmd[1] = 0xA4;
@@ -142,6 +144,26 @@
 	goto return_check;
 }
 
+static void
+check_for_record_struct(tlv)
+	u_char *tlv;
+{
+	unsigned reclen;
+
+	if (tlv[1] != 5)
+		return;
+	if (tlv[2] & 0x80)
+		return;
+	if ((tlv[2] & 0x38) == 0x38)
+		return;
+	if ((tlv[2] & 0x03) != 0x02)
+		return;
+	reclen = (tlv[4] << 8) | tlv[5];
+	if (reclen < 1 || reclen > 255)
+		return;
+	last_sel_file_record_len = reclen;
+}
+
 parse_and_display_select_response()
 {
 	unsigned offset, totlen, reclen, n;
@@ -172,6 +194,8 @@
 		reclen = dp[1] + 2;
 		if (endp - dp < reclen)
 			goto trunc_error;
+		if (dp[0] == 0x82)
+			check_for_record_struct(dp);
 		for (n = 0; n < reclen; n++) {
 			if (n)
 				putchar(' ');