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

Annotation of src/usr.bin/sectok/cyberflex.c, Revision 1.23

1.23    ! deraadt     1: /*     $OpenBSD: cyberflex.c,v 1.22 2002/03/20 22:30:58 rees Exp $ */
1.1       rees        2:
                      3: /*
1.23    ! deraadt     4:  * copyright 1999, 2000
        !             5:  * the regents of the university of michigan
        !             6:  * all rights reserved
        !             7:  *
        !             8:  * permission is granted to use, copy, create derivative works
        !             9:  * and redistribute this software and such derivative works
        !            10:  * for any purpose, so long as the name of the university of
        !            11:  * michigan is not used in any advertising or publicity
        !            12:  * pertaining to the use or distribution of this software
        !            13:  * without specific, written prior authorization.  if the
        !            14:  * above copyright notice or any other identification of the
        !            15:  * university of michigan is included in any copy of any
        !            16:  * portion of this software, then the disclaimer below must
        !            17:  * also be included.
        !            18:  *
        !            19:  * this software is provided as is, without representation
        !            20:  * from the university of michigan as to its fitness for any
        !            21:  * purpose, and without warranty by the university of
        !            22:  * michigan of any kind, either express or implied, including
        !            23:  * without limitation the implied warranties of
        !            24:  * merchantability and fitness for a particular purpose. the
        !            25:  * regents of the university of michigan shall not be liable
        !            26:  * for any damages, including special, indirect, incidental, or
        !            27:  * consequential damages, with respect to any claim arising
        !            28:  * out of or in connection with the use of the software, even
        !            29:  * if it has been or is hereafter advised of the possibility of
        !            30:  * such damages.
        !            31:  */
1.1       rees       32:
1.18      rees       33: #ifndef __palmos__
1.5       rees       34: #include <sys/types.h>
1.1       rees       35: #include <unistd.h>
                     36: #include <stdlib.h>
                     37: #include <stdio.h>
                     38: #include <signal.h>
                     39: #include <string.h>
                     40: #include <fcntl.h>
1.17      rees       41: #include <des.h>
1.1       rees       42: #ifdef __linux
1.17      rees       43: #include <sha.h>
                     44: #define SHA1_CTX SHA_CTX
                     45: #define SHA1Init SHA1_Init
                     46: #define SHA1Update SHA1_Update
                     47: #define SHA1Final SHA1_Final
1.23    ! deraadt    48: #else                          /* __linux */
1.17      rees       49: #include <sha1.h>
1.1       rees       50: #endif
1.18      rees       51: #else
                     52: #pragma pack(2)
                     53: #include <Common.h>
                     54: #include <System/SysAll.h>
                     55: #include <System/Unix/sys_types.h>
                     56: #include <System/Unix/unix_stdio.h>
                     57: #include <System/Unix/unix_stdlib.h>
                     58: #include <System/Unix/unix_string.h>
                     59: #include <UI/UIAll.h>
                     60: #include "getopt.h"
                     61: #include "field.h"
                     62: #define NO_SHA
                     63: #endif
1.1       rees       64: #include <sectok.h>
                     65:
                     66: #include "sc.h"
                     67:
                     68: #ifdef __sun
                     69: #define des_set_key(key, schedule) des_key_sched(key, schedule)
                     70: #endif
                     71:
                     72: #define MAX_KEY_FILE_SIZE 1024
                     73: #define NUM_RSA_KEY_ELEMENTS 5
                     74: #define RSA_BIT_LEN 1024
                     75: #define KEY_FILE_HEADER_SIZE 8
                     76:
1.12      rees       77: #define myisprint(x) ((x) >= '!' && (x) <= 'z')
                     78:
1.23    ! deraadt    79: static u_char key_fid[] = {0x00, 0x11};
        !            80: static u_char DFLTATR[] = {0x81, 0x10, 0x06, 0x01};
        !            81: static u_char DFLTAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
        !            82: static u_char AUT0[20];
1.1       rees       83:
1.23    ! deraadt    84: int    aut0_vfyd;
1.4       rees       85:
1.23    ! deraadt    86: static void print_acl(int isdir, u_char *acl);
1.18      rees       87:
                     88: #ifndef __palmos__
1.1       rees       89: /* default signed applet key of Cyberflex Access */
                     90: static des_cblock app_key = {0x6A, 0x21, 0x36, 0xF5, 0xD8, 0x0C, 0x47, 0x83};
1.18      rees       91: #endif
1.9       rees       92:
1.5       rees       93: static int
1.23    ! deraadt    94: get_AUT0(int argc, char *argv[], char *prompt, int confirm, u_char *digest)
1.5       rees       95: {
1.18      rees       96: #ifdef NO_SHA
1.23    ! deraadt    97:        memcpy(digest, DFLTAUT0, sizeof DFLTAUT0);
1.18      rees       98: #else
1.23    ! deraadt    99:        int     i, dflag = 0, xflag = 0;
        !           100:        SHA1_CTX ctx;
        !           101:        char   *s, *s2;
        !           102:
        !           103:        optind = optreset = 1;
        !           104:        opterr = 0;
        !           105:
        !           106:        while ((i = getopt(argc, argv, "dk:x:")) != -1) {
        !           107:                switch (i) {
        !           108:                case 'd':
        !           109:                        memcpy(digest, DFLTAUT0, sizeof DFLTAUT0);
        !           110:                        dflag = 1;
        !           111:                        break;
        !           112:                case 'x':
        !           113:                        if (sectok_parse_input(optarg, digest, 8) != 8) {
        !           114:                                printf("AUT0 must be length 8\n");
        !           115:                                return -1;
        !           116:                        }
        !           117:                        xflag = 1;
        !           118:                        break;
        !           119:                }
        !           120:        }
        !           121:
        !           122:        if (!dflag && !xflag) {
        !           123:                SHA1Init(&ctx);
        !           124:                /* "-" means DFLTAUT0 */
        !           125:                s = getpass(prompt);
        !           126:                if (!strcmp(s, "-"))
        !           127:                        memcpy(digest, DFLTAUT0, sizeof DFLTAUT0);
        !           128:                else {
        !           129:                        if (confirm) {
        !           130:                                s2 = strdup(s);
        !           131:                                s = getpass("Re-enter passphrase: ");
        !           132:                                if (strcmp(s, s2)) {
        !           133:                                        printf("passphrase mismatch\n");
        !           134:                                        return -1;
        !           135:                                }
        !           136:                                bzero(s2, strlen(s2));
        !           137:                                free(s2);
        !           138:                        }
        !           139:                        SHA1Update(&ctx, s, strlen(s));
        !           140:                        bzero(s, strlen(s));
        !           141:                        SHA1Final(digest, &ctx);
1.22      rees      142:                }
1.14      rees      143:        }
1.18      rees      144: #endif
1.5       rees      145:
1.23    ! deraadt   146:        return 0;
1.5       rees      147: }
                    148:
