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