diff options
author | Jim Rees <rees@cvs.openbsd.org> | 2001-06-27 19:41:47 +0000 |
---|---|---|
committer | Jim Rees <rees@cvs.openbsd.org> | 2001-06-27 19:41:47 +0000 |
commit | 59f7b0f9c704dfafb40649b8ca882cb927015e05 (patch) | |
tree | 7f78cf385966c87a50659c2eb87e7f056fe45857 /usr.bin/sectok/cmds.c | |
parent | 380782c0107ce913906c07d3c9746aeacfc58256 (diff) |
sectok control program
Diffstat (limited to 'usr.bin/sectok/cmds.c')
-rw-r--r-- | usr.bin/sectok/cmds.c | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/usr.bin/sectok/cmds.c b/usr.bin/sectok/cmds.c new file mode 100644 index 00000000000..44b39d627d8 --- /dev/null +++ b/usr.bin/sectok/cmds.c @@ -0,0 +1,323 @@ +/* $Id: cmds.c,v 1.1 2001/06/27 19:41:45 rees Exp $ */ + +/* + * Smartcard commander. + * Written by Jim Rees and others at University of Michigan. + */ + +/* +copyright 2001 +the regents of the university of michigan +all rights reserved + +permission is granted to use, copy, create derivative works +and redistribute this software and such derivative works +for any purpose, so long as the name of the university of +michigan is not used in any advertising or publicity +pertaining to the use or distribution of this software +without specific, written prior authorization. if the +above copyright notice or any other identification of the +university of michigan is included in any copy of any +portion of this software, then the disclaimer below must +also be included. + +this software is provided as is, without representation +from the university of michigan as to its fitness for any +purpose, and without warranty by the university of +michigan of any kind, either express or implied, including +without limitation the implied warranties of +merchantability and fitness for a particular purpose. the +regents of the university of michigan shall not be liable +for any damages, including special, indirect, incidental, or +consequential damages, with respect to any claim arising +out of or in connection with the use of the software, even +if it has been or is hereafter advised of the possibility of +such damages. +*/ + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <signal.h> +#include <string.h> +#include <sectok.h> + +#include "sc.h" + +#define CARDIOSIZE 200 + +struct { + char *cmd; + int (*action) (int ac, char *av[]); +} dispatch_table[] = { + /* Non-card commands */ + { "help", help }, + { "?", help }, + { "reset", reset }, + { "r", reset }, + { "open", reset }, + { "close", dclose }, + { "quit", quit }, + { "q", quit }, + + /* 7816-4 commands */ + { "apdu", apdu }, + { "a", apdu }, + { "fid", selfid }, + { "f", selfid }, + { "class", class }, + { "read", dread }, + { "write", dwrite }, + + /* Cyberflex commands */ + { "ls", ls }, + { "jdefault", jdefault }, + { "jatr", jatr }, + { "jdata", jdata }, + { "jaut", jaut }, + { "jload", jload }, + { "junload", junload }, + { "jselect", jselect }, + { "jdeselect", jdeselect }, + { NULL, NULL } +}; +/* + { "", }, +*/ + +int dispatch(int ac, char *av[]) +{ + int i; + + for (i = 0; dispatch_table[i].cmd; i++) { + if (!strcmp(av[0], dispatch_table[i].cmd)) { + (dispatch_table[i].action) (ac, av); + break; + } + } + if (!dispatch_table[i].cmd) { + printf("unknown command \"%s\"\n", av[0]); + return -1; + } + return 0; +} + +int help(int ac, char *av[]) +{ + int i; + + for (i = 0; dispatch_table[i].cmd; i++) { + if (strlen(dispatch_table[i].cmd) > 1) + printf("%s\n", dispatch_table[i].cmd); + } + + return 0; +} + +int reset(int ac, char *av[]) +{ + int i, n, port = 0, oflags = SCODSR, rflags = 0, err; + unsigned char buf[34]; + + optind = optreset = 1; + + while ((i = getopt(ac, av, "1234ivf")) != -1) { + switch (i) { + case '1': + case '2': + case '3': + case '4': + port = i - '1'; + break; + case 'i': + oflags &= ~SCODSR; + break; + case 'v': + rflags |= SCRV; + break; + case 'f': + rflags |= SCRFORCE; + break; + } + } + + if (fd < 0) { + fd = scopen(0, oflags, &err); + if (fd < 0) { + printf("%s\n", scerrtab[err]); + return -1; + } + } + + n = scxreset(fd, rflags, buf, &err); + if (n && !(rflags & SCRV)) { + printf("atr "); + dump_reply(buf, n, 0, 0); + } + if (err != SCEOK) { + printf("%s\n", scerrtab[err]); + return -1; + } + + return 0; +} + +int dclose(int ac, char *av[]) +{ + if (fd >= 0) { + scclose(fd); + fd = -1; + } + return 0; +} + +int quit(int ac, char *av[]) +{ + exit(0); +} + +int apdu(int ac, char *av[]) +{ + int i, n, ins, xcl = cla, p1, p2, p3, r1, r2; + unsigned char buf[256], obuf[256], *bp; + + optind = optreset = 1; + + while ((i = getopt(ac, av, "c:")) != -1) { + switch (i) { + case 'c': + sscanf(optarg, "%x", &xcl); + break; + } + } + + if (ac - optind < 4) { + printf("usage: apdu [ -c cla ] ins p1 p2 p3 data ...\n"); + return -1; + } + + sscanf(av[optind++], "%x", &ins); + sscanf(av[optind++], "%x", &p1); + sscanf(av[optind++], "%x", &p2); + sscanf(av[optind++], "%x", &p3); + +#if 0 + for (bp = buf, i = optind; i < ac; i++) + bp += parse_input(av[i], bp, (int) (sizeof buf - (bp - buf))); +#else + for (bp = buf, i = optind; i < ac; i++) { + sscanf(av[i], "%x", &n); + *bp++ = n; + } +#endif + + if (fd < 0) + reset(0, NULL); + + n = scrw(fd, xcl, ins, p1, p2, p3, buf, sizeof obuf, obuf, &r1, &r2); + + if (n < 0) { + printf("scrw failed\n"); + return -1; + } + + dump_reply(obuf, n, r1, r2); + + return 0; +} + +int selfid(int ac, char *av[]) +{ + unsigned char fid[2]; + + if (ac != 2) { + printf("usage: f fid\n"); + return -1; + } + + if (fd < 0) + reset(0, NULL); + + sectok_parse_fname(av[1], fid); + sectok_selectfile(fd, cla, fid, 1); + + return 0; +} + +int class(int ac, char *av[]) +{ + if (ac > 1) + sscanf(av[1], "%x", &cla); + else + printf("Class %02x\n", cla); + return 0; +} + +int dread(int ac, char *av[]) +{ + int n, p3, fsize, r1, r2; + unsigned char buf[CARDIOSIZE]; + + if (ac != 2) { + printf("usage: read filesize\n"); + return -1; + } + + sscanf(av[1], "%d", &fsize); + + if (fd < 0) + reset(0, NULL); + + for (p3 = 0; fsize && p3 < 100000; p3 += n) { + n = (fsize < CARDIOSIZE) ? fsize : CARDIOSIZE; + if (scread(fd, cla, 0xb0, p3 >> 8, p3 & 0xff, n, buf, &r1, &r2) < 0) { + printf("scread failed\n"); + break; + } + if (r1 != 0x90 && r1 != 0x61) { + print_r1r2(r1, r2); + break; + } + fwrite(buf, 1, n, stdout); + fsize -= n; + } + + return 0; +} + +int dwrite(int ac, char *av[]) +{ + int n, p3, r1, r2; + FILE *f; + unsigned char buf[CARDIOSIZE]; + + if (ac != 2) { + printf("usage: write input-filename\n"); + return -1; + } + + if (fd < 0) + reset(0, NULL); + + f = fopen(av[1], "r"); + if (!f) { + printf("can't open %s\n", av[1]); + return -1; + } + + n = 0; + while ((p3 = fread(buf, 1, CARDIOSIZE, f)) > 0) { + if (scwrite(fd, cla, 0xd6, n >> 8, n & 0xff, p3, buf, &r1, &r2) < 0) { + printf("scwrite failed\n"); + break; + } + if (r1 != 0x90 && r1 != 0x61) { + print_r1r2(r1, r2); + break; + } + n += p3; + } + fclose(f); + + return (n ? 0 : -1); +} |