1.23    ! deraadt   149: int
        !           150: jlogin(int argc, char *argv[])
1.4       rees      151: {
1.23    ! deraadt   152:        int     i, keyno = 0, vflag = 0, sw;
        !           153:
        !           154:        if (fd < 0 && reset(0, NULL) < 0)
        !           155:                return -1;
1.4       rees      156:
1.23    ! deraadt   157:        cla = cyberflex_inq_class(fd);
        !           158:        if (cla < 0) {
        !           159:                printf("can't determine Cyberflex application class\n");
        !           160:                return -1;
        !           161:        }
        !           162:        optind = optreset = 1;
        !           163:
        !           164:        while ((i = getopt(argc, argv, "dk:vx:")) != -1) {
        !           165:                switch (i) {
        !           166:                case 'k':
        !           167:                        keyno = atoi(optarg);
        !           168:                        break;
        !           169:                case 'v':
        !           170:                        vflag = 1;
        !           171:                        break;
        !           172:                }
        !           173:        }
1.7       rees      174:
1.23    ! deraadt   175:        if (get_AUT0(argc, argv, "Enter AUT0 passphrase: ", 0, AUT0) < 0)
        !           176:                return -1;
1.5       rees      177:
1.23    ! deraadt   178:        if (vflag) {
        !           179:                printf("Class %02x\n", cla);
        !           180:                for (i = 0; i < 8; i++)
        !           181:                        printf("%02x ", AUT0[i]);
        !           182:                printf("\n");
        !           183:        }
        !           184:        sectok_apdu(fd, cla, 0x2a, 0, keyno, 8, AUT0, 0, NULL, &sw);
1.4       rees      185:
1.23    ! deraadt   186:        if (!sectok_swOK(sw)) {
        !           187:                printf("AUT0 failed: %s\n", sectok_get_sw(sw));
        !           188:                aut0_vfyd = 0;
        !           189:                return -1;
        !           190:        }
        !           191:        aut0_vfyd = 1;
        !           192:        return 0;
1.6       rees      193: }
                    194:
1.23    ! deraadt   195: int
        !           196: jaut(int argc, char *argv[])
1.6       rees      197: {
1.23    ! deraadt   198:        static char *jlav[] = {"login", "-d", NULL};
1.6       rees      199:
1.23    ! deraadt   200:        return jlogin(2, jlav);
1.4       rees      201: }
                    202:
1.23    ! deraadt   203: int
        !           204: jdefault(int argc, char *argv[])
1.1       rees      205: {
1.23    ! deraadt   206:        u_char buf[8];
        !           207:        int     i, p1 = 4, sw;
1.1       rees      208:
1.23    ! deraadt   209:        optind = optreset = 1;
1.1       rees      210:
1.23    ! deraadt   211:        while ((i = getopt(argc, argv, "d")) != -1) {
        !           212:                switch (i) {
        !           213:                case 'd':
        !           214:                        p1 = 5;
        !           215:                        break;
        !           216:                }
        !           217:        }
        !           218:
        !           219:        if (fd < 0 && reset(0, NULL) < 0)
        !           220:                return -1;
        !           221:        if (!aut0_vfyd)
        !           222:                jaut(0, NULL);
        !           223:
        !           224:        sectok_apdu(fd, cla, 0x08, p1, 0, 0, buf, 0, NULL, &sw);
        !           225:        if (!sectok_swOK(sw)) {
        !           226:                /* error */
        !           227:                sectok_print_sw(sw);
        !           228:                return -1;
        !           229:        }
        !           230:        return 0;
1.1       rees      231: }
                    232:
1.23    ! deraadt   233: int
        !           234: jatr(int argc, char *argv[])
1.1       rees      235: {
1.23    ! deraadt   236:        u_char buf[64];
        !           237:        int     n = 0, sw;
        !           238:
        !           239:        buf[n++] = 0x90;
        !           240:        buf[n++] = 0x94;        /* TA1 */
        !           241:        buf[n++] = 0x40;        /* TD1 */
        !           242:        buf[n++] = 0x28;        /* TC2 (WWT=4sec) */
        !           243:        if (argc > 1) {
        !           244:                /* set historical bytes from command line */
        !           245:                n += sectok_parse_input(argv[1], &buf[n], 15);
        !           246:        } else {
        !           247:                /* no historical bytes given, use default */
        !           248:                memcpy(&buf[n], DFLTATR, sizeof DFLTATR);
        !           249:                n += sizeof DFLTATR;
        !           250:        }
        !           251:        buf[0] |= ((n - 2) & 0xf);
1.1       rees      252:
1.23    ! deraadt   253:        if (fd < 0 && reset(0, NULL) < 0)
        !           254:                return -1;
        !           255:
        !           256:        sectok_apdu(fd, cla, 0xfa, 0, 0, n, buf, 0, NULL, &sw);
        !           257:        if (!sectok_swOK(sw)) {
        !           258:                /* error */
        !           259:                sectok_print_sw(sw);
        !           260:                return -1;
        !           261:        }
        !           262:        return 0;
1.1       rees      263: }
                    264:
1.23    ! deraadt   265: int
        !           266: jdata(int argc, char *argv[])
