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

1.28    ! sobrado     1: /*     $OpenBSD: cyberflex.c,v 1.27 2006/12/06 05:03:29 ray 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
1.26      aaron     290:                                if (buf[21] != 0x0b)
1.23      deraadt   291:                                        printf("unknown ");
                    292:                        printf("crypto %5.5s class %02x\n", &buf[14],
                    293:                            cyberflex_inq_class(fd));
                    294:                } else {
                    295:                        printf("batch %02x sver %d.%02d ", buf[6], buf[7], buf[8]);
                    296:                        if (buf[9] == 0x0c)
                    297:                                printf("augmented ");
                    298:                        else
1.26      aaron     299:                                if (buf[9] != 0x0b)
1.23      deraadt   300:                                        printf("unknown ");
                    301:                        printf("crypto %9.9s class %02x\n", &buf[10], buf[19]);
                    302:                }
1.10      rees      303:        } else {
1.23      deraadt   304:                /* error */
                    305:                sectok_print_sw(sw);
                    306:        }
                    307:        return 0;
1.1       rees      308: }
                    309: #define JDIRSIZE 40
                    310:
1.8       rees      311: static char *apptype[] = {
1.23      deraadt   312:        "?",
                    313:        "applet",
                    314:        "app",
                    315:        "app/applet",
1.8       rees      316: };
                    317:
                    318: static char *appstat[] = {
1.23      deraadt   319:        "?",
                    320:        "created",
                    321:        "installed",
                    322:        "registered",
1.8       rees      323: };
                    324:
                    325: static char *filestruct[] = {
1.23      deraadt   326:        "binary",
                    327:        "fixed rec",
                    328:        "variable rec",
                    329:        "cyclic",
                    330:        "program",
1.8       rees      331: };
                    332:
                    333: static char *principals[] = {
1.23      deraadt   334:        "world", "CHV1", "CHV2", "AUT0", "AUT1", "AUT2", "AUT3", "AUT4"
1.8       rees      335: };
                    336:
                    337: static char *f_rights[] = {
1.23      deraadt   338:        "r", "w", "x/a", "inval", "rehab", NULL, "dec", "inc"
1.8       rees      339: };
                    340:
                    341: static char *d_rights[] = {
1.23      deraadt   342:        "l", "d", "a", NULL, NULL, "i", "manage", NULL
1.8       rees      343: };
                    344:
1.9       rees      345: static void
1.23      deraadt   346: print_acl(int isdir, u_char *acl)
1.9       rees      347: {
1.23      deraadt   348:        int     i, j;
                    349:        char   *as;
1.9       rees      350:
1.23      deraadt   351:        for (i = 0; i < 8; i++) {
                    352:                if (acl[i]) {
                    353:                        printf(" %s: ", principals[i]);
                    354:                        for (j = 0; j < 8; j++)
                    355:                                if (acl[i] & (1 << j)) {
                    356:                                        as = isdir ? d_rights[j] : f_rights[j];
                    357:                                        if (as)
                    358:                                                printf("%s ", as);
                    359:                                }
                    360:                        printf("\n");
1.9       rees      361:                }
                    362:        }
                    363: }
                    364:
1.12      rees      365: void
1.25      dhartmei  366: sectok_fmt_aidname(char *aidname, int aidlen, u_char *aid, size_t len)
1.12      rees      367: {
1.23      deraadt   368:        int     i, istext = 1;
1.12      rees      369:
1.23      deraadt   370:        for (i = 1; i < aidlen; i++)
                    371:                if (!myisprint(aid[i])) {
                    372:                        istext = 0;
                    373:                        break;
                    374:                }
                    375:        if (istext) {
1.25      dhartmei  376:                if (aidlen + 1 > len)
                    377:                        aidlen = len - 1;
1.23      deraadt   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++)
1.25      dhartmei  384:                        snprintf(&aidname[i * 2], len - ( i * 2),
                    385:                            "%02x", aid[i]);
1.23      deraadt   386:        }
1.12      rees      387: }
                    388:
1.23      deraadt   389: int
                    390: ls(int argc, char *argv[])
