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: }