Annotation of src/usr.bin/sectok/cmds.c, Revision 1.3
1.2 rees 1: /* $Id: cmds.c,v 1.1 2001/06/27 19:41:45 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 {
51: char *cmd;
52: int (*action) (int ac, char *av[]);
53: } dispatch_table[] = {
54: /* Non-card commands */
55: { "help", help },
56: { "?", help },
57: { "reset", reset },
58: { "open", reset },
59: { "close", dclose },
60: { "quit", quit },
61:
62: /* 7816-4 commands */
63: { "apdu", apdu },
64: { "fid", selfid },
1.3 ! rees 65: { "isearch", isearch },
1.1 rees 66: { "class", class },
67: { "read", dread },
68: { "write", dwrite },
69:
70: /* Cyberflex commands */
71: { "ls", ls },
1.3 ! rees 72: { "create", jcreate },
! 73: { "delete", jdelete },
1.1 rees 74: { "jdefault", jdefault },
75: { "jatr", jatr },
76: { "jdata", jdata },
77: { "jaut", jaut },
78: { "jload", jload },
79: { "junload", junload },
80: { "jselect", jselect },
81: { "jdeselect", jdeselect },
82: { NULL, NULL }
83: };
84: /*
85: { "", },
86: */
87:
88: int dispatch(int ac, char *av[])
89: {
90: int i;
91:
1.2 rees 92: if (ac < 1)
93: return 0;
94:
1.1 rees 95: for (i = 0; dispatch_table[i].cmd; i++) {
1.2 rees 96: if (!strncmp(av[0], dispatch_table[i].cmd, strlen(av[0]))) {
1.1 rees 97: (dispatch_table[i].action) (ac, av);
98: break;
99: }
100: }
101: if (!dispatch_table[i].cmd) {
102: printf("unknown command \"%s\"\n", av[0]);
103: return -1;
104: }
105: return 0;
106: }
107:
108: int help(int ac, char *av[])
109: {
110: int i;
111:
112: for (i = 0; dispatch_table[i].cmd; i++) {
113: if (strlen(dispatch_table[i].cmd) > 1)
114: printf("%s\n", dispatch_table[i].cmd);
115: }
116:
117: return 0;
118: }
119:
120: int reset(int ac, char *av[])
121: {
1.3 ! rees 122: int i, n, oflags = 0, rflags = 0, vflag = 0, sw;
! 123: unsigned char atr[34];
! 124: struct scparam param;
1.1 rees 125:
126: optind = optreset = 1;
127:
128: while ((i = getopt(ac, av, "1234ivf")) != -1) {
129: switch (i) {
130: case '1':
131: case '2':
132: case '3':
133: case '4':
134: port = i - '1';
135: break;
136: case 'i':
1.3 ! rees 137: oflags |= STONOWAIT;
1.1 rees 138: break;
139: case 'v':
1.3 ! rees 140: vflag = 1;
1.1 rees 141: break;
142: case 'f':
143: rflags |= SCRFORCE;
144: break;
145: }
146: }
147:
148: if (fd < 0) {
1.3 ! rees 149: fd = sectok_open(port, oflags, &sw);
1.1 rees 150: if (fd < 0) {
1.3 ! rees 151: sectok_print_sw(sw);
1.1 rees 152: return -1;
153: }
154: }
155:
1.3 ! rees 156: n = scxreset(fd, rflags, atr, &sw);
! 157: if (n && !vflag) {
1.1 rees 158: printf("atr ");
1.3 ! rees 159: dump_reply(atr, n, 0, 0);
1.1 rees 160: }
1.3 ! rees 161: if (vflag)
! 162: parse_atr(fd, SCRV, atr, n, ¶m);
! 163: if (sw != SCEOK) {
! 164: printf("%s\n", scerrtab[sw]);
1.1 rees 165: return -1;
166: }
167:
168: return 0;
169: }
170:
171: int dclose(int ac, char *av[])
172: {
173: if (fd >= 0) {
174: scclose(fd);
175: fd = -1;
176: }
177: return 0;
178: }
179:
180: int quit(int ac, char *av[])
181: {
182: exit(0);
183: }
184:
185: int apdu(int ac, char *av[])
186: {
187: int i, n, ins, xcl = cla, p1, p2, p3, r1, r2;
188: unsigned char buf[256], obuf[256], *bp;
189:
190: optind = optreset = 1;
191:
192: while ((i = getopt(ac, av, "c:")) != -1) {
193: switch (i) {
194: case 'c':
195: sscanf(optarg, "%x", &xcl);
196: break;
197: }
198: }
199:
200: if (ac - optind < 4) {
201: printf("usage: apdu [ -c cla ] ins p1 p2 p3 data ...\n");
202: return -1;
203: }
204:
205: sscanf(av[optind++], "%x", &ins);
206: sscanf(av[optind++], "%x", &p1);
207: sscanf(av[optind++], "%x", &p2);
208: sscanf(av[optind++], "%x", &p3);
209:
210: #if 0
211: for (bp = buf, i = optind; i < ac; i++)
212: bp += parse_input(av[i], bp, (int) (sizeof buf - (bp - buf)));
213: #else
214: for (bp = buf, i = optind; i < ac; i++) {
215: sscanf(av[i], "%x", &n);
216: *bp++ = n;
217: }
218: #endif
219:
220: if (fd < 0)
221: reset(0, NULL);
222:
223: n = scrw(fd, xcl, ins, p1, p2, p3, buf, sizeof obuf, obuf, &r1, &r2);
224:
225: if (n < 0) {
226: printf("scrw failed\n");
227: return -1;
228: }
229:
230: dump_reply(obuf, n, r1, r2);
231:
232: return 0;
233: }
234:
235: int selfid(int ac, char *av[])
236: {
237: unsigned char fid[2];
1.3 ! rees 238: int sw;
1.1 rees 239:
240: if (ac != 2) {
241: printf("usage: f fid\n");
242: return -1;
243: }
244:
245: if (fd < 0)
246: reset(0, NULL);
247:
248: sectok_parse_fname(av[1], fid);
1.3 ! rees 249: if (sectok_selectfile(fd, cla, fid, &sw) < 0) {
! 250: printf("selectfile: %s\n", sectok_get_sw(sw));
1.2 rees 251: return -1;
252: }
1.1 rees 253:
1.3 ! rees 254: return 0;
! 255: }
! 256:
! 257: int isearch(int ac, char *av[])
! 258: {
! 259: int i, r1, r2;
! 260: unsigned char buf[256];
! 261:
! 262: if (fd < 0)
! 263: reset(0, NULL);
! 264:
! 265: /* find instructions */
! 266: for (i = 0; i < 0xff; i += 2)
! 267: if (scread(fd, cla, i, 0, 0, 0, buf, &r1, &r2) == 0
! 268: && r1 != 0x6d && r1 != 0x6e)
! 269: printf("%02x %s %s\n", i, lookup_cmdname(i), get_r1r2s(r1, r2));
1.1 rees 270: return 0;
271: }
272:
273: int class(int ac, char *av[])
274: {
275: if (ac > 1)
276: sscanf(av[1], "%x", &cla);
277: else
278: printf("Class %02x\n", cla);
279: return 0;
280: }
281:
282: int dread(int ac, char *av[])
283: {
284: int n, p3, fsize, r1, r2;
285: unsigned char buf[CARDIOSIZE];
286:
287: if (ac != 2) {
288: printf("usage: read filesize\n");
289: return -1;
290: }
291:
292: sscanf(av[1], "%d", &fsize);
293:
294: if (fd < 0)
295: reset(0, NULL);
296:
297: for (p3 = 0; fsize && p3 < 100000; p3 += n) {
298: n = (fsize < CARDIOSIZE) ? fsize : CARDIOSIZE;
299: if (scread(fd, cla, 0xb0, p3 >> 8, p3 & 0xff, n, buf, &r1, &r2) < 0) {
300: printf("scread failed\n");
301: break;
302: }
303: if (r1 != 0x90 && r1 != 0x61) {
304: print_r1r2(r1, r2);
305: break;
306: }
307: fwrite(buf, 1, n, stdout);
308: fsize -= n;
309: }
310:
311: return 0;
312: }
313:
314: int dwrite(int ac, char *av[])
315: {
316: int n, p3, r1, r2;
317: FILE *f;
318: unsigned char buf[CARDIOSIZE];
319:
320: if (ac != 2) {
321: printf("usage: write input-filename\n");
322: return -1;
323: }
324:
325: if (fd < 0)
326: reset(0, NULL);
327:
328: f = fopen(av[1], "r");
329: if (!f) {
330: printf("can't open %s\n", av[1]);
331: return -1;
332: }
333:
334: n = 0;
335: while ((p3 = fread(buf, 1, CARDIOSIZE, f)) > 0) {
336: if (scwrite(fd, cla, 0xd6, n >> 8, n & 0xff, p3, buf, &r1, &r2) < 0) {
337: printf("scwrite failed\n");
338: break;
339: }
340: if (r1 != 0x90 && r1 != 0x61) {
341: print_r1r2(r1, r2);
342: break;
343: }
344: n += p3;
345: }
346: fclose(f);
347:
348: return (n ? 0 : -1);
349: }