1.1       rees      391: {
1.23      deraadt   392:        int     i, p2, fid, lflag = 0, buflen, sw;
                    393:        int     isdir, fsize;
                    394:        char    ftype[32], fname[6], aidname[34];
                    395:        u_char buf[JDIRSIZE];
                    396:
                    397:        optind = optreset = 1;
                    398:
                    399:        while ((i = getopt(argc, argv, "l")) != -1) {
                    400:                switch (i) {
                    401:                case 'l':
                    402:                        lflag = 1;
                    403:                        break;
                    404:                }
1.8       rees      405:        }
                    406:
1.23      deraadt   407:        if (fd < 0 && reset(0, NULL) < 0)
                    408:                return -1;
1.1       rees      409:
1.23      deraadt   410:        for (p2 = 0;; p2++) {
                    411:                buflen = sectok_apdu(fd, cla, 0xa8, 0, p2, 0, NULL,
                    412:                    JDIRSIZE, buf, &sw);
                    413:                if (!sectok_swOK(sw))
                    414:                        break;
                    415:
                    416:                /* Don't show reserved fids */
                    417:                fid = sectok_mksw(buf[4], buf[5]);
                    418:                if (fid == 0x3f11 || fid == 0x3fff || fid == 0xffff)
                    419:                        continue;
                    420:
                    421:                /* Format name */
1.24      deraadt   422:                sectok_fmt_fid(fname, sizeof fname, &buf[4]);
1.23      deraadt   423:
                    424:                /* Format size */
                    425:                fsize = (buf[2] << 8) | buf[3];
                    426:
                    427:                /* Format file type */
                    428:                isdir = 0;
                    429:                aidname[0] = '\0';
                    430:                if (buf[6] == 1) {
                    431:                        /* root */
                    432:                        snprintf(ftype, sizeof ftype, "root");
                    433:                        isdir = 1;
                    434:                } else
                    435:                        if (buf[6] == 2) {
                    436:                                /* DF */
                    437:                                if (buf[12] == 27) {
                    438:                                        /* application */
                    439:                                        snprintf(ftype, sizeof ftype, "%s %s",
                    440:                                            appstat[buf[10]], apptype[buf[9]]);
                    441:                                        if (buflen > 23 && buf[23]) {
                    442:                                                aidname[0] = ' ';
                    443:                                                sectok_fmt_aidname(&aidname[1],
1.25      dhartmei  444:                                                    buf[23], &buf[24],
                    445:                                                    sizeof aidname - 1);
1.23      deraadt   446:                                        }
                    447:                                } else
                    448:                                        snprintf(ftype, sizeof ftype,
                    449:                                            "directory");
                    450:                                isdir = 1;
                    451:                        } else
                    452:                                if (buf[6] == 4) {
                    453:                                        /* EF */
                    454:                                        snprintf(ftype, sizeof ftype, "%s",
                    455:                                            filestruct[buf[13]]);
                    456:                                }
                    457:                if (!lflag)
                    458:                        printf("%-4s\n", fname);
                    459:                else
                    460:                        printf("%-4s %5d %s%s\n", fname, fsize, ftype, aidname);
                    461:        }
                    462:        return 0;
                    463: }
1.21      rees      464:
1.23      deraadt   465: int
                    466: acl(int argc, char *argv[])
                    467: {
                    468:        int     i, j, xflag = 0, isdir, prno, rt, sw;
                    469:        u_char fid[2], buf[256], acl[8];
                    470:        char   *prin;
                    471:
                    472:        optind = optreset = 1;
                    473:
                    474:        while ((i = getopt(argc, argv, "x")) != -1) {
                    475:                switch (i) {
                    476:                case 'x':
                    477:                        xflag = 1;
                    478:                        break;
1.12      rees      479:                }
1.8       rees      480:        }
                    481:
1.23      deraadt   482:        if (argc - optind < 1) {
1.27      ray       483:  usage:
1.23      deraadt   484:                printf("usage: acl [-x] fid [principal: r1 r2 ...]\n");
                    485:                return -1;
                    486:        }
                    487:        /* Select the fid */
                    488:        sectok_parse_fname(argv[optind++], fid);
                    489:        sectok_apdu(fd, cla, 0xa4, 0, 0, 2, fid, sizeof buf, buf, &sw);
                    490:        if (!sectok_swOK(sw)) {
                    491:                printf("Select: %s\n", sectok_get_sw(sw));
                    492:                return -1;
                    493:        }
                    494:        isdir = (buf[6] == 1 || buf[6] == 2);
1.9       rees      495:
1.23      deraadt   496:        /* Get current acl */
                    497:        sectok_apdu(fd, cla, 0xfe, 0, 0, 0, NULL, 8, acl, &sw);
                    498:        if (!sectok_swOK(sw)) {
                    499:                printf("GetFileACL: %s\n", sectok_get_sw(sw));
                    500:                return -1;
                    501:        }
                    502:        if (argc - optind < 1) {
                    503:                /* No acl given; print acl and exit */
                    504:                if (xflag) {
                    505:                        for (i = 0; i < 8; i++)
                    506:                                printf("%02x ", acl[i]);
                    507:                        printf("\n");
                    508:                } else
                    509:                        print_acl(isdir, acl);
                    510:                return 0;
                    511:        }
                    512:        prin = argv[optind++];
1.9       rees      513:
1.23      deraadt   514:        /* strip trailing ':' */
1.27      ray       515:        if (prin[0] != '\0' && prin[strlen(prin) - 1] == ':')
                    516:                prin[strlen(prin) - 1] = '\0';
                    517:        else
                    518:                goto usage;
1.16      rees      519:
1.23      deraadt   520:        /* Find principal */
                    521:        for (prno = 0; prno < 8; prno++)
                    522:                if (!strcasecmp(prin, principals[prno]))
                    523:                        break;
                    524:        if (prno >= 8) {
                    525:                printf("unknown principal \"%s\"\n", prin);
                    526:                return -1;
                    527:        }
                    528:        /* Parse new rights */
                    529:        rt = 0;
                    530:        for (i = optind; i < optind + 8 && i < argc; i++) {
                    531:                for (j = 0; j < 8; j++) {
                    532:                        if ((d_rights[j] && !strcasecmp(argv[i], d_rights[j])) ||
                    533:                            (f_rights[j] && !strcasecmp(argv[i], f_rights[j])))
                    534:                                rt |= (1 << j);
                    535:                }
                    536:        }
                    537:        acl[prno] = rt;
1.9       rees      538:
1.23      deraadt   539:        /* Set acl */
                    540:        sectok_apdu(fd, cla, 0xfc, 0, 0, 8, acl, 0, NULL, &sw);
                    541:        if (!sectok_swOK(sw)) {
                    542:                printf("ChangeFileACL: %s\n", sectok_get_sw(sw));
                    543:                return -1;
                    544:        }
                    545:        print_acl(isdir, acl);
1.9       rees      546:
1.23      deraadt   547:        return 0;
1.1       rees      548: }
                    549:
1.23      deraadt   550: int
                    551: jcreate(int argc, char *argv[])
1.3       rees      552: {
1.23      deraadt   553:        u_char fid[2];
                    554:        int     sw, fsize;
                    555:
                    556:        if (argc != 3) {
                    557:                printf("usage: create fid size\n");
                    558:                return -1;
                    559:        }
                    560:        sectok_parse_fname(argv[1], fid);
                    561:        sscanf(argv[2], "%d", &fsize);
1.3       rees      562:
1.23      deraadt   563:        if (fd < 0 && reset(0, NULL) < 0)
                    564:                return -1;
                    565:        if (!aut0_vfyd)
                    566:                jaut(0, NULL);
1.3       rees      567:
1.23      deraadt   568:        if (cyberflex_create_file(fd, cla, fid, fsize, 3, &sw) < 0) {
                    569:                printf("create_file: %s\n", sectok_get_sw(sw));
                    570:                return -1;
                    571:        }
                    572:        return 0;
1.3       rees      573: }
                    574:
1.23      deraadt   575: int
                    576: jdelete(int argc, char *argv[])
1.3       rees      577: {
1.23      deraadt   578:        u_char fid[2];
                    579:        int     sw;
1.3       rees      580:
1.23      deraadt   581:        if (argc != 2) {
                    582:                printf("usage: delete fid\n");
                    583:                return -1;
                    584:        }
                    585:        sectok_parse_fname(argv[1], fid);
                    586:
                    587:        if (fd < 0 && reset(0, NULL) < 0)
                    588:                return -1;
                    589:        if (!aut0_vfyd)
                    590:                jaut(0, NULL);
1.3       rees      591:
1.23      deraadt   592:        if (cyberflex_delete_file(fd, cla, fid, &sw) < 0) {
                    593:                printf("delete_file: %s\n", sectok_get_sw(sw));
                    594:                return -1;
                    595:        }
                    596:        return 0;
1.3       rees      597: }
1.1       rees      598: #define MAX_BUF_SIZE 256
                    599: #define MAX_APP_SIZE 4096
                    600: #define MAX_APDU_SIZE 0xfa
                    601: #define BLOCK_SIZE 8
                    602: #define MAXTOKENS 16
                    603:
1.23      deraadt   604: u_char progID[2], contID[2];
1.1       rees      605:
1.18      rees      606: #ifndef __palmos__
1.23      deraadt   607: int
                    608: jload(int argc, char *argv[])