1.1       rees      267: {
1.23    ! deraadt   268:        u_char buf[32];
        !           269:        int     i, sw;
1.1       rees      270:
1.23    ! deraadt   271:        if (fd < 0 && reset(0, NULL) < 0)
        !           272:                return -1;
1.1       rees      273:
1.23    ! deraadt   274:        cla = cyberflex_inq_class(fd);
        !           275:        if (cla < 0) {
        !           276:                printf("can't determine Cyberflex application class\n");
        !           277:                return -1;
        !           278:        }
        !           279:        sectok_apdu(fd, cla, 0xca, 0, 1, 0, NULL, 0x16, buf, &sw);
        !           280:        if (sectok_swOK(sw)) {
        !           281:                printf("serno ");
        !           282:                for (i = 0; i < 6; i++)
        !           283:                        printf("%02x ", buf[i]);
        !           284:                if (buf[20] == 0x13) {
        !           285:                        /* these cards have a different format */
        !           286:                        printf("scrambled sver %d.%02d ", buf[19], buf[20]);
        !           287:                        if (buf[21] == 0x0c)
        !           288:                                printf("augmented ");
        !           289:                        else
        !           290:                                if (buf[21] == 0x0b);
        !           291:                                else
        !           292:                                        printf("unknown ");
        !           293:                        printf("crypto %5.5s class %02x\n", &buf[14],
        !           294:                            cyberflex_inq_class(fd));
        !           295:                } else {
        !           296:                        printf("batch %02x sver %d.%02d ", buf[6], buf[7], buf[8]);
        !           297:                        if (buf[9] == 0x0c)
        !           298:                                printf("augmented ");
        !           299:                        else
        !           300:                                if (buf[9] == 0x0b);
        !           301:                                else
        !           302:                                        printf("unknown ");
        !           303:                        printf("crypto %9.9s class %02x\n", &buf[10], buf[19]);
        !           304:                }
1.10      rees      305:        } else {
1.23    ! deraadt   306:                /* error */
        !           307:                sectok_print_sw(sw);
        !           308:        }
        !           309:        return 0;
1.1       rees      310: }
                    311: #define JDIRSIZE 40
                    312:
1.8       rees      313: static char *apptype[] = {
1.23    ! deraadt   314:        "?",
        !           315:        "applet",
        !           316:        "app",
        !           317:        "app/applet",
1.8       rees      318: };
                    319:
                    320: static char *appstat[] = {
1.23    ! deraadt   321:        "?",
        !           322:        "created",
        !           323:        "installed",
        !           324:        "registered",
1.8       rees      325: };
                    326:
                    327: static char *filestruct[] = {
1.23    ! deraadt   328:        "binary",
        !           329:        "fixed rec",
        !           330:        "variable rec",
        !           331:        "cyclic",
        !           332:        "program",
1.8       rees      333: };
                    334:
                    335: static char *principals[] = {
1.23    ! deraadt   336:        "world", "CHV1", "CHV2", "AUT0", "AUT1", "AUT2", "AUT3", "AUT4"
1.8       rees      337: };
                    338:
                    339: static char *f_rights[] = {
1.23    ! deraadt   340:        "r", "w", "x/a", "inval", "rehab", NULL, "dec", "inc"
1.8       rees      341: };
                    342:
                    343: static char *d_rights[] = {
1.23    ! deraadt   344:        "l", "d", "a", NULL, NULL, "i", "manage", NULL
1.8       rees      345: };
                    346:
1.9       rees      347: static void
1.23    ! deraadt   348: print_acl(int isdir, u_char *acl)
1.9       rees      349: {
1.23    ! deraadt   350:        int     i, j;
        !           351:        char   *as;
1.9       rees      352:
1.23    ! deraadt   353:        for (i = 0; i < 8; i++) {
        !           354:                if (acl[i]) {
        !           355:                        printf(" %s: ", principals[i]);
        !           356:                        for (j = 0; j < 8; j++)
        !           357:                                if (acl[i] & (1 << j)) {
        !           358:                                        as = isdir ? d_rights[j] : f_rights[j];
        !           359:                                        if (as)
        !           360:                                                printf("%s ", as);
        !           361:                                }
        !           362:                        printf("\n");
1.9       rees      363:                }
                    364:        }
                    365: }
                    366:
1.12      rees      367: void
1.23    ! deraadt   368: sectok_fmt_aidname(char *aidname, int aidlen, u_char *aid)
1.12      rees      369: {
1.23    ! deraadt   370:        int     i, istext = 1;
1.12      rees      371:
1.23    ! deraadt   372:        for (i = 1; i < aidlen; i++)
        !           373:                if (!myisprint(aid[i])) {
        !           374:                        istext = 0;
        !           375:                        break;
        !           376:                }
        !           377:        if (istext) {
        !           378:                memcpy(aidname, aid, aidlen);
        !           379:                aidname[aidlen] = '\0';
        !           380:                if (aid[0] == 0xfc)
        !           381:                        aidname[0] = '#';
        !           382:        } else {
        !           383:                for (i = 0; i < aidlen; i++)
        !           384:                        sprintf(&aidname[i * 2], "%02x", aid[i]);
        !           385:        }
1.12      rees      386: }
                    387:
1.23    ! deraadt   388: int
        !           389: ls(int argc, char *argv[])
1.1       rees      390: {
1.23    ! deraadt   391:        int     i, p2, fid, lflag = 0, buflen, sw;
        !           392:        int     isdir, fsize;
        !           393:        char    ftype[32], fname[6], aidname[34];
        !           394:        u_char buf[JDIRSIZE];
        !           395:
        !           396:        optind = optreset = 1;
        !           397:
        !           398:        while ((i = getopt(argc, argv, "l")) != -1) {
        !           399:                switch (i) {
        !           400:                case 'l':
        !           401:                        lflag = 1;
        !           402:                        break;
        !           403:                }
1.8       rees      404:        }
                    405:
1.23    ! deraadt   406:        if (fd < 0 && reset(0, NULL) < 0)
        !           407:                return -1;
1.1       rees      408:
1.23    ! deraadt   409:        for (p2 = 0;; p2++) {
        !           410:                buflen = sectok_apdu(fd, cla, 0xa8, 0, p2, 0, NULL,
        !           411:                    JDIRSIZE, buf, &sw);
        !           412:                if (!sectok_swOK(sw))
        !           413:                        break;
        !           414:
        !           415:                /* Don't show reserved fids */
        !           416:                fid = sectok_mksw(buf[4], buf[5]);
        !           417:                if (fid == 0x3f11 || fid == 0x3fff || fid == 0xffff)
        !           418:                        continue;
        !           419:
        !           420:                /* Format name */
        !           421:                sectok_fmt_fid(fname, &buf[4]);
        !           422:
        !           423:                /* Format size */
        !           424:                fsize = (buf[2] << 8) | buf[3];
        !           425:
        !           426:                /* Format file type */
        !           427:                isdir = 0;
        !           428:                aidname[0] = '\0';
        !           429:                if (buf[6] == 1) {
        !           430:                        /* root */
        !           431:                        snprintf(ftype, sizeof ftype, "root");
        !           432:                        isdir = 1;
        !           433:                } else
        !           434:                        if (buf[6] == 2) {
        !           435:                                /* DF */
        !           436:                                if (buf[12] == 27) {
        !           437:                                        /* application */
        !           438:                                        snprintf(ftype, sizeof ftype, "%s %s",
        !           439:                                            appstat[buf[10]], apptype[buf[9]]);
        !           440:                                        if (buflen > 23 && buf[23]) {
        !           441:                                                aidname[0] = ' ';
        !           442:                                                sectok_fmt_aidname(&aidname[1],
        !           443:                                                    buf[23], &buf[24]);
        !           444:                                        }
        !           445:                                } else
        !           446:                                        snprintf(ftype, sizeof ftype,
        !           447:                                            "directory");
        !           448:                                isdir = 1;
        !           449:                        } else
        !           450:                                if (buf[6] == 4) {
        !           451:                                        /* EF */
        !           452:                                        snprintf(ftype, sizeof ftype, "%s",
        !           453:                                            filestruct[buf[13]]);
        !           454:                                }
        !           455:                if (!lflag)
        !           456:                        printf("%-4s\n", fname);
        !           457:                else
        !           458:                        printf("%-4s %5d %s%s\n", fname, fsize, ftype, aidname);
        !           459:        }
        !           460:        return 0;
        !           461: }
