[BACK]Return to scard.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/scard.c, Revision 1.35

1.35    ! deraadt     1: /* $OpenBSD: scard.c,v 1.34 2006/08/01 23:36:12 stevesk Exp $ */
1.1       markus      2: /*
                      3:  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  *
                     14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     15:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     16:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     17:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     18:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     19:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     20:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     21:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     22:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     23:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     24:  */
                     25:
                     26: #ifdef SMARTCARD
1.35    ! deraadt    27:
        !            28: #include <sys/types.h>
1.1       markus     29:
1.19      markus     30: #include <openssl/evp.h>
1.33      stevesk    31:
1.1       markus     32: #include <sectok.h>
1.33      stevesk    33: #include <string.h>
1.1       markus     34:
1.35    ! deraadt    35: #include "xmalloc.h"
1.1       markus     36: #include "key.h"
                     37: #include "log.h"
1.29      djm        38: #include "misc.h"
1.1       markus     39: #include "scard.h"
                     40:
1.24      markus     41: #if OPENSSL_VERSION_NUMBER < 0x00907000L
                     42: #define USE_ENGINE
                     43: #define RSA_get_default_method RSA_get_default_openssl_method
                     44: #else
1.18      markus     45: #endif
1.24      markus     46:
                     47: #ifdef USE_ENGINE
                     48: #include <openssl/engine.h>
                     49: #define sc_get_rsa sc_get_engine
                     50: #else
                     51: #define sc_get_rsa sc_get_rsa_method
1.18      markus     52: #endif
                     53:
1.1       markus     54: #define CLA_SSH 0x05
                     55: #define INS_DECRYPT 0x10
                     56: #define INS_GET_KEYLENGTH 0x20
                     57: #define INS_GET_PUBKEY 0x30
                     58: #define INS_GET_RESPONSE 0xc0
                     59:
                     60: #define MAX_BUF_SIZE 256
                     61:
1.22      rees       62: u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
                     63:
1.1       markus     64: static int sc_fd = -1;
1.11      markus     65: static char *sc_reader_id = NULL;
1.22      rees       66: static char *sc_pin = NULL;
1.1       markus     67: static int cla = 0x00; /* class */
                     68:
1.22      rees       69: static void sc_mk_digest(const char *pin, u_char *digest);
                     70: static int get_AUT0(u_char *aut0);
1.25      rees       71: static int try_AUT0(void);
1.22      rees       72:
1.1       markus     73: /* interface to libsectok */
                     74:
1.16      deraadt    75: static int
1.5       markus     76: sc_open(void)
1.1       markus     77: {
1.4       markus     78:        int sw;
1.1       markus     79:
                     80:        if (sc_fd >= 0)
                     81:                return sc_fd;
                     82:
1.11      markus     83:        sc_fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
1.1       markus     84:        if (sc_fd < 0) {
1.5       markus     85:                error("sectok_open failed: %s", sectok_get_sw(sw));
1.8       jakob      86:                return SCARD_ERROR_FAIL;
                     87:        }
                     88:        if (! sectok_cardpresent(sc_fd)) {
1.11      markus     89:                debug("smartcard in reader %s not present, skipping",
                     90:                    sc_reader_id);
1.10      jakob      91:                sc_close();
1.8       jakob      92:                return SCARD_ERROR_NOCARD;
1.1       markus     93:        }
1.7       rees       94:        if (sectok_reset(sc_fd, 0, NULL, &sw) <= 0) {
1.4       markus     95:                error("sectok_reset failed: %s", sectok_get_sw(sw));
1.1       markus     96:                sc_fd = -1;
1.8       jakob      97:                return SCARD_ERROR_FAIL;
1.1       markus     98:        }
1.7       rees       99:        if ((cla = cyberflex_inq_class(sc_fd)) < 0)
                    100:                cla = 0;
1.5       markus    101:
1.4       markus    102:        debug("sc_open ok %d", sc_fd);
1.1       markus    103:        return sc_fd;
                    104: }
                    105:
1.16      deraadt   106: static int
1.4       markus    107: sc_enable_applet(void)
1.1       markus    108: {
1.7       rees      109:        static u_char aid[] = {0xfc, 0x53, 0x73, 0x68, 0x2e, 0x62, 0x69, 0x6e};
                    110:        int sw = 0;
1.1       markus    111:
1.7       rees      112:        /* select applet id */
                    113:        sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, sizeof aid, aid, 0, NULL, &sw);
