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

1.24    ! deraadt     1: /*     $OpenBSD: cyberflex.c,v 1.23 2002/06/17 07:10:52 deraadt 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 */
1.24    ! deraadt   421:                sectok_fmt_fid(fname, sizeof fname, &buf[4]);
1.23      deraadt   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:
1.24    ! deraadt   682:        sectok_fmt_fid(progname, sizeof progname, progID);
        !           683:        sectok_fmt_fid(contname, sizeof contname, contID);
1.23      deraadt   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.24    ! deraadt   872:        sectok_fmt_fid(progname, sizeof progname, progID);
        !           873:        sectok_fmt_fid(contname, sizeof 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