# HG changeset patch # User Mychaela Falconia # Date 1616479626 0 # Node ID 97646b363eaa07404ed07f96ffedf4649284e97f # Parent a4ffd4e44b76fa7ffac84f60a456891ec546af29 fc-uicc-tool: sws-lookup and sws-auth-* commands ported over diff -r a4ffd4e44b76 -r 97646b363eaa uicc/Makefile --- 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 diff -r a4ffd4e44b76 -r 97646b363eaa uicc/cmdtab.c --- 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}, diff -r a4ffd4e44b76 -r 97646b363eaa uicc/hlread.c --- 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); } diff -r a4ffd4e44b76 -r 97646b363eaa uicc/pins.c --- 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; { diff -r a4ffd4e44b76 -r 97646b363eaa uicc/sws.c --- /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 +#include +#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); +}