Annotation of src/usr.bin/sectok/cmds.c, Revision 1.4
1.4 ! rees 1: /* $Id: cmds.c,v 1.3 2001/07/02 20:15:06 rees Exp $ */
1.1 rees 2:
3: /*
4: * Smartcard commander.
5: * Written by Jim Rees and others at University of Michigan.
6: */
7:
8: /*
9: copyright 2001
10: the regents of the university of michigan
11: all rights reserved
12:
13: permission is granted to use, copy, create derivative works
14: and redistribute this software and such derivative works
15: for any purpose, so long as the name of the university of
16: michigan is not used in any advertising or publicity
17: pertaining to the use or distribution of this software
18: without specific, written prior authorization. if the
19: above copyright notice or any other identification of the
20: university of michigan is included in any copy of any
21: portion of this software, then the disclaimer below must
22: also be included.
23:
24: this software is provided as is, without representation
25: from the university of michigan as to its fitness for any
26: purpose, and without warranty by the university of
27: michigan of any kind, either express or implied, including
28: without limitation the implied warranties of
29: merchantability and fitness for a particular purpose. the
30: regents of the university of michigan shall not be liable
31: for any damages, including special, indirect, incidental, or
32: consequential damages, with respect to any claim arising
33: out of or in connection with the use of the software, even
34: if it has been or is hereafter advised of the possibility of
35: such damages.
36: */
37:
38: #include <unistd.h>
39: #include <stdlib.h>
40: #include <stdio.h>
41: #include <signal.h>
42: #include <string.h>
43: #include <sectok.h>
1.3 rees 44: #include <sc7816.h>
1.1 rees 45:
46: #include "sc.h"
47:
48: #define CARDIOSIZE 200
49:
50: struct {
1.4 ! rees 51: char *cmd, *help;
1.1 rees 52: int (*action) (int ac, char *av[]);
53: } dispatch_table[] = {
54: /* Non-card commands */
1.4 ! rees 55: { "help", "[command]", help },
! 56: { "?", "[command]", help },
! 57: { "reset", "[ -1234ivf ]", reset },
! 58: { "open", "[ -1234ivf ]", reset },
! 59: { "close", "", dclose },
! 60: { "quit", "", quit },
1.1 rees 61:
62: /* 7816-4 commands */
1.4 ! rees 63: { "apdu", "[ -c class ] ins p1 p2 p3 data ...", apdu },
! 64: { "fid", "fid", selfid },
! 65: { "isearch", "", isearch },
! 66: { "class", "[ class ]", class },
! 67: { "read", "filesize", dread },
! 68: { "write", "input-filename", dwrite },
1.1 rees 69:
70: /* Cyberflex commands */
1.4 ! rees 71: { "ls", "", ls },
! 72: { "create", "fid size", jcreate },
! 73: { "delete", "fid", jdelete },
! 74: { "jdefault", "[ -d ]", jdefault },
! 75: { "jatr", "", jatr },
! 76: { "jdata", "", jdata },
! 77: { "jaut", "[ -v ]", jaut },
! 78: { "jload", "[ -p progID ] [ -c contID ] [ -s cont_size ] [ -i inst_size ] [ -a aid ] filename", jload },
! 79: { "junload", "[ -p progID ] [ -c contID ]", junload },
! 80: { "jselect", "[ -a aid ]", jselect },
! 81: { "jdeselect", "", jdeselect },
! 82: { NULL, NULL, NULL }
1.1 rees 83: };
84:
85: int dispatch(int ac, char *av[])
86: {
87: int i;
88:
1.2 rees 89: if (ac < 1)
90: return 0;
91:
1.1 rees 92: for (i = 0; dispatch_table[i].cmd; i++) {
1.2 rees 93: if (!strncmp(av[0], dispatch_table[i].cmd, strlen(av[0]))) {
1.1 rees 94: (dispatch_table[i].action) (ac, av);
95: break;
96: }
97: }
98: if (!dispatch_table[i].cmd) {
99: printf("unknown command \"%s\"\n", av[0]);
100: return -1;
101: }
102: return 0;
103: }
104:
105: int help(int ac, char *av[])
106: {
1.4 ! rees 107: int i, j;
1.1 rees 108:
1.4 ! rees 109: if (ac < 2) {
! 110: for (i = 0; dispatch_table[i].cmd; i++)
1.1 rees 111: printf("%s\n", dispatch_table[i].cmd);
1.4 ! rees 112: } else {
! 113: for (j = 1; j < ac; j++) {
! 114: for (i = 0; dispatch_table[i].cmd; i++)
! 115: if (!strncmp(av[j], dispatch_table[i].cmd, strlen(av[0])))
! 116: break;
! 117: if (dispatch_table[i].help)
! 118: printf("%s %s\n", dispatch_table[i].cmd, dispatch_table[i].help);
! 119: else
! 120: printf("no help on \"%s\"\n", av[j]);
! 121: }
1.1 rees 122: }
123:
124: return 0;
125: }
126:
127: int reset(int ac, char *av[])
128: {
1.3 rees 129: int i, n, oflags = 0, rflags = 0, vflag = 0, sw;
130: unsigned char atr[34];
131: struct scparam param;
1.1 rees 132:
133: optind = optreset = 1;
134:
135: while ((i = getopt(ac, av, "1234ivf")) != -1) {
136: switch (i) {
137: case '1':
138: case '2':
139: case '3':
140: case '4':
141: port = i - '1';
142: break;
143: case 'i':
1.3 rees 144: oflags |= STONOWAIT;
1.1 rees 145: break;
146: case 'v':
1.3 rees 147: vflag = 1;
1.1 rees 148: break;
149: case 'f':
150: rflags |= SCRFORCE;
151: break;
152: }
153: }
154:
155: if (fd < 0) {
1.3 rees 156: fd = sectok_open(port, oflags, &sw);
1.1 rees 157: if (fd < 0) {
1.3 rees 158: sectok_print_sw(sw);
1.1 rees 159: return -1;
160: }
161: }
162:
1.4 ! rees 163: aut0_vfyd = 0;
! 164:
1.3 rees 165: n = scxreset(fd, rflags, atr, &sw);
166: if (vflag)
167: parse_atr(fd, SCRV, atr, n, ¶m);
168: if (sw != SCEOK) {
169: printf("%s\n", scerrtab[sw]);
1.1 rees 170: return -1;
171: }
172:
173: return 0;
174: }
175:
176: int dclose(int ac, char *av[])
177: {
178: if (fd >= 0) {
179: scclose(fd);
180: fd = -1;
181: }
182: return 0;
183: }
184:
185: int quit(int ac, char *av[])
186: {
187: exit(0);
188: }
189:
190: int apdu(int ac, char *av[])
191: {
192: int i, n, ins, xcl = cla, p1, p2, p3, r1, r2;
193: unsigned char buf[256], obuf[256], *bp;
194:
195: optind = optreset = 1;
196:
197: while ((i = getopt(ac, av, "c:")) != -1) {
198: switch (i) {
199: case 'c':
200: sscanf(optarg, "%x", &xcl);
201: break;
202: }
203: }
204:
205: if (ac - optind < 4) {
1.4 ! rees 206: printf("usage: apdu [ -c class ] ins p1 p2 p3 data ...\n");
1.1 rees 207: return -1;
208: }
209:
210: sscanf(av[optind++], "%x", &ins);
211: sscanf(av[optind++], "%x", &p1);
212: sscanf(av[optind++], "%x", &p2);
213: sscanf(av[optind++], "%x", &p3);
214:
215: #if 0
216: for (bp = buf, i = optind; i < ac; i++)
217: bp += parse_input(av[i], bp, (int) (sizeof buf - (bp - buf)));
218: #else
219: for (bp = buf, i = optind; i < ac; i++) {
220: sscanf(av[i], "%x", &n);
221: *bp++ = n;
222: }
223: #endif
224:
225: if (fd < 0)
226: reset(0, NULL);
227:
228: n = scrw(fd, xcl, ins, p1, p2, p3, buf, sizeof obuf, obuf, &r1, &r2);
229:
230: if (n < 0) {
231: printf("scrw failed\n");
232: return -1;
233: }
234:
235: dump_reply(obuf, n, r1, r2);
236:
237: return 0;
238: }
239:
240: int selfid(int ac, char *av[])
241: {
242: unsigned char fid[2];
1.3 rees 243: int sw;
1.1 rees 244:
245: if (ac != 2) {
246: printf("usage: f fid\n");
247: return -1;
248: }
249:
250: if (fd < 0)
251: reset(0, NULL);
252:
253: sectok_parse_fname(av[1], fid);
1.3 rees 254: if (sectok_selectfile(fd, cla, fid, &sw) < 0) {
255: printf("selectfile: %s\n", sectok_get_sw(sw));
1.2 rees 256: return -1;
257: }
1.1 rees 258:
1.3 rees 259: return 0;
260: }
261:
262: int isearch(int ac, char *av[])
263: {
264: int i, r1, r2;
265: unsigned char buf[256];
266:
267: if (fd < 0)
268: reset(0, NULL);
269:
270: /* find instructions */
271: for (i = 0; i < 0xff; i += 2)
272: if (scread(fd, cla, i, 0, 0, 0, buf, &r1, &r2) == 0
273: && r1 != 0x6d && r1 != 0x6e)
274: printf("%02x %s %s\n", i, lookup_cmdname(i), get_r1r2s(r1, r2));
1.1 rees 275: return 0;
276: }
277:
278: int class(int ac, char *av[])
279: {
280: if (ac > 1)
281: sscanf(av[1], "%x", &cla);
282: else
283: printf("Class %02x\n", cla);
284: return 0;
285: }
286:
287: int dread(int ac, char *av[])
288: {
289: int n, p3, fsize, r1, r2;
290: unsigned char buf[CARDIOSIZE];
291:
292: if (ac != 2) {
293: printf("usage: read filesize\n");
294: return -1;
295: }
296:
297: sscanf(av[1], "%d", &fsize);
298:
299: if (fd < 0)
300: reset(0, NULL);
301:
302: for (p3 = 0; fsize && p3 < 100000; p3 += n) {
303: n = (fsize < CARDIOSIZE) ? fsize : CARDIOSIZE;
304: if (scread(fd, cla, 0xb0, p3 >> 8, p3 & 0xff, n, buf, &r1, &r2) < 0) {
305: printf("scread failed\n");
306: break;
307: }
308: if (r1 != 0x90 && r1 != 0x61) {
309: print_r1r2(r1, r2);
310: break;
311: }
312: fwrite(buf, 1, n, stdout);
313: fsize -= n;
314: }
315:
316: return 0;
317: }
318:
319: int dwrite(int ac, char *av[])
320: {
321: int n, p3, r1, r2;
322: FILE *f;
323: unsigned char buf[CARDIOSIZE];
324:
325: if (ac != 2) {
326: printf("usage: write input-filename\n");
327: return -1;
328: }
329:
330: if (fd < 0)
331: reset(0, NULL);
332:
333: f = fopen(av[1], "r");
334: if (!f) {
335: printf("can't open %s\n", av[1]);
336: return -1;
337: }
338:
339: n = 0;
340: while ((p3 = fread(buf, 1, CARDIOSIZE, f)) > 0) {
341: if (scwrite(fd, cla, 0xd6, n >> 8, n & 0xff, p3, buf, &r1, &r2) < 0) {
342: printf("scwrite failed\n");
343: break;
344: }
345: if (r1 != 0x90 && r1 != 0x61) {
346: print_r1r2(r1, r2);
347: break;
348: }
349: n += p3;
350: }
351: fclose(f);
352:
353: return (n ? 0 : -1);
354: }