1.10      rees      609: {
1.23      deraadt   610:        char   *cp, *filename, progname[5], contname[5];
                    611:        u_char aid[16], app_data[MAX_APP_SIZE], data[MAX_BUF_SIZE];
                    612:        int     i, j, vflag = 0, gotprog = 0, gotcont = 0, fd_app, size;
                    613:        int     aidlen = 0, sw;
                    614:        int     cont_size = 1152, inst_size = 1024;
                    615:        des_cblock tmp;
                    616:        des_key_schedule schedule;
                    617:        static u_char acl[] = {0x81, 0, 0, 0xff, 0, 0, 0, 0};
                    618:
                    619:        optind = optreset = 1;
                    620:
                    621:        while ((i = getopt(argc, argv, "p:c:s:i:a:v")) != -1) {
                    622:                switch (i) {
                    623:                case 'p':
                    624:                        sectok_parse_input(optarg, progID, 2);
                    625:                        gotprog = 1;
                    626:                        break;
                    627:                case 'c':
                    628:                        sectok_parse_input(optarg, contID, 2);
                    629:                        gotcont = 1;
                    630:                        break;
                    631:                case 's':
                    632:                        sscanf(optarg, "%d", &cont_size);
                    633:                        break;
                    634:                case 'i':
                    635:                        sscanf(optarg, "%d", &inst_size);
                    636:                        break;
                    637:                case 'a':
                    638:                        aidlen = sectok_parse_input(optarg, aid, sizeof aid);
                    639:                        break;
                    640:                case 'v':
                    641:                        vflag = 1;
                    642:                        break;
                    643:                default:
                    644:                        printf("unknown option.  command aborted.\n");
                    645:                        return -1;
                    646:                }
                    647:        }
1.1       rees      648:
1.23      deraadt   649:        if (argc - optind < 1) {
                    650:                printf("missing file name\n");
                    651:                return -1;
                    652:        }
                    653:        filename = argv[optind++];
1.1       rees      654:
1.23      deraadt   655:        /*
                    656:          * We prepend 0xfc to the aid to make it a "proprietary aid".
                    657:          * See 7816-5 sec 5.2.4.
                    658:          */
                    659:        if (aidlen <= 0) {
                    660:                /* No aid given, derive from file name */
                    661:                cp = strrchr(filename, '/');
                    662:                if (cp)
                    663:                        cp++;
                    664:                else
                    665:                        cp = filename;
                    666:                aid[0] = 0xfc;
                    667:                strncpy(&aid[1], cp, sizeof aid - 1);
                    668:                aidlen = (aid[15] == '\0') ? strlen(aid) : 16;
                    669:        } else
                    670:                if (aid[0] == '#')
                    671:                        aid[0] = 0xfc;
                    672:
                    673:        if (!gotprog) {
                    674:                /* No progID given, derive from aid */
                    675:                progID[0] = aid[1];
                    676:                progID[1] = 'p';
                    677:        }
                    678:        if (!gotcont) {
                    679:                /* No contID given, derive from aid */
                    680:                contID[0] = aid[1];
                    681:                contID[1] = 'c';
                    682:        }
                    683:        if (fd < 0 && reset(0, NULL) < 0)
                    684:                return -1;
                    685:        if (!aut0_vfyd)
                    686:                jaut(0, NULL);
                    687:
1.24      deraadt   688:        sectok_fmt_fid(progname, sizeof progname, progID);
                    689:        sectok_fmt_fid(contname, sizeof contname, contID);
1.23      deraadt   690:
                    691:        if (vflag) {
                    692:                printf("applet file             \"%s\"\n", filename);
                    693:                printf("program ID              %s\n", progname);
                    694:                printf("container ID            %s\n", contname);
                    695:                printf("instance container size %d\n", cont_size);
                    696:                printf("instance data size      %d\n", inst_size);
                    697:                printf("AID                     ");
                    698:                for (i = 0; i < aidlen; i++)
                    699:                        printf("%02x ", aid[i]);
                    700:                printf("\n");
                    701:        }
                    702:        /* open the input file */
                    703:        fd_app = open(filename, O_RDONLY, NULL);
                    704:        if (fd_app == -1) {
                    705:                fprintf(stderr, "cannot open file \"%s\"\n", filename);
                    706:                return -1;
                    707:        }
                    708:        /* read the input file */
                    709:        size = read(fd_app, app_data, MAX_APP_SIZE);
                    710:        if (size <= 0) {
                    711:                fprintf(stderr, "error reading file %s\n", filename);
                    712:                return -1;
                    713:        }
                    714:        /* size must be able to be divided by BLOCK_SIZE */
                    715:        if (size % BLOCK_SIZE != 0) {
                    716:                fprintf(stderr, "file \"%s\" size %d not divisible by %d\n", filename, size, BLOCK_SIZE);
                    717:                return -1;
                    718:        }
                    719:        /* compute the signature of the applet */
                    720:        /* initialize the result buffer */
                    721:        memset(tmp, 0, BLOCK_SIZE);
                    722:
                    723:        /* chain.  DES encrypt one block, XOR the cyphertext with the next
                    724:         * block, ... continues until the end of the buffer */
                    725:
                    726:        des_set_key(&app_key, schedule);
                    727:
                    728:        for (i = 0; i < size / BLOCK_SIZE; i++) {
                    729:                for (j = 0; j < BLOCK_SIZE; j++)
                    730:                        tmp[j] = tmp[j] ^ app_data[i * BLOCK_SIZE + j];
                    731:                des_ecb_encrypt(&tmp, &tmp, schedule, DES_ENCRYPT);
                    732:        }
                    733:
                    734:        if (vflag) {
                    735:                /* print out the signature */
                    736:                printf("signature ");
                    737:                for (j = 0; j < BLOCK_SIZE; j++)
                    738:                        printf("%02x ", tmp[j]);
                    739:                printf("\n");
                    740:        }
                    741:        /* select the default loader */
                    742:        sectok_apdu(fd, cla, 0xa4, 0x04, 0, 0, NULL, 0, NULL, &sw);
1.4       rees      743:        if (!sectok_swOK(sw)) {
1.23      deraadt   744:                /* error */
                    745:                printf("can't select default loader: %s\n", sectok_get_sw(sw));
                    746:                return -1;
                    747:        }
                    748:        /* select 3f.00 (root) */
                    749:        if (sectok_selectfile(fd, cla, root_fid, &sw) < 0)
                    750:                return -1;
1.1       rees      751:
1.23      deraadt   752:        /* create program file */
                    753:        if (cyberflex_create_file_acl(fd, cla, progID, size, 3, acl, &sw) < 0) {
                    754:                /* error */
                    755:                printf("can't create %s: %s\n", progname, sectok_get_sw(sw));
                    756:                return -1;
                    757:        }
                    758:        /* update binary */
                    759:        for (i = 0; i < size; i += MAX_APDU_SIZE) {
                    760:                int     send_size;
                    761:
                    762:                /* compute the size to be sent */
                    763:                if (size - i > MAX_APDU_SIZE)
                    764:                        send_size = MAX_APDU_SIZE;
                    765:                else
                    766:                        send_size = size - i;
                    767:
                    768:                sectok_apdu(fd, cla, 0xd6, i / 256, i % 256, send_size,
                    769:                    app_data + i, 0, NULL, &sw);
                    770:
                    771:                if (!sectok_swOK(sw)) {
                    772:                        /* error */
                    773:                        printf("updating binary %s: %s\n", progname,
                    774:                            sectok_get_sw(sw));
                    775:                        return -1;
                    776:                }
                    777:        }
                    778:
                    779:        /* manage program .. validate */
                    780:        sectok_apdu(fd, cla, 0x0a, 01, 0, 0x08, tmp, 0, NULL, &sw);
                    781:
                    782:        if (!sectok_swOK(sw)) {
                    783:                /* error */
                    784:                printf("validating applet in %s: %s\n", progname,
                    785:                    sectok_get_sw(sw));
                    786:                return -1;
                    787:        }
                    788:        /* select the default loader */
                    789:        sectok_apdu(fd, cla, 0xa4, 0x04, 0, 0, NULL, 0, NULL, &sw);
                    790:        if (!sectok_swOK(sw)) {
                    791:                /* error */
                    792:                printf("selecting default loader: %s\n", sectok_get_sw(sw));
                    793:                return -1;
                    794:        }
                    795:        /* execute method -- call the install() method in the cardlet. cardlet
                    796:         * type 01 (applet, not application) */
                    797:
                    798:        data[0] = 0x01;         /* cardlet type = 1 (applet, not application) */
                    799:        data[1] = progID[0];    /* FID, upper */
                    800:        data[2] = progID[1];    /* FID, lower */
                    801:        data[3] = cont_size >> 8;       /* instance container size 0x0800
                    802:                                         * (1152) byte, upper */
                    803:        data[4] = cont_size & 0xff;     /* instance container size 0x0800
                    804:                                         * (1152) byte, lower */
                    805:        data[5] = contID[0];    /* container ID (7778), upper */
                    806:        data[6] = contID[1];    /* container ID (7778), lower */
                    807:        data[7] = inst_size >> 8;       /* instance size 0x0400 (1024) byte,
                    808:                                         * upper */
                    809:        data[8] = inst_size & 0xff;     /* instance size 0x0400 (1024) byte,
                    810:                                         * lower */
                    811:        data[9] = 0x00;         /* AID length 0x0005, upper */
                    812:        data[10] = aidlen;      /* AID length 0x0005, lower */
                    813:        memcpy(&data[11], aid, aidlen);
                    814:
                    815:        sectok_apdu(fd, cla, 0x0c, 0x13, 0, 11 + aidlen, data, 0, NULL, &sw);
                    816:        if (!sectok_swOK(sw)) {
                    817:                /* error */
                    818:                printf("executing install() method in applet %s: %s\n",
                    819:                    progname, sectok_get_sw(sw));
                    820:                return -1;
                    821:        }
                    822:        /* That's it! :) */
                    823:        return 0;
1.1       rees      824: }
1.18      rees      825: #endif
1.1       rees      826:
1.23      deraadt   827: int
                    828: junload(int argc, char *argv[])
