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

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