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

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