Annotation of src/usr.bin/ssh/scard.c, Revision 1.28
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.28 ! markus 27: RCSID("$OpenBSD: scard.c,v 1.27 2003/04/08 20:21:29 itojun 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);
1.25 rees 68: static int try_AUT0(void);
1.22 rees 69:
1.1 markus 70: /* interface to libsectok */
71:
1.16 deraadt 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.16 deraadt 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.16 deraadt 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.16 deraadt 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.15 djm 147: n = NULL;
1.1 markus 148:
1.8 jakob 149: if (sc_fd < 0) {
1.24 markus 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.16 deraadt 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.25 rees 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);
1.26 deraadt 194: debug("fingerprint %u %s", key_size(k), p);
1.1 markus 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.20 markus 207: sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
1.18 markus 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.22 rees 227: sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
228:
229: if (sw == 0x6982) {
1.23 markus 230: if (try_AUT0() < 0)
231: goto err;
1.22 rees 232: sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
233: }
1.4 markus 234: if (!sectok_swOK(sw)) {
235: error("sc_private_decrypt: INS_DECRYPT failed: %s",
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.20 markus 249: sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
1.18 markus 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.18 markus 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.22 rees 272: sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
1.23 markus 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);
277: }
1.4 markus 278: if (!sectok_swOK(sw)) {
1.23 markus 279: error("sc_private_encrypt: INS_DECRYPT failed: %s",
1.4 markus 280: sectok_get_sw(sw));
281: goto err;
282: }
1.1 markus 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.24 markus 305: static RSA_METHOD *
306: sc_get_rsa_method(void)
1.1 markus 307: {
1.24 markus 308: static RSA_METHOD smart_rsa;
309: const RSA_METHOD *def = RSA_get_default_method();
1.1 markus 310:
1.18 markus 311: /* use the OpenSSL version */
312: memcpy(&smart_rsa, def, sizeof(smart_rsa));
313:
314: smart_rsa.name = "sectok";
315:
1.1 markus 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.24 markus 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;
332:
1.17 markus 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.18 markus 338:
1.24 markus 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.24 markus 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.24 markus 358: Key **
359: sc_get_keys(const char *id, const char *pin)
1.1 markus 360: {
1.24 markus 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.22 rees 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.24 markus 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;
1.19 markus 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:
1.22 rees 418: static void
419: sc_mk_digest(const char *pin, u_char *digest)
1.19 markus 420: {
421: const EVP_MD *evp_md = EVP_sha1();
422: EVP_MD_CTX md;
1.22 rees 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: {
1.19 markus 432: char *pass;
433:
434: pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
435: if (pass == NULL)
436: return -1;
1.22 rees 437: if (!strcmp(pass, "-")) {
438: memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
439: return 0;
440: }
441: sc_mk_digest(pass, aut0);
1.19 markus 442: memset(pass, 0, strlen(pass));
443: xfree(pass);
444: return 0;
1.25 rees 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);
1.19 markus 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);
1.21 rees 492: fd = sectok_friendly_open(id, STONOWAIT, &sw);
1.19 markus 493: if (fd < 0) {
494: error("sectok_open failed: %s", sectok_get_sw(sw));
495: goto done;
496: }
497: if (! sectok_cardpresent(fd)) {
1.21 rees 498: error("smartcard in reader %s not present", id);
1.19 markus 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) {
1.22 rees 514: memset(AUT0, 0, sizeof(DEFAUT0));
515: error("smartcard passphrase incorrect");
1.19 markus 516: goto done;
517: }
518: }
1.22 rees 519: memset(AUT0, 0, sizeof(DEFAUT0));
1.19 markus 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;
1.27 itojun 529: logit("cyberflex_load_rsa_priv done");
1.19 markus 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;
1.27 itojun 539: logit("cyberflex_load_rsa_pub done");
1.19 markus 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.28 ! markus 557:
! 558: char *
! 559: sc_get_key_label(Key *key)
! 560: {
! 561: return xstrdup("smartcard key");
! 562: }
! 563:
1.13 jakob 564: #endif /* SMARTCARD */