1.1       rees      829: {
1.23      deraadt   830:        char    progname[5], contname[5];
                    831:        int     i, vflag = 0, gotprog = 0, gotcont = 0, sw;
1.10      rees      832:
1.23      deraadt   833:        optind = optreset = 1;
1.1       rees      834:
1.23      deraadt   835:        while ((i = getopt(argc, argv, "p:c:v")) != -1) {
                    836:                switch (i) {
                    837:                case 'p':
                    838:                        sectok_parse_input(optarg, progID, 2);
                    839:                        gotprog = 1;
                    840:                        break;
                    841:                case 'c':
                    842:                        sectok_parse_input(optarg, contID, 2);
                    843:                        gotcont = 1;
                    844:                        break;
                    845:                case 'v':
                    846:                        vflag = 1;
                    847:                        break;
                    848:                default:
                    849:                        printf("unknown option.  command aborted.\n");
                    850:                        return -1;
                    851:                }
1.10      rees      852:        }
1.20      rees      853:
1.23      deraadt   854:        if (argc - optind >= 1) {
                    855:                /* Derive progID and contID from filename */
                    856:                if (!gotprog) {
                    857:                        progID[0] = argv[optind][0];
                    858:                        progID[1] = 'p';
                    859:                        gotprog = 1;
                    860:                }
                    861:                if (!gotcont) {
                    862:                        contID[0] = argv[optind][0];
                    863:                        contID[1] = 'c';
                    864:                        gotcont = 1;
                    865:                }
1.20      rees      866:        }
1.23      deraadt   867:        /* Use old defaults */
                    868:        if (!gotprog)
                    869:                memcpy(progID, "ww", 2);
                    870:        if (!gotcont)
                    871:                memcpy(contID, "wx", 2);
                    872:
                    873:        if (fd < 0 && reset(0, NULL) < 0)
                    874:                return -1;
                    875:        if (!aut0_vfyd)
                    876:                jaut(0, NULL);
1.1       rees      877:
1.24      deraadt   878:        sectok_fmt_fid(progname, sizeof progname, progID);
                    879:        sectok_fmt_fid(contname, sizeof contname, contID);
1.1       rees      880:
1.23      deraadt   881:        if (vflag) {
                    882:                printf("program ID              %s\n", progname);
                    883:                printf("container ID            %s\n", contname);
                    884:        }
                    885:        /* select 3f.00 (root) */
                    886:        if (sectok_selectfile(fd, cla, root_fid, &sw) < 0) {
                    887:                printf("can't select root: %s\n", sectok_get_sw(sw));
                    888:                return -1;
1.2       rees      889:        }
1.23      deraadt   890:        /* select program file */
                    891:        if (sectok_selectfile(fd, cla, progID, &sw) >= 0) {
1.1       rees      892:
1.23      deraadt   893:                /* manage program -- reset */
                    894:                sectok_apdu(fd, cla, 0x0a, 02, 0, 0, NULL, 0, NULL, &sw);
                    895:                if (!sectok_swOK(sw)) {
                    896:                        /* error */
                    897:                        printf("resetting applet: %s\n", sectok_get_sw(sw));
                    898:                }
                    899:                /* delete program file */
                    900:                if (cyberflex_delete_file(fd, cla, progID, &sw) < 0)
                    901:                        printf("delete_file %s: %s\n", progname, sectok_get_sw(sw));
                    902:        } else
                    903:                if (vflag)
                    904:                        printf("no program file... proceed to delete data container\n");
1.1       rees      905:
1.23      deraadt   906:        /* delete data container */
                    907:        if (cyberflex_delete_file(fd, cla, contID, &sw) < 0)
                    908:                printf("delete_file %s: %s\n", contname, sectok_get_sw(sw));
1.1       rees      909:
1.23      deraadt   910:        return 0;
1.1       rees      911: }
                    912:
1.18      rees      913: #ifndef __palmos__
1.1       rees      914: #define DELIMITER " :\t\n"
                    915: #define KEY_BLOCK_SIZE 14
                    916:
                    917: /* download DES keys into 3f.00/00.11 */
1.23      deraadt   918: int
                    919: cyberflex_load_key(int fd, u_char *buf)
1.1       rees      920: {
1.23      deraadt   921:        int     sw, argc = 0, i, j, tmp;
                    922:        u_char *token;
                    923:        u_char data[MAX_BUF_SIZE];
                    924:        u_char key[BLOCK_SIZE];
1.1       rees      925:
                    926: #if 0
1.23      deraadt   927:        /* select the default loader */
                    928:        rv = scwrite(fd, cla, 0xa4, 0x04, 0, 0x00, NULL, &r1, &r2);
                    929:        if (r1 != 0x90 && r1 != 0x61) {
                    930:                //error
                    931:                    printf("selecting the default loader: ");
                    932:                print_r1r2(r1, r2);
                    933:                return -1;
                    934:        }
1.1       rees      935: #endif
                    936:
1.23      deraadt   937:        printf("ca_load_key buf=%s\n", buf);
                    938:        token = strtok(buf, DELIMITER);
                    939:        token = strtok(NULL, DELIMITER);
                    940:        if (token == NULL) {
1.28    ! sobrado   941:                printf("usage: jk number_of_keys\n");
1.23      deraadt   942:                return -1;
                    943:        }
                    944:        argc = atoi(token);
                    945:
                    946:        if (argc > 2) {
                    947:                printf("current Cyberflex Access cannot download more than 2 keys to the key file.  Sorry. :(\n");
                    948:                return -1;
                    949:        }
                    950:        if (argc < 0) {
                    951:                printf("you want to down load %d keys??\n", argc);
                    952:                return -1;
                    953:        }
                    954:        if (!aut0_vfyd)
                    955:                jaut(0, NULL);
                    956:
                    957:        /* Now let's do it. :) */
                    958:
                    959:        /* add the AUT0 */
                    960:        cyberflex_fill_key_block(data, 0, 1, AUT0);
                    961:
                    962:        /* add the applet sign key */
                    963:        cyberflex_fill_key_block(data + KEY_BLOCK_SIZE, 5, 0, app_key);
                    964:
                    965:        /* then add user defined keys */
                    966:        for (i = 0; i < argc; i++) {
                    967:                printf("key %d : ", i);
                    968:                for (j = 0; j < BLOCK_SIZE; j++) {
                    969:                        fscanf(cmdf, "%02x", &tmp);
                    970:                        key[j] = (u_char) tmp;
                    971:                }
                    972:
                    973:                cyberflex_fill_key_block(data + 28 + i * KEY_BLOCK_SIZE,
                    974:                    6 + i, 0, key);
                    975:        }
                    976:
                    977:        /* add the suffix */
                    978:        data[28 + argc * KEY_BLOCK_SIZE] = 0;
                    979:        data[28 + argc * KEY_BLOCK_SIZE + 1] = 0;
                    980:
                    981:        for (i = 0; i < KEY_BLOCK_SIZE * (argc + 2) + 2; i++)
                    982:                printf("%02x ", data[i]);
                    983:        printf("\n");
1.1       rees      984:
1.23      deraadt   985:        /* select 3f.00 (root) */
                    986:        if (sectok_selectfile(fd, cla, root_fid, &sw) < 0) {
                    987:                printf("select root: %s\n", sectok_get_sw(sw));
                    988:                return -1;
                    989:        }
                    990:        /* select 00.11 (key file) */
                    991:        if (sectok_selectfile(fd, cla, key_fid, &sw) < 0) {
                    992:                printf("select key file: %s\n", sectok_get_sw(sw));
                    993:                return -1;
                    994:        }
                    995:        /* all righty, now let's send it to the card! :) */
                    996:        sectok_apdu(fd, cla, 0xd6, 0, 0, KEY_BLOCK_SIZE * (argc + 2) + 2,
                    997:            data, 0, NULL, &sw);
                    998:        if (!sectok_swOK(sw)) {
                    999:                /* error */
                   1000:                printf("writing the key file 00.11: %s\n", sectok_get_sw(sw));
                   1001:                return -1;
                   1002:        }
                   1003:        return 0;
1.1       rees     1004: }
                   1005:
                   1006: /* download AUT0 key into 3f.00/00.11 */