1.4       markus    114:        if (!sectok_swOK(sw)) {
                    115:                error("sectok_apdu failed: %s", sectok_get_sw(sw));
1.5       markus    116:                sc_close();
                    117:                return -1;
                    118:        }
                    119:        return 0;
                    120: }
                    121:
1.16      deraadt   122: static int
1.5       markus    123: sc_init(void)
                    124: {
1.8       jakob     125:        int status;
                    126:
                    127:        status = sc_open();
                    128:        if (status == SCARD_ERROR_NOCARD) {
                    129:                return SCARD_ERROR_NOCARD;
                    130:        }
1.34      stevesk   131:        if (status < 0) {
1.5       markus    132:                error("sc_open failed");
1.8       jakob     133:                return status;
1.5       markus    134:        }
                    135:        if (sc_enable_applet() < 0) {
                    136:                error("sc_enable_applet failed");
1.8       jakob     137:                return SCARD_ERROR_APPLET;
1.1       markus    138:        }
                    139:        return 0;
                    140: }
                    141:
1.16      deraadt   142: static int
1.1       markus    143: sc_read_pubkey(Key * k)
                    144: {
1.4       markus    145:        u_char buf[2], *n;
                    146:        char *p;
1.14      markus    147:        int len, sw, status = -1;
1.1       markus    148:
1.4       markus    149:        len = sw = 0;
1.15      djm       150:        n = NULL;
1.1       markus    151:
1.8       jakob     152:        if (sc_fd < 0) {
1.24      markus    153:                if (sc_init() < 0)
1.14      markus    154:                        goto err;
1.8       jakob     155:        }
1.5       markus    156:
1.1       markus    157:        /* get key size */
1.4       markus    158:        sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL,
1.16      deraadt   159:            sizeof(buf), buf, &sw);
1.4       markus    160:        if (!sectok_swOK(sw)) {
                    161:                error("could not obtain key length: %s", sectok_get_sw(sw));
1.14      markus    162:                goto err;
1.1       markus    163:        }
                    164:        len = (buf[0] << 8) | buf[1];
                    165:        len /= 8;
1.4       markus    166:        debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw));
1.1       markus    167:
1.4       markus    168:        n = xmalloc(len);
1.1       markus    169:        /* get n */
1.4       markus    170:        sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
1.25      rees      171:
                    172:        if (sw == 0x6982) {
                    173:                if (try_AUT0() < 0)
                    174:                        goto err;
                    175:                sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
                    176:        }
1.4       markus    177:        if (!sectok_swOK(sw)) {
                    178:                error("could not obtain public key: %s", sectok_get_sw(sw));
1.14      markus    179:                goto err;
1.1       markus    180:        }
1.14      markus    181:
1.4       markus    182:        debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw));
                    183:
                    184:        if (BN_bin2bn(n, len, k->rsa->n) == NULL) {
                    185:                error("c_read_pubkey: BN_bin2bn failed");
1.14      markus    186:                goto err;
1.4       markus    187:        }
1.1       markus    188:
                    189:        /* currently the java applet just stores 'n' */
1.4       markus    190:        if (!BN_set_word(k->rsa->e, 35)) {
                    191:                error("c_read_pubkey: BN_set_word(e, 35) failed");
1.14      markus    192:                goto err;
1.4       markus    193:        }
1.1       markus    194:
1.14      markus    195:        status = 0;
1.1       markus    196:        p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
1.26      deraadt   197:        debug("fingerprint %u %s", key_size(k), p);
1.1       markus    198:        xfree(p);
                    199:
1.14      markus    200: err:
                    201:        if (n != NULL)
                    202:                xfree(n);
                    203:        sc_close();
                    204:        return status;
1.1       markus    205: }
                    206:
                    207: /* private key operations */
                    208:
                    209: static int
1.20      markus    210: sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
1.18      markus    211:     int padding)
1.1       markus    212: {
1.4       markus    213:        u_char *padded = NULL;
1.14      markus    214:        int sw, len, olen, status = -1;
1.1       markus    215:
                    216:        debug("sc_private_decrypt called");
                    217:
1.4       markus    218:        olen = len = sw = 0;
1.8       jakob     219:        if (sc_fd < 0) {
                    220:                status = sc_init();
1.34      stevesk   221:                if (status < 0)
1.5       markus    222:                        goto err;
1.8       jakob     223:        }
1.4       markus    224:        if (padding != RSA_PKCS1_PADDING)
1.1       markus    225:                goto err;
                    226:
1.4       markus    227:        len = BN_num_bytes(rsa->n);
                    228:        padded = xmalloc(len);
1.1       markus    229:
1.22      rees      230:        sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
                    231:
                    232:        if (sw == 0x6982) {
1.23      markus    233:                if (try_AUT0() < 0)
                    234:                        goto err;
1.22      rees      235:                sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
                    236:        }
1.4       markus    237:        if (!sectok_swOK(sw)) {
                    238:                error("sc_private_decrypt: INS_DECRYPT failed: %s",
                    239:                    sectok_get_sw(sw));
1.1       markus    240:                goto err;
                    241:        }
1.4       markus    242:        olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
                    243:            len);
