summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-07-04 04:52:03 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-07-04 04:52:03 +0000
commitc5b680018b1fbc58ad2316199693e2805dadf638 (patch)
treec01554c5d55ef51cc90b52dbc28c7513f75fc0bd
parenteb7a84c49e6248279ba130f8592bae356e7fb61e (diff)
- 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).
-rw-r--r--key.c3
-rw-r--r--key.h9
-rw-r--r--ssh.c49
-rw-r--r--sshconnect1.c35
-rw-r--r--sshconnect2.c7
5 files changed, 79 insertions, 24 deletions
diff --git a/key.c b/key.c
index 2000c2755..0ddd3d9d4 100644
--- a/key.c
+++ b/key.c
@@ -32,7 +32,7 @@
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34#include "includes.h" 34#include "includes.h"
35RCSID("$OpenBSD: key.c,v 1.28 2001/06/25 08:25:37 markus Exp $"); 35RCSID("$OpenBSD: key.c,v 1.29 2001/06/26 20:14:10 markus Exp $");
36 36
37#include <openssl/evp.h> 37#include <openssl/evp.h>
38 38
@@ -54,6 +54,7 @@ key_new(int type)
54 DSA *dsa; 54 DSA *dsa;
55 k = xmalloc(sizeof(*k)); 55 k = xmalloc(sizeof(*k));
56 k->type = type; 56 k->type = type;
57 k->flags = 0;
57 k->dsa = NULL; 58 k->dsa = NULL;
58 k->rsa = NULL; 59 k->rsa = NULL;
59 switch (k->type) { 60 switch (k->type) {
diff --git a/key.h b/key.h
index 562834c98..2b4fbce04 100644
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.h,v 1.15 2001/06/26 17:27:23 markus Exp $ */ 1/* $OpenBSD: key.h,v 1.16 2001/06/26 20:14:10 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -44,8 +44,13 @@ enum fp_rep {
44 SSH_FP_HEX, 44 SSH_FP_HEX,
45 SSH_FP_BUBBLEBABBLE 45 SSH_FP_BUBBLEBABBLE
46}; 46};
47
48/* key is stored in external hardware */
49#define KEY_FLAG_EXT 0x0001
50
47struct Key { 51struct Key {
48 int type; 52 int type;
53 int flags;
49 RSA *rsa; 54 RSA *rsa;
50 DSA *dsa; 55 DSA *dsa;
51}; 56};
diff --git a/ssh.c b/ssh.c
index 484e5de46..a7fe1408a 100644
--- a/ssh.c
+++ b/ssh.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: ssh.c,v 1.126 2001/06/23 15:12:21 itojun Exp $"); 42RCSID("$OpenBSD: ssh.c,v 1.127 2001/06/26 20:14:11 markus Exp $");
43 43
44#include <openssl/evp.h> 44#include <openssl/evp.h>
45#include <openssl/err.h> 45#include <openssl/err.h>
@@ -69,6 +69,11 @@ RCSID("$OpenBSD: ssh.c,v 1.126 2001/06/23 15:12:21 itojun Exp $");
69#include "mac.h" 69#include "mac.h"
70#include "sshtty.h" 70#include "sshtty.h"
71 71
72#ifdef SMARTCARD
73#include <openssl/engine.h>
74#include "scard.h"
75#endif
76
72#ifdef HAVE___PROGNAME 77#ifdef HAVE___PROGNAME
73extern char *__progname; 78extern char *__progname;
74#else 79#else
@@ -146,6 +151,11 @@ Buffer command;
146/* Should we execute a command or invoke a subsystem? */ 151/* Should we execute a command or invoke a subsystem? */
147int subsystem_flag = 0; 152int subsystem_flag = 0;
148 153
154#ifdef SMARTCARD
155/* Smartcard reader id */
156int sc_reader_num = -1;
157#endif
158
149/* Prints a help message to the user. This function never returns. */ 159/* Prints a help message to the user. This function never returns. */
150 160
151static void 161static void
@@ -320,7 +330,7 @@ main(int ac, char **av)
320 opt = av[optind][1]; 330 opt = av[optind][1];
321 if (!opt) 331 if (!opt)
322 usage(); 332 usage();
323 if (strchr("eilcmpbLRDo", opt)) { /* options with arguments */ 333 if (strchr("eilcmpbILRDo", opt)) { /* options with arguments */
324 optarg = av[optind] + 2; 334 optarg = av[optind] + 2;
325 if (strcmp(optarg, "") == 0) { 335 if (strcmp(optarg, "") == 0) {
326 if (optind >= ac - 1) 336 if (optind >= ac - 1)
@@ -387,6 +397,13 @@ main(int ac, char **av)
387 SSH_MAX_IDENTITY_FILES); 397 SSH_MAX_IDENTITY_FILES);
388 options.identity_files[options.num_identity_files++] = xstrdup(optarg); 398 options.identity_files[options.num_identity_files++] = xstrdup(optarg);
389 break; 399 break;
400 case 'I':
401#ifdef SMARTCARD
402 sc_reader_num = atoi(optarg);
403#else
404 fprintf(stderr, "no support for smartcards.\n");
405#endif
406 break;
390 case 't': 407 case 't':
391 if (tty_flag) 408 if (tty_flag)
392 force_tty_flag = 1; 409 force_tty_flag = 1;
@@ -1140,4 +1157,32 @@ load_public_identity_files(void)
1140 options.identity_files[i] = filename; 1157 options.identity_files[i] = filename;
1141 options.identity_keys[i] = public; 1158 options.identity_keys[i] = public;
1142 } 1159 }
1160#ifdef SMARTCARD
1161 if (sc_reader_num != -1 &&
1162 options.num_identity_files + 1 < SSH_MAX_IDENTITY_FILES &&
1163 (public = sc_get_key(sc_reader_num)) != NULL ) {
1164 Key *new;
1165
1166 /* XXX ssh1 vs ssh2 */
1167 new = key_new(KEY_RSA);
1168 new->flags = KEY_FLAG_EXT;
1169 BN_copy(new->rsa->n, public->rsa->n);
1170 BN_copy(new->rsa->e, public->rsa->e);
1171 RSA_set_method(new->rsa, sc_get_engine());
1172 i = options.num_identity_files++;
1173 options.identity_keys[i] = new;
1174 options.identity_files[i] = xstrdup("smartcard rsa key");;
1175
1176 new = key_new(KEY_RSA1);
1177 new->flags = KEY_FLAG_EXT;
1178 BN_copy(new->rsa->n, public->rsa->n);
1179 BN_copy(new->rsa->e, public->rsa->e);
1180 RSA_set_method(new->rsa, sc_get_engine());
1181 i = options.num_identity_files++;
1182 options.identity_keys[i] = new;
1183 options.identity_files[i] = xstrdup("smartcard rsa1 key");;
1184
1185 key_free(public);
1186 }
1187#endif
1143} 1188}
diff --git a/sshconnect1.c b/sshconnect1.c
index 09203d714..166fdc17f 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include "includes.h" 15#include "includes.h"
16RCSID("$OpenBSD: sshconnect1.c,v 1.37 2001/06/26 16:15:24 dugsong Exp $"); 16RCSID("$OpenBSD: sshconnect1.c,v 1.38 2001/06/26 20:14:11 markus Exp $");
17 17
18#include <openssl/bn.h> 18#include <openssl/bn.h>
19#include <openssl/evp.h> 19#include <openssl/evp.h>
@@ -205,20 +205,17 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
205 * the user using it. 205 * the user using it.
206 */ 206 */
207static int 207static int
208try_rsa_authentication(const char *authfile) 208try_rsa_authentication(int idx)
209{ 209{
210 BIGNUM *challenge; 210 BIGNUM *challenge;
211 Key *public, *private; 211 Key *public, *private;
212 char buf[300], *passphrase, *comment; 212 char buf[300], *passphrase, *comment, *authfile;
213 int i, type, quit, plen, clen; 213 int i, type, quit, plen, clen;
214 214
215 /* Try to load identification for the authentication key. */ 215 public = options.identity_keys[idx];
216 /* XXKEYLOAD */ 216 authfile = options.identity_files[idx];
217 public = key_load_public_type(KEY_RSA1, authfile, &comment); 217 comment = xstrdup(authfile);
218 if (public == NULL) { 218
219 /* Could not load it. Fail. */
220 return 0;
221 }
222 debug("Trying RSA authentication with key '%.100s'", comment); 219 debug("Trying RSA authentication with key '%.100s'", comment);
223 220
224 /* Tell the server that we are willing to authenticate using this key. */ 221 /* Tell the server that we are willing to authenticate using this key. */
@@ -227,9 +224,6 @@ try_rsa_authentication(const char *authfile)
227 packet_send(); 224 packet_send();
228 packet_write_wait(); 225 packet_write_wait();
229 226
230 /* We no longer need the public key. */
231 key_free(public);
232
233 /* Wait for server's response. */ 227 /* Wait for server's response. */
234 type = packet_read(&plen); 228 type = packet_read(&plen);
235 229
@@ -255,10 +249,14 @@ try_rsa_authentication(const char *authfile)
255 debug("Received RSA challenge from server."); 249 debug("Received RSA challenge from server.");
256 250
257 /* 251 /*
258 * Load the private key. Try first with empty passphrase; if it 252 * If the key is not stored in external hardware, we have to
253 * load the private key. Try first with empty passphrase; if it
259 * fails, ask for a passphrase. 254 * fails, ask for a passphrase.
260 */ 255 */
261 private = key_load_private_type(KEY_RSA1, authfile, "", NULL); 256 if (public->flags && KEY_FLAG_EXT)
257 private = public;
258 else
259 private = key_load_private_type(KEY_RSA1, authfile, "", NULL);
262 if (private == NULL && !options.batch_mode) { 260 if (private == NULL && !options.batch_mode) {
263 snprintf(buf, sizeof(buf), 261 snprintf(buf, sizeof(buf),
264 "Enter passphrase for RSA key '%.100s': ", comment); 262 "Enter passphrase for RSA key '%.100s': ", comment);
@@ -302,8 +300,9 @@ try_rsa_authentication(const char *authfile)
302 /* Compute and send a response to the challenge. */ 300 /* Compute and send a response to the challenge. */
303 respond_to_rsa_challenge(challenge, private->rsa); 301 respond_to_rsa_challenge(challenge, private->rsa);
304 302
305 /* Destroy the private key. */ 303 /* Destroy the private key unless it in external hardware. */
306 key_free(private); 304 if (!(private->flags & KEY_FLAG_EXT))
305 key_free(private);
307 306
308 /* We no longer need the challenge. */ 307 /* We no longer need the challenge. */
309 BN_clear_free(challenge); 308 BN_clear_free(challenge);
@@ -1218,7 +1217,7 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
1218 for (i = 0; i < options.num_identity_files; i++) 1217 for (i = 0; i < options.num_identity_files; i++)
1219 if (options.identity_keys[i] != NULL && 1218 if (options.identity_keys[i] != NULL &&
1220 options.identity_keys[i]->type == KEY_RSA1 && 1219 options.identity_keys[i]->type == KEY_RSA1 &&
1221 try_rsa_authentication(options.identity_files[i])) 1220 try_rsa_authentication(i))
1222 goto success; 1221 goto success;
1223 } 1222 }
1224 /* Try challenge response authentication if the server supports it. */ 1223 /* Try challenge response authentication if the server supports it. */
diff --git a/sshconnect2.c b/sshconnect2.c
index 258ee4834..2e2452801 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: sshconnect2.c,v 1.79 2001/06/25 20:26:37 stevesk Exp $"); 26RCSID("$OpenBSD: sshconnect2.c,v 1.80 2001/06/26 20:14:11 markus Exp $");
27 27
28#include <openssl/bn.h> 28#include <openssl/bn.h>
29#include <openssl/md5.h> 29#include <openssl/md5.h>
@@ -640,6 +640,11 @@ identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
640 idx = authctxt->last_key_hint; 640 idx = authctxt->last_key_hint;
641 if (idx < 0) 641 if (idx < 0)
642 return -1; 642 return -1;
643
644 /* private key is stored in external hardware */
645 if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
646 return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
647
643 private = load_identity_file(options.identity_files[idx]); 648 private = load_identity_file(options.identity_files[idx]);
644 if (private == NULL) 649 if (private == NULL)
645 return -1; 650 return -1;