changeset 61:97646b363eaa

fc-uicc-tool: sws-lookup and sws-auth-* commands ported over
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 23 Mar 2021 06:07:06 +0000
parents a4ffd4e44b76
children 6ccc4d952830
files uicc/Makefile uicc/cmdtab.c uicc/hlread.c uicc/pins.c uicc/sws.c
diffstat 5 files changed, 146 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/uicc/Makefile	Tue Mar 23 05:27:28 2021 +0000
+++ b/uicc/Makefile	Tue Mar 23 06:07:06 2021 +0000
@@ -3,7 +3,7 @@
 CPPFLAGS=-I../libcommon
 PROG=	fc-uicc-tool
 OBJS=	bfsearch.o cmdtab.o createfile.o dumpdir.o getresp.o hlread.o main.o \
-	pins.o readcmd.o readops.o select.o writecmd.o writeops.o
+	pins.o readcmd.o readops.o select.o sws.o writecmd.o writeops.o
 LIBS=	../libcommon/libcommon.a ../libutil/libutil.a
 
 INSTALL_PREFIX=	/opt/freecalypso
--- a/uicc/cmdtab.c	Tue Mar 23 05:27:28 2021 +0000
+++ b/uicc/cmdtab.c	Tue Mar 23 06:07:06 2021 +0000
@@ -30,6 +30,10 @@
 extern int cmd_select_isim();
 extern int cmd_select_usim();
 extern int cmd_sim_resp();
+extern int cmd_sws_auth_adm1();
+extern int cmd_sws_auth_pin1();
+extern int cmd_sws_auth_pin2();
+extern int cmd_sws_lookup();
 extern int cmd_unblock_pin();
 extern int cmd_update_bin();
 extern int cmd_update_bin_imm();
@@ -65,6 +69,10 @@
 	{"select-isim", 0, 0, 1, cmd_select_isim},
 	{"select-usim", 0, 0, 1, cmd_select_usim},
 	{"sim-resp", 0, 0, 1, cmd_sim_resp},
+	{"sws-auth-adm1", 0, 0, 0, cmd_sws_auth_adm1},
+	{"sws-auth-pin1", 0, 0, 0, cmd_sws_auth_pin1},
+	{"sws-auth-pin2", 0, 0, 0, cmd_sws_auth_pin2},
+	{"sws-lookup", 1, 18, 1, cmd_sws_lookup},
 	{"unblock-pin", 3, 3, 0, cmd_unblock_pin},
 	{"update-bin", 2, 2, 0, cmd_update_bin},
 	{"update-bin-imm", 2, 2, 0, cmd_update_bin_imm},
--- a/uicc/hlread.c	Tue Mar 23 05:27:28 2021 +0000
+++ b/uicc/hlread.c	Tue Mar 23 06:07:06 2021 +0000
@@ -7,13 +7,12 @@
 #include "simresp.h"
 #include "file_id.h"
 
-cmd_iccid(argc, argv, outf)
-	char **argv;
-	FILE *outf;
+retrieve_iccid(buf)
+	char *buf;
 {
 	int rc;
 	unsigned len;
-	char buf[21], *cp;
+	char *cp;
 
 	rc = select_op(FILEID_MF);
 	if (rc < 0)
@@ -35,6 +34,19 @@
 	for (cp = buf + 20; (cp > buf + 1) && (cp[-1] == 'F'); cp--)
 		;
 	*cp = '\0';
+	return(0);
+}
+
+cmd_iccid(argc, argv, outf)
+	char **argv;
+	FILE *outf;
+{
+	int rc;
+	char buf[21];
+
+	rc = retrieve_iccid(buf);
+	if (rc < 0)
+		return(rc);
 	fprintf(outf, "%s\n", buf);
 	return(0);
 }
--- a/uicc/pins.c	Tue Mar 23 05:27:28 2021 +0000
+++ b/uicc/pins.c	Tue Mar 23 06:07:06 2021 +0000
@@ -59,6 +59,33 @@
 	return(0);
 }
 
+verify_pin_func(p2, pin)
+	unsigned p2;
+	char *pin;
+{
+	u_char cmd[13];
+	int rc;
+
+	/* VERIFY PIN command APDU */
+	cmd[0] = 0x00;
+	cmd[1] = 0x20;
+	cmd[2] = 0x00;
+	cmd[3] = p2;
+	cmd[4] = 8;
+	rc = encode_pin_entry(pin, cmd + 5);
+	if (rc < 0)
+		return(rc);
+	rc = apdu_exchange(cmd, 13);
+	if (rc < 0)
+		return(rc);
+	if (sim_resp_sw != 0x9000) {
+		fprintf(stderr, "bad SW response to VERIFY PIN: %04X\n",
+			sim_resp_sw);
+		return(-1);
+	}
+	return(0);
+}
+
 cmd_change_pin(argc, argv)
 	char **argv;
 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uicc/sws.c	Tue Mar 23 06:07:06 2021 +0000
@@ -0,0 +1,94 @@
+/*
+ * This module implements a few high-level commands for working with
+ * Sysmocom webshop SIM cards, using sws-card-db to look up per-card data.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include "../libutil/dbread.h"
+
+static char sws_card_db_file[] = "/opt/freecalypso/sim-data/sws-card-db";
+
+static
+lookup_sws_card(dbs)
+	struct dbread_state *dbs;
+{
+	int rc;
+	char iccid[21];
+
+	rc = retrieve_iccid(iccid);
+	if (rc < 0)
+		return(rc);
+	return dbread_find_record(sws_card_db_file, dbs, "ICCID", iccid);
+}
+
+cmd_sws_lookup(argc, argv, outf)
+	char **argv;
+	FILE *outf;
+{
+	int rc;
+	struct dbread_state dbs;
+	char **kp, *val;
+
+	rc = lookup_sws_card(&dbs);
+	if (rc < 0)
+		return(rc);
+	if (argc == 2) {
+		val = dbread_find_key_req(&dbs, argv[1]);
+		if (!val)
+			return(-1);
+		fprintf(outf, "%s\n", val);
+		return(0);
+	}
+	for (kp = argv + 1; *kp; kp++) {
+		val = dbread_find_key(&dbs, *kp);
+		if (val)
+			fprintf(outf, "%s=%s\n", *kp, val);
+	}
+	return(0);
+}
+
+cmd_sws_auth_adm1()
+{
+	int rc;
+	struct dbread_state dbs;
+	char *pin;
+
+	rc = lookup_sws_card(&dbs);
+	if (rc < 0)
+		return(rc);
+	pin = dbread_find_key_req(&dbs, "ADM1");
+	if (!pin)
+		return(-1);
+	return verify_pin_func(0x0A, pin);
+}
+
+cmd_sws_auth_pin1()
+{
+	int rc;
+	struct dbread_state dbs;
+	char *pin;
+
+	rc = lookup_sws_card(&dbs);
+	if (rc < 0)
+		return(rc);
+	pin = dbread_find_key_req(&dbs, "PIN1");
+	if (!pin)
+		return(-1);
+	return verify_pin_func(0x01, pin);
+}
+
+cmd_sws_auth_pin2()
+{
+	int rc;
+	struct dbread_state dbs;
+	char *pin;
+
+	rc = lookup_sws_card(&dbs);
+	if (rc < 0)
+		return(rc);
+	pin = dbread_find_key_req(&dbs, "PIN2");
+	if (!pin)
+		return(-1);
+	return verify_pin_func(0x81, pin);
+}