1.1       markus    244: err:
                    245:        if (padded)
                    246:                xfree(padded);
1.14      markus    247:        sc_close();
1.8       jakob     248:        return (olen >= 0 ? olen : status);
1.1       markus    249: }
                    250:
                    251: static int
1.20      markus    252: sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
1.18      markus    253:     int padding)
1.1       markus    254: {
1.4       markus    255:        u_char *padded = NULL;
1.14      markus    256:        int sw, len, status = -1;
1.1       markus    257:
1.4       markus    258:        len = sw = 0;
1.8       jakob     259:        if (sc_fd < 0) {
                    260:                status = sc_init();
1.34      stevesk   261:                if (status < 0)
1.5       markus    262:                        goto err;
1.8       jakob     263:        }
1.4       markus    264:        if (padding != RSA_PKCS1_PADDING)
1.1       markus    265:                goto err;
                    266:
1.3       markus    267:        debug("sc_private_encrypt called");
1.4       markus    268:        len = BN_num_bytes(rsa->n);
                    269:        padded = xmalloc(len);
                    270:
1.18      markus    271:        if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)from, flen) <= 0) {
1.1       markus    272:                error("RSA_padding_add_PKCS1_type_1 failed");
                    273:                goto err;
                    274:        }
1.22      rees      275:        sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
1.23      markus    276:        if (sw == 0x6982) {
                    277:                if (try_AUT0() < 0)
                    278:                        goto err;
                    279:                sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
                    280:        }
1.4       markus    281:        if (!sectok_swOK(sw)) {
1.23      markus    282:                error("sc_private_encrypt: INS_DECRYPT failed: %s",
1.4       markus    283:                    sectok_get_sw(sw));
                    284:                goto err;
                    285:        }
1.1       markus    286: err:
                    287:        if (padded)
                    288:                xfree(padded);
1.14      markus    289:        sc_close();
1.8       jakob     290:        return (len >= 0 ? len : status);
1.1       markus    291: }
                    292:
1.12      markus    293: /* called on free */
                    294:
                    295: static int (*orig_finish)(RSA *rsa) = NULL;
                    296:
                    297: static int
                    298: sc_finish(RSA *rsa)
                    299: {
                    300:        if (orig_finish)
                    301:                orig_finish(rsa);
                    302:        sc_close();
                    303:        return 1;
                    304: }
                    305:
1.1       markus    306: /* engine for overloading private key operations */
                    307:
1.24      markus    308: static RSA_METHOD *
                    309: sc_get_rsa_method(void)
1.1       markus    310: {
1.24      markus    311:        static RSA_METHOD smart_rsa;
                    312:        const RSA_METHOD *def = RSA_get_default_method();
1.1       markus    313:
1.18      markus    314:        /* use the OpenSSL version */
                    315:        memcpy(&smart_rsa, def, sizeof(smart_rsa));
                    316:
                    317:        smart_rsa.name          = "sectok";
                    318:
1.1       markus    319:        /* overload */
                    320:        smart_rsa.rsa_priv_enc  = sc_private_encrypt;
                    321:        smart_rsa.rsa_priv_dec  = sc_private_decrypt;
                    322:
1.12      markus    323:        /* save original */
                    324:        orig_finish             = def->finish;
                    325:        smart_rsa.finish        = sc_finish;
                    326:
1.24      markus    327:        return &smart_rsa;
                    328: }
                    329:
                    330: #ifdef USE_ENGINE
                    331: static ENGINE *
                    332: sc_get_engine(void)
                    333: {
                    334:        static ENGINE *smart_engine = NULL;
                    335:
1.17      markus    336:        if ((smart_engine = ENGINE_new()) == NULL)
                    337:                fatal("ENGINE_new failed");
1.1       markus    338:
1.4       markus    339:        ENGINE_set_id(smart_engine, "sectok");
                    340:        ENGINE_set_name(smart_engine, "libsectok");
1.18      markus    341:
1.24      markus    342:        ENGINE_set_RSA(smart_engine, sc_get_rsa_method());
1.1       markus    343:        ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
                    344:        ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
                    345:        ENGINE_set_RAND(smart_engine, RAND_SSLeay());
                    346:        ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
                    347:
                    348:        return smart_engine;
                    349: }