1.23      deraadt  1007: int
                   1008: jsetpass(int argc, char *argv[])
1.1       rees     1009: {
1.23      deraadt  1010:        int     sw;
                   1011:        u_char data[MAX_BUF_SIZE];
                   1012:        u_char AUT0[20];
1.1       rees     1013:
1.23      deraadt  1014:        if (!aut0_vfyd && jaut(0, NULL) < 0)
                   1015:                return -1;
1.1       rees     1016:
1.23      deraadt  1017:        if (get_AUT0(argc, argv, "Enter new AUT0 passphrase: ", 1, AUT0) < 0)
                   1018:                return -1;
1.1       rees     1019:
1.23      deraadt  1020:        cyberflex_fill_key_block(data, 0, 1, AUT0);
1.1       rees     1021:
                   1022: #if 0
1.23      deraadt  1023:        /* add the suffix */
                   1024:        data[KEY_BLOCK_SIZE] = 0;
                   1025:        data[KEY_BLOCK_SIZE + 1] = 0;
1.1       rees     1026: #endif
                   1027:
1.5       rees     1028: #ifdef DEBUG
1.23      deraadt  1029:        for (i = 0; i < KEY_BLOCK_SIZE; i++)
                   1030:                printf("%02x ", data[i]);
                   1031:        printf("\n");
1.5       rees     1032: #endif
1.1       rees     1033:
1.23      deraadt  1034:        /* select 3f.00 (root) */
                   1035:        if (sectok_selectfile(fd, cla, root_fid, &sw) < 0)
                   1036:                return -1;
                   1037:
                   1038:        /* select 00.11 (key file) */
                   1039:        if (sectok_selectfile(fd, cla, key_fid, &sw) < 0)
                   1040:                return -1;
1.1       rees     1041:
1.23      deraadt  1042:        /* all righty, now let's send it to the card! :) */
                   1043:        sectok_apdu(fd, cla, 0xd6, 0, 0, KEY_BLOCK_SIZE, data, 0, NULL, &sw);
                   1044:        if (!sectok_swOK(sw)) {
                   1045:                /* error */
                   1046:                printf("writing the key file 00.11: %s\n", sectok_get_sw(sw));
                   1047:                return -1;
                   1048:        }
                   1049:        return 0;
1.1       rees     1050: }
                   1051:
                   1052: /* download RSA private key into 3f.00/00.12 */