1.21      rees      462:
1.23    ! deraadt   463: int
        !           464: acl(int argc, char *argv[])
        !           465: {
        !           466:        int     i, j, xflag = 0, isdir, prno, rt, sw;
        !           467:        u_char fid[2], buf[256], acl[8];
        !           468:        char   *prin;
        !           469:
        !           470:        optind = optreset = 1;
        !           471:
        !           472:        while ((i = getopt(argc, argv, "x")) != -1) {
        !           473:                switch (i) {
        !           474:                case 'x':
        !           475:                        xflag = 1;
        !           476:                        break;
1.12      rees      477:                }
1.8       rees      478:        }
                    479:
1.23    ! deraadt   480:        if (argc - optind < 1) {
        !           481:                printf("usage: acl [-x] fid [principal: r1 r2 ...]\n");
        !           482:                return -1;
        !           483:        }
        !           484:        /* Select the fid */
        !           485:        sectok_parse_fname(argv[optind++], fid);
        !           486:        sectok_apdu(fd, cla, 0xa4, 0, 0, 2, fid, sizeof buf, buf, &sw);
        !           487:        if (!sectok_swOK(sw)) {
        !           488:                printf("Select: %s\n", sectok_get_sw(sw));
        !           489:                return -1;
        !           490:        }
        !           491:        isdir = (buf[6] == 1 || buf[6] == 2);
1.9       rees      492:
1.23    ! deraadt   493:        /* Get current acl */
        !           494:        sectok_apdu(fd, cla, 0xfe, 0, 0, 0, NULL, 8, acl, &sw);
        !           495:        if (!sectok_swOK(sw)) {
        !           496:                printf("GetFileACL: %s\n", sectok_get_sw(sw));
        !           497:                return -1;
        !           498:        }
        !           499:        if (argc - optind < 1) {
        !           500:                /* No acl given; print acl and exit */
        !           501:                if (xflag) {
        !           502:                        for (i = 0; i < 8; i++)
        !           503:                                printf("%02x ", acl[i]);
        !           504:                        printf("\n");
        !           505:                } else
        !           506:                        print_acl(isdir, acl);
        !           507:                return 0;
        !           508:        }
        !           509:        prin = argv[optind++];
1.9       rees      510:
1.23    ! deraadt   511:        /* strip trailing ':' */
        !           512:        prin[strlen(prin) - 1] = '\0';
1.16      rees      513:
1.23    ! deraadt   514:        /* Find principal */
        !           515:        for (prno = 0; prno < 8; prno++)
        !           516:                if (!strcasecmp(prin, principals[prno]))
        !           517:                        break;
        !           518:        if (prno >= 8) {
        !           519:                printf("unknown principal \"%s\"\n", prin);
        !           520:                return -1;
        !           521:        }
        !           522:        /* Parse new rights */
        !           523:        rt = 0;
        !           524:        for (i = optind; i < optind + 8 && i < argc; i++) {
        !           525:                for (j = 0; j < 8; j++) {
        !           526:                        if ((d_rights[j] && !strcasecmp(argv[i], d_rights[j])) ||
        !           527:                            (f_rights[j] && !strcasecmp(argv[i], f_rights[j])))
        !           528:                                rt |= (1 << j);
        !           529:                }
        !           530:        }
        !           531:        acl[prno] = rt;
1.9       rees      532:
1.23    ! deraadt   533:        /* Set acl */
        !           534:        sectok_apdu(fd, cla, 0xfc, 0, 0, 8, acl, 0, NULL, &sw);
        !           535:        if (!sectok_swOK(sw)) {
        !           536:                printf("ChangeFileACL: %s\n", sectok_get_sw(sw));
        !           537:                return -1;
        !           538:        }
        !           539:        print_acl(isdir, acl);
1.9       rees      540:
1.23    ! deraadt   541:        return 0;
1.1       rees      542: }
                    543:
1.23    ! deraadt   544: int
        !           545: jcreate(int argc, char *argv[])
1.3       rees      546: {
1.23    ! deraadt   547:        u_char fid[2];
        !           548:        int     sw, fsize;
        !           549:
        !           550:        if (argc != 3) {
        !           551:                printf("usage: create fid size\n");
        !           552:                return -1;
        !           553:        }
        !           554:        sectok_parse_fname(argv[1], fid);
        !           555:        sscanf(argv[2], "%d", &fsize);
1.3       rees      556:
1.23    ! deraadt   557:        if (fd < 0 && reset(0, NULL) < 0)
        !           558:                return -1;
        !           559:        if (!aut0_vfyd)
        !           560:                jaut(0, NULL);
1.3       rees      561:
1.23    ! deraadt   562:        if (cyberflex_create_file(fd, cla, fid, fsize, 3, &sw) < 0) {
        !           563:                printf("create_file: %s\n", sectok_get_sw(sw));
        !           564:                return -1;
        !           565:        }
        !           566:        return 0;
1.3       rees      567: }
                    568:
1.23    ! deraadt   569: int
        !           570: jdelete(int argc, char *argv[])
