[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.19

1.19    ! rees        1: /* $Id: cmds.c,v 1.10 2002/03/14 22:24:00 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 },
1.17      rees       78:     { "csearch", "", csearch },
1.4       rees       79:     { "class", "[ class ]", class },
1.18      rees       80:     { "read", "[ -x ] [ filesize ]", dread },
1.4       rees       81:     { "write", "input-filename", dwrite },
1.16      rees       82:     { "challenge", "[ size ]", challenge },
1.18      rees       83:     { "pin", "[ -k keyno ] [ PIN ]", vfypin },
1.19    ! rees       84: #ifndef __palmos__
1.18      rees       85:     { "chpin", "[ -k keyno ]", chpin },
1.19    ! rees       86: #endif
1.1       rees       87:
                     88:     /* Cyberflex commands */
1.9       rees       89:     { "ls", "[ -l ]", ls },
1.14      rees       90:     { "acl", "[ -x ] fid [ principal: r1 r2 ... ]", acl },
1.4       rees       91:     { "create", "fid size", jcreate },
                     92:     { "delete", "fid", jdelete },
                     93:     { "jdefault", "[ -d ]", jdefault },
                     94:     { "jatr", "", jatr },
                     95:     { "jdata", "", jdata },
1.10      rees       96:     { "login", "[ -d ] [ -k keyno ] [ -v ] [ -x hex-aut0 ]", jlogin },
1.15      rees       97: #ifndef __palmos__
1.6       rees       98:     { "jaut", "", jaut },
1.10      rees       99:     { "jload", "[ -p progID ] [ -c contID ] [ -s cont_size ] [ -i inst_size ] [ -a aid ] [ -v ] filename", jload },
1.15      rees      100: #endif
1.4       rees      101:     { "junload", "[ -p progID ] [ -c contID ]", junload },
1.15      rees      102: #ifndef __palmos__
1.5       rees      103:     { "setpass", "[ -d ] [ -x hex-aut0 ]", jsetpass },
1.15      rees      104: #endif
1.4       rees      105:     { NULL, NULL, NULL }
1.1       rees      106: };
                    107:
1.16      rees      108: int curlen;
                    109:
1.1       rees      110: int dispatch(int ac, char *av[])
                    111: {
                    112:     int i;
                    113:
1.2       rees      114:     if (ac < 1)
                    115:        return 0;
                    116:
1.1       rees      117:     for (i = 0; dispatch_table[i].cmd; i++) {
1.2       rees      118:        if (!strncmp(av[0], dispatch_table[i].cmd, strlen(av[0]))) {
1.1       rees      119:            (dispatch_table[i].action) (ac, av);
                    120:            break;
                    121:        }
                    122:     }
                    123:     if (!dispatch_table[i].cmd) {
                    124:        printf("unknown command \"%s\"\n", av[0]);
                    125:        return -1;
                    126:     }
                    127:     return 0;
                    128: }
                    129:
                    130: int help(int ac, char *av[])
                    131: {
1.4       rees      132:     int i, j;
1.1       rees      133:
1.4       rees      134:     if (ac < 2) {
                    135:        for (i = 0; dispatch_table[i].cmd; i++)
1.1       rees      136:            printf("%s\n", dispatch_table[i].cmd);
1.4       rees      137:     } else {
                    138:        for (j = 1; j < ac; j++) {
                    139:            for (i = 0; dispatch_table[i].cmd; i++)
1.14      rees      140:                if (!strncmp(av[j], dispatch_table[i].cmd, strlen(av[j])))
1.4       rees      141:                    break;
                    142:            if (dispatch_table[i].help)
                    143:                printf("%s %s\n", dispatch_table[i].cmd, dispatch_table[i].help);
                    144:            else
                    145:                printf("no help on \"%s\"\n", av[j]);
                    146:        }
1.1       rees      147:     }
                    148:
                    149:     return 0;
                    150: }
                    151:
                    152: int reset(int ac, char *av[])
                    153: {
1.3       rees      154:     int i, n, oflags = 0, rflags = 0, vflag = 0, sw;
                    155:     unsigned char atr[34];
                    156:     struct scparam param;
1.1       rees      157:
                    158:     optind = optreset = 1;
                    159:
1.12      rees      160:     while ((i = getopt(ac, av, "0123ivf")) != -1) {
1.1       rees      161:        switch (i) {
1.12      rees      162:        case '0':
1.1       rees      163:        case '1':
                    164:        case '2':
                    165:        case '3':
1.12      rees      166:            port = i - '0';
1.1       rees      167:            break;
                    168:        case 'i':
1.3       rees      169:            oflags |= STONOWAIT;
1.1       rees      170:            break;
                    171:        case 'v':
1.3       rees      172:            vflag = 1;
1.1       rees      173:            break;
                    174:        case 'f':
1.7       rees      175:            rflags |= STRFORCE;
1.1       rees      176:            break;
                    177:        }
                    178:     }
                    179:
                    180:     if (fd < 0) {
1.3       rees      181:        fd = sectok_open(port, oflags, &sw);
1.1       rees      182:        if (fd < 0) {
1.3       rees      183:            sectok_print_sw(sw);
1.1       rees      184:            return -1;
                    185:        }
                    186:     }
                    187:
1.4       rees      188:     aut0_vfyd = 0;
                    189:
1.7       rees      190:     n = sectok_reset(fd, rflags, atr, &sw);
1.16      rees      191:     if (vflag) {
                    192: #ifdef __palmos__
                    193:        hidefield(printfield->id);
                    194:        sectok_parse_atr(fd, STRV, atr, n, &param);
                    195:        showfield(printfield->id);
                    196: #else
1.11      rees      197:        sectok_parse_atr(fd, STRV, atr, n, &param);
1.16      rees      198: #endif
                    199:     }
1.7       rees      200:     if (!sectok_swOK(sw)) {
                    201:        printf("sectok_reset: %s\n", sectok_get_sw(sw));
                    202:        dclose(0, NULL);
1.1       rees      203:        return -1;
                    204:     }
                    205:
                    206:     return 0;
                    207: }
                    208:
                    209: int dclose(int ac, char *av[])
                    210: {
                    211:     if (fd >= 0) {
1.11      rees      212:        sectok_close(fd);
1.1       rees      213:        fd = -1;
                    214:     }
                    215:     return 0;
                    216: }
                    217:
                    218: int quit(int ac, char *av[])
                    219: {
1.17      rees      220:     dclose(0, NULL);
1.15      rees      221: #ifndef __palmos__
1.1       rees      222:     exit(0);
1.15      rees      223: #else
                    224:     return -1;
                    225: #endif
1.1       rees      226: }
                    227:
                    228: int apdu(int ac, char *av[])
                    229: {
1.9       rees      230:     int i, ilen, olen, n, ins, xcl = cla, p1, p2, p3, sw;
                    231:     unsigned char ibuf[256], obuf[256], *bp;
1.1       rees      232:
                    233:     optind = optreset = 1;
                    234:
                    235:     while ((i = getopt(ac, av, "c:")) != -1) {
                    236:        switch (i) {
                    237:        case 'c':
                    238:            sscanf(optarg, "%x", &xcl);
                    239:            break;
                    240:        }
                    241:     }
                    242:
                    243:     if (ac - optind < 4) {
1.4       rees      244:        printf("usage: apdu [ -c class ] ins p1 p2 p3 data ...\n");
1.1       rees      245:        return -1;
                    246:     }
                    247:
                    248:     sscanf(av[optind++], "%x", &ins);
                    249:     sscanf(av[optind++], "%x", &p1);
                    250:     sscanf(av[optind++], "%x", &p2);
                    251:     sscanf(av[optind++], "%x", &p3);
                    252:
1.9       rees      253:     for (bp = ibuf, i = optind, ilen = 0; i < ac; i++) {
1.1       rees      254:        sscanf(av[i], "%x", &n);
                    255:        *bp++ = n;
1.9       rees      256:        ilen++;
1.1       rees      257:     }
                    258:
1.7       rees      259:     if (fd < 0 && reset(0, NULL) < 0)
                    260:        return -1;
1.1       rees      261:
1.9       rees      262:     olen = (p3 && !ilen) ? p3 : sizeof obuf;
1.1       rees      263:
1.9       rees      264:     n = sectok_apdu(fd, xcl, ins, p1, p2, ilen, ibuf, olen, obuf, &sw);
1.1       rees      265:
1.9       rees      266:     sectok_dump_reply(obuf, n, sw);
1.1       rees      267:
                    268:     return 0;
                    269: }
                    270:
                    271: int selfid(int ac, char *av[])
                    272: {
1.12      rees      273:     unsigned char fid[16], obuf[256];
                    274:     char *fname;
1.16      rees      275:     int i, n, sel, fidlen, vflag = 0, sw;
1.1       rees      276:
1.11      rees      277:     optind = optreset = 1;
                    278:
                    279:     while ((i = getopt(ac, av, "v")) != -1) {
                    280:        switch (i) {
                    281:        case 'v':
1.16      rees      282:            vflag = 1;
1.11      rees      283:            break;
                    284:        }
                    285:     }
                    286:
1.12      rees      287:     if (ac - optind == 0) {
                    288:        /* No fid/aid given; select null aid (default loader for Cyberflex) */
                    289:        sel = 4;
                    290:        fidlen = 0;
                    291:     } else {
                    292:        fname = av[optind++];
                    293:        if (!strcmp(fname, "..")) {
                    294:            /* Special case ".." means parent */
                    295:            sel = 3;
                    296:            fidlen = 0;
                    297:        } else if (strlen(fname) < 5) {
                    298:            /* fid */
                    299:            sel = 0;
                    300:            fidlen = 2;
                    301:            sectok_parse_fname(fname, fid);
                    302:        } else {
                    303:            /* aid */
                    304:            sel = 4;
                    305:            fidlen = sectok_parse_input(fname, fid, sizeof fid);
1.13      rees      306:            if (fname[0] == '#') {
                    307:                /* Prepend 0xfc to the aid to make it a "proprietary aid". */
                    308:                fid[0] = 0xfc;
                    309:            }
1.12      rees      310:        }
1.1       rees      311:     }
                    312:
1.7       rees      313:     if (fd < 0 && reset(0, NULL) < 0)
                    314:        return -1;
1.1       rees      315:
1.16      rees      316:     n = sectok_apdu(fd, cla, 0xa4, sel, 0, fidlen, fid, 256, obuf, &sw);
1.11      rees      317:     if (!sectok_swOK(sw)) {
                    318:        printf("Select %02x%02x: %s\n", fid[0], fid[1], sectok_get_sw(sw));
1.2       rees      319:        return -1;
1.12      rees      320:     }
                    321:
1.16      rees      322:     if (vflag && !n && sectok_r1(sw) == 0x61 && sectok_r2(sw)) {
1.12      rees      323:        /* The card has out data but we must explicitly ask for it */
                    324:        n = sectok_apdu(fd, cla, 0xc0, 0, 0, 0, NULL, sectok_r2(sw), obuf, &sw);
1.2       rees      325:     }
1.1       rees      326:
1.16      rees      327:     if (n >= 4) {
                    328:        /* Some cards put the file length here. No guarantees. */
                    329:        curlen = (obuf[2] << 8) | obuf[3];
                    330:     }
                    331:
                    332:     if (vflag)
1.11      rees      333:        sectok_dump_reply(obuf, n, sw);
                    334:
1.3       rees      335:     return 0;
                    336: }
                    337:
                    338: int isearch(int ac, char *av[])
                    339: {
1.11      rees      340:     int i, r1, sw;
1.3       rees      341:
1.7       rees      342:     if (fd < 0 && reset(0, NULL) < 0)
                    343:        return -1;
1.3       rees      344:
                    345:     /* find instructions */
1.11      rees      346:     for (i = 0; i < 0xff; i += 2) {
                    347:        sectok_apdu(fd, cla, i, 0, 0, 0, NULL, 0, NULL, &sw);
                    348:        r1 = sectok_r1(sw);
                    349:        if (r1 != 0x06 && r1 != 0x6d && r1 != 0x6e)
                    350:            printf("%02x %s %s\n", i, sectok_get_ins(i), sectok_get_sw(sw));
1.17      rees      351:     }
                    352:     return 0;
                    353: }
                    354:
                    355: int csearch(int ac, char *av[])
                    356: {
                    357:     int i, r1, sw;
                    358:
                    359:     if (fd < 0 && reset(0, NULL) < 0)
                    360:        return -1;
                    361:
                    362:     /* find app classes */
                    363:     for (i = 0; i <= 0xff; i++) {
                    364:        sectok_apdu(fd, i, 0xa4, 0, 0, 2, root_fid, 0, NULL, &sw);
                    365:        r1 = sectok_r1(sw);
                    366:        if (r1 != 0x06 && r1 != 0x6d && r1 != 0x6e)
                    367:            printf("%02x %s\n", i, sectok_get_sw(sw));
1.11      rees      368:     }
1.1       rees      369:     return 0;
                    370: }
                    371:
                    372: int class(int ac, char *av[])
                    373: {
                    374:     if (ac > 1)
                    375:        sscanf(av[1], "%x", &cla);
                    376:     else
                    377:        printf("Class %02x\n", cla);
                    378:     return 0;
                    379: }
                    380:
                    381: int dread(int ac, char *av[])
                    382: {
1.15      rees      383:     int i, n, col = 0, fsize, xflag = 0, sw;
                    384:     unsigned int p3;
                    385:     unsigned char buf[CARDIOSIZE+1];
1.1       rees      386:
1.10      rees      387:     optind = optreset = 1;
                    388:
                    389:     while ((i = getopt(ac, av, "x")) != -1) {
                    390:        switch (i) {
                    391:        case 'x':
                    392:            xflag = 1;
                    393:            break;
                    394:        }
                    395:     }
                    396:
1.16      rees      397:     if (ac - optind < 1)
                    398:        fsize = curlen;
                    399:     else
                    400:        sscanf(av[optind++], "%d", &fsize);
                    401:
                    402:     if (!fsize) {
                    403:        printf("please specify filesize\n");
1.1       rees      404:        return -1;
                    405:     }
                    406:
1.7       rees      407:     if (fd < 0 && reset(0, NULL) < 0)
                    408:        return -1;
1.1       rees      409:
1.15      rees      410:     for (p3 = 0; fsize && p3 < MAXFILELEN; p3 += n) {
1.1       rees      411:        n = (fsize < CARDIOSIZE) ? fsize : CARDIOSIZE;
1.10      rees      412:        n = sectok_apdu(fd, cla, 0xb0, p3 >> 8, p3 & 0xff, 0, NULL, n, buf, &sw);
                    413:        if (!sectok_swOK(sw)) {
1.11      rees      414:            printf("ReadBinary: %s\n", sectok_get_sw(sw));
1.1       rees      415:            break;
                    416:        }
1.16      rees      417: #ifdef __palmos__
1.10      rees      418:        if (xflag) {
1.16      rees      419:            hidefield(printfield->id);
1.10      rees      420:            for (i = 0; i < n; i++) {
                    421:                printf("%02x ", buf[i]);
1.16      rees      422:                if (col++ % 12 == 11)
1.10      rees      423:                    printf("\n");
                    424:            }
1.16      rees      425:            showfield(printfield->id);
1.15      rees      426:        } else {
                    427:            buf[n] = '\0';
                    428:            printf("%s", buf);
1.16      rees      429:        }
1.15      rees      430: #else
1.16      rees      431:        if (xflag) {
                    432:            for (i = 0; i < n; i++) {
                    433:                printf("%02x ", buf[i]);
                    434:                if (col++ % 16 == 15)
                    435:                    printf("\n");
                    436:            }
                    437:        } else
1.10      rees      438:            fwrite(buf, 1, n, stdout);
1.15      rees      439: #endif
1.1       rees      440:        fsize -= n;
                    441:     }
1.10      rees      442:
                    443:     if (xflag && col % 16 != 0)
                    444:        printf("\n");
1.1       rees      445:
                    446:     return 0;
                    447: }
                    448:
1.15      rees      449: #ifndef __palmos__
1.1       rees      450: int dwrite(int ac, char *av[])
                    451: {
1.11      rees      452:     int n, p3, sw;
1.1       rees      453:     FILE *f;
                    454:     unsigned char buf[CARDIOSIZE];
                    455:
                    456:     if (ac != 2) {
                    457:        printf("usage: write input-filename\n");
                    458:        return -1;
                    459:     }
                    460:
1.7       rees      461:     if (fd < 0 && reset(0, NULL) < 0)
                    462:        return -1;
1.1       rees      463:
                    464:     f = fopen(av[1], "r");
                    465:     if (!f) {
                    466:        printf("can't open %s\n", av[1]);
                    467:        return -1;
                    468:     }
                    469:
                    470:     n = 0;
                    471:     while ((p3 = fread(buf, 1, CARDIOSIZE, f)) > 0) {
1.11      rees      472:        sectok_apdu(fd, cla, 0xd6, n >> 8, n & 0xff, p3, buf, 0, NULL, &sw);
                    473:        if (!sectok_swOK(sw)) {
                    474:            printf("UpdateBinary: %s\n", sectok_get_sw(sw));
1.1       rees      475:            break;
                    476:        }
                    477:        n += p3;
                    478:     }
                    479:     fclose(f);
                    480:
                    481:     return (n ? 0 : -1);
                    482: }
