[BACK]Return to cmds.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / sectok

Annotation of src/usr.bin/sectok/cmds.c, Revision 1.16

1.16    ! rees        1: /* $Id: cmds.c,v 1.6 2001/08/15 19:41:05 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:
1.15      rees       38: #ifdef __palmos__
                     39: #pragma pack(2)
                     40: #include <Common.h>
                     41: #include <System/SysAll.h>
                     42: #include <UI/UIAll.h>
                     43: #include <System/Unix/sys_types.h>
                     44: #include <System/Unix/unix_stdio.h>
                     45: #include <System/Unix/unix_stdlib.h>
                     46: #include <System/Unix/unix_string.h>
                     47: #include <string.h>
                     48: #include "getopt.h"
                     49: #include "sectok.h"
                     50: #include "field.h"
                     51: #else
1.1       rees       52: #include <unistd.h>
                     53: #include <stdlib.h>
                     54: #include <stdio.h>
                     55: #include <signal.h>
                     56: #include <string.h>
                     57: #include <sectok.h>
1.15      rees       58: #endif
1.1       rees       59:
                     60: #include "sc.h"
                     61:
1.15      rees       62: #define MAXFILELEN 0xffff
1.1       rees       63: #define CARDIOSIZE 200
                     64:
1.15      rees       65: struct dispatchtable dispatch_table[] = {
1.1       rees       66:     /* Non-card commands */
1.4       rees       67:     { "help", "[command]", help },
                     68:     { "?", "[command]", help },
                     69:     { "reset", "[ -1234ivf ]", reset },
                     70:     { "open", "[ -1234ivf ]", reset },
                     71:     { "close", "", dclose },
                     72:     { "quit", "", quit },
1.1       rees       73:
                     74:     /* 7816-4 commands */
1.4       rees       75:     { "apdu", "[ -c class ] ins p1 p2 p3 data ...", apdu },
1.12      rees       76:     { "fid", "[ -v ] fid/aid", selfid },
1.4       rees       77:     { "isearch", "", isearch },
                     78:     { "class", "[ class ]", class },
1.10      rees       79:     { "read", "[ -x ] filesize", dread },
1.4       rees       80:     { "write", "input-filename", dwrite },
1.16    ! rees       81:     { "challenge", "[ size ]", challenge },
1.1       rees       82:
                     83:     /* Cyberflex commands */
1.9       rees       84:     { "ls", "[ -l ]", ls },
1.14      rees       85:     { "acl", "[ -x ] fid [ principal: r1 r2 ... ]", acl },
1.4       rees       86:     { "create", "fid size", jcreate },
                     87:     { "delete", "fid", jdelete },
                     88:     { "jdefault", "[ -d ]", jdefault },
                     89:     { "jatr", "", jatr },
                     90:     { "jdata", "", jdata },
1.10      rees       91:     { "login", "[ -d ] [ -k keyno ] [ -v ] [ -x hex-aut0 ]", jlogin },
1.15      rees       92: #ifndef __palmos__
1.6       rees       93:     { "jaut", "", jaut },
1.10      rees       94:     { "jload", "[ -p progID ] [ -c contID ] [ -s cont_size ] [ -i inst_size ] [ -a aid ] [ -v ] filename", jload },
1.15      rees       95: #endif
1.4       rees       96:     { "junload", "[ -p progID ] [ -c contID ]", junload },
1.15      rees       97: #ifndef __palmos__
1.5       rees       98:     { "setpass", "[ -d ] [ -x hex-aut0 ]", jsetpass },
1.15      rees       99: #endif
1.4       rees      100:     { NULL, NULL, NULL }
1.1       rees      101: };
                    102:
1.16    ! rees      103: int curlen;
        !           104:
1.1       rees      105: int dispatch(int ac, char *av[])
                    106: {
                    107:     int i;
                    108:
1.2       rees      109:     if (ac < 1)
                    110:        return 0;
                    111:
1.1       rees      112:     for (i = 0; dispatch_table[i].cmd; i++) {
1.2       rees      113:        if (!strncmp(av[0], dispatch_table[i].cmd, strlen(av[0]))) {
1.1       rees      114:            (dispatch_table[i].action) (ac, av);
                    115:            break;
                    116:        }
                    117:     }
                    118:     if (!dispatch_table[i].cmd) {
                    119:        printf("unknown command \"%s\"\n", av[0]);
                    120:        return -1;
                    121:     }
                    122:     return 0;
                    123: }
                    124:
                    125: int help(int ac, char *av[])
                    126: {
1.4       rees      127:     int i, j;
1.1       rees      128:
1.4       rees      129:     if (ac < 2) {
                    130:        for (i = 0; dispatch_table[i].cmd; i++)
1.1       rees      131:            printf("%s\n", dispatch_table[i].cmd);
1.4       rees      132:     } else {
                    133:        for (j = 1; j < ac; j++) {
                    134:            for (i = 0; dispatch_table[i].cmd; i++)
1.14      rees      135:                if (!strncmp(av[j], dispatch_table[i].cmd, strlen(av[j])))
1.4       rees      136:                    break;
                    137:            if (dispatch_table[i].help)
                    138:                printf("%s %s\n", dispatch_table[i].cmd, dispatch_table[i].help);
                    139:            else
                    140:                printf("no help on \"%s\"\n", av[j]);
                    141:        }
1.1       rees      142:     }
                    143:
                    144:     return 0;
                    145: }
                    146:
                    147: int reset(int ac, char *av[])
                    148: {
1.3       rees      149:     int i, n, oflags = 0, rflags = 0, vflag = 0, sw;
                    150:     unsigned char atr[34];
                    151:     struct scparam param;
1.1       rees      152:
                    153:     optind = optreset = 1;
                    154:
1.12      rees      155:     while ((i = getopt(ac, av, "0123ivf")) != -1) {
1.1       rees      156:        switch (i) {
1.12      rees      157:        case '0':
1.1       rees      158:        case '1':
                    159:        case '2':
                    160:        case '3':
1.12      rees      161:            port = i - '0';
1.1       rees      162:            break;
                    163:        case 'i':
1.3       rees      164:            oflags |= STONOWAIT;
1.1       rees      165:            break;
                    166:        case 'v':
1.3       rees      167:            vflag = 1;
1.1       rees      168:            break;
                    169:        case 'f':
1.7       rees      170:            rflags |= STRFORCE;
1.1       rees      171:            break;
                    172:        }
                    173:     }
                    174:
                    175:     if (fd < 0) {
1.3       rees      176:        fd = sectok_open(port, oflags, &sw);
1.1       rees      177:        if (fd < 0) {
1.3       rees      178:            sectok_print_sw(sw);
1.1       rees      179:            return -1;
                    180:        }
                    181:     }
                    182:
1.4       rees      183:     aut0_vfyd = 0;
                    184:
1.7       rees      185:     n = sectok_reset(fd, rflags, atr, &sw);
1.16    ! rees      186:     if (vflag) {
        !           187: #ifdef __palmos__
        !           188:        hidefield(printfield->id);
        !           189:        sectok_parse_atr(fd, STRV, atr, n, &param);
        !           190:        showfield(printfield->id);
        !           191: #else
1.11      rees      192:        sectok_parse_atr(fd, STRV, atr, n, &param);
1.16    ! rees      193: #endif
        !           194:     }
1.7       rees      195:     if (!sectok_swOK(sw)) {
                    196:        printf("sectok_reset: %s\n", sectok_get_sw(sw));
                    197:        dclose(0, NULL);
1.1       rees      198:        return -1;
                    199:     }
                    200:
                    201:     return 0;
                    202: }
                    203:
                    204: int dclose(int ac, char *av[])
                    205: {
                    206:     if (fd >= 0) {
1.11      rees      207:        sectok_close(fd);
1.1       rees      208:        fd = -1;
                    209:     }
                    210:     return 0;
                    211: }
                    212:
                    213: int quit(int ac, char *av[])
                    214: {
1.15      rees      215: #ifndef __palmos__
1.1       rees      216:     exit(0);
1.15      rees      217: #else
                    218:     return -1;
                    219: #endif
1.1       rees      220: }
                    221:
                    222: int apdu(int ac, char *av[])
                    223: {
1.9       rees      224:     int i, ilen, olen, n, ins, xcl = cla, p1, p2, p3, sw;
                    225:     unsigned char ibuf[256], obuf[256], *bp;
1.1       rees      226:
                    227:     optind = optreset = 1;
                    228:
                    229:     while ((i = getopt(ac, av, "c:")) != -1) {
                    230:        switch (i) {
                    231:        case 'c':
                    232:            sscanf(optarg, "%x", &xcl);
                    233:            break;
                    234:        }
                    235:     }
                    236:
                    237:     if (ac - optind < 4) {
1.4       rees      238:        printf("usage: apdu [ -c class ] ins p1 p2 p3 data ...\n");
1.1       rees      239:        return -1;
                    240:     }
                    241:
                    242:     sscanf(av[optind++], "%x", &ins);
                    243:     sscanf(av[optind++], "%x", &p1);
                    244:     sscanf(av[optind++], "%x", &p2);
                    245:     sscanf(av[optind++], "%x", &p3);
                    246:
1.9       rees      247:     for (bp = ibuf, i = optind, ilen = 0; i < ac; i++) {
1.1       rees      248:        sscanf(av[i], "%x", &n);
                    249:        *bp++ = n;
1.9       rees      250:        ilen++;
1.1       rees      251:     }
                    252:
1.7       rees      253:     if (fd < 0 && reset(0, NULL) < 0)
                    254:        return -1;
1.1       rees      255:
1.9       rees      256:     olen = (p3 && !ilen) ? p3 : sizeof obuf;
1.1       rees      257:
1.9       rees      258:     n = sectok_apdu(fd, xcl, ins, p1, p2, ilen, ibuf, olen, obuf, &sw);
1.1       rees      259:
1.9       rees      260:     sectok_dump_reply(obuf, n, sw);
1.1       rees      261:
                    262:     return 0;
                    263: }
                    264:
                    265: int selfid(int ac, char *av[])
                    266: {
1.12      rees      267:     unsigned char fid[16], obuf[256];
                    268:     char *fname;
1.16    ! rees      269:     int i, n, sel, fidlen, vflag = 0, sw;
1.1       rees      270:
1.11      rees      271:     optind = optreset = 1;
                    272:
                    273:     while ((i = getopt(ac, av, "v")) != -1) {
                    274:        switch (i) {
                    275:        case 'v':
1.16    ! rees      276:            vflag = 1;
1.11      rees      277:            break;
                    278:        }
                    279:     }
                    280:
1.12      rees      281:     if (ac - optind == 0) {
                    282:        /* No fid/aid given; select null aid (default loader for Cyberflex) */
                    283:        sel = 4;
                    284:        fidlen = 0;
                    285:     } else {
                    286:        fname = av[optind++];
                    287:        if (!strcmp(fname, "..")) {
                    288:            /* Special case ".." means parent */
                    289:            sel = 3;
                    290:            fidlen = 0;
                    291:        } else if (strlen(fname) < 5) {
                    292:            /* fid */
                    293:            sel = 0;
                    294:            fidlen = 2;
                    295:            sectok_parse_fname(fname, fid);
                    296:        } else {
                    297:            /* aid */
                    298:            sel = 4;
                    299:            fidlen = sectok_parse_input(fname, fid, sizeof fid);
1.13      rees      300:            if (fname[0] == '#') {
                    301:                /* Prepend 0xfc to the aid to make it a "proprietary aid". */
                    302:                fid[0] = 0xfc;
                    303:            }
1.12      rees      304:        }
1.1       rees      305:     }
                    306:
1.7       rees      307:     if (fd < 0 && reset(0, NULL) < 0)
                    308:        return -1;
1.1       rees      309:
1.16    ! rees      310:     n = sectok_apdu(fd, cla, 0xa4, sel, 0, fidlen, fid, 256, obuf, &sw);
1.11      rees      311:     if (!sectok_swOK(sw)) {
                    312:        printf("Select %02x%02x: %s\n", fid[0], fid[1], sectok_get_sw(sw));
1.2       rees      313:        return -1;
1.12      rees      314:     }
                    315:
1.16    ! rees      316:     if (vflag && !n && sectok_r1(sw) == 0x61 && sectok_r2(sw)) {
1.12      rees      317:        /* The card has out data but we must explicitly ask for it */
                    318:        n = sectok_apdu(fd, cla, 0xc0, 0, 0, 0, NULL, sectok_r2(sw), obuf, &sw);
1.2       rees      319:     }
1.1       rees      320:
1.16    ! rees      321:     if (n >= 4) {
        !           322:        /* Some cards put the file length here. No guarantees. */
        !           323:        curlen = (obuf[2] << 8) | obuf[3];
        !           324:     }
        !           325:
        !           326:     if (vflag)
1.11      rees      327:        sectok_dump_reply(obuf, n, sw);
                    328:
1.3       rees      329:     return 0;
                    330: }
                    331:
                    332: int isearch(int ac, char *av[])
                    333: {
1.11      rees      334:     int i, r1, sw;
1.3       rees      335:
1.7       rees      336:     if (fd < 0 && reset(0, NULL) < 0)
                    337:        return -1;
1.3       rees      338:
                    339:     /* find instructions */
1.11      rees      340:     for (i = 0; i < 0xff; i += 2) {
                    341:        sectok_apdu(fd, cla, i, 0, 0, 0, NULL, 0, NULL, &sw);
                    342:        r1 = sectok_r1(sw);
                    343:        if (r1 != 0x06 && r1 != 0x6d && r1 != 0x6e)
                    344:            printf("%02x %s %s\n", i, sectok_get_ins(i), sectok_get_sw(sw));
                    345:     }
1.1       rees      346:     return 0;
                    347: }
                    348:
                    349: int class(int ac, char *av[])
                    350: {
                    351:     if (ac > 1)
                    352:        sscanf(av[1], "%x", &cla);
                    353:     else
                    354:        printf("Class %02x\n", cla);
                    355:     return 0;
                    356: }
                    357:
                    358: int dread(int ac, char *av[])
                    359: {
1.15      rees      360:     int i, n, col = 0, fsize, xflag = 0, sw;
                    361:     unsigned int p3;
                    362:     unsigned char buf[CARDIOSIZE+1];
1.1       rees      363:
1.10      rees      364:     optind = optreset = 1;
                    365:
                    366:     while ((i = getopt(ac, av, "x")) != -1) {
                    367:        switch (i) {
                    368:        case 'x':
                    369:            xflag = 1;
                    370:            break;
                    371:        }
                    372:     }
                    373:
1.16    ! rees      374:     if (ac - optind < 1)
        !           375:        fsize = curlen;
        !           376:     else
        !           377:        sscanf(av[optind++], "%d", &fsize);
        !           378:
        !           379:     if (!fsize) {
        !           380:        printf("please specify filesize\n");
1.1       rees      381:        return -1;
                    382:     }
                    383:
1.7       rees      384:     if (fd < 0 && reset(0, NULL) < 0)
                    385:        return -1;
1.1       rees      386:
1.15      rees      387:     for (p3 = 0; fsize && p3 < MAXFILELEN; p3 += n) {
1.1       rees      388:        n = (fsize < CARDIOSIZE) ? fsize : CARDIOSIZE;
1.10      rees      389:        n = sectok_apdu(fd, cla, 0xb0, p3 >> 8, p3 & 0xff, 0, NULL, n, buf, &sw);
                    390:        if (!sectok_swOK(sw)) {
1.11      rees      391:            printf("ReadBinary: %s\n", sectok_get_sw(sw));
1.1       rees      392:            break;
                    393:        }
1.16    ! rees      394: #ifdef __palmos__
1.10      rees      395:        if (xflag) {
1.16    ! rees      396:            hidefield(printfield->id);
1.10      rees      397:            for (i = 0; i < n; i++) {
                    398:                printf("%02x ", buf[i]);
1.16    ! rees      399:                if (col++ % 12 == 11)
1.10      rees      400:                    printf("\n");
                    401:            }
1.16    ! rees      402:            showfield(printfield->id);
1.15      rees      403:        } else {
                    404:            buf[n] = '\0';
                    405:            printf("%s", buf);
1.16    ! rees      406:        }
1.15      rees      407: #else
1.16    ! rees      408:        if (xflag) {
        !           409:            for (i = 0; i < n; i++) {
        !           410:                printf("%02x ", buf[i]);
        !           411:                if (col++ % 16 == 15)
        !           412:                    printf("\n");
        !           413:            }
        !           414:        } else
1.10      rees      415:            fwrite(buf, 1, n, stdout);
1.15      rees      416: #endif
1.1       rees      417:        fsize -= n;
                    418:     }
1.10      rees      419:
                    420:     if (xflag && col % 16 != 0)
                    421:        printf("\n");
1.1       rees      422:
                    423:     return 0;
                    424: }
                    425:
1.15      rees      426: #ifndef __palmos__
1.1       rees      427: int dwrite(int ac, char *av[])
                    428: {
1.11      rees      429:     int n, p3, sw;
1.1       rees      430:     FILE *f;
                    431:     unsigned char buf[CARDIOSIZE];
                    432:
                    433:     if (ac != 2) {
                    434:        printf("usage: write input-filename\n");
                    435:        return -1;
                    436:     }
                    437:
1.7       rees      438:     if (fd < 0 && reset(0, NULL) < 0)
                    439:        return -1;
1.1       rees      440:
                    441:     f = fopen(av[1], "r");
                    442:     if (!f) {
                    443:        printf("can't open %s\n", av[1]);
                    444:        return -1;
                    445:     }
                    446:
                    447:     n = 0;
                    448:     while ((p3 = fread(buf, 1, CARDIOSIZE, f)) > 0) {
1.11      rees      449:        sectok_apdu(fd, cla, 0xd6, n >> 8, n & 0xff, p3, buf, 0, NULL, &sw);
                    450:        if (!sectok_swOK(sw)) {
                    451:            printf("UpdateBinary: %s\n", sectok_get_sw(sw));
1.1       rees      452:            break;
                    453:        }
                    454:        n += p3;
                    455:     }
                    456:     fclose(f);
                    457:
                    458:     return (n ? 0 : -1);
                    459: }