1.3       rees      571: {
1.23    ! deraadt   572:        u_char fid[2];
        !           573:        int     sw;
1.3       rees      574:
1.23    ! deraadt   575:        if (argc != 2) {
        !           576:                printf("usage: delete fid\n");
        !           577:                return -1;
        !           578:        }
        !           579:        sectok_parse_fname(argv[1], fid);
        !           580:
        !           581:        if (fd < 0 && reset(0, NULL) < 0)
        !           582:                return -1;
        !           583:        if (!aut0_vfyd)
        !           584:                jaut(0, NULL);
1.3       rees      585:
1.23    ! deraadt   586:        if (cyberflex_delete_file(fd, cla, fid, &sw) < 0) {
        !           587:                printf("delete_file: %s\n", sectok_get_sw(sw));
        !           588:                return -1;
        !           589:        }
        !           590:        return 0;
1.3       rees      591: }
1.1       rees      592: #define MAX_BUF_SIZE 256
                    593: #define MAX_APP_SIZE 4096
                    594: #define MAX_APDU_SIZE 0xfa
                    595: #define BLOCK_SIZE 8
                    596: #define MAXTOKENS 16
                    597:
1.23    ! deraadt   598: u_char progID[2], contID[2];
1.1       rees      599:
1.18      rees      600: #ifndef __palmos__
1.23    ! deraadt   601: int
        !           602: jload(int argc, char *argv[])
