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

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