Annotation of src/usr.bin/ssh/scard.c, Revision 1.24
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.24 ! markus 27: RCSID("$OpenBSD: scard.c,v 1.23 2002/03/24 18:05:29 markus Exp $");
1.1 markus 28:
1.19 markus 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.22 rees 35: #include "readpass.h"
1.1 markus 36: #include "scard.h"
37:
1.24 ! markus 38: #if OPENSSL_VERSION_NUMBER < 0x00907000L
! 39: #define USE_ENGINE
! 40: #define RSA_get_default_method RSA_get_default_openssl_method
! 41: #else
1.18 markus 42: #endif
1.24 ! markus 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
1.18 markus 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.22 rees 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.22 rees 63: static char *sc_pin = NULL;
1.1 markus 64: static int cla = 0x00; /* class */
65:
1.22 rees 66: static void sc_mk_digest(const char *pin, u_char *digest);
67: static int get_AUT0(u_char *aut0);
68:
1.1 markus 69: /* interface to libsectok */
70:
1.16 deraadt 71: static int
1.5 markus 72: sc_open(void)
1.1 markus 73: {
1.4 markus 74: int sw;
1.1 markus 75:
76: if (sc_fd >= 0)
77: return sc_fd;
78:
1.11 markus 79: sc_fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
1.1 markus 80: if (sc_fd < 0) {
1.5 markus 81: error("sectok_open failed: %s", sectok_get_sw(sw));
1.8 jakob 82: return SCARD_ERROR_FAIL;
83: }
84: if (! sectok_cardpresent(sc_fd)) {
1.11 markus 85: debug("smartcard in reader %s not present, skipping",
86: sc_reader_id);
1.10 jakob 87: sc_close();
1.8 jakob 88: return SCARD_ERROR_NOCARD;
1.1 markus 89: }
1.7 rees 90: if (sectok_reset(sc_fd, 0, NULL, &sw) <= 0) {
1.4 markus 91: error("sectok_reset failed: %s", sectok_get_sw(sw));
1.1 markus 92: sc_fd = -1;
1.8 jakob 93: return SCARD_ERROR_FAIL;
1.1 markus 94: }
1.7 rees 95: if ((cla = cyberflex_inq_class(sc_fd)) < 0)
96: cla = 0;
1.5 markus 97:
1.4 markus 98: debug("sc_open ok %d", sc_fd);
1.1 markus 99: return sc_fd;
100: }
101:
1.16 deraadt 102: static int
1.4 markus 103: sc_enable_applet(void)
1.1 markus 104: {
1.7 rees 105: static u_char aid[] = {0xfc, 0x53, 0x73, 0x68, 0x2e, 0x62, 0x69, 0x6e};
106: int sw = 0;
1.1 markus 107:
1.7 rees 108: /* select applet id */
109: sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, sizeof aid, aid, 0, NULL, &sw);
1.4 markus 110: if (!sectok_swOK(sw)) {
111: error("sectok_apdu failed: %s", sectok_get_sw(sw));
1.5 markus 112: sc_close();
113: return -1;
114: }
115: return 0;
116: }
117:
1.16 deraadt 118: static int
1.5 markus 119: sc_init(void)
120: {
1.8 jakob 121: int status;
122:
123: status = sc_open();
124: if (status == SCARD_ERROR_NOCARD) {
125: return SCARD_ERROR_NOCARD;
126: }
127: if (status < 0 ) {
1.5 markus 128: error("sc_open failed");
1.8 jakob 129: return status;
1.5 markus 130: }
131: if (sc_enable_applet() < 0) {
132: error("sc_enable_applet failed");
1.8 jakob 133: return SCARD_ERROR_APPLET;
1.1 markus 134: }
135: return 0;
136: }
137:
1.16 deraadt 138: static int
1.1 markus 139: sc_read_pubkey(Key * k)
140: {
1.4 markus 141: u_char buf[2], *n;
142: char *p;
1.14 markus 143: int len, sw, status = -1;
1.1 markus 144:
1.4 markus 145: len = sw = 0;
1.15 djm 146: n = NULL;
1.1 markus 147:
1.8 jakob 148: if (sc_fd < 0) {
1.24 ! markus 149: if (sc_init() < 0)
1.14 markus 150: goto err;
1.8 jakob 151: }
1.5 markus 152:
1.1 markus 153: /* get key size */
1.4 markus 154: sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL,
1.16 deraadt 155: sizeof(buf), buf, &sw);
1.4 markus 156: if (!sectok_swOK(sw)) {
157: error("could not obtain key length: %s", sectok_get_sw(sw));
1.14 markus 158: goto err;
1.1 markus 159: }
160: len = (buf[0] << 8) | buf[1];
161: len /= 8;
1.4 markus 162: debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw));
1.1 markus 163:
1.4 markus 164: n = xmalloc(len);
1.1 markus 165: /* get n */
1.4 markus 166: sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
167: if (!sectok_swOK(sw)) {
168: error("could not obtain public key: %s", sectok_get_sw(sw));
1.14 markus 169: goto err;
1.1 markus 170: }
1.14 markus 171:
1.4 markus 172: debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw));
173:
174: if (BN_bin2bn(n, len, k->rsa->n) == NULL) {
175: error("c_read_pubkey: BN_bin2bn failed");
1.14 markus 176: goto err;
1.4 markus 177: }
1.1 markus 178:
179: /* currently the java applet just stores 'n' */
1.4 markus 180: if (!BN_set_word(k->rsa->e, 35)) {
181: error("c_read_pubkey: BN_set_word(e, 35) failed");
1.14 markus 182: goto err;
1.4 markus 183: }
1.1 markus 184:
1.14 markus 185: status = 0;
1.1 markus 186: p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
187: debug("fingerprint %d %s", key_size(k), p);
188: xfree(p);
189:
1.14 markus 190: err:
191: if (n != NULL)
192: xfree(n);
193: sc_close();
194: return status;
1.1 markus 195: }
196:
1.23 markus 197: static int
198: try_AUT0(void)
199: {
200: u_char aut0[EVP_MAX_MD_SIZE];
201:
202: /* permission denied; try PIN if provided */
203: if (sc_pin && strlen(sc_pin) > 0) {
204: sc_mk_digest(sc_pin, aut0);
205: if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
206: error("smartcard passphrase incorrect");
207: return (-1);
208: }
209: } else {
210: /* try default AUT0 key */
211: if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) {
212: /* default AUT0 key failed; prompt for passphrase */
213: if (get_AUT0(aut0) < 0 ||
214: cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
215: error("smartcard passphrase incorrect");
216: return (-1);
217: }
218: }
219: }
220: return (0);
221: }
222:
1.1 markus 223: /* private key operations */
224:
225: static int
1.20 markus 226: sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
1.18 markus 227: int padding)
1.1 markus 228: {
1.4 markus 229: u_char *padded = NULL;
1.14 markus 230: int sw, len, olen, status = -1;
1.1 markus 231:
232: debug("sc_private_decrypt called");
233:
1.4 markus 234: olen = len = sw = 0;
1.8 jakob 235: if (sc_fd < 0) {
236: status = sc_init();
237: if (status < 0 )
1.5 markus 238: goto err;
1.8 jakob 239: }
1.4 markus 240: if (padding != RSA_PKCS1_PADDING)
1.1 markus 241: goto err;
242:
1.4 markus 243: len = BN_num_bytes(rsa->n);
244: padded = xmalloc(len);
1.1 markus 245:
1.22 rees 246: sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
247:
248: if (sw == 0x6982) {
1.23 markus 249: if (try_AUT0() < 0)
250: goto err;
1.22 rees 251: sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
252: }
1.4 markus 253: if (!sectok_swOK(sw)) {
254: error("sc_private_decrypt: INS_DECRYPT failed: %s",
255: sectok_get_sw(sw));
1.1 markus 256: goto err;
257: }
1.4 markus 258: olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
259: len);
1.1 markus 260: err:
261: if (padded)
262: xfree(padded);
1.14 markus 263: sc_close();
1.8 jakob 264: return (olen >= 0 ? olen : status);
1.1 markus 265: }
266:
267: static int
1.20 markus 268: sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
1.18 markus 269: int padding)
1.1 markus 270: {
1.4 markus 271: u_char *padded = NULL;
1.14 markus 272: int sw, len, status = -1;
1.1 markus 273:
1.4 markus 274: len = sw = 0;
1.8 jakob 275: if (sc_fd < 0) {
276: status = sc_init();
277: if (status < 0 )
1.5 markus 278: goto err;
1.8 jakob 279: }
1.4 markus 280: if (padding != RSA_PKCS1_PADDING)
1.1 markus 281: goto err;
282:
1.3 markus 283: debug("sc_private_encrypt called");
1.4 markus 284: len = BN_num_bytes(rsa->n);
285: padded = xmalloc(len);
286:
1.18 markus 287: if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)from, flen) <= 0) {
1.1 markus 288: error("RSA_padding_add_PKCS1_type_1 failed");
289: goto err;
290: }
1.22 rees 291: sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
1.23 markus 292: if (sw == 0x6982) {
293: if (try_AUT0() < 0)
294: goto err;
295: sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
296: }
1.4 markus 297: if (!sectok_swOK(sw)) {
1.23 markus 298: error("sc_private_encrypt: INS_DECRYPT failed: %s",
1.4 markus 299: sectok_get_sw(sw));
300: goto err;
301: }
1.1 markus 302: err:
303: if (padded)
304: xfree(padded);
1.14 markus 305: sc_close();
1.8 jakob 306: return (len >= 0 ? len : status);
1.1 markus 307: }
308:
1.12 markus 309: /* called on free */
310:
311: static int (*orig_finish)(RSA *rsa) = NULL;
312:
313: static int
314: sc_finish(RSA *rsa)
315: {
316: if (orig_finish)
317: orig_finish(rsa);
318: sc_close();
319: return 1;
320: }
321:
1.1 markus 322: /* engine for overloading private key operations */
323:
1.24 ! markus 324: static RSA_METHOD *
! 325: sc_get_rsa_method(void)
1.1 markus 326: {
1.24 ! markus 327: static RSA_METHOD smart_rsa;
! 328: const RSA_METHOD *def = RSA_get_default_method();
1.1 markus 329:
1.18 markus 330: /* use the OpenSSL version */
331: memcpy(&smart_rsa, def, sizeof(smart_rsa));
332:
333: smart_rsa.name = "sectok";
334:
1.1 markus 335: /* overload */
336: smart_rsa.rsa_priv_enc = sc_private_encrypt;
337: smart_rsa.rsa_priv_dec = sc_private_decrypt;
338:
1.12 markus 339: /* save original */
340: orig_finish = def->finish;
341: smart_rsa.finish = sc_finish;
342:
1.24 ! markus 343: return &smart_rsa;
! 344: }
! 345:
! 346: #ifdef USE_ENGINE
! 347: static ENGINE *
! 348: sc_get_engine(void)
! 349: {
! 350: static ENGINE *smart_engine = NULL;
! 351:
1.17 markus 352: if ((smart_engine = ENGINE_new()) == NULL)
353: fatal("ENGINE_new failed");
1.1 markus 354:
1.4 markus 355: ENGINE_set_id(smart_engine, "sectok");
356: ENGINE_set_name(smart_engine, "libsectok");
1.18 markus 357:
1.24 ! markus 358: ENGINE_set_RSA(smart_engine, sc_get_rsa_method());
1.1 markus 359: ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
360: ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
361: ENGINE_set_RAND(smart_engine, RAND_SSLeay());
362: ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
363:
364: return smart_engine;
365: }
1.24 ! markus 366: #endif
1.1 markus 367:
1.5 markus 368: void
369: sc_close(void)
370: {
371: if (sc_fd >= 0) {
372: sectok_close(sc_fd);
373: sc_fd = -1;
374: }
375: }
376:
1.24 ! markus 377: Key **
! 378: sc_get_keys(const char *id, const char *pin)
1.1 markus 379: {
1.24 ! markus 380: Key *k, *n, **keys;
! 381: int status, nkeys = 2;
1.1 markus 382:
1.11 markus 383: if (sc_reader_id != NULL)
384: xfree(sc_reader_id);
385: sc_reader_id = xstrdup(id);
386:
1.22 rees 387: if (sc_pin != NULL)
388: xfree(sc_pin);
389: sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
390:
1.1 markus 391: k = key_new(KEY_RSA);
392: if (k == NULL) {
393: return NULL;
394: }
1.9 jakob 395: status = sc_read_pubkey(k);
396: if (status == SCARD_ERROR_NOCARD) {
397: key_free(k);
398: return NULL;
399: }
400: if (status < 0 ) {
1.1 markus 401: error("sc_read_pubkey failed");
402: key_free(k);
403: return NULL;
404: }
1.24 ! markus 405: keys = xmalloc((nkeys+1) * sizeof(Key *));
! 406:
! 407: n = key_new(KEY_RSA1);
! 408: BN_copy(n->rsa->n, k->rsa->n);
! 409: BN_copy(n->rsa->e, k->rsa->e);
! 410: RSA_set_method(n->rsa, sc_get_rsa());
! 411: n->flags |= KEY_FLAG_EXT;
! 412: keys[0] = n;
! 413:
! 414: n = key_new(KEY_RSA);
! 415: BN_copy(n->rsa->n, k->rsa->n);
! 416: BN_copy(n->rsa->e, k->rsa->e);
! 417: RSA_set_method(n->rsa, sc_get_rsa());
! 418: n->flags |= KEY_FLAG_EXT;
! 419: keys[1] = n;
! 420:
! 421: keys[2] = NULL;
! 422:
! 423: key_free(k);
! 424: return keys;
1.19 markus 425: }
426:
427: #define NUM_RSA_KEY_ELEMENTS 5+1
428: #define COPY_RSA_KEY(x, i) \
429: do { \
430: len = BN_num_bytes(prv->rsa->x); \
431: elements[i] = xmalloc(len); \
432: debug("#bytes %d", len); \
433: if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
434: goto done; \
435: } while (0)
436:
1.22 rees 437: static void
438: sc_mk_digest(const char *pin, u_char *digest)
1.19 markus 439: {
440: const EVP_MD *evp_md = EVP_sha1();
441: EVP_MD_CTX md;
1.22 rees 442:
443: EVP_DigestInit(&md, evp_md);
444: EVP_DigestUpdate(&md, pin, strlen(pin));
445: EVP_DigestFinal(&md, digest, NULL);
446: }
447:
448: static int
449: get_AUT0(u_char *aut0)
450: {
1.19 markus 451: char *pass;
452:
453: pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
454: if (pass == NULL)
455: return -1;
1.22 rees 456: if (!strcmp(pass, "-")) {
457: memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
458: return 0;
459: }
460: sc_mk_digest(pass, aut0);
1.19 markus 461: memset(pass, 0, strlen(pass));
462: xfree(pass);
463: return 0;
464: }
465:
466: int
467: sc_put_key(Key *prv, const char *id)
468: {
469: u_char *elements[NUM_RSA_KEY_ELEMENTS];
470: u_char key_fid[2];
471: u_char AUT0[EVP_MAX_MD_SIZE];
472: int len, status = -1, i, fd = -1, ret;
473: int sw = 0, cla = 0x00;
474:
475: for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
476: elements[i] = NULL;
477:
478: COPY_RSA_KEY(q, 0);
479: COPY_RSA_KEY(p, 1);
480: COPY_RSA_KEY(iqmp, 2);
481: COPY_RSA_KEY(dmq1, 3);
482: COPY_RSA_KEY(dmp1, 4);
483: COPY_RSA_KEY(n, 5);
484: len = BN_num_bytes(prv->rsa->n);
1.21 rees 485: fd = sectok_friendly_open(id, STONOWAIT, &sw);
1.19 markus 486: if (fd < 0) {
487: error("sectok_open failed: %s", sectok_get_sw(sw));
488: goto done;
489: }
490: if (! sectok_cardpresent(fd)) {
1.21 rees 491: error("smartcard in reader %s not present", id);
1.19 markus 492: goto done;
493: }
494: ret = sectok_reset(fd, 0, NULL, &sw);
495: if (ret <= 0) {
496: error("sectok_reset failed: %s", sectok_get_sw(sw));
497: goto done;
498: }
499: if ((cla = cyberflex_inq_class(fd)) < 0) {
500: error("cyberflex_inq_class failed");
501: goto done;
502: }
503: memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));
504: if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
505: if (get_AUT0(AUT0) < 0 ||
506: cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
1.22 rees 507: memset(AUT0, 0, sizeof(DEFAUT0));
508: error("smartcard passphrase incorrect");
1.19 markus 509: goto done;
510: }
511: }
1.22 rees 512: memset(AUT0, 0, sizeof(DEFAUT0));
1.19 markus 513: key_fid[0] = 0x00;
514: key_fid[1] = 0x12;
515: if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
516: &sw) < 0) {
517: error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));
518: goto done;
519: }
520: if (!sectok_swOK(sw))
521: goto done;
522: log("cyberflex_load_rsa_priv done");
523: key_fid[0] = 0x73;
524: key_fid[1] = 0x68;
525: if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],
526: &sw) < 0) {
527: error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));
528: goto done;
529: }
530: if (!sectok_swOK(sw))
531: goto done;
532: log("cyberflex_load_rsa_pub done");
533: status = 0;
534:
535: done:
536: memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));
537: memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));
538: memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));
539: memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));
540: memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));
541: memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));
542:
543: for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
544: if (elements[i])
545: xfree(elements[i]);
546: if (fd != -1)
547: sectok_close(fd);
548: return (status);
1.1 markus 549: }
1.13 jakob 550: #endif /* SMARTCARD */