From 383546c4b6c84ea01336f570806c6f03bfd5394b Mon Sep 17 00:00:00 2001 From: mouring Date: Wed, 4 Jul 2001 04:52:03 +0000 Subject: [PATCH] - markus@cvs.openbsd.org 2001/06/26 20:14:11 [key.c key.h ssh.c sshconnect1.c sshconnect2.c] add smartcard support to the client, too (now you can use both the agent and the client). --- key.c | 3 ++- key.h | 9 +++++++-- ssh.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- sshconnect1.c | 35 +++++++++++++++++------------------ sshconnect2.c | 7 ++++++- 5 files changed, 79 insertions(+), 24 deletions(-) diff --git a/key.c b/key.c index 2000c275..0ddd3d9d 100644 --- a/key.c +++ b/key.c @@ -32,7 +32,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: key.c,v 1.28 2001/06/25 08:25:37 markus Exp $"); +RCSID("$OpenBSD: key.c,v 1.29 2001/06/26 20:14:10 markus Exp $"); #include @@ -54,6 +54,7 @@ key_new(int type) DSA *dsa; k = xmalloc(sizeof(*k)); k->type = type; + k->flags = 0; k->dsa = NULL; k->rsa = NULL; switch (k->type) { diff --git a/key.h b/key.h index 562834c9..2b4fbce0 100644 --- a/key.h +++ b/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.15 2001/06/26 17:27:23 markus Exp $ */ +/* $OpenBSD: key.h,v 1.16 2001/06/26 20:14:10 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -44,8 +44,13 @@ enum fp_rep { SSH_FP_HEX, SSH_FP_BUBBLEBABBLE }; + +/* key is stored in external hardware */ +#define KEY_FLAG_EXT 0x0001 + struct Key { - int type; + int type; + int flags; RSA *rsa; DSA *dsa; }; diff --git a/ssh.c b/ssh.c index 484e5de4..a7fe1408 100644 --- a/ssh.c +++ b/ssh.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.126 2001/06/23 15:12:21 itojun Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.127 2001/06/26 20:14:11 markus Exp $"); #include #include @@ -69,6 +69,11 @@ RCSID("$OpenBSD: ssh.c,v 1.126 2001/06/23 15:12:21 itojun Exp $"); #include "mac.h" #include "sshtty.h" +#ifdef SMARTCARD +#include +#include "scard.h" +#endif + #ifdef HAVE___PROGNAME extern char *__progname; #else @@ -146,6 +151,11 @@ Buffer command; /* Should we execute a command or invoke a subsystem? */ int subsystem_flag = 0; +#ifdef SMARTCARD +/* Smartcard reader id */ +int sc_reader_num = -1; +#endif + /* Prints a help message to the user. This function never returns. */ static void @@ -320,7 +330,7 @@ main(int ac, char **av) opt = av[optind][1]; if (!opt) usage(); - if (strchr("eilcmpbLRDo", opt)) { /* options with arguments */ + if (strchr("eilcmpbILRDo", opt)) { /* options with arguments */ optarg = av[optind] + 2; if (strcmp(optarg, "") == 0) { if (optind >= ac - 1) @@ -387,6 +397,13 @@ main(int ac, char **av) SSH_MAX_IDENTITY_FILES); options.identity_files[options.num_identity_files++] = xstrdup(optarg); break; + case 'I': +#ifdef SMARTCARD + sc_reader_num = atoi(optarg); +#else + fprintf(stderr, "no support for smartcards.\n"); +#endif + break; case 't': if (tty_flag) force_tty_flag = 1; @@ -1140,4 +1157,32 @@ load_public_identity_files(void) options.identity_files[i] = filename; options.identity_keys[i] = public; } +#ifdef SMARTCARD + if (sc_reader_num != -1 && + options.num_identity_files + 1 < SSH_MAX_IDENTITY_FILES && + (public = sc_get_key(sc_reader_num)) != NULL ) { + Key *new; + + /* XXX ssh1 vs ssh2 */ + new = key_new(KEY_RSA); + new->flags = KEY_FLAG_EXT; + BN_copy(new->rsa->n, public->rsa->n); + BN_copy(new->rsa->e, public->rsa->e); + RSA_set_method(new->rsa, sc_get_engine()); + i = options.num_identity_files++; + options.identity_keys[i] = new; + options.identity_files[i] = xstrdup("smartcard rsa key");; + + new = key_new(KEY_RSA1); + new->flags = KEY_FLAG_EXT; + BN_copy(new->rsa->n, public->rsa->n); + BN_copy(new->rsa->e, public->rsa->e); + RSA_set_method(new->rsa, sc_get_engine()); + i = options.num_identity_files++; + options.identity_keys[i] = new; + options.identity_files[i] = xstrdup("smartcard rsa1 key");; + + key_free(public); + } +#endif } diff --git a/sshconnect1.c b/sshconnect1.c index 09203d71..166fdc17 100644 --- a/sshconnect1.c +++ b/sshconnect1.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.37 2001/06/26 16:15:24 dugsong Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.38 2001/06/26 20:14:11 markus Exp $"); #include #include @@ -205,20 +205,17 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) * the user using it. */ static int -try_rsa_authentication(const char *authfile) +try_rsa_authentication(int idx) { BIGNUM *challenge; Key *public, *private; - char buf[300], *passphrase, *comment; + char buf[300], *passphrase, *comment, *authfile; int i, type, quit, plen, clen; - /* Try to load identification for the authentication key. */ - /* XXKEYLOAD */ - public = key_load_public_type(KEY_RSA1, authfile, &comment); - if (public == NULL) { - /* Could not load it. Fail. */ - return 0; - } + public = options.identity_keys[idx]; + authfile = options.identity_files[idx]; + comment = xstrdup(authfile); + debug("Trying RSA authentication with key '%.100s'", comment); /* Tell the server that we are willing to authenticate using this key. */ @@ -227,9 +224,6 @@ try_rsa_authentication(const char *authfile) packet_send(); packet_write_wait(); - /* We no longer need the public key. */ - key_free(public); - /* Wait for server's response. */ type = packet_read(&plen); @@ -255,10 +249,14 @@ try_rsa_authentication(const char *authfile) debug("Received RSA challenge from server."); /* - * Load the private key. Try first with empty passphrase; if it + * If the key is not stored in external hardware, we have to + * load the private key. Try first with empty passphrase; if it * fails, ask for a passphrase. */ - private = key_load_private_type(KEY_RSA1, authfile, "", NULL); + if (public->flags && KEY_FLAG_EXT) + private = public; + else + private = key_load_private_type(KEY_RSA1, authfile, "", NULL); if (private == NULL && !options.batch_mode) { snprintf(buf, sizeof(buf), "Enter passphrase for RSA key '%.100s': ", comment); @@ -302,8 +300,9 @@ try_rsa_authentication(const char *authfile) /* Compute and send a response to the challenge. */ respond_to_rsa_challenge(challenge, private->rsa); - /* Destroy the private key. */ - key_free(private); + /* Destroy the private key unless it in external hardware. */ + if (!(private->flags & KEY_FLAG_EXT)) + key_free(private); /* We no longer need the challenge. */ BN_clear_free(challenge); @@ -1218,7 +1217,7 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host, for (i = 0; i < options.num_identity_files; i++) if (options.identity_keys[i] != NULL && options.identity_keys[i]->type == KEY_RSA1 && - try_rsa_authentication(options.identity_files[i])) + try_rsa_authentication(i)) goto success; } /* Try challenge response authentication if the server supports it. */ diff --git a/sshconnect2.c b/sshconnect2.c index 258ee483..2e245280 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.79 2001/06/25 20:26:37 stevesk Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.80 2001/06/26 20:14:11 markus Exp $"); #include #include @@ -640,6 +640,11 @@ identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp, idx = authctxt->last_key_hint; if (idx < 0) return -1; + + /* private key is stored in external hardware */ + if (options.identity_keys[idx]->flags & KEY_FLAG_EXT) + return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen); + private = load_identity_file(options.identity_files[idx]); if (private == NULL) return -1; -- 2.45.1