diff options
author | Ben Lindstrom <mouring@eviladmin.org> | 2001-07-04 04:52:03 +0000 |
---|---|---|
committer | Ben Lindstrom <mouring@eviladmin.org> | 2001-07-04 04:52:03 +0000 |
commit | c5b680018b1fbc58ad2316199693e2805dadf638 (patch) | |
tree | c01554c5d55ef51cc90b52dbc28c7513f75fc0bd | |
parent | eb7a84c49e6248279ba130f8592bae356e7fb61e (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.c | 3 | ||||
-rw-r--r-- | key.h | 9 | ||||
-rw-r--r-- | ssh.c | 49 | ||||
-rw-r--r-- | sshconnect1.c | 35 | ||||
-rw-r--r-- | sshconnect2.c | 7 |
5 files changed, 79 insertions, 24 deletions
@@ -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" |
35 | RCSID("$OpenBSD: key.c,v 1.28 2001/06/25 08:25:37 markus Exp $"); | 35 | RCSID("$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) { |
@@ -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 | |||
47 | struct Key { | 51 | struct Key { |
48 | int type; | 52 | int type; |
53 | int flags; | ||
49 | RSA *rsa; | 54 | RSA *rsa; |
50 | DSA *dsa; | 55 | DSA *dsa; |
51 | }; | 56 | }; |
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: ssh.c,v 1.126 2001/06/23 15:12:21 itojun Exp $"); | 42 | RCSID("$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 |
73 | extern char *__progname; | 78 | extern 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? */ |
147 | int subsystem_flag = 0; | 152 | int subsystem_flag = 0; |
148 | 153 | ||
154 | #ifdef SMARTCARD | ||
155 | /* Smartcard reader id */ | ||
156 | int 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 | ||
151 | static void | 161 | static 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" |
16 | RCSID("$OpenBSD: sshconnect1.c,v 1.37 2001/06/26 16:15:24 dugsong Exp $"); | 16 | RCSID("$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 | */ |
207 | static int | 207 | static int |
208 | try_rsa_authentication(const char *authfile) | 208 | try_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" |
26 | RCSID("$OpenBSD: sshconnect2.c,v 1.79 2001/06/25 20:26:37 stevesk Exp $"); | 26 | RCSID("$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; |