changeset 66:3ef90bd13fbe

fc-simtool write-imsi command implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 15 Feb 2021 00:28:10 +0000
parents cc48ac3b151c
children 9ff7ee99346f
files libcommon/Makefile libcommon/decimal_str.c simtool/Makefile simtool/miscadm.c
diffstat 4 files changed, 109 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/libcommon/Makefile	Sun Feb 14 23:03:00 2021 +0000
+++ b/libcommon/Makefile	Mon Feb 15 00:28:10 2021 +0000
@@ -1,10 +1,10 @@
 CC=	gcc
 CFLAGS=	-O2 -I/usr/include/PCSC
 OBJS=	alpha_decode.o alpha_fromfile.o alpha_valid.o apdu.o atr.o \
-	cardconnect.o chkblank.o dumpdirfunc.o exit.o globalopts.o \
-	gsm7_decode.o gsm7_encode.o gsm7_encode_table.o gsm7_unpack.o hexdump.o\
-	hexread.o hexstr.o names.o number_decode.o number_encode.o pinentry.o \
-	plmncodes.o revnibbles.o
+	cardconnect.o chkblank.o decimal_str.o dumpdirfunc.o exit.o \
+	globalopts.o gsm7_decode.o gsm7_encode.o gsm7_encode_table.o \
+	gsm7_unpack.o hexdump.o hexread.o hexstr.o names.o number_decode.o \
+	number_encode.o pinentry.o plmncodes.o revnibbles.o
 LIB=	libcommon.a
 
 all:	${LIB}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/decimal_str.c	Mon Feb 15 00:28:10 2021 +0000
@@ -0,0 +1,56 @@
+/*
+ * This module implements some functions for initial parsing of decimal
+ * string arguments, intended for implementation of commands like
+ * write-iccid and write-imsi.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <stdio.h>
+
+parse_decimal_string_arg(arg, dest, maxdigits)
+	char *arg;
+	u_char *dest;
+	unsigned maxdigits;
+{
+	unsigned n, ndig;
+
+	if (!*arg) {
+		fprintf(stderr,
+			"error: empty argument given for decimal string\n");
+		return(-1);
+	}
+	for (n = 0; *arg; ) {
+		if (!isdigit(*arg)) {
+			fprintf(stderr,
+			"error: non-digit char in decimal string argument\n");
+			return(-1);
+		}
+		if (n >= maxdigits) {
+			fprintf(stderr,
+			"error: decimal string exceeds limit of %u digits\n",
+				maxdigits);
+			return(-1);
+		}
+		dest[n++] = *arg++ - '0';
+	}
+	ndig = n;
+	while (n < maxdigits)
+		dest[n++] = 0xF;
+	return ndig;
+}
+
+pack_reversed_nibbles(nibbles, bytes, nbytes)
+	u_char *nibbles, *bytes;
+	unsigned nbytes;
+{
+	u_char *sp, *dp;
+	unsigned n;
+
+	sp = nibbles;
+	dp = bytes;
+	for (n = 0; n < nbytes; n++) {
+		*dp++ = sp[0] | (sp[1] << 4);
+		sp += 2;
+	}
+}
--- a/simtool/Makefile	Sun Feb 14 23:03:00 2021 +0000
+++ b/simtool/Makefile	Mon Feb 15 00:28:10 2021 +0000
@@ -2,11 +2,11 @@
 CFLAGS=	-O2 -I/usr/include/PCSC -I../libcommon
 PROG=	fc-simtool
 OBJS=	a38.o chv.o chvext.o curfile.o dispatch.o dumpdir.o grcard1.o grcard2.o\
-	hlread.o main.o opldump.o pbcommon.o pbdump.o pberase.o pbupd_file.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 sysmo.o \
-	telsum.o usersum.o writecmd.o writeops.o
+	hlread.o main.o miscadm.o opldump.o pbcommon.o pbdump.o pberase.o \
+	pbupd_file.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 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/miscadm.c	Mon Feb 15 00:28:10 2021 +0000
@@ -0,0 +1,44 @@
+/*
+ * This module implements write-iccid and write-imsi commands,
+ * available only in the admin programming phase after authenticating
+ * with some card-vendor-dependent ADM key.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include "curfile.h"
+#include "file_id.h"
+
+cmd_write_imsi(argc, argv)
+	char **argv;
+{
+	int rc;
+	u_char nibbles[16], binrec[9];
+	unsigned ndig;
+
+	rc = parse_decimal_string_arg(argv[1], nibbles + 1, 15);
+	if (rc < 0)
+		return(rc);
+	ndig = rc;
+	if (ndig & 1)
+		nibbles[0] = 9;
+	else
+		nibbles[0] = 1;
+	binrec[0] = (ndig + 2) >> 1;
+	pack_reversed_nibbles(nibbles, binrec + 1, 8);
+	rc = select_op(DF_GSM);
+	if (rc < 0)
+		return(rc);
+	rc = select_op(EF_IMSI);
+	if (rc < 0)
+		return(rc);
+	rc = parse_ef_select_response();
+	if (rc < 0)
+		return(rc);
+	if (curfile_structure != 0x00 || curfile_total_size != 9) {
+		fprintf(stderr,
+			"error: EF_IMSI is not a transparent EF of 9 bytes\n");
+		return(-1);
+	}
+	return update_bin_op(0, binrec, 9);
+}