FreeCalypso > hg > fc-pcsc-tools
view simtool/chv.c @ 1:2071b28cd0c7
simtool: first refactored version
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 11 Feb 2021 23:04:28 +0000 |
parents | |
children | e9e8ce12f5a5 |
line wrap: on
line source
/* * This module implements the standard set of CHV commands * for GSM 11.11 SIMs. */ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include "simresp.h" encode_pin_entry(arg, dest) char *arg; u_char *dest; { unsigned n; n = 0; while (*arg) { if (!isdigit(*arg)) { fprintf(stderr, "error: PIN argument contains a non-digit character\n"); return(-1); } if (n >= 8) { fprintf(stderr, "error: PIN argument is too long\n"); return(-1); } *dest++ = *arg++; n++; } for (; n < 8; n++) *dest++ = 0xFF; return(0); } cmd_verify_chv(argc, argv) char **argv; { u_char cmd[13]; int rc; /* VERIFY CHV command APDU */ cmd[0] = 0xA0; cmd[1] = 0x20; cmd[2] = 0x00; switch (argv[0][10]) { case '1': cmd[3] = 0x01; break; case '2': cmd[3] = 0x02; break; default: fprintf(stderr, "BUG in verify-chvN command\n"); return(-1); } cmd[4] = 8; rc = encode_pin_entry(argv[1], 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: %04X\n", sim_resp_sw); return(-1); } return(0); } cmd_verify_ext(argc, argv) char **argv; { u_char cmd[13]; int rc; /* VERIFY CHV command APDU */ cmd[0] = 0xA0; cmd[1] = 0x20; cmd[2] = 0x00; cmd[3] = strtoul(argv[1], 0, 0); cmd[4] = 8; rc = encode_pin_entry(argv[2], 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: %04X\n", sim_resp_sw); return(-1); } return(0); } cmd_change_chv(argc, argv) char **argv; { u_char cmd[21]; int rc; /* CHANGE CHV command APDU */ cmd[0] = 0xA0; cmd[1] = 0x24; cmd[2] = 0x00; switch (argv[0][10]) { case '1': cmd[3] = 0x01; break; case '2': cmd[3] = 0x02; break; default: fprintf(stderr, "BUG in change-chvN command\n"); return(-1); } cmd[4] = 16; rc = encode_pin_entry(argv[1], cmd + 5); if (rc < 0) return(rc); rc = encode_pin_entry(argv[2], cmd + 13); if (rc < 0) return(rc); rc = apdu_exchange(cmd, 21); if (rc < 0) return(rc); if (sim_resp_sw != 0x9000) { fprintf(stderr, "bad SW response: %04X\n", sim_resp_sw); return(-1); } return(0); } cmd_disable_chv(argc, argv) char **argv; { u_char cmd[13]; int rc; /* DISABLE CHV command APDU */ cmd[0] = 0xA0; cmd[1] = 0x26; cmd[2] = 0x00; cmd[3] = 0x01; cmd[4] = 8; rc = encode_pin_entry(argv[1], 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: %04X\n", sim_resp_sw); return(-1); } return(0); } cmd_enable_chv(argc, argv) char **argv; { u_char cmd[13]; int rc; /* ENABLE CHV command APDU */ cmd[0] = 0xA0; cmd[1] = 0x28; cmd[2] = 0x00; cmd[3] = 0x01; cmd[4] = 8; rc = encode_pin_entry(argv[1], 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: %04X\n", sim_resp_sw); return(-1); } return(0); } cmd_unblock_chv(argc, argv) char **argv; { u_char cmd[21]; int rc; /* UNBLOCK CHV command APDU */ cmd[0] = 0xA0; cmd[1] = 0x2C; cmd[2] = 0x00; switch (argv[0][11]) { case '1': cmd[3] = 0x00; break; case '2': cmd[3] = 0x02; break; default: fprintf(stderr, "BUG in unblock-chvN command\n"); return(-1); } cmd[4] = 16; rc = encode_pin_entry(argv[1], cmd + 5); if (rc < 0) return(rc); rc = encode_pin_entry(argv[2], cmd + 13); if (rc < 0) return(rc); rc = apdu_exchange(cmd, 21); if (rc < 0) return(rc); if (sim_resp_sw != 0x9000) { fprintf(stderr, "bad SW response: %04X\n", sim_resp_sw); return(-1); } return(0); }