1.23      deraadt  1053: int
                   1054: cyberflex_load_rsa(int fd, u_char *buf)
1.1       rees     1055: {
1.23      deraadt  1056:        int     sw, i, j, tmp;
                   1057:        static u_char key_fid[] = {0x00, 0x12};
                   1058:        static char *key_names[NUM_RSA_KEY_ELEMENTS] = {
                   1059:                "p", "q", "1/p mod q", "d mod (p-1)", "d mod (q-1)"
                   1060:        };
                   1061:        u_char *key_elements[NUM_RSA_KEY_ELEMENTS];
                   1062:
                   1063:        printf("ca_load_rsa_priv buf=%s\n", buf);
                   1064:
                   1065:        printf("input 1024 bit RSA CRT key\n");
                   1066:        for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++) {
                   1067:                printf("%s (%d bit == %d byte) : ", key_names[i],
                   1068:                    RSA_BIT_LEN / 2, RSA_BIT_LEN / 2 / 8);
                   1069:                key_elements[i] = (u_char *) malloc(RSA_BIT_LEN / 8);
                   1070:                for (j = 0; j < RSA_BIT_LEN / 8 / 2; j++) {
                   1071:                        fscanf(cmdf, "%02x", &tmp);
                   1072:                        key_elements[i][j] = (u_char) tmp;
                   1073:                }
1.1       rees     1074:        }
                   1075:
                   1076: #ifdef DEBUG
1.23      deraadt  1077:        printf("print RSA CRT key\n");
                   1078:        for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++) {
                   1079:                printf("%s : ", key_names[i]);
                   1080:                for (j = 0; j < RSA_BIT_LEN / 8 / 2; j++) {
                   1081:                        printf("%02x ", key_elements[i][j]);
                   1082:                }
1.1       rees     1083:        }
                   1084: #endif
1.4       rees     1085:
1.23      deraadt  1086:        if (!aut0_vfyd)
                   1087:                jaut(0, NULL);
1.1       rees     1088:
1.23      deraadt  1089:        cyberflex_load_rsa_priv(fd, cla, key_fid, NUM_RSA_KEY_ELEMENTS, RSA_BIT_LEN,
                   1090:            key_elements, &sw);
1.2       rees     1091:
1.23      deraadt  1092:        if (!sectok_swOK(sw))
                   1093:                printf("load_rsa_priv: %s\n", sectok_get_sw(sw));
1.1       rees     1094:
1.23      deraadt  1095:        for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
                   1096:                free(key_elements[i]);
                   1097:        return 0;
1.1       rees     1098: }
1.18      rees     1099: #endif