1.16      rees      483: #else
                    484: int dwrite(int ac, char *av[])
                    485: {
                    486:     int n, sw;
                    487:     char *s;
                    488:
                    489:     if (ac != 2) {
                    490:        printf("usage: write text\n");
                    491:        return -1;
                    492:     }
                    493:     s = av[1];
                    494:     n = strlen(s);
                    495:     sectok_apdu(fd, cla, 0xd6, 0, 0, n, s, 0, NULL, &sw);
                    496:     if (!sectok_swOK(sw)) {
                    497:        printf("UpdateBinary: %s\n", sectok_get_sw(sw));
                    498:        return -1;
                    499:     }
                    500:     return 0;
                    501: }
1.15      rees      502: #endif
1.16      rees      503:
                    504: int challenge(int ac, char *av[])
                    505: {
                    506:     int n = 8, sw;
                    507:     unsigned char buf[256];
                    508:
                    509:     if (ac > 1)
                    510:        n = atoi(av[1]);
                    511:
                    512:     n = sectok_apdu(fd, cla, 0x84, 0, 0, 0, NULL, n, buf, &sw);
                    513:
                    514:     if (!sectok_swOK(sw)) {
                    515:        printf("GetChallenge: %s\n", sectok_get_sw(sw));
                    516:        return -1;
                    517:     }
                    518:
                    519:     sectok_dump_reply(buf, n, sw);
1.18      rees      520:     return 0;
                    521: }
                    522:
                    523: int vfypin(int ac, char *av[])
                    524: {
                    525:     int keyno = 1, i, sw;
                    526:     char *pin;
                    527:
                    528:     optind = optreset = 1;
                    529:
                    530:     while ((i = getopt(ac, av, "k:")) != -1) {
                    531:        switch (i) {
                    532:        case 'k':
                    533:            keyno = atoi(optarg);
                    534:            break;
                    535:        }
                    536:     }
                    537:
                    538:     if (ac - optind >= 1)
                    539:        pin = av[optind++];
1.19    ! rees      540:     else {
        !           541: #ifndef __palmos__
1.18      rees      542:        pin = getpass("Enter PIN: ");
1.19    ! rees      543: #else
        !           544:        printf("usage: pin PIN\n");
        !           545:        return -1;
        !           546: #endif
        !           547:     }
1.18      rees      548:
                    549:     sectok_apdu(fd, cla, 0x20, 0, keyno, strlen(pin), pin, 0, NULL, &sw);
                    550:     bzero(pin, strlen(pin));
                    551:
                    552:     if (!sectok_swOK(sw)) {
                    553:        printf("VerifyCHV: %s\n", sectok_get_sw(sw));
                    554:        return -1;
                    555:     }
                    556:     return 0;
                    557: }
                    558:
1.19    ! rees      559: #ifndef __palmos__
1.18      rees      560: int chpin(int ac, char *av[])
                    561: {
                    562:     int keyno = 1, i, sw;
                    563:     char pin[255];
                    564:
                    565:     optind = optreset = 1;
                    566:
                    567:     while ((i = getopt(ac, av, "k:")) != -1) {
                    568:        switch (i) {
                    569:        case 'k':
                    570:            keyno = atoi(optarg);
                    571:            break;
                    572:        }
                    573:     }
                    574:
                    575:     strcpy(pin, getpass("Enter Old PIN: "));
                    576:     strcat(pin, getpass("Enter New PIN: "));
                    577:
                    578:     sectok_apdu(fd, cla, 0x24, 0, keyno, strlen(pin), pin, 0, NULL, &sw);
                    579:     bzero(pin, strlen(pin));
                    580:
                    581:     if (!sectok_swOK(sw)) {
                    582:        printf("UpdateCHV: %s\n", sectok_get_sw(sw));
                    583:        return -1;
                    584:     }
1.16      rees      585:     return 0;
                    586: }
1.19    ! rees      587: #endif