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

1.2       rees        1: /* $Id: cyberflex.c,v 1.1 2001/06/27 19:41:45 rees Exp $ */
1.1       rees        2:
                      3: /*
                      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: */
                     32:
                     33: #include <unistd.h>
                     34: #include <stdlib.h>
                     35: #include <stdio.h>
                     36: #include <signal.h>
                     37: #include <string.h>
                     38: #include <fcntl.h>
                     39: #ifdef __linux
                     40: #include <openssl/des.h>
                     41: #else /* __linux */
                     42: #include <des.h>
                     43: #endif
                     44: #include <sectok.h>
1.3     ! rees       45: #include <sc7816.h>
1.1       rees       46:
                     47: #include "sc.h"
                     48:
                     49: #ifdef __sun
                     50: #define des_set_key(key, schedule) des_key_sched(key, schedule)
                     51: #endif
                     52:
                     53: #define MAX_KEY_FILE_SIZE 1024
                     54: #define NUM_RSA_KEY_ELEMENTS 5
                     55: #define RSA_BIT_LEN 1024
                     56: #define KEY_FILE_HEADER_SIZE 8
                     57:
                     58: static unsigned char key_fid[] = {0x00, 0x11};
                     59: static unsigned char DFLTATR[] = {0x81, 0x10, 0x06, 0x01};
                     60: static unsigned char AUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
                     61:
                     62: /* default signed applet key of Cyberflex Access */
                     63: static des_cblock app_key = {0x6A, 0x21, 0x36, 0xF5, 0xD8, 0x0C, 0x47, 0x83};
                     64:
                     65: char *apptype[] = {
                     66:     "?",
                     67:     "applet",
                     68:     "app",
                     69:     "app/applet",
                     70: };
                     71:
                     72: char *appstat[] = {
                     73:     "?",
                     74:     "created",
                     75:     "installed",
                     76:     "registered",
                     77: };
                     78:
                     79: char *filestruct[] = {
                     80:     "binary",
                     81:     "fixed rec",
                     82:     "variable rec",
                     83:     "cyclic",
                     84:     "program",
                     85: };
                     86:
                     87: int jdefault(int ac, char *av[])
                     88: {
                     89:     unsigned char buf[8];
                     90:     int i, p1 = 4, r1, r2;
                     91:
                     92:     optind = optreset = 1;
                     93:
                     94:     while ((i = getopt(ac, av, "d")) != -1) {
                     95:        switch (i) {
                     96:        case 'd':
                     97:            p1 = 5;
                     98:            break;
                     99:        }
                    100:     }
                    101:
                    102:     if (fd < 0)
                    103:        reset(0, NULL);
                    104:
                    105:     scwrite(fd, cla, 0x08, p1, 0, 0, buf, &r1, &r2);
                    106:     if (r1 != 0x90) {
                    107:        /* error */
                    108:        print_r1r2(r1, r2);
                    109:        return -1;
                    110:     }
                    111:     return 0;
                    112: }
                    113:
                    114: int jatr(int ac, char *av[])
                    115: {
                    116:     unsigned char buf[64];
                    117:     int n = 0, r1, r2;
                    118:
                    119:     if (fd < 0)
                    120:        reset(0, NULL);
                    121:
                    122:     buf[n++] = 0x90;
                    123:     buf[n++] = 0x94;           /* TA1 */
                    124:     buf[n++] = 0x40;           /* TD1 */
                    125:     buf[n++] = 0x28;           /* TC2 (WWT=4sec) */
                    126:     if (ac > optind) {
                    127:        /* set historical bytes from command line */
                    128:        n += parse_input(av[1], &buf[n], 15);
                    129:     } else {
                    130:        /* no historical bytes given, use default */
                    131:        memmove(&buf[n], DFLTATR, sizeof DFLTATR);
                    132:        n += sizeof DFLTATR;
                    133:     }
                    134:     buf[0] |= ((n - 2) & 0xf);
                    135:     scwrite(fd, cla, 0xfa, 0, 0, n, buf, &r1, &r2);
                    136:     if (r1 != 0x90) {
                    137:        /* error */
                    138:        print_r1r2(r1, r2);
                    139:        return -1;
                    140:     }
                    141:     return 0;
                    142: }
                    143:
                    144: int jdata(int ac, char *av[])
                    145: {
                    146:     unsigned char buf[32];
                    147:     int i, r1, r2;
                    148:
                    149:     if (fd < 0)
                    150:        reset(0, NULL);
                    151:
                    152:     scread(fd, cla, 0xca, 0, 1, 0x16, buf, &r1, &r2);
                    153:     if (r1 == 0x90) {
                    154:        printf("serno ");
                    155:        for (i = 0; i < 6; i++)
                    156:            printf("%02x ", buf[i]);
                    157:        printf("batch %02x sver %d.%02d ", buf[6], buf[7], buf[8]);
                    158:        if (buf[9] == 0x0c)
                    159:            printf("augmented ");
                    160:        else if (buf[9] == 0x0b)
                    161:            ;
                    162:        else
                    163:            printf("unknown ");
                    164:        printf("crypto %9.9s class %02x\n", &buf[10], buf[19]);
                    165:     } else {
                    166:        /* error */
                    167:        print_r1r2(r1, r2);
                    168:     }
                    169:     return 0;
                    170: }
                    171:
                    172: #define JDIRSIZE 40
                    173:
                    174: int ls(int ac, char *av[])
                    175: {
                    176:     int p2, f0, f1, r1, r2;
                    177:     char ftype[32], fname[6];
                    178:     unsigned char buf[JDIRSIZE];
                    179:
                    180:     if (fd < 0)
                    181:        reset(0, NULL);
                    182:
                    183:     for (p2 = 0; ; p2++) {
                    184:        if (scread(fd, cla, 0xa8, 0, p2, JDIRSIZE, buf, &r1, &r2) < 0)
                    185:            break;
                    186:        if (r1 != 0x90)
                    187:            break;
                    188:        f0 = buf[4];
                    189:        f1 = buf[5];
                    190:        if (f0 == 0xff || f0 + f1 == 0)
                    191:            continue;
                    192:        sectok_fmt_fid(fname, f0, f1);
                    193:        if (buf[6] == 1)
                    194:            /* root */
                    195:            sprintf(ftype, "root");
                    196:        else if (buf[6] == 2) {
                    197:            /* DF */
                    198:            if (buf[12] == 27)
                    199:                sprintf(ftype, "%s %s", appstat[buf[10]], apptype[buf[9]]);
                    200:            else
                    201:                sprintf(ftype, "directory");
                    202:        } else if (buf[6] == 4)
                    203:            /* EF */
                    204:            sprintf(ftype, "%s", filestruct[buf[13]]);
                    205:        printf("%4s %5d %s\n", fname, (buf[2] << 8) | buf[3], ftype);
                    206:     }
                    207:     return 0;
                    208: }
                    209:
1.3     ! rees      210: int jcreate(int ac, char *av[])
        !           211: {
        !           212:     unsigned char fid[2];
        !           213:     int sw, fsize;
        !           214:
        !           215:     if (ac != 3) {
        !           216:        printf("usage: create fid size\n");
        !           217:        return -1;
        !           218:     }
        !           219:
        !           220:     sectok_parse_fname(av[1], fid);
        !           221:     sscanf(av[2], "%d", &fsize);
        !           222:
        !           223:     if (fd < 0)
        !           224:        reset(0, NULL);
        !           225:
        !           226:     if (cyberflex_create_file(fd, cla, fid, fsize, 3, &sw) < 0) {
        !           227:        printf("create_file: %s\n", sectok_get_sw(sw));
        !           228:        return -1;
        !           229:     }
        !           230:
        !           231:     return 0;
        !           232: }
        !           233:
        !           234: int jdelete(int ac, char *av[])
        !           235: {
        !           236:     unsigned char fid[2];
        !           237:     int sw;
        !           238:
        !           239:     if (ac != 2) {
        !           240:        printf("usage: delete fid\n");
        !           241:        return -1;
        !           242:     }
        !           243:
        !           244:     sectok_parse_fname(av[1], fid);
        !           245:
        !           246:     if (fd < 0)
        !           247:        reset(0, NULL);
        !           248:
        !           249:     if (cyberflex_delete_file(fd, cla, fid, &sw) < 0) {
        !           250:        printf("delete_file: %s\n", sectok_get_sw(sw));
        !           251:        return -1;
        !           252:     }
        !           253:
        !           254:     return 0;
        !           255: }
        !           256:
1.1       rees      257: int jaut(int ac, char *av[])
                    258: {
                    259:     if (fd < 0)
                    260:        reset(0, NULL);
                    261:
                    262:     cla = cyberflex_inq_class(fd);
                    263:     printf("Class %02x\n", cla);
                    264:     return cyberflex_verify_AUT0(fd, cla, AUT0, sizeof AUT0);
                    265: }
                    266:
                    267: #define MAX_BUF_SIZE 256
                    268: #define MAX_APP_SIZE 4096
                    269: #define MAX_APDU_SIZE 0xfa
                    270: #define BLOCK_SIZE 8
                    271: #define MAXTOKENS 16
                    272:
                    273: unsigned char *app_name;
                    274: unsigned char progID[2], contID[2], aid[MAX_BUF_SIZE];
                    275: int cont_size, inst_size;
                    276: int aid_len;
                    277:
                    278: int analyze_load_options(int ac, char *av[])
                    279: {
                    280:     int i, rv;
                    281:
                    282:     progID[0] = 0x77;
                    283:     progID[1] = 0x77;
                    284:     contID[0] = 0x77;
                    285:     contID[1] = 0x78;
                    286:     cont_size = 1152;
                    287:     inst_size = 1024;
                    288:     aid_len = 5;
                    289:
                    290:     for (i = 0 ; i < 16 ; i ++)
                    291:        aid[i] = 0x77;
                    292:
                    293:     /* applet file name */
                    294:     app_name = av[ac - 1];
                    295:
                    296:     optind = optreset = 1;
                    297:
                    298:     /* switch on options */
                    299:     while (1) {
                    300:        rv = getopt (ac, av, "p:c:s:i:a:");
                    301:        if (rv == -1) break;
                    302:        /*printf ("rv=%c, optarg=%s\n", rv, optarg);*/
                    303:        switch (rv) {
                    304:        case 'p':
                    305:            parse_input(optarg, progID, 2);
                    306:            break;
                    307:        case 'c':
                    308:            parse_input(optarg, contID, 2);
                    309:            break;
                    310:        case 's':
                    311:            sscanf(optarg, "%d", &cont_size);
                    312:            break;
                    313:        case 'i':
                    314:            sscanf(optarg, "%d", &inst_size);
                    315:            break;
                    316:        case 'a':
                    317:            aid_len = parse_input(optarg, aid, sizeof aid);
                    318:            /*printf ("aid_len = %d\n", aid_len);*/
                    319:            break;
                    320:        default:
                    321:            printf ("unknown option.  command aborted.\n");
                    322:            return -1;
                    323:        }
                    324:     }
                    325:
                    326:     return 0;
                    327: }
                    328:
                    329: int jload(int ac, char *av[])
                    330: {
                    331:     char progname[5], contname[5];
                    332:     unsigned char app_data[MAX_APP_SIZE],
                    333:     data[MAX_BUF_SIZE];
1.3     ! rees      334:     int i, j, fd_app, size, rv, sw, r1, r2;
1.1       rees      335:     des_cblock tmp;
                    336:     des_key_schedule schedule;
                    337:
                    338:     if (analyze_load_options(ac, av) < 0)
                    339:        return -1;
                    340:
                    341:     if (fd < 0)
                    342:        reset(0, NULL);
                    343:
                    344:     sectok_fmt_fid(progname, progID[0], progID[1]);
                    345:     sectok_fmt_fid(contname, contID[0], contID[1]);
                    346:
                    347:     printf ("applet file             \"%s\"\n", app_name);
                    348:     printf ("program ID              %s\n", progname);
                    349:     printf ("container ID            %s\n", contname);
                    350:     printf ("instance container size %d\n", cont_size);
                    351:     printf ("instance data size      %d\n", inst_size);
                    352:     printf ("AID                     ");
                    353:     for (i = 0 ; i < aid_len ; i ++ )
                    354:        printf ("%02x", (unsigned char)aid[i]);
                    355:     printf ("\n");
                    356:
                    357:     /* open the input file */
                    358:     fd_app = open (app_name, O_RDONLY, NULL);
                    359:     if (fd_app == -1) {
                    360:        fprintf (stderr, "cannot open file \"%s\"\n", app_name);
                    361:        return -1;
                    362:     }
                    363:
                    364:     /* read the input file */
                    365:     size = read (fd_app, app_data, MAX_APP_SIZE);
                    366:     if (size == 0) {
                    367:        fprintf (stderr, "file %s size 0??\n", app_name);
                    368:        return -1;
                    369:     }
                    370:     if (size == -1) {
                    371:        fprintf (stderr, "error reading file %s\n", app_name);
                    372:        return -1;
                    373:     }
                    374:
                    375:     /*printf ("file size %d\n", size);*/
                    376:
                    377:     /* size must be able to be divided by BLOCK_SIZE */
                    378:     if (size % BLOCK_SIZE != 0) {
                    379:        fprintf (stderr, "file (%s) size cannot be divided by BLOCK_SIZE.\n",
                    380:                 app_name);
                    381:        return -1;
                    382:     }
                    383:
                    384:     /* compute the signature of the applet */
                    385:     /* initialize the result buffer */
                    386:     for (j = 0; j < BLOCK_SIZE; j++ ) {
                    387:        tmp[j] = 0;
                    388:     }
                    389:
                    390:     /* chain.  DES encrypt one block, XOR the cyphertext with the next block,
                    391:        ... continues until the end of the buffer */
                    392:
                    393:     des_set_key (&app_key, schedule);
                    394:
                    395:     for (i = 0; i < size/BLOCK_SIZE; i++) {
                    396:        for (j = 0; j < BLOCK_SIZE; j++ ){
                    397:            tmp[j] = tmp[j] ^ app_data[i*BLOCK_SIZE + j];
                    398:        }
                    399:        des_ecb_encrypt (&tmp, &tmp, schedule, DES_ENCRYPT);
                    400:     }
                    401:
                    402:     /* print out the signature */
                    403:     printf ("signature ");
                    404:     for (j = 0; j < BLOCK_SIZE; j++ ) {
                    405:        printf ("%02x", tmp[j]);
                    406:     }
                    407:     printf ("\n");
                    408:
                    409:     /* select the default loader */
                    410:     rv = scwrite(fd, cla, 0xa4, 0x04, 0, 0, NULL, &r1, &r2);
                    411:     if (r1 != 0x90 && r1 != 0x61) {
                    412:        /* error */
1.2       rees      413:        printf("can't select default loader: %s\n", get_r1r2s(r1, r2));
1.1       rees      414:        return -1;
                    415:     }
                    416:
                    417:     /* select 3f.00 (root) */
1.3     ! rees      418:     if (sectok_selectfile(fd, cla, root_fid, &sw) < 0)
1.2       rees      419:        return -1;
1.1       rees      420:
                    421:     /* create program file */
1.3     ! rees      422:     if (cyberflex_create_file(fd, cla, progID, size, 3, &sw) < 0) {
1.1       rees      423:        /* error */
1.3     ! rees      424:        printf("can't create %s: %s\n", progname, sectok_get_sw(sw));
1.1       rees      425:        return -1;
                    426:     }
                    427:
                    428:     /* update binary */
                    429:     for (i = 0; i < size; i += MAX_APDU_SIZE) {
                    430:        int send_size;
                    431:
                    432:        /* compute the size to be sent */
                    433:        if (size - i > MAX_APDU_SIZE) send_size = MAX_APDU_SIZE;
                    434:        else send_size = size - i;
                    435:
                    436:        rv = scwrite(fd, cla, 0xd6,
                    437:                     i / 256,   /* offset, upper byte */
                    438:                     i % 256,   /* offset, lower byte */
                    439:                     send_size,
                    440:                     app_data + i, /* program file */
                    441:                     &r1, &r2);
                    442:
                    443:        if (r1 != 0x90 && r1 != 0x61) {
                    444:            /* error */
                    445:            printf("updating binary %s: %s\n", progname, get_r1r2s(r1, r2));
                    446:            return -1;
                    447:        }
                    448:     }
                    449:
                    450:     /* manage program .. validate */
                    451:     rv = scwrite(fd, cla, 0x0a, 01, 0, 0x08,
                    452:                 tmp,           /* signature */
                    453:                 &r1, &r2);
                    454:
                    455:     if (r1 != 0x90 && r1 != 0x61) {
                    456:        /* error */
                    457:        printf("validating applet in %s: %s\n", progname, get_r1r2s(r1, r2));
                    458:        return -1;
                    459:     }
                    460:
                    461:     /* select the default loader */
                    462:     rv = scwrite(fd, cla, 0xa4, 0x04, 0, 0, NULL, &r1, &r2);
                    463:     if (r1 != 0x90 && r1 != 0x61) {
                    464:        /* error */
                    465:        printf("selecting default loader: %s\n", get_r1r2s(r1, r2));
                    466:        return -1;
                    467:     }
                    468:
                    469:     /* execute method -- call the install() method in the cardlet.
                    470:        cardlet type 01 (applet, not application)
                    471:        program ID (7777)
                    472:        instance container size (0800 (1152))
                    473:        instance container ID (7778)
                    474:        instance data size (0400 (1024))
                    475:        AID length (0005 (5 byte))
                    476:        AID (7777777777) */
                    477:
                    478:     data[0] = 0x01;            /* cardlet type = 1 (applet, not application) */
                    479:     data[1] = progID[0];       /* FID, upper */
                    480:     data[2] = progID[1];       /* FID, lower */
                    481:     data[3] = cont_size / 256; /* instance container size 0x0800 (1152) byte, upper */
                    482:     data[4] = cont_size % 256; /* instance container size 0x0800 (1152) byte, lower */
                    483:     data[5] = contID[0];       /* container ID (7778), upper */
                    484:     data[6] = contID[1];       /* container ID (7778), lower */
                    485:     data[7] = inst_size / 256; /* instance size 0x0400 (1024) byte, upper */
                    486:     data[8] = inst_size % 256; /* instance size 0x0400 (1024) byte, lower */
                    487:     data[9] = 0x00;            /* AID length 0x0005, upper */
                    488:     data[10] = aid_len;                /* AID length 0x0005, lower */
                    489:     for (i = 0; i < aid_len; i++) data[i + 11] = (unsigned int)aid[i];
                    490:     /* AID (7777777777) */
                    491:
                    492:     rv = scwrite(fd, cla, 0x0c, 0x13, 0, 11 + aid_len, data, &r1, &r2);
                    493:     if (r1 != 0x90 && r1 != 0x61) {
                    494:        /* error */
                    495:        printf("executing install() method in applet %s: %s\n", progname, get_r1r2s(r1, r2));
                    496:        return -1;
                    497:     }
                    498:
                    499:     /* That's it! :) */
                    500:     return 0;
                    501: }
                    502:
                    503: int junload(int ac, char *av[])
                    504: {
                    505:     char progname[5], contname[5];
1.3     ! rees      506:     int sw, r1, r2, rv;
1.1       rees      507:
                    508:     if (analyze_load_options(ac, av) < 0)
                    509:        return -1;
                    510:
                    511:     if (fd < 0)
                    512:        reset(0, NULL);
                    513:
                    514:     sectok_fmt_fid(progname, progID[0], progID[1]);
                    515:     sectok_fmt_fid(contname, contID[0], contID[1]);
                    516:
                    517:     printf ("program ID              %s\n", progname);
                    518:     printf ("container ID            %s\n", contname);
                    519:     /*printf ("AID                     ");
                    520:       for (i = 0 ; i < aid_len ; i ++ ) {
                    521:       printf ("%02x", (unsigned char)aid[i]);
                    522:       }
                    523:       printf ("\n");*/
                    524:
                    525:     /*printf ("unload applet\n");*/
                    526:
                    527:     /* select 3f.00 (root) */
1.3     ! rees      528:     if (sectok_selectfile(fd, cla, root_fid, &sw) < 0) {
        !           529:        printf("can't select root: %s\n", sectok_get_sw(sw));
1.2       rees      530:        return -1;
1.3     ! rees      531:     }
1.1       rees      532:
                    533:     /* select program file */
1.3     ! rees      534:     if (sectok_selectfile(fd, cla, progID, &sw) >= 0) {
1.1       rees      535:
1.2       rees      536:        /* manage program -- reset */
                    537:        rv = scwrite(fd, cla, 0x0a, 02, 0, 0x0, NULL, &r1, &r2);
                    538:        if (rv < 0 || (r1 != 0x90 && r1 != 0x61)) {
                    539:            /* error */
                    540:            printf("resetting applet: %s\n", get_r1r2s(r1, r2));
                    541:        }
1.1       rees      542:
1.2       rees      543:        /* delete program file */
1.3     ! rees      544:        if (cyberflex_delete_file(fd, cla, progID, &sw) < 0)
        !           545:            printf("delete_file %s: %s\n", progname, sectok_get_sw(sw));
1.2       rees      546:     } else
                    547:        printf ("no program file... proceed to delete data container\n");
1.1       rees      548:
                    549:     /* delete data container */
1.3     ! rees      550:     if (cyberflex_delete_file(fd, cla, contID, &sw) < 0)
        !           551:        printf("delete_file %s: %s\n", contname, sectok_get_sw(sw));
1.1       rees      552:
                    553:     return 0;
                    554: }
                    555:
                    556: int jselect(int ac, char *av[])
                    557: {
                    558:     int i, r1, r2, rv;
                    559:     unsigned char data[MAX_BUF_SIZE];
                    560:
                    561:     optind = optreset = 1;
                    562:
                    563:     if (analyze_load_options(ac, av) < 0)
                    564:        return -1;
                    565:
                    566:     if (fd < 0)
                    567:        reset(0, NULL);
                    568:
                    569:     printf ("select applet\n");
                    570:     printf ("AID                     ");
                    571:     for (i = 0 ; i < aid_len ; i ++ )
                    572:        printf ("%02x", (unsigned char)aid[i]);
                    573:     printf ("\n");
                    574:
                    575:     /* select the cardlet (7777777777) */
                    576:     for (i = 0; i < aid_len; i++) data[i] = (unsigned char)aid[i];
                    577:     /* quick hack in select_applet()
                    578:        even with F0 card, select applet APDU (00 a4 04)
                    579:        only accepts class byte 00 (not f0) */
                    580:
                    581:     rv = scwrite(fd, cla, 0xa4, 0x04, 0, aid_len, data, &r1, &r2);
                    582:     if (r1 != 0x90 && r1 != 0x61) {
                    583:        /* error */
                    584:        printf ("selecting the cardlet: ");
                    585:        for (i = 0 ; i < aid_len ; i ++ ) {
                    586:            printf ("%02x", (unsigned char)aid[i]);
                    587:        }
                    588:        printf ("\n");
                    589:        print_r1r2 (r1, r2);
                    590:        return -1;
                    591:     }
                    592:
                    593:     return 0;
                    594: }
                    595:
                    596: int jdeselect(int ac, char *av[])
                    597: {
1.3     ! rees      598:     int sw;
1.1       rees      599:
                    600:     if (fd < 0)
                    601:        reset(0, NULL);
                    602:
1.3     ! rees      603:     sectok_apdu(fd, cla, 0xa4, 0x04, 0, 0, NULL, 0, NULL, &sw);
        !           604:     if (!sectok_swOK(sw)) {
1.1       rees      605:        /* error */
1.3     ! rees      606:        printf("selecting default loader: %s\n", sectok_get_sw(sw));
1.1       rees      607:        return -1;
                    608:     }
                    609:
                    610:     return 0;
                    611: }
                    612:
                    613: #define DELIMITER " :\t\n"
                    614: #define KEY_BLOCK_SIZE 14
                    615:
                    616: /* download DES keys into 3f.00/00.11 */
                    617: int cyberflex_load_key (int fd, unsigned char *buf)
                    618: {
1.3     ! rees      619:     int sw, r1, r2, rv, argc = 0, i, j, tmp;
1.1       rees      620:     unsigned char *token;
                    621:     unsigned char data[MAX_BUF_SIZE];
                    622:     unsigned char key[BLOCK_SIZE];
                    623:
                    624: #if 0
                    625:     /* select the default loader */
                    626:     rv = scwrite(fd, cla, 0xa4, 0x04, 0, 0x00, NULL, &r1, &r2);
                    627:     if (r1 != 0x90 && r1 != 0x61) {
                    628:        // error
                    629:            printf ("selecting the default loader: ");
                    630:        print_r1r2 (r1, r2);
                    631:        return -1;
                    632:     }
                    633: #endif
                    634:
                    635:     printf ("ca_load_key buf=%s\n", buf);
                    636:     token = strtok (buf, DELIMITER);
                    637:     token = strtok (NULL, DELIMITER);
                    638:     if (token == NULL) {
                    639:        printf ("Usage: jk number_of_keys\n");
                    640:        return -1;
                    641:     }
                    642:     argc = atoi (token);
                    643:
                    644:     if (argc > 2) {
                    645:        printf ("current Cyberflex Access cannot download more than 2 keys to the key file.  Sorry. :(\n");
                    646:        return -1;
                    647:     }
                    648:
                    649:     if (argc < 0) {
                    650:        printf ("you want to down load %d keys??\n", argc);
                    651:        return -1;
                    652:     }
                    653:
                    654:     /* Now let's do it. :) */
                    655:
                    656:     /* add the AUT0 */
                    657:     cyberflex_fill_key_block (data,    0, 1, AUT0);
                    658:
                    659:     /* add the applet sign key */
                    660:     cyberflex_fill_key_block (data+KEY_BLOCK_SIZE, 5, 0, app_key);
                    661:
                    662:     /* then add user defined keys */
                    663:     for ( i = 0 ; i < argc ; i++ ) {
                    664:        printf ("key %d : ", i);
                    665:        for ( j = 0 ; j < BLOCK_SIZE ; j++ ) {
                    666:            fscanf (cmdf, "%02x", &tmp);
                    667:            key[j] = (unsigned char)tmp;
                    668:        }
                    669:
                    670:        cyberflex_fill_key_block (data + 28 + i*KEY_BLOCK_SIZE, 6 + i, 0, key);
                    671:     }
                    672:
                    673:     /* add the suffix */
                    674:     data[28 + argc*KEY_BLOCK_SIZE] = 0;
                    675:     data[28 + argc*KEY_BLOCK_SIZE + 1] = 0;
                    676:
                    677:     for ( i = 0 ; i < KEY_BLOCK_SIZE * (argc + 2) + 2; i++ )
                    678:        printf ("%02x ", data[i]);
                    679:     printf ("\n");
                    680:
                    681:     /* select 3f.00 (root) */
1.3     ! rees      682:     if (sectok_selectfile(fd, cla, root_fid, &sw) < 0) {
        !           683:        printf("select root: %s\n", sectok_get_sw(sw));
1.2       rees      684:        return -1;
1.3     ! rees      685:     }
1.1       rees      686:
                    687:     /* select 00.11 (key file) */
1.3     ! rees      688:     if (sectok_selectfile(fd, cla, key_fid, &sw) < 0) {
        !           689:        printf("select key file: %s\n", sectok_get_sw(sw));
1.2       rees      690:        return -1;
1.3     ! rees      691:     }
1.1       rees      692:
                    693:     /* all righty, now let's send it to the card! :) */
                    694:     rv = scwrite(fd, cla, 0xd6, 0, 0, KEY_BLOCK_SIZE * (argc + 2) + 2,
                    695:                 data, &r1, &r2);
                    696:     if (r1 != 0x90 && r1 != 0x61) {
                    697:        /* error */
1.2       rees      698:        printf("writing the key file 00.11: %s\n", get_r1r2s(r1, r2));
1.1       rees      699:        return -1;
                    700:     }
                    701:
                    702:     return 0;
                    703: }
                    704:
                    705: /* download AUT0 key into 3f.00/00.11 */
                    706: int load_AUT0(int fd, unsigned char *buf)
                    707: {
1.3     ! rees      708:     int sw, r1, r2, rv, i, tmp;
1.1       rees      709:     unsigned char data[MAX_BUF_SIZE];
                    710:     unsigned char key[BLOCK_SIZE];
                    711:
                    712:     printf ("load AUT0\n");
                    713:
                    714:     printf ("ca_load_AUT0 buf=%s\n", buf);
                    715:
                    716:     /* Now let's do it. :) */
                    717:
                    718:     /* get the AUT0 */
                    719:     printf ("input AUT0 : ");
                    720:     for ( i = 0 ; i < BLOCK_SIZE ; i++ ) {
                    721:        fscanf (cmdf, "%02x", &tmp);
                    722:        key[i] = (unsigned char)tmp;
                    723:     }
                    724:     cyberflex_fill_key_block (data, 0, 1, key);
                    725:
                    726: #if 0
                    727:     /* add the suffix */
                    728:     data[KEY_BLOCK_SIZE] = 0;
                    729:     data[KEY_BLOCK_SIZE + 1] = 0;
                    730: #endif
                    731:
                    732:     for ( i = 0 ; i < KEY_BLOCK_SIZE ; i++ )
                    733:        printf ("%02x ", data[i]);
                    734:     printf ("\n");
                    735:
                    736:     /* select 3f.00 (root) */
1.3     ! rees      737:     if (sectok_selectfile(fd, cla, root_fid, &sw) < 0)
1.2       rees      738:        return -1;
1.1       rees      739:
                    740:     /* select 00.11 (key file) */
1.3     ! rees      741:     if (sectok_selectfile(fd, cla, key_fid, &sw) < 0)
1.2       rees      742:        return -1;
1.1       rees      743:
                    744:     /* all righty, now let's send it to the card! :) */
                    745:     rv = scwrite(fd, cla, 0xd6, 0, 0, KEY_BLOCK_SIZE,
                    746:                 data, &r1, &r2);
                    747:     if (r1 != 0x90 && r1 != 0x61) {
                    748:        /* error */
1.2       rees      749:        printf("writing the key file 00.11: %s\n", get_r1r2s(r1, r2));
1.1       rees      750:        return -1;
                    751:     }
                    752:
                    753:     return 0;
                    754: }
                    755:
                    756: /* download RSA private key into 3f.00/00.12 */
                    757: int cyberflex_load_rsa(int fd, unsigned char *buf)
                    758: {
1.3     ! rees      759:     int rv, sw, i, j, tmp;
1.1       rees      760:     static unsigned char key_fid[] = {0x00, 0x12};
                    761:     static char *key_names[NUM_RSA_KEY_ELEMENTS]= {"p", "q", "1/p mod q",
                    762:                                                       "d mod (p-1)", "d mod (q-1)"};
                    763:     unsigned char *key_elements[NUM_RSA_KEY_ELEMENTS];
                    764:
                    765:     printf ("ca_load_rsa_priv buf=%s\n", buf);
                    766:
                    767:     printf ("input 1024 bit RSA CRT key\n");
                    768:     for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++) {
                    769:        printf ("%s (%d bit == %d byte) : ", key_names[i],
                    770:                RSA_BIT_LEN/2, RSA_BIT_LEN/2/8);
                    771:        key_elements[i] = (unsigned char *) malloc(RSA_BIT_LEN/8);
                    772:        for ( j = 0 ; j < RSA_BIT_LEN/8/2 ; j++ ) {
                    773:            fscanf (cmdf, "%02x", &tmp);
                    774:            key_elements[i][j] = (unsigned char)tmp;
                    775:        }
                    776:     }
                    777:
                    778: #ifdef DEBUG
                    779:     printf ("print RSA CRT key\n");
                    780:     for (i = 0 ; i < NUM_RSA_KEY_ELEMENTS ; i ++ ) {
                    781:        printf ("%s : ", key_names[i]);
                    782:        for ( j = 0 ; j < RSA_BIT_LEN/8/2 ; j++ ) {
                    783:            printf ("%02x ", key_elements[i][j]);
                    784:        }
                    785:     }
                    786: #endif
                    787:
1.2       rees      788:     rv = cyberflex_load_rsa_priv(fd, cla, key_fid, NUM_RSA_KEY_ELEMENTS, RSA_BIT_LEN,
1.3     ! rees      789:                                 key_elements, &sw);
1.2       rees      790:
                    791:     if (rv < 0)
1.3     ! rees      792:        printf("load_rsa_priv: %s\n", sectok_get_sw(sw));
1.1       rees      793:
                    794:     for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
                    795:        free(key_elements[i]);
                    796:     return rv;
                    797: }