X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/0659cace63872d60958464ea8f037fc0da9a38d5..6d6695ca36935a779e72674c24c7d2c6b01d90ab:/scard.c diff --git a/scard.c b/scard.c index 779106f8..9fd3ca1b 100644 --- a/scard.c +++ b/scard.c @@ -1,3 +1,4 @@ +/* $OpenBSD: scard.c,v 1.36 2006/11/06 21:25:28 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -23,16 +24,20 @@ */ #include "includes.h" -#ifdef SMARTCARD -RCSID("$OpenBSD: scard.c,v 1.24 2002/03/25 17:34:27 markus Exp $"); +#if defined(SMARTCARD) && defined(USE_SECTOK) + +#include -#include #include +#include +#include +#include + +#include "xmalloc.h" #include "key.h" #include "log.h" -#include "xmalloc.h" -#include "readpass.h" +#include "misc.h" #include "scard.h" #if OPENSSL_VERSION_NUMBER < 0x00907000L @@ -65,6 +70,7 @@ static int cla = 0x00; /* class */ static void sc_mk_digest(const char *pin, u_char *digest); static int get_AUT0(u_char *aut0); +static int try_AUT0(void); /* interface to libsectok */ @@ -124,7 +130,7 @@ sc_init(void) if (status == SCARD_ERROR_NOCARD) { return SCARD_ERROR_NOCARD; } - if (status < 0 ) { + if (status < 0) { error("sc_open failed"); return status; } @@ -164,6 +170,12 @@ sc_read_pubkey(Key * k) n = xmalloc(len); /* get n */ sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw); + + if (sw == 0x6982) { + if (try_AUT0() < 0) + goto err; + sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw); + } if (!sectok_swOK(sw)) { error("could not obtain public key: %s", sectok_get_sw(sw)); goto err; @@ -184,7 +196,7 @@ sc_read_pubkey(Key * k) status = 0; p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX); - debug("fingerprint %d %s", key_size(k), p); + debug("fingerprint %u %s", key_size(k), p); xfree(p); err: @@ -194,32 +206,6 @@ err: return status; } -static int -try_AUT0(void) -{ - u_char aut0[EVP_MAX_MD_SIZE]; - - /* permission denied; try PIN if provided */ - if (sc_pin && strlen(sc_pin) > 0) { - sc_mk_digest(sc_pin, aut0); - if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) { - error("smartcard passphrase incorrect"); - return (-1); - } - } else { - /* try default AUT0 key */ - if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) { - /* default AUT0 key failed; prompt for passphrase */ - if (get_AUT0(aut0) < 0 || - cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) { - error("smartcard passphrase incorrect"); - return (-1); - } - } - } - return (0); -} - /* private key operations */ static int @@ -234,7 +220,7 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, olen = len = sw = 0; if (sc_fd < 0) { status = sc_init(); - if (status < 0 ) + if (status < 0) goto err; } if (padding != RSA_PKCS1_PADDING) @@ -274,7 +260,7 @@ sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, len = sw = 0; if (sc_fd < 0) { status = sc_init(); - if (status < 0 ) + if (status < 0) goto err; } if (padding != RSA_PKCS1_PADDING) @@ -397,23 +383,25 @@ sc_get_keys(const char *id, const char *pin) key_free(k); return NULL; } - if (status < 0 ) { + if (status < 0) { error("sc_read_pubkey failed"); key_free(k); return NULL; } - keys = xmalloc((nkeys+1) * sizeof(Key *)); + keys = xcalloc((nkeys+1), sizeof(Key *)); n = key_new(KEY_RSA1); - BN_copy(n->rsa->n, k->rsa->n); - BN_copy(n->rsa->e, k->rsa->e); + if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || + (BN_copy(n->rsa->e, k->rsa->e) == NULL)) + fatal("sc_get_keys: BN_copy failed"); RSA_set_method(n->rsa, sc_get_rsa()); n->flags |= KEY_FLAG_EXT; keys[0] = n; n = key_new(KEY_RSA); - BN_copy(n->rsa->n, k->rsa->n); - BN_copy(n->rsa->e, k->rsa->e); + if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || + (BN_copy(n->rsa->e, k->rsa->e) == NULL)) + fatal("sc_get_keys: BN_copy failed"); RSA_set_method(n->rsa, sc_get_rsa()); n->flags |= KEY_FLAG_EXT; keys[1] = n; @@ -463,6 +451,32 @@ get_AUT0(u_char *aut0) return 0; } +static int +try_AUT0(void) +{ + u_char aut0[EVP_MAX_MD_SIZE]; + + /* permission denied; try PIN if provided */ + if (sc_pin && strlen(sc_pin) > 0) { + sc_mk_digest(sc_pin, aut0); + if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) { + error("smartcard passphrase incorrect"); + return (-1); + } + } else { + /* try default AUT0 key */ + if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) { + /* default AUT0 key failed; prompt for passphrase */ + if (get_AUT0(aut0) < 0 || + cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) { + error("smartcard passphrase incorrect"); + return (-1); + } + } + } + return (0); +} + int sc_put_key(Key *prv, const char *id) { @@ -519,7 +533,7 @@ sc_put_key(Key *prv, const char *id) } if (!sectok_swOK(sw)) goto done; - log("cyberflex_load_rsa_priv done"); + logit("cyberflex_load_rsa_priv done"); key_fid[0] = 0x73; key_fid[1] = 0x68; if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5], @@ -529,7 +543,7 @@ sc_put_key(Key *prv, const char *id) } if (!sectok_swOK(sw)) goto done; - log("cyberflex_load_rsa_pub done"); + logit("cyberflex_load_rsa_pub done"); status = 0; done: @@ -547,4 +561,11 @@ done: sectok_close(fd); return (status); } -#endif /* SMARTCARD */ + +char * +sc_get_key_label(Key *key) +{ + return xstrdup("smartcard key"); +} + +#endif /* SMARTCARD && USE_SECTOK */