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