1.10      rees      603: {
1.23    ! deraadt   604:        char   *cp, *filename, progname[5], contname[5];
        !           605:        u_char aid[16], app_data[MAX_APP_SIZE], data[MAX_BUF_SIZE];
        !           606:        int     i, j, vflag = 0, gotprog = 0, gotcont = 0, fd_app, size;
        !           607:        int     aidlen = 0, sw;
        !           608:        int     cont_size = 1152, inst_size = 1024;
        !           609:        des_cblock tmp;
        !           610:        des_key_schedule schedule;
        !           611:        static u_char acl[] = {0x81, 0, 0, 0xff, 0, 0, 0, 0};
        !           612:
        !           613:        optind = optreset = 1;
        !           614:
        !           615:        while ((i = getopt(argc, argv, "p:c:s:i:a:v")) != -1) {
        !           616:                switch (i) {
        !           617:                case 'p':
        !           618:                        sectok_parse_input(optarg, progID, 2);
        !           619:                        gotprog = 1;
        !           620:                        break;
        !           621:                case 'c':
        !           622:                        sectok_parse_input(optarg, contID, 2);
        !           623:                        gotcont = 1;
        !           624:                        break;
        !           625:                case 's':
        !           626:                        sscanf(optarg, "%d", &cont_size);
        !           627:                        break;
        !           628:                case 'i':
        !           629:                        sscanf(optarg, "%d", &inst_size);
        !           630:                        break;
        !           631:                case 'a':
        !           632:                        aidlen = sectok_parse_input(optarg, aid, sizeof aid);
        !           633:                        break;
        !           634:                case 'v':
        !           635:                        vflag = 1;
        !           636:                        break;
        !           637:                default:
        !           638:                        printf("unknown option.  command aborted.\n");
        !           639:                        return -1;
        !           640:                }
        !           641:        }
1.1       rees      642:
1.23    ! deraadt   643:        if (argc - optind < 1) {
        !           644:                printf("missing file name\n");
        !           645:                return -1;
        !           646:        }
        !           647:        filename = argv[optind++];
1.1       rees      648:
1.23    ! deraadt   649:        /*
        !           650:          * We prepend 0xfc to the aid to make it a "proprietary aid".
        !           651:          * See 7816-5 sec 5.2.4.
        !           652:          */
        !           653:        if (aidlen <= 0) {
        !           654:                /* No aid given, derive from file name */
        !           655:                cp = strrchr(filename, '/');
        !           656:                if (cp)
        !           657:                        cp++;
        !           658:                else
        !           659:                        cp = filename;
        !           660:                aid[0] = 0xfc;
        !           661:                strncpy(&aid[1], cp, sizeof aid - 1);
        !           662:                aidlen = (aid[15] == '\0') ? strlen(aid) : 16;
        !           663:        } else
        !           664:                if (aid[0] == '#')
        !           665:                        aid[0] = 0xfc;
        !           666:
        !           667:        if (!gotprog) {
        !           668:                /* No progID given, derive from aid */
        !           669:                progID[0] = aid[1];
        !           670:                progID[1] = 'p';
        !           671:        }
        !           672:        if (!gotcont) {
        !           673:                /* No contID given, derive from aid */
        !           674:                contID[0] = aid[1];
        !           675:                contID[1] = 'c';
        !           676:        }
        !           677:        if (fd < 0 && reset(0, NULL) < 0)
        !           678:                return -1;
        !           679:        if (!aut0_vfyd)
        !           680:                jaut(0, NULL);
        !           681:
        !           682:        sectok_fmt_fid(progname, progID);
        !           683:        sectok_fmt_fid(contname, contID);
        !           684:
        !           685:        if (vflag) {
        !           686:                printf("applet file             \"%s\"\n", filename);
        !           687:                printf("program ID              %s\n", progname);
        !           688:                printf("container ID            %s\n", contname);
        !           689:                printf("instance container size %d\n", cont_size);
        !           690:                printf("instance data size      %d\n", inst_size);
        !           691:                printf("AID                     ");
        !           692:                for (i = 0; i < aidlen; i++)
        !           693:                        printf("%02x ", aid[i]);
        !           694:                printf("\n");
        !           695:        }
        !           696:        /* open the input file */
        !           697:        fd_app = open(filename, O_RDONLY, NULL);
        !           698:        if (fd_app == -1) {
        !           699:                fprintf(stderr, "cannot open file \"%s\"\n", filename);
        !           700:                return -1;
        !           701:        }
        !           702:        /* read the input file */
        !           703:        size = read(fd_app, app_data, MAX_APP_SIZE);
        !           704:        if (size <= 0) {
        !           705:                fprintf(stderr, "error reading file %s\n", filename);
        !           706:                return -1;
        !           707:        }
        !           708:        /* size must be able to be divided by BLOCK_SIZE */
        !           709:        if (size % BLOCK_SIZE != 0) {
        !           710:                fprintf(stderr, "file \"%s\" size %d not divisible by %d\n", filename, size, BLOCK_SIZE);
        !           711:                return -1;
        !           712:        }
        !           713:        /* compute the signature of the applet */
        !           714:        /* initialize the result buffer */
        !           715:        memset(tmp, 0, BLOCK_SIZE);
        !           716:
        !           717:        /* chain.  DES encrypt one block, XOR the cyphertext with the next
        !           718:         * block, ... continues until the end of the buffer */
        !           719:
        !           720:        des_set_key(&app_key, schedule);
        !           721:
        !           722:        for (i = 0; i < size / BLOCK_SIZE; i++) {
        !           723:                for (j = 0; j < BLOCK_SIZE; j++)
        !           724:                        tmp[j] = tmp[j] ^ app_data[i * BLOCK_SIZE + j];
        !           725:                des_ecb_encrypt(&tmp, &tmp, schedule, DES_ENCRYPT);
        !           726:        }
        !           727:
        !           728:        if (vflag) {
        !           729:                /* print out the signature */
        !           730:                printf("signature ");
        !           731:                for (j = 0; j < BLOCK_SIZE; j++)
        !           732:                        printf("%02x ", tmp[j]);
        !           733:                printf("\n");
        !           734:        }
        !           735:        /* select the default loader */
        !           736:        sectok_apdu(fd, cla, 0xa4, 0x04, 0, 0, NULL, 0, NULL, &sw);
1.4       rees      737:        if (!sectok_swOK(sw)) {
1.23    ! deraadt   738:                /* error */
        !           739:                printf("can't select default loader: %s\n", sectok_get_sw(sw));
        !           740:                return -1;
        !           741:        }
        !           742:        /* select 3f.00 (root) */
        !           743:        if (sectok_selectfile(fd, cla, root_fid, &sw) < 0)
        !           744:                return -1;
1.1       rees      745:
1.23    ! deraadt   746:        /* create program file */
        !           747:        if (cyberflex_create_file_acl(fd, cla, progID, size, 3, acl, &sw) < 0) {
        !           748:                /* error */
        !           749:                printf("can't create %s: %s\n", progname, sectok_get_sw(sw));
        !           750:                return -1;
        !           751:        }
        !           752:        /* update binary */
        !           753:        for (i = 0; i < size; i += MAX_APDU_SIZE) {
        !           754:                int     send_size;
        !           755:
        !           756:                /* compute the size to be sent */
        !           757:                if (size - i > MAX_APDU_SIZE)
        !           758:                        send_size = MAX_APDU_SIZE;
        !           759:                else
        !           760:                        send_size = size - i;
        !           761:
        !           762:                sectok_apdu(fd, cla, 0xd6, i / 256, i % 256, send_size,
        !           763:                    app_data + i, 0, NULL, &sw);
        !           764:
        !           765:                if (!sectok_swOK(sw)) {
        !           766:                        /* error */
        !           767:                        printf("updating binary %s: %s\n", progname,
        !           768:                            sectok_get_sw(sw));
        !           769:                        return -1;
        !           770:                }
        !           771:        }
        !           772:
        !           773:        /* manage program .. validate */
        !           774:        sectok_apdu(fd, cla, 0x0a, 01, 0, 0x08, tmp, 0, NULL, &sw);
        !           775:
        !           776:        if (!sectok_swOK(sw)) {
        !           777:                /* error */
        !           778:                printf("validating applet in %s: %s\n", progname,
        !           779:                    sectok_get_sw(sw));
        !           780:                return -1;
        !           781:        }
        !           782:        /* select the default loader */
        !           783:        sectok_apdu(fd, cla, 0xa4, 0x04, 0, 0, NULL, 0, NULL, &sw);
        !           784:        if (!sectok_swOK(sw)) {
        !           785:                /* error */
        !           786:                printf("selecting default loader: %s\n", sectok_get_sw(sw));
        !           787:                return -1;
        !           788:        }
        !           789:        /* execute method -- call the install() method in the cardlet. cardlet
        !           790:         * type 01 (applet, not application) */
        !           791:
        !           792:        data[0] = 0x01;         /* cardlet type = 1 (applet, not application) */
        !           793:        data[1] = progID[0];    /* FID, upper */
        !           794:        data[2] = progID[1];    /* FID, lower */
        !           795:        data[3] = cont_size >> 8;       /* instance container size 0x0800
        !           796:                                         * (1152) byte, upper */
        !           797:        data[4] = cont_size & 0xff;     /* instance container size 0x0800
        !           798:                                         * (1152) byte, lower */
        !           799:        data[5] = contID[0];    /* container ID (7778), upper */
        !           800:        data[6] = contID[1];    /* container ID (7778), lower */
        !           801:        data[7] = inst_size >> 8;       /* instance size 0x0400 (1024) byte,
        !           802:                                         * upper */
        !           803:        data[8] = inst_size & 0xff;     /* instance size 0x0400 (1024) byte,
        !           804:                                         * lower */
        !           805:        data[9] = 0x00;         /* AID length 0x0005, upper */
        !           806:        data[10] = aidlen;      /* AID length 0x0005, lower */
        !           807:        memcpy(&data[11], aid, aidlen);
        !           808:
        !           809:        sectok_apdu(fd, cla, 0x0c, 0x13, 0, 11 + aidlen, data, 0, NULL, &sw);
        !           810:        if (!sectok_swOK(sw)) {
        !           811:                /* error */
        !           812:                printf("executing install() method in applet %s: %s\n",
        !           813:                    progname, sectok_get_sw(sw));
        !           814:                return -1;
        !           815:        }
        !           816:        /* That's it! :) */
        !           817:        return 0;
1.1       rees      818: }
1.18      rees      819: #endif
1.1       rees      820:
1.23    ! deraadt   821: int
        !           822: junload(int argc, char *argv[])
