diff options
-rw-r--r-- | README.smartcard | 93 | ||||
-rw-r--r-- | scard-opensc.c | 532 | ||||
-rw-r--r-- | scard.c | 571 | ||||
-rw-r--r-- | scard.h | 39 | ||||
-rw-r--r-- | scard/Makefile.in | 29 | ||||
-rw-r--r-- | scard/Ssh.bin | bin | 600 -> 0 bytes | |||
-rw-r--r-- | scard/Ssh.bin.uu | 17 | ||||
-rw-r--r-- | scard/Ssh.java | 164 |
8 files changed, 0 insertions, 1445 deletions
diff --git a/README.smartcard b/README.smartcard deleted file mode 100644 index fdf83ec..0000000 --- a/README.smartcard +++ /dev/null @@ -1,93 +0,0 @@ -How to use smartcards with OpenSSH? - -OpenSSH contains experimental support for authentication using -Cyberflex smartcards and TODOS card readers, in addition to the cards -with PKCS#15 structure supported by OpenSC. To enable this you -need to: - -Using libsectok: - -(1) enable sectok support in OpenSSH: - - $ ./configure --with-sectok - -(2) If you have used a previous version of ssh with your card, you - must remove the old applet and keys. - - $ sectok - sectok> login -d - sectok> junload Ssh.bin - sectok> delete 0012 - sectok> delete sh - sectok> quit - -(3) load the Java Cardlet to the Cyberflex card and set card passphrase: - - $ sectok - sectok> login -d - sectok> jload /usr/libdata/ssh/Ssh.bin - sectok> setpass - Enter new AUT0 passphrase: - Re-enter passphrase: - sectok> quit - - Do not forget the passphrase. There is no way to - recover if you do. - - IMPORTANT WARNING: If you attempt to login with the - wrong passphrase three times in a row, you will - destroy your card. - -(4) load a RSA key to the card: - - $ ssh-keygen -f /path/to/rsakey -U 1 - (where 1 is the reader number, you can also try 0) - - In spite of the name, this does not generate a key. - It just loads an already existing key on to the card. - -(5) Optional: If you don't want to use a card passphrase, change the - acl on the private key file: - - $ sectok - sectok> login -d - sectok> acl 0012 world: w - world: w - AUT0: w inval - sectok> quit - - If you do this, anyone who has access to your card - can assume your identity. This is not recommended. - - -Using OpenSC: - -(1) install OpenSC: - - Sources and instructions are available from - http://www.opensc.org/ - -(2) enable OpenSC support in OpenSSH: - - $ ./configure --with-opensc[=/path/to/opensc] [options] - -(3) load a RSA key to the card: - - Not supported yet. - - -Common operations: - -(1) tell the ssh client to use the card reader: - - $ ssh -I 1 otherhost - -(2) or tell the agent (don't forget to restart) to use the smartcard: - - $ ssh-add -s 1 - - --markus, -Tue Jul 17 23:54:51 CEST 2001 - -$OpenBSD: README.smartcard,v 1.9 2003/11/21 11:57:02 djm Exp $ diff --git a/scard-opensc.c b/scard-opensc.c deleted file mode 100644 index 36dae05..0000000 --- a/scard-opensc.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (c) 2002 Juha Yrjölä. All rights reserved. - * Copyright (c) 2001 Markus Friedl. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -#if defined(SMARTCARD) && defined(USE_OPENSC) - -#include <sys/types.h> - -#include <openssl/evp.h> -#include <openssl/x509.h> - -#include <stdarg.h> -#include <string.h> - -#include <opensc/opensc.h> -#include <opensc/pkcs15.h> - -#include "key.h" -#include "log.h" -#include "xmalloc.h" -#include "misc.h" -#include "scard.h" - -#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE) -#define USE_ENGINE -#define RSA_get_default_method RSA_get_default_openssl_method -#else -#endif - -#ifdef USE_ENGINE -#include <openssl/engine.h> -#define sc_get_rsa sc_get_engine -#else -#define sc_get_rsa sc_get_rsa_method -#endif - -static int sc_reader_id; -static sc_context_t *ctx = NULL; -static sc_card_t *card = NULL; -static sc_pkcs15_card_t *p15card = NULL; - -static char *sc_pin = NULL; - -struct sc_priv_data -{ - struct sc_pkcs15_id cert_id; - int ref_count; -}; - -void -sc_close(void) -{ - if (p15card) { - sc_pkcs15_unbind(p15card); - p15card = NULL; - } - if (card) { - sc_disconnect_card(card, 0); - card = NULL; - } - if (ctx) { - sc_release_context(ctx); - ctx = NULL; - } -} - -static int -sc_init(void) -{ - int r; - - r = sc_establish_context(&ctx, "openssh"); - if (r) - goto err; - if (sc_reader_id >= ctx->reader_count) { - r = SC_ERROR_NO_READERS_FOUND; - error("Illegal reader number %d (max %d)", sc_reader_id, - ctx->reader_count -1); - goto err; - } - r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card); - if (r) - goto err; - r = sc_pkcs15_bind(card, &p15card); - if (r) - goto err; - return 0; -err: - sc_close(); - return r; -} - -/* private key operations */ - -static int -sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out, - unsigned int usage) -{ - int r; - struct sc_priv_data *priv; - struct sc_pkcs15_object *key_obj; - struct sc_pkcs15_prkey_info *key; - struct sc_pkcs15_object *pin_obj; - struct sc_pkcs15_pin_info *pin; - - priv = (struct sc_priv_data *) RSA_get_app_data(rsa); - if (priv == NULL) - return -1; - if (p15card == NULL) { - sc_close(); - r = sc_init(); - if (r) { - error("SmartCard init failed: %s", sc_strerror(r)); - goto err; - } - } - r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id, - usage, &key_obj); - if (r) { - error("Unable to find private key from SmartCard: %s", - sc_strerror(r)); - goto err; - } - key = key_obj->data; - r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id, - &pin_obj); - if (r == SC_ERROR_OBJECT_NOT_FOUND) { - /* no pin required */ - r = sc_lock(card); - if (r) { - error("Unable to lock smartcard: %s", sc_strerror(r)); - goto err; - } - *key_obj_out = key_obj; - return 0; - } else if (r) { - error("Unable to find PIN object from SmartCard: %s", - sc_strerror(r)); - goto err; - } - pin = pin_obj->data; - r = sc_lock(card); - if (r) { - error("Unable to lock smartcard: %s", sc_strerror(r)); - goto err; - } - if (sc_pin != NULL) { - r = sc_pkcs15_verify_pin(p15card, pin, sc_pin, - strlen(sc_pin)); - if (r) { - sc_unlock(card); - error("PIN code verification failed: %s", - sc_strerror(r)); - goto err; - } - } - *key_obj_out = key_obj; - return 0; -err: - sc_close(); - return -1; -} - -#define SC_USAGE_DECRYPT SC_PKCS15_PRKEY_USAGE_DECRYPT | \ - SC_PKCS15_PRKEY_USAGE_UNWRAP - -static int -sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, - int padding) -{ - struct sc_pkcs15_object *key_obj; - int r; - - if (padding != RSA_PKCS1_PADDING) - return -1; - r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_DECRYPT); - if (r) - return -1; - r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1, - from, flen, to, flen); - sc_unlock(card); - if (r < 0) { - error("sc_pkcs15_decipher() failed: %s", sc_strerror(r)); - goto err; - } - return r; -err: - sc_close(); - return -1; -} - -#define SC_USAGE_SIGN SC_PKCS15_PRKEY_USAGE_SIGN | \ - SC_PKCS15_PRKEY_USAGE_SIGNRECOVER - -static int -sc_sign(int type, u_char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, RSA *rsa) -{ - struct sc_pkcs15_object *key_obj; - int r; - unsigned long flags = 0; - - /* XXX: sc_prkey_op_init will search for a pkcs15 private - * key object with the sign or signrecover usage flag set. - * If the signing key has only the non-repudiation flag set - * the key will be rejected as using a non-repudiation key - * for authentication is not recommended. Note: This does not - * prevent the use of a non-repudiation key for authentication - * if the sign or signrecover flag is set as well. - */ - r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN); - if (r) - return -1; - /* FIXME: length of sigret correct? */ - /* FIXME: check 'type' and modify flags accordingly */ - flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1; - r = sc_pkcs15_compute_signature(p15card, key_obj, flags, - m, m_len, sigret, RSA_size(rsa)); - sc_unlock(card); - if (r < 0) { - error("sc_pkcs15_compute_signature() failed: %s", - sc_strerror(r)); - goto err; - } - *siglen = r; - return 1; -err: - sc_close(); - return 0; -} - -static int -sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, - int padding) -{ - error("Private key encryption not supported"); - return -1; -} - -/* called on free */ - -static int (*orig_finish)(RSA *rsa) = NULL; - -static int -sc_finish(RSA *rsa) -{ - struct sc_priv_data *priv; - - priv = RSA_get_app_data(rsa); - priv->ref_count--; - if (priv->ref_count == 0) { - free(priv); - sc_close(); - } - if (orig_finish) - orig_finish(rsa); - return 1; -} - -/* engine for overloading private key operations */ - -static RSA_METHOD * -sc_get_rsa_method(void) -{ - static RSA_METHOD smart_rsa; - const RSA_METHOD *def = RSA_get_default_method(); - - /* use the OpenSSL version */ - memcpy(&smart_rsa, def, sizeof(smart_rsa)); - - smart_rsa.name = "opensc"; - - /* overload */ - smart_rsa.rsa_priv_enc = sc_private_encrypt; - smart_rsa.rsa_priv_dec = sc_private_decrypt; - smart_rsa.rsa_sign = sc_sign; - - /* save original */ - orig_finish = def->finish; - smart_rsa.finish = sc_finish; - - return &smart_rsa; -} - -#ifdef USE_ENGINE -static ENGINE * -sc_get_engine(void) -{ - static ENGINE *smart_engine = NULL; - - if ((smart_engine = ENGINE_new()) == NULL) - fatal("ENGINE_new failed"); - - ENGINE_set_id(smart_engine, "opensc"); - ENGINE_set_name(smart_engine, "OpenSC"); - - ENGINE_set_RSA(smart_engine, sc_get_rsa_method()); - ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method()); - ENGINE_set_DH(smart_engine, DH_get_default_openssl_method()); - ENGINE_set_RAND(smart_engine, RAND_SSLeay()); - ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp); - - return smart_engine; -} -#endif - -static void -convert_rsa_to_rsa1(Key * in, Key * out) -{ - struct sc_priv_data *priv; - - out->rsa->flags = in->rsa->flags; - out->flags = in->flags; - RSA_set_method(out->rsa, RSA_get_method(in->rsa)); - BN_copy(out->rsa->n, in->rsa->n); - BN_copy(out->rsa->e, in->rsa->e); - priv = RSA_get_app_data(in->rsa); - priv->ref_count++; - RSA_set_app_data(out->rsa, priv); - return; -} - -static int -sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj) -{ - int r; - sc_pkcs15_cert_t *cert = NULL; - struct sc_priv_data *priv = NULL; - sc_pkcs15_cert_info_t *cinfo = cert_obj->data; - - X509 *x509 = NULL; - EVP_PKEY *pubkey = NULL; - u8 *p; - char *tmp; - - debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]); - r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); - if (r) { - logit("Certificate read failed: %s", sc_strerror(r)); - goto err; - } - x509 = X509_new(); - if (x509 == NULL) { - r = -1; - goto err; - } - p = cert->data; - if (!d2i_X509(&x509, &p, cert->data_len)) { - logit("Unable to parse X.509 certificate"); - r = -1; - goto err; - } - sc_pkcs15_free_certificate(cert); - cert = NULL; - pubkey = X509_get_pubkey(x509); - X509_free(x509); - x509 = NULL; - if (pubkey->type != EVP_PKEY_RSA) { - logit("Public key is of unknown type"); - r = -1; - goto err; - } - k->rsa = EVP_PKEY_get1_RSA(pubkey); - EVP_PKEY_free(pubkey); - - k->rsa->flags |= RSA_FLAG_SIGN_VER; - RSA_set_method(k->rsa, sc_get_rsa_method()); - priv = xmalloc(sizeof(struct sc_priv_data)); - priv->cert_id = cinfo->id; - priv->ref_count = 1; - RSA_set_app_data(k->rsa, priv); - - k->flags = KEY_FLAG_EXT; - tmp = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX); - debug("fingerprint %d %s", key_size(k), tmp); - xfree(tmp); - - return 0; -err: - if (cert) - sc_pkcs15_free_certificate(cert); - if (pubkey) - EVP_PKEY_free(pubkey); - if (x509) - X509_free(x509); - return r; -} - -Key ** -sc_get_keys(const char *id, const char *pin) -{ - Key *k, **keys; - int i, r, real_count = 0, key_count; - sc_pkcs15_id_t cert_id; - sc_pkcs15_object_t *certs[32]; - char *buf = xstrdup(id), *p; - - debug("sc_get_keys called: id = %s", id); - - if (sc_pin != NULL) - xfree(sc_pin); - sc_pin = (pin == NULL) ? NULL : xstrdup(pin); - - cert_id.len = 0; - if ((p = strchr(buf, ':')) != NULL) { - *p = 0; - p++; - sc_pkcs15_hex_string_to_id(p, &cert_id); - } - r = sscanf(buf, "%d", &sc_reader_id); - xfree(buf); - if (r != 1) - goto err; - if (p15card == NULL) { - sc_close(); - r = sc_init(); - if (r) { - error("Smartcard init failed: %s", sc_strerror(r)); - goto err; - } - } - if (cert_id.len) { - r = sc_pkcs15_find_cert_by_id(p15card, &cert_id, &certs[0]); - if (r < 0) - goto err; - key_count = 1; - } else { - r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, - certs, 32); - if (r == 0) { - logit("No certificates found on smartcard"); - r = -1; - goto err; - } else if (r < 0) { - error("Certificate enumeration failed: %s", - sc_strerror(r)); - goto err; - } - key_count = r; - } - if (key_count > 1024) - fatal("Too many keys (%u), expected <= 1024", key_count); - keys = xcalloc(key_count * 2 + 1, sizeof(Key *)); - for (i = 0; i < key_count; i++) { - sc_pkcs15_object_t *tmp_obj = NULL; - cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id; - if (sc_pkcs15_find_prkey_by_id(p15card, &cert_id, &tmp_obj)) - /* skip the public key (certificate) if no - * corresponding private key is present */ - continue; - k = key_new(KEY_RSA); - if (k == NULL) - break; - r = sc_read_pubkey(k, certs[i]); - if (r) { - error("sc_read_pubkey failed: %s", sc_strerror(r)); - key_free(k); - continue; - } - keys[real_count] = k; - real_count++; - k = key_new(KEY_RSA1); - if (k == NULL) - break; - convert_rsa_to_rsa1(keys[real_count-1], k); - keys[real_count] = k; - real_count++; - } - keys[real_count] = NULL; - - return keys; -err: - sc_close(); - return NULL; -} - -int -sc_put_key(Key *prv, const char *id) -{ - error("key uploading not yet supported"); - return -1; -} - -char * -sc_get_key_label(Key *key) -{ - int r; - const struct sc_priv_data *priv; - struct sc_pkcs15_object *key_obj; - - priv = (const struct sc_priv_data *) RSA_get_app_data(key->rsa); - if (priv == NULL || p15card == NULL) { - logit("SmartCard key not loaded"); - /* internal error => return default label */ - return xstrdup("smartcard key"); - } - r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj); - if (r) { - logit("Unable to find private key from SmartCard: %s", - sc_strerror(r)); - return xstrdup("smartcard key"); - } - if (key_obj == NULL || key_obj->label == NULL) - /* the optional PKCS#15 label does not exists - * => return the default label */ - return xstrdup("smartcard key"); - return xstrdup(key_obj->label); -} - -#endif /* SMARTCARD */ diff --git a/scard.c b/scard.c deleted file mode 100644 index 9fd3ca1..0000000 --- a/scard.c +++ /dev/null @@ -1,571 +0,0 @@ -/* $OpenBSD: scard.c,v 1.36 2006/11/06 21:25:28 markus Exp $ */ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -#if defined(SMARTCARD) && defined(USE_SECTOK) - -#include <sys/types.h> - -#include <sectok.h> -#include <stdarg.h> -#include <string.h> - -#include <openssl/evp.h> - -#include "xmalloc.h" -#include "key.h" -#include "log.h" -#include "misc.h" -#include "scard.h" - -#if OPENSSL_VERSION_NUMBER < 0x00907000L -#define USE_ENGINE -#define RSA_get_default_method RSA_get_default_openssl_method -#else -#endif - -#ifdef USE_ENGINE -#include <openssl/engine.h> -#define sc_get_rsa sc_get_engine -#else -#define sc_get_rsa sc_get_rsa_method -#endif - -#define CLA_SSH 0x05 -#define INS_DECRYPT 0x10 -#define INS_GET_KEYLENGTH 0x20 -#define INS_GET_PUBKEY 0x30 -#define INS_GET_RESPONSE 0xc0 - -#define MAX_BUF_SIZE 256 - -u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63}; - -static int sc_fd = -1; -static char *sc_reader_id = NULL; -static char *sc_pin = NULL; -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 */ - -static int -sc_open(void) -{ - int sw; - - if (sc_fd >= 0) - return sc_fd; - - sc_fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw); - if (sc_fd < 0) { - error("sectok_open failed: %s", sectok_get_sw(sw)); - return SCARD_ERROR_FAIL; - } - if (! sectok_cardpresent(sc_fd)) { - debug("smartcard in reader %s not present, skipping", - sc_reader_id); - sc_close(); - return SCARD_ERROR_NOCARD; - } - if (sectok_reset(sc_fd, 0, NULL, &sw) <= 0) { - error("sectok_reset failed: %s", sectok_get_sw(sw)); - sc_fd = -1; - return SCARD_ERROR_FAIL; - } - if ((cla = cyberflex_inq_class(sc_fd)) < 0) - cla = 0; - - debug("sc_open ok %d", sc_fd); - return sc_fd; -} - -static int -sc_enable_applet(void) -{ - static u_char aid[] = {0xfc, 0x53, 0x73, 0x68, 0x2e, 0x62, 0x69, 0x6e}; - int sw = 0; - - /* select applet id */ - sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, sizeof aid, aid, 0, NULL, &sw); - if (!sectok_swOK(sw)) { - error("sectok_apdu failed: %s", sectok_get_sw(sw)); - sc_close(); - return -1; - } - return 0; -} - -static int -sc_init(void) -{ - int status; - - status = sc_open(); - if (status == SCARD_ERROR_NOCARD) { - return SCARD_ERROR_NOCARD; - } - if (status < 0) { - error("sc_open failed"); - return status; - } - if (sc_enable_applet() < 0) { - error("sc_enable_applet failed"); - return SCARD_ERROR_APPLET; - } - return 0; -} - -static int -sc_read_pubkey(Key * k) -{ - u_char buf[2], *n; - char *p; - int len, sw, status = -1; - - len = sw = 0; - n = NULL; - - if (sc_fd < 0) { - if (sc_init() < 0) - goto err; - } - - /* get key size */ - sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL, - sizeof(buf), buf, &sw); - if (!sectok_swOK(sw)) { - error("could not obtain key length: %s", sectok_get_sw(sw)); - goto err; - } - len = (buf[0] << 8) | buf[1]; - len /= 8; - debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw)); - - 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; - } - - debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw)); - - if (BN_bin2bn(n, len, k->rsa->n) == NULL) { - error("c_read_pubkey: BN_bin2bn failed"); - goto err; - } - - /* currently the java applet just stores 'n' */ - if (!BN_set_word(k->rsa->e, 35)) { - error("c_read_pubkey: BN_set_word(e, 35) failed"); - goto err; - } - - status = 0; - p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX); - debug("fingerprint %u %s", key_size(k), p); - xfree(p); - -err: - if (n != NULL) - xfree(n); - sc_close(); - return status; -} - -/* private key operations */ - -static int -sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, - int padding) -{ - u_char *padded = NULL; - int sw, len, olen, status = -1; - - debug("sc_private_decrypt called"); - - olen = len = sw = 0; - if (sc_fd < 0) { - status = sc_init(); - if (status < 0) - goto err; - } - if (padding != RSA_PKCS1_PADDING) - goto err; - - len = BN_num_bytes(rsa->n); - padded = xmalloc(len); - - sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw); - - if (sw == 0x6982) { - if (try_AUT0() < 0) - goto err; - sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw); - } - if (!sectok_swOK(sw)) { - error("sc_private_decrypt: INS_DECRYPT failed: %s", - sectok_get_sw(sw)); - goto err; - } - olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1, - len); -err: - if (padded) - xfree(padded); - sc_close(); - return (olen >= 0 ? olen : status); -} - -static int -sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, - int padding) -{ - u_char *padded = NULL; - int sw, len, status = -1; - - len = sw = 0; - if (sc_fd < 0) { - status = sc_init(); - if (status < 0) - goto err; - } - if (padding != RSA_PKCS1_PADDING) - goto err; - - debug("sc_private_encrypt called"); - len = BN_num_bytes(rsa->n); - padded = xmalloc(len); - - if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)from, flen) <= 0) { - error("RSA_padding_add_PKCS1_type_1 failed"); - goto err; - } - sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw); - if (sw == 0x6982) { - if (try_AUT0() < 0) - goto err; - sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw); - } - if (!sectok_swOK(sw)) { - error("sc_private_encrypt: INS_DECRYPT failed: %s", - sectok_get_sw(sw)); - goto err; - } -err: - if (padded) - xfree(padded); - sc_close(); - return (len >= 0 ? len : status); -} - -/* called on free */ - -static int (*orig_finish)(RSA *rsa) = NULL; - -static int -sc_finish(RSA *rsa) -{ - if (orig_finish) - orig_finish(rsa); - sc_close(); - return 1; -} - -/* engine for overloading private key operations */ - -static RSA_METHOD * -sc_get_rsa_method(void) -{ - static RSA_METHOD smart_rsa; - const RSA_METHOD *def = RSA_get_default_method(); - - /* use the OpenSSL version */ - memcpy(&smart_rsa, def, sizeof(smart_rsa)); - - smart_rsa.name = "sectok"; - - /* overload */ - smart_rsa.rsa_priv_enc = sc_private_encrypt; - smart_rsa.rsa_priv_dec = sc_private_decrypt; - - /* save original */ - orig_finish = def->finish; - smart_rsa.finish = sc_finish; - - return &smart_rsa; -} - -#ifdef USE_ENGINE -static ENGINE * -sc_get_engine(void) -{ - static ENGINE *smart_engine = NULL; - - if ((smart_engine = ENGINE_new()) == NULL) - fatal("ENGINE_new failed"); - - ENGINE_set_id(smart_engine, "sectok"); - ENGINE_set_name(smart_engine, "libsectok"); - - ENGINE_set_RSA(smart_engine, sc_get_rsa_method()); - ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method()); - ENGINE_set_DH(smart_engine, DH_get_default_openssl_method()); - ENGINE_set_RAND(smart_engine, RAND_SSLeay()); - ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp); - - return smart_engine; -} -#endif - -void -sc_close(void) -{ - if (sc_fd >= 0) { - sectok_close(sc_fd); - sc_fd = -1; - } -} - -Key ** -sc_get_keys(const char *id, const char *pin) -{ - Key *k, *n, **keys; - int status, nkeys = 2; - - if (sc_reader_id != NULL) - xfree(sc_reader_id); - sc_reader_id = xstrdup(id); - - if (sc_pin != NULL) - xfree(sc_pin); - sc_pin = (pin == NULL) ? NULL : xstrdup(pin); - - k = key_new(KEY_RSA); - if (k == NULL) { - return NULL; - } - status = sc_read_pubkey(k); - if (status == SCARD_ERROR_NOCARD) { - key_free(k); - return NULL; - } - if (status < 0) { - error("sc_read_pubkey failed"); - key_free(k); - return NULL; - } - keys = xcalloc((nkeys+1), sizeof(Key *)); - - n = key_new(KEY_RSA1); - 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); - 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; - - keys[2] = NULL; - - key_free(k); - return keys; -} - -#define NUM_RSA_KEY_ELEMENTS 5+1 -#define COPY_RSA_KEY(x, i) \ - do { \ - len = BN_num_bytes(prv->rsa->x); \ - elements[i] = xmalloc(len); \ - debug("#bytes %d", len); \ - if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \ - goto done; \ - } while (0) - -static void -sc_mk_digest(const char *pin, u_char *digest) -{ - const EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, pin, strlen(pin)); - EVP_DigestFinal(&md, digest, NULL); -} - -static int -get_AUT0(u_char *aut0) -{ - char *pass; - - pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN); - if (pass == NULL) - return -1; - if (!strcmp(pass, "-")) { - memcpy(aut0, DEFAUT0, sizeof DEFAUT0); - return 0; - } - sc_mk_digest(pass, aut0); - memset(pass, 0, strlen(pass)); - xfree(pass); - 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) -{ - u_char *elements[NUM_RSA_KEY_ELEMENTS]; - u_char key_fid[2]; - u_char AUT0[EVP_MAX_MD_SIZE]; - int len, status = -1, i, fd = -1, ret; - int sw = 0, cla = 0x00; - - for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++) - elements[i] = NULL; - - COPY_RSA_KEY(q, 0); - COPY_RSA_KEY(p, 1); - COPY_RSA_KEY(iqmp, 2); - COPY_RSA_KEY(dmq1, 3); - COPY_RSA_KEY(dmp1, 4); - COPY_RSA_KEY(n, 5); - len = BN_num_bytes(prv->rsa->n); - fd = sectok_friendly_open(id, STONOWAIT, &sw); - if (fd < 0) { - error("sectok_open failed: %s", sectok_get_sw(sw)); - goto done; - } - if (! sectok_cardpresent(fd)) { - error("smartcard in reader %s not present", id); - goto done; - } - ret = sectok_reset(fd, 0, NULL, &sw); - if (ret <= 0) { - error("sectok_reset failed: %s", sectok_get_sw(sw)); - goto done; - } - if ((cla = cyberflex_inq_class(fd)) < 0) { - error("cyberflex_inq_class failed"); - goto done; - } - memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0)); - if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) { - if (get_AUT0(AUT0) < 0 || - cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) { - memset(AUT0, 0, sizeof(DEFAUT0)); - error("smartcard passphrase incorrect"); - goto done; - } - } - memset(AUT0, 0, sizeof(DEFAUT0)); - key_fid[0] = 0x00; - key_fid[1] = 0x12; - if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements, - &sw) < 0) { - error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw)); - goto done; - } - if (!sectok_swOK(sw)) - goto 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], - &sw) < 0) { - error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw)); - goto done; - } - if (!sectok_swOK(sw)) - goto done; - logit("cyberflex_load_rsa_pub done"); - status = 0; - -done: - memset(elements[0], '\0', BN_num_bytes(prv->rsa->q)); - memset(elements[1], '\0', BN_num_bytes(prv->rsa->p)); - memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp)); - memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1)); - memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1)); - memset(elements[5], '\0', BN_num_bytes(prv->rsa->n)); - - for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++) - if (elements[i]) - xfree(elements[i]); - if (fd != -1) - sectok_close(fd); - return (status); -} - -char * -sc_get_key_label(Key *key) -{ - return xstrdup("smartcard key"); -} - -#endif /* SMARTCARD && USE_SECTOK */ diff --git a/scard.h b/scard.h deleted file mode 100644 index 82efe48..0000000 --- a/scard.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $OpenBSD: scard.h,v 1.14 2006/08/03 03:34:42 deraadt Exp $ */ - -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SCARD_H -#define SCARD_H - -#define SCARD_ERROR_FAIL -1 -#define SCARD_ERROR_NOCARD -2 -#define SCARD_ERROR_APPLET -3 - -Key **sc_get_keys(const char *, const char *); -void sc_close(void); -int sc_put_key(Key *, const char *); -char *sc_get_key_label(Key *); - -#endif diff --git a/scard/Makefile.in b/scard/Makefile.in deleted file mode 100644 index 8519e20..0000000 --- a/scard/Makefile.in +++ /dev/null @@ -1,29 +0,0 @@ -# $Id: Makefile.in,v 1.5 2006/10/23 21:44:47 tim Exp $ - -prefix=@prefix@ -datadir=@datadir@ -datarootdir=@datarootdir@ -srcdir=@srcdir@ -top_srcdir=@top_srcdir@ - -INSTALL=@INSTALL@ - -VPATH=@srcdir@ - -all: - -#Ssh.bin: Ssh.bin.uu -# uudecode Ssh.bin.uu - -clean: -# rm -rf Ssh.bin - -distprep: - uudecode Ssh.bin.uu - -distclean: clean - rm -f Makefile *~ - -install: $(srcdir)/Ssh.bin - $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir) - $(INSTALL) -m 0644 $(srcdir)/Ssh.bin $(DESTDIR)$(datadir)/Ssh.bin diff --git a/scard/Ssh.bin b/scard/Ssh.bin Binary files differdeleted file mode 100644 index edbadc6..0000000 --- a/scard/Ssh.bin +++ /dev/null diff --git a/scard/Ssh.bin.uu b/scard/Ssh.bin.uu deleted file mode 100644 index ea3986a..0000000 --- a/scard/Ssh.bin.uu +++ /dev/null @@ -1,17 +0,0 @@ -begin 644 Ssh.bin -M`P)!&P`801X`>``!`E@"`/Y@\`4`_J'P!0!!&T$=`?Z@\`4`01M!'`'^>/,! -M`4$;01X!_G#S%P'^0],1`?Y@\!0`_G/S'0#^<]4``D$;L`4`_F'3``#^8=,% -M`/ZAT`$!_J#0)P'^H],*`?ZCTPD`_G/5"P7^8=,'`OZAT`H`_J#0$@3^:-,@ -M`T$;`P`%`/Y@`<P``$$<\@\``$$=\B$``$$>\A```/`0__(%`@8!`0H``&`` -M0205!!D)I$L`"0J0`&``*!4$&58``````.P````%____P````.D````0```` -M,P```"````#'````,````(T````R````V!4#&0A*``D*;@!@`"@5!QD*`/\] -M(6``1A)*``D*9P!@`"@*/P!@`$LK"1)@`$LK!6``4!P$#00#2@`.#01@`%5@ -M`%I@`"@37``>%0@2%0A>`%\($F``9%(`:`H_`&``2RL*<VA@`$LK8`!I"1`U -M(14#`Q)@`&X<!`T$`TL`"P,28`!D4@`.#01@`%5@`%I@`"A2`"X5`PH$`&`` -M<RL#!6``9%(`'14#"@$"8`!S*P,%8`!D4@`,4@`)"FT`8``H60``\`+_\@$! -M`0D`"```"I``8``H60#P$__R`0$""0`,``!B01LM7P`\*UD```#P$O_V`0$# -M`0`8```37``>7@`R10`/$UP`'@H`R`D07@`W!%>P!?_R`0$$`@`\```37P`` -M$V+^H2U?``5=``H38OZ@+5\`#UT`%!-B_G@M"@0`7P`970`>"@0`8``C10`) -/"F<`8``H$UX`+5D````` -` -end diff --git a/scard/Ssh.java b/scard/Ssh.java deleted file mode 100644 index 6418957..0000000 --- a/scard/Ssh.java +++ /dev/null @@ -1,164 +0,0 @@ -// $Id: Ssh.java,v 1.3 2002/05/22 04:24:02 djm Exp $ -// -// Ssh.java -// SSH / smartcard integration project, smartcard side -// -// Tomoko Fukuzawa, created, Feb., 2000 -// -// Naomaru Itoi, modified, Apr., 2000 -// - -// copyright 2000 -// the regents of the university of michigan -// all rights reserved -// -// permission is granted to use, copy, create derivative works -// and redistribute this software and such derivative works -// for any purpose, so long as the name of the university of -// michigan is not used in any advertising or publicity -// pertaining to the use or distribution of this software -// without specific, written prior authorization. if the -// above copyright notice or any other identification of the -// university of michigan is included in any copy of any -// portion of this software, then the disclaimer below must -// also be included. -// -// this software is provided as is, without representation -// from the university of michigan as to its fitness for any -// purpose, and without warranty by the university of -// michigan of any kind, either express or implied, including -// without limitation the implied warranties of -// merchantability and fitness for a particular purpose. the -// regents of the university of michigan shall not be liable -// for any damages, including special, indirect, incidental, or -// consequential damages, with respect to any claim arising -// out of or in connection with the use of the software, even -// if it has been or is hereafter advised of the possibility of -// such damages. - -import javacard.framework.*; -import javacardx.framework.*; -import javacardx.crypto.*; - -public class Ssh extends javacard.framework.Applet -{ - // Change this when the applet changes; hi byte is major, low byte is minor - static final short applet_version = (short)0x0102; - - /* constants declaration */ - // code of CLA byte in the command APDU header - static final byte Ssh_CLA =(byte)0x05; - - // codes of INS byte in the command APDU header - static final byte DECRYPT = (byte) 0x10; - static final byte GET_KEYLENGTH = (byte) 0x20; - static final byte GET_PUBKEY = (byte) 0x30; - static final byte GET_VERSION = (byte) 0x32; - static final byte GET_RESPONSE = (byte) 0xc0; - - static final short keysize = 1024; - static final short root_fid = (short)0x3f00; - static final short privkey_fid = (short)0x0012; - static final short pubkey_fid = (short)(('s'<<8)|'h'); - - /* instance variables declaration */ - AsymKey rsakey; - CyberflexFile file; - CyberflexOS os; - - private Ssh() - { - file = new CyberflexFile(); - os = new CyberflexOS(); - - rsakey = new RSA_CRT_PrivateKey (keysize); - - if ( ! rsakey.isSupportedLength (keysize) ) - ISOException.throwIt (ISO.SW_WRONG_LENGTH); - - register(); - } // end of the constructor - - public boolean select() { - if (!rsakey.isInitialized()) - rsakey.setKeyInstance ((short)0xc8, (short)0x10); - - return true; - } - - public static void install(APDU apdu) - { - new Ssh(); // create a Ssh applet instance (card) - } // end of install method - - public static void main(String args[]) { - ISOException.throwIt((short) 0x9000); - } - - public void process(APDU apdu) - { - // APDU object carries a byte array (buffer) to - // transfer incoming and outgoing APDU header - // and data bytes between card and CAD - byte buffer[] = apdu.getBuffer(); - short size, st; - - // verify that if the applet can accept this - // APDU message - // NI: change suggested by Wayne Dyksen, Purdue - if (buffer[ISO.OFFSET_INS] == ISO.INS_SELECT) - ISOException.throwIt(ISO.SW_NO_ERROR); - - switch (buffer[ISO.OFFSET_INS]) { - case DECRYPT: - if (buffer[ISO.OFFSET_CLA] != Ssh_CLA) - ISOException.throwIt(ISO.SW_CLA_NOT_SUPPORTED); - //decrypt (apdu); - size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF); - - if (apdu.setIncomingAndReceive() != size) - ISOException.throwIt (ISO.SW_WRONG_LENGTH); - - // check access; depends on bit 2 (x/a) - file.selectFile(root_fid); - file.selectFile(privkey_fid); - st = os.checkAccess(ACL.EXECUTE); - if (st != ST.ACCESS_CLEARED) { - CyberflexAPDU.prepareSW1SW2(st); - ISOException.throwIt(CyberflexAPDU.getSW1SW2()); - } - - rsakey.cryptoUpdate (buffer, (short) ISO.OFFSET_CDATA, size, - buffer, (short) ISO.OFFSET_CDATA); - - apdu.setOutgoingAndSend ((short) ISO.OFFSET_CDATA, size); - break; - case GET_PUBKEY: - file.selectFile(root_fid); // select root - file.selectFile(pubkey_fid); // select public key file - size = (short)(file.getFileSize() - 16); - st = os.readBinaryFile(buffer, (short)0, (short)0, size); - if (st == ST.SUCCESS) - apdu.setOutgoingAndSend((short)0, size); - else { - CyberflexAPDU.prepareSW1SW2(st); - ISOException.throwIt(CyberflexAPDU.getSW1SW2()); - } - break; - case GET_KEYLENGTH: - Util.setShort(buffer, (short)0, keysize); - apdu.setOutgoingAndSend ((short)0, (short)2); - break; - case GET_VERSION: - Util.setShort(buffer, (short)0, applet_version); - apdu.setOutgoingAndSend ((short)0, (short)2); - break; - case GET_RESPONSE: - break; - default: - ISOException.throwIt (ISO.SW_INS_NOT_SUPPORTED); - } - - } // end of process method - -} // end of class Ssh |