1.24      markus    350: #endif
1.1       markus    351:
1.5       markus    352: void
                    353: sc_close(void)
                    354: {
                    355:        if (sc_fd >= 0) {
                    356:                sectok_close(sc_fd);
                    357:                sc_fd = -1;
                    358:        }
                    359: }
                    360:
1.24      markus    361: Key **
                    362: sc_get_keys(const char *id, const char *pin)
1.1       markus    363: {
1.24      markus    364:        Key *k, *n, **keys;
                    365:        int status, nkeys = 2;
1.1       markus    366:
1.11      markus    367:        if (sc_reader_id != NULL)
                    368:                xfree(sc_reader_id);
                    369:        sc_reader_id = xstrdup(id);
                    370:
1.22      rees      371:        if (sc_pin != NULL)
                    372:                xfree(sc_pin);
                    373:        sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
                    374:
1.1       markus    375:        k = key_new(KEY_RSA);
                    376:        if (k == NULL) {
                    377:                return NULL;
                    378:        }
1.9       jakob     379:        status = sc_read_pubkey(k);
                    380:        if (status == SCARD_ERROR_NOCARD) {
                    381:                key_free(k);
                    382:                return NULL;
                    383:        }
1.34      stevesk   384:        if (status < 0) {
1.1       markus    385:                error("sc_read_pubkey failed");
                    386:                key_free(k);
                    387:                return NULL;
                    388:        }
1.31      djm       389:        keys = xcalloc((nkeys+1), sizeof(Key *));
1.24      markus    390:
                    391:        n = key_new(KEY_RSA1);
                    392:        BN_copy(n->rsa->n, k->rsa->n);
                    393:        BN_copy(n->rsa->e, k->rsa->e);
                    394:        RSA_set_method(n->rsa, sc_get_rsa());
                    395:        n->flags |= KEY_FLAG_EXT;
                    396:        keys[0] = n;
                    397:
                    398:        n = key_new(KEY_RSA);
                    399:        BN_copy(n->rsa->n, k->rsa->n);
                    400:        BN_copy(n->rsa->e, k->rsa->e);
                    401:        RSA_set_method(n->rsa, sc_get_rsa());
                    402:        n->flags |= KEY_FLAG_EXT;
                    403:        keys[1] = n;
                    404:
                    405:        keys[2] = NULL;
                    406:
                    407:        key_free(k);
                    408:        return keys;
1.19      markus    409: }
                    410:
                    411: #define NUM_RSA_KEY_ELEMENTS 5+1
                    412: #define COPY_RSA_KEY(x, i) \
                    413:        do { \
                    414:                len = BN_num_bytes(prv->rsa->x); \
                    415:                elements[i] = xmalloc(len); \
                    416:                debug("#bytes %d", len); \
                    417:                if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
                    418:                        goto done; \
                    419:        } while (0)
                    420:
1.22      rees      421: static void
                    422: sc_mk_digest(const char *pin, u_char *digest)
1.19      markus    423: {
                    424:        const EVP_MD *evp_md = EVP_sha1();
                    425:        EVP_MD_CTX md;
1.22      rees      426:
                    427:        EVP_DigestInit(&md, evp_md);
                    428:        EVP_DigestUpdate(&md, pin, strlen(pin));
                    429:        EVP_DigestFinal(&md, digest, NULL);
                    430: }
                    431:
                    432: static int
                    433: get_AUT0(u_char *aut0)
                    434: {
1.19      markus    435:        char *pass;
                    436:
                    437:        pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
                    438:        if (pass == NULL)
                    439:                return -1;
1.22      rees      440:        if (!strcmp(pass, "-")) {
                    441:                memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
                    442:                return 0;
                    443:        }
                    444:        sc_mk_digest(pass, aut0);
1.19      markus    445:        memset(pass, 0, strlen(pass));
                    446:        xfree(pass);
                    447:        return 0;
1.25      rees      448: }
                    449:
                    450: static int
                    451: try_AUT0(void)
                    452: {
                    453:        u_char aut0[EVP_MAX_MD_SIZE];
                    454:
                    455:        /* permission denied; try PIN if provided */
                    456:        if (sc_pin && strlen(sc_pin) > 0) {
                    457:                sc_mk_digest(sc_pin, aut0);
                    458:                if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
                    459:                        error("smartcard passphrase incorrect");
                    460:                        return (-1);
                    461:                }
                    462:        } else {
                    463:                /* try default AUT0 key */
                    464:                if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) {
                    465:                        /* default AUT0 key failed; prompt for passphrase */
                    466:                        if (get_AUT0(aut0) < 0 ||
                    467:                            cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
                    468:                                error("smartcard passphrase incorrect");
                    469:                                return (-1);
                    470:                        }
                    471:                }
                    472:        }
                    473:        return (0);