1.1       rees      823: {
1.23    ! deraadt   824:        char    progname[5], contname[5];
        !           825:        int     i, vflag = 0, gotprog = 0, gotcont = 0, sw;
1.10      rees      826:
1.23    ! deraadt   827:        optind = optreset = 1;
1.1       rees      828:
1.23    ! deraadt   829:        while ((i = getopt(argc, argv, "p:c:v")) != -1) {
        !           830:                switch (i) {
        !           831:                case 'p':
        !           832:                        sectok_parse_input(optarg, progID, 2);
        !           833:                        gotprog = 1;
        !           834:                        break;
        !           835:                case 'c':
        !           836:                        sectok_parse_input(optarg, contID, 2);
        !           837:                        gotcont = 1;
        !           838:                        break;
        !           839:                case 'v':
        !           840:                        vflag = 1;
        !           841:                        break;
        !           842:                default:
        !           843:                        printf("unknown option.  command aborted.\n");
        !           844:                        return -1;
        !           845:                }
1.10      rees      846:        }
1.20      rees      847:
1.23    ! deraadt   848:        if (argc - optind >= 1) {
        !           849:                /* Derive progID and contID from filename */
        !           850:                if (!gotprog) {
        !           851:                        progID[0] = argv[optind][0];
        !           852:                        progID[1] = 'p';
        !           853:                        gotprog = 1;
        !           854:                }
        !           855:                if (!gotcont) {
        !           856:                        contID[0] = argv[optind][0];
        !           857:                        contID[1] = 'c';
        !           858:                        gotcont = 1;
        !           859:                }
1.20      rees      860:        }
1.23    ! deraadt   861:        /* Use old defaults */
        !           862:        if (!gotprog)
        !           863:                memcpy(progID, "ww", 2);
        !           864:        if (!gotcont)
        !           865:                memcpy(contID, "wx", 2);
        !           866:
        !           867:        if (fd < 0 && reset(0, NULL) < 0)
        !           868:                return -1;
        !           869:        if (!aut0_vfyd)
        !           870:                jaut(0, NULL);
1.1       rees      871:
1.23    ! deraadt   872:        sectok_fmt_fid(progname, progID);
        !           873:        sectok_fmt_fid(contname, contID);
1.1       rees      874:
1.23    ! deraadt   875:        if (vflag) {
        !           876:                printf("program ID              %s\n", progname);
        !           877:                printf("container ID            %s\n", contname);
        !           878:        }
        !           879:        /* select 3f.00 (root) */
        !           880:        if (sectok_selectfile(fd, cla, root_fid, &sw) < 0) {
        !           881:                printf("can't select root: %s\n", sectok_get_sw(sw));
        !           882:                return -1;
1.2       rees      883:        }
1.23    ! deraadt   884:        /* select program file */
        !           885:        if (sectok_selectfile(fd, cla, progID, &sw) >= 0) {
1.1       rees      886:
1.23    ! deraadt   887:                /* manage program -- reset */
        !           888:                sectok_apdu(fd, cla, 0x0a, 02, 0, 0, NULL, 0, NULL, &sw);
        !           889:                if (!sectok_swOK(sw)) {
        !           890:                        /* error */
        !           891:                        printf("resetting applet: %s\n", sectok_get_sw(sw));
        !           892:                }
        !           893:                /* delete program file */
        !           894:                if (cyberflex_delete_file(fd, cla, progID, &sw) < 0)
        !           895:                        printf("delete_file %s: %s\n", progname, sectok_get_sw(sw));
        !           896:        } else
        !           897:                if (vflag)
        !           898:                        printf("no program file... proceed to delete data container\n");
1.1       rees      899:
1.23    ! deraadt   900:        /* delete data container */
        !           901:        if (cyberflex_delete_file(fd, cla, contID, &sw) < 0)
        !           902:                printf("delete_file %s: %s\n", contname, sectok_get_sw(sw));
1.1       rees      903:
1.23    ! deraadt   904:        return 0;
1.1       rees      905: }
                    906:
1.18      rees      907: #ifndef __palmos__
1.1       rees      908: #define DELIMITER " :\t\n"
                    909: #define KEY_BLOCK_SIZE 14
                    910:
                    911: /* download DES keys into 3f.00/00.11 */
1.23    ! deraadt   912: int
        !           913: cyberflex_load_key(int fd, u_char *buf)
1.1       rees      914: {
1.23    ! deraadt   915:        int     sw, argc = 0, i, j, tmp;
        !           916:        u_char *token;
        !           917:        u_char data[MAX_BUF_SIZE];
        !           918:        u_char key[BLOCK_SIZE];
1.1       rees      919:
                    920: #if 0
1.23    ! deraadt   921:        /* select the default loader */
        !           922:        rv = scwrite(fd, cla, 0xa4, 0x04, 0, 0x00, NULL, &r1, &r2);
        !           923:        if (r1 != 0x90 && r1 != 0x61) {
        !           924:                //error
        !           925:                    printf("selecting the default loader: ");
        !           926:                print_r1r2(r1, r2);
        !           927:                return -1;
        !           928:        }
1.1       rees      929: #endif
                    930:
1.23    ! deraadt   931:        printf("ca_load_key buf=%s\n", buf);
        !           932:        token = strtok(buf, DELIMITER);
        !           933:        token = strtok(NULL, DELIMITER);
        !           934:        if (token == NULL) {
        !           935:                printf("Usage: jk number_of_keys\n");
        !           936:                return -1;
        !           937:        }
        !           938:        argc = atoi(token);
        !           939:
        !           940:        if (argc > 2) {
        !           941:                printf("current Cyberflex Access cannot download more than 2 keys to the key file.  Sorry. :(\n");
        !           942:                return -1;
        !           943:        }
        !           944:        if (argc < 0) {
        !           945:                printf("you want to down load %d keys??\n", argc);
        !           946:                return -1;
        !           947:        }
        !           948:        if (!aut0_vfyd)
        !           949:                jaut(0, NULL);
        !           950:
        !           951:        /* Now let's do it. :) */
        !           952:
        !           953:        /* add the AUT0 */
        !           954:        cyberflex_fill_key_block(data, 0, 1, AUT0);
        !           955:
        !           956:        /* add the applet sign key */
        !           957:        cyberflex_fill_key_block(data + KEY_BLOCK_SIZE, 5, 0, app_key);
        !           958:
        !           959:        /* then add user defined keys */
        !           960:        for (i = 0; i < argc; i++) {
        !           961:                printf("key %d : ", i);
        !           962:                for (j = 0; j < BLOCK_SIZE; j++) {
        !           963:                        fscanf(cmdf, "%02x", &tmp);
        !           964:                        key[j] = (u_char) tmp;
        !           965:                }
        !           966:
        !           967:                cyberflex_fill_key_block(data + 28 + i * KEY_BLOCK_SIZE,
        !           968:                    6 + i, 0, key);
        !           969:        }
        !           970:
        !           971:        /* add the suffix */
        !           972:        data[28 + argc * KEY_BLOCK_SIZE] = 0;
        !           973:        data[28 + argc * KEY_BLOCK_SIZE + 1] = 0;
        !           974:
        !           975:        for (i = 0; i < KEY_BLOCK_SIZE * (argc + 2) + 2; i++)
        !           976:                printf("%02x ", data[i]);
        !           977:        printf("\n");
1.1       rees      978:
1.23    ! deraadt   979:        /* select 3f.00 (root) */
        !           980:        if (sectok_selectfile(fd, cla, root_fid, &sw) < 0) {
        !           981:                printf("select root: %s\n", sectok_get_sw(sw));
        !           982:                return -1;
        !           983:        }
        !           984:        /* select 00.11 (key file) */
        !           985:        if (sectok_selectfile(fd, cla, key_fid, &sw) < 0) {
        !           986:                printf("select key file: %s\n", sectok_get_sw(sw));
        !           987:                return -1;
        !           988:        }
        !           989:        /* all righty, now let's send it to the card! :) */
        !           990:        sectok_apdu(fd, cla, 0xd6, 0, 0, KEY_BLOCK_SIZE * (argc + 2) + 2,
        !           991:            data, 0, NULL, &sw);
        !           992:        if (!sectok_swOK(sw)) {
        !           993:                /* error */
        !           994:                printf("writing the key file 00.11: %s\n", sectok_get_sw(sw));
        !           995:                return -1;
        !           996:        }
        !           997:        return 0;
1.1       rees      998: }
                    999:
                   1000: /* download AUT0 key into 3f.00/00.11 */
