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

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