1.19      markus    474: }
                    475:
                    476: int
                    477: sc_put_key(Key *prv, const char *id)
                    478: {
                    479:        u_char *elements[NUM_RSA_KEY_ELEMENTS];
                    480:        u_char key_fid[2];
                    481:        u_char AUT0[EVP_MAX_MD_SIZE];
                    482:        int len, status = -1, i, fd = -1, ret;
                    483:        int sw = 0, cla = 0x00;
                    484:
                    485:        for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
                    486:                elements[i] = NULL;
                    487:
                    488:        COPY_RSA_KEY(q, 0);
                    489:        COPY_RSA_KEY(p, 1);
                    490:        COPY_RSA_KEY(iqmp, 2);
                    491:        COPY_RSA_KEY(dmq1, 3);
                    492:        COPY_RSA_KEY(dmp1, 4);
                    493:        COPY_RSA_KEY(n, 5);
                    494:        len = BN_num_bytes(prv->rsa->n);
1.21      rees      495:        fd = sectok_friendly_open(id, STONOWAIT, &sw);
1.19      markus    496:        if (fd < 0) {
                    497:                error("sectok_open failed: %s", sectok_get_sw(sw));
                    498:                goto done;
                    499:        }
                    500:        if (! sectok_cardpresent(fd)) {
1.21      rees      501:                error("smartcard in reader %s not present", id);
1.19      markus    502:                goto done;
                    503:        }
                    504:        ret = sectok_reset(fd, 0, NULL, &sw);
                    505:        if (ret <= 0) {
                    506:                error("sectok_reset failed: %s", sectok_get_sw(sw));
                    507:                goto done;
                    508:        }
                    509:        if ((cla = cyberflex_inq_class(fd)) < 0) {
                    510:                error("cyberflex_inq_class failed");
                    511:                goto done;
                    512:        }
                    513:        memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));
                    514:        if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
                    515:                if (get_AUT0(AUT0) < 0 ||
                    516:                    cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
1.22      rees      517:                        memset(AUT0, 0, sizeof(DEFAUT0));
                    518:                        error("smartcard passphrase incorrect");
1.19      markus    519:                        goto done;
                    520:                }
                    521:        }
1.22      rees      522:        memset(AUT0, 0, sizeof(DEFAUT0));
1.19      markus    523:        key_fid[0] = 0x00;
                    524:        key_fid[1] = 0x12;
                    525:        if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
                    526:            &sw) < 0) {
                    527:                error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));
                    528:                goto done;
                    529:        }
                    530:        if (!sectok_swOK(sw))
                    531:                goto done;
1.27      itojun    532:        logit("cyberflex_load_rsa_priv done");
1.19      markus    533:        key_fid[0] = 0x73;
                    534:        key_fid[1] = 0x68;
                    535:        if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],
                    536:            &sw) < 0) {
                    537:                error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));
                    538:                goto done;
                    539:        }
                    540:        if (!sectok_swOK(sw))
                    541:                goto done;
1.27      itojun    542:        logit("cyberflex_load_rsa_pub done");
1.19      markus    543:        status = 0;
                    544:
                    545: done:
                    546:        memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));
                    547:        memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));
                    548:        memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));
                    549:        memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));
                    550:        memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));
                    551:        memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));
                    552:
                    553:        for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
                    554:                if (elements[i])
                    555:                        xfree(elements[i]);
                    556:        if (fd != -1)
                    557:                sectok_close(fd);
                    558:        return (status);
1.1       markus    559: }
1.28      markus    560:
                    561: char *
                    562: sc_get_key_label(Key *key)
                    563: {
                    564:        return xstrdup("smartcard key");
                    565: }
                    566:
1.13      jakob     567: #endif /* SMARTCARD */