1.23    ! deraadt  1001: int
        !          1002: jsetpass(int argc, char *argv[])
1.1       rees     1003: {
1.23    ! deraadt  1004:        int     sw;
        !          1005:        u_char data[MAX_BUF_SIZE];
        !          1006:        u_char AUT0[20];
1.1       rees     1007:
1.23    ! deraadt  1008:        if (!aut0_vfyd && jaut(0, NULL) < 0)
        !          1009:                return -1;
1.1       rees     1010:
1.23    ! deraadt  1011:        if (get_AUT0(argc, argv, "Enter new AUT0 passphrase: ", 1, AUT0) < 0)
        !          1012:                return -1;
1.1       rees     1013:
1.23    ! deraadt  1014:        cyberflex_fill_key_block(data, 0, 1, AUT0);
1.1       rees     1015:
                   1016: #if 0
1.23    ! deraadt  1017:        /* add the suffix */
        !          1018:        data[KEY_BLOCK_SIZE] = 0;
        !          1019:        data[KEY_BLOCK_SIZE + 1] = 0;
1.1       rees     1020: #endif
                   1021:
1.5       rees     1022: #ifdef DEBUG
1.23    ! deraadt  1023:        for (i = 0; i < KEY_BLOCK_SIZE; i++)
        !          1024:                printf("%02x ", data[i]);
        !          1025:        printf("\n");
1.5       rees     1026: #endif
1.1       rees     1027:
1.23    ! deraadt  1028:        /* select 3f.00 (root) */
        !          1029:        if (sectok_selectfile(fd, cla, root_fid, &sw) < 0)
        !          1030:                return -1;
        !          1031:
        !          1032:        /* select 00.11 (key file) */
        !          1033:        if (sectok_selectfile(fd, cla, key_fid, &sw) < 0)
        !          1034:                return -1;
1.1       rees     1035:
1.23    ! deraadt  1036:        /* all righty, now let's send it to the card! :) */
        !          1037:        sectok_apdu(fd, cla, 0xd6, 0, 0, KEY_BLOCK_SIZE, data, 0, NULL, &sw);
        !          1038:        if (!sectok_swOK(sw)) {
        !          1039:                /* error */
        !          1040:                printf("writing the key file 00.11: %s\n", sectok_get_sw(sw));
        !          1041:                return -1;
        !          1042:        }
        !          1043:        return 0;
1.1       rees     1044: }
                   1045:
                   1046: /* download RSA private key into 3f.00/00.12 */
1.23    ! deraadt  1047: int
        !          1048: cyberflex_load_rsa(int fd, u_char *buf)
1.1       rees     1049: {
1.23    ! deraadt  1050:        int     sw, i, j, tmp;
        !          1051:        static u_char key_fid[] = {0x00, 0x12};
        !          1052:        static char *key_names[NUM_RSA_KEY_ELEMENTS] = {
        !          1053:                "p", "q", "1/p mod q", "d mod (p-1)", "d mod (q-1)"
        !          1054:        };
        !          1055:        u_char *key_elements[NUM_RSA_KEY_ELEMENTS];
        !          1056:
        !          1057:        printf("ca_load_rsa_priv buf=%s\n", buf);
        !          1058:
        !          1059:        printf("input 1024 bit RSA CRT key\n");
        !          1060:        for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++) {
        !          1061:                printf("%s (%d bit == %d byte) : ", key_names[i],
        !          1062:                    RSA_BIT_LEN / 2, RSA_BIT_LEN / 2 / 8);
        !          1063:                key_elements[i] = (u_char *) malloc(RSA_BIT_LEN / 8);
        !          1064:                for (j = 0; j < RSA_BIT_LEN / 8 / 2; j++) {
        !          1065:                        fscanf(cmdf, "%02x", &tmp);
        !          1066:                        key_elements[i][j] = (u_char) tmp;
        !          1067:                }
1.1       rees     1068:        }
                   1069:
                   1070: #ifdef DEBUG
1.23    ! deraadt  1071:        printf("print RSA CRT key\n");
        !          1072:        for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++) {
        !          1073:                printf("%s : ", key_names[i]);
        !          1074:                for (j = 0; j < RSA_BIT_LEN / 8 / 2; j++) {
        !          1075:                        printf("%02x ", key_elements[i][j]);
        !          1076:                }
1.1       rees     1077:        }
                   1078: #endif
1.4       rees     1079:
1.23    ! deraadt  1080:        if (!aut0_vfyd)
        !          1081:                jaut(0, NULL);
1.1       rees     1082:
1.23    ! deraadt  1083:        cyberflex_load_rsa_priv(fd, cla, key_fid, NUM_RSA_KEY_ELEMENTS, RSA_BIT_LEN,
        !          1084:            key_elements, &sw);
1.2       rees     1085:
1.23    ! deraadt  1086:        if (!sectok_swOK(sw))
        !          1087:                printf("load_rsa_priv: %s\n", sectok_get_sw(sw));
1.1       rees     1088:
1.23    ! deraadt  1089:        for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
        !          1090:                free(key_elements[i]);
        !          1091:        return 0;
1.1       rees     1092: }
1.18      rees     1093: #endif