1.16    ! rees      460: #else
        !           461: int dwrite(int ac, char *av[])
        !           462: {
        !           463:     int n, sw;
        !           464:     char *s;
        !           465:
        !           466:     if (ac != 2) {
        !           467:        printf("usage: write text\n");
        !           468:        return -1;
        !           469:     }
        !           470:     s = av[1];
        !           471:     n = strlen(s);
        !           472:     sectok_apdu(fd, cla, 0xd6, 0, 0, n, s, 0, NULL, &sw);
        !           473:     if (!sectok_swOK(sw)) {
        !           474:        printf("UpdateBinary: %s\n", sectok_get_sw(sw));
        !           475:        return -1;
        !           476:     }
        !           477:     return 0;
        !           478: }
1.15      rees      479: #endif
1.16    ! rees      480:
        !           481: int challenge(int ac, char *av[])
        !           482: {
        !           483:     int n = 8, sw;
        !           484:     unsigned char buf[256];
        !           485:
        !           486:     if (ac > 1)
        !           487:        n = atoi(av[1]);
        !           488:
        !           489:     n = sectok_apdu(fd, cla, 0x84, 0, 0, 0, NULL, n, buf, &sw);
        !           490:
        !           491:     if (!sectok_swOK(sw)) {
        !           492:        printf("GetChallenge: %s\n", sectok_get_sw(sw));
        !           493:        return -1;
        !           494:     }
        !           495:
        !           496:     sectok_dump_reply(buf, n, sw);
        !           497:     return 0;
        !           498: }