diff options
author | Ben Lindstrom <mouring@eviladmin.org> | 2001-03-26 13:44:06 +0000 |
---|---|---|
committer | Ben Lindstrom <mouring@eviladmin.org> | 2001-03-26 13:44:06 +0000 |
commit | d0fca423fcee576f4787d01f8bad3f9c0efd62ab (patch) | |
tree | 696cb73350804862b8e39ccb53dc4edff2f68976 | |
parent | 7bfff36ca3acf469de9fcad98826562ea6c1fbbe (diff) |
- markus@cvs.openbsd.org 2001/03/26 08:07:09
[authfile.c authfile.h ssh-add.c ssh-keygen.c ssh.c sshconnect.c
sshconnect.h sshconnect1.c sshconnect2.c sshd.c]
simpler key load/save interface, see authfile.h
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | authfile.c | 343 | ||||
-rw-r--r-- | authfile.h | 45 | ||||
-rw-r--r-- | ssh-add.c | 56 | ||||
-rw-r--r-- | ssh-keygen.c | 133 | ||||
-rw-r--r-- | ssh.c | 54 | ||||
-rw-r--r-- | sshconnect.c | 6 | ||||
-rw-r--r-- | sshconnect.h | 6 | ||||
-rw-r--r-- | sshconnect1.c | 30 | ||||
-rw-r--r-- | sshconnect2.c | 22 | ||||
-rw-r--r-- | sshd.c | 43 |
11 files changed, 323 insertions, 424 deletions
@@ -1,3 +1,10 @@ | |||
1 | 20010328 | ||
2 | - OpenBSD CVS Sync | ||
3 | - markus@cvs.openbsd.org 2001/03/26 08:07:09 | ||
4 | [authfile.c authfile.h ssh-add.c ssh-keygen.c ssh.c sshconnect.c | ||
5 | sshconnect.h sshconnect1.c sshconnect2.c sshd.c] | ||
6 | simpler key load/save interface, see authfile.h | ||
7 | |||
1 | 20010327 | 8 | 20010327 |
2 | - Attempt sync with sshlogin.c w/ OpenBSD (mainly CVS ID) | 9 | - Attempt sync with sshlogin.c w/ OpenBSD (mainly CVS ID) |
3 | - Fix pointer issues in waitpid() and wait() replaces. Patch by Lutz | 10 | - Fix pointer issues in waitpid() and wait() replaces. Patch by Lutz |
@@ -4718,4 +4725,4 @@ | |||
4718 | - Wrote replacements for strlcpy and mkdtemp | 4725 | - Wrote replacements for strlcpy and mkdtemp |
4719 | - Released 1.0pre1 | 4726 | - Released 1.0pre1 |
4720 | 4727 | ||
4721 | $Id: ChangeLog,v 1.1019 2001/03/26 05:45:53 mouring Exp $ | 4728 | $Id: ChangeLog,v 1.1020 2001/03/26 13:44:06 mouring Exp $ |
diff --git a/authfile.c b/authfile.c index 9f03d5137..c867724db 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -36,7 +36,7 @@ | |||
36 | */ | 36 | */ |
37 | 37 | ||
38 | #include "includes.h" | 38 | #include "includes.h" |
39 | RCSID("$OpenBSD: authfile.c,v 1.28 2001/02/21 09:05:54 deraadt Exp $"); | 39 | RCSID("$OpenBSD: authfile.c,v 1.29 2001/03/26 08:07:07 markus Exp $"); |
40 | 40 | ||
41 | #include <openssl/err.h> | 41 | #include <openssl/err.h> |
42 | #include <openssl/evp.h> | 42 | #include <openssl/evp.h> |
@@ -51,7 +51,7 @@ RCSID("$OpenBSD: authfile.c,v 1.28 2001/02/21 09:05:54 deraadt Exp $"); | |||
51 | #include "log.h" | 51 | #include "log.h" |
52 | #include "authfile.h" | 52 | #include "authfile.h" |
53 | 53 | ||
54 | /* Version identification string for identity files. */ | 54 | /* Version identification string for SSH v1 identity files. */ |
55 | static const char authfile_id_string[] = | 55 | static const char authfile_id_string[] = |
56 | "SSH PRIVATE KEY FILE FORMAT 1.1\n"; | 56 | "SSH PRIVATE KEY FILE FORMAT 1.1\n"; |
57 | 57 | ||
@@ -63,8 +63,8 @@ static const char authfile_id_string[] = | |||
63 | */ | 63 | */ |
64 | 64 | ||
65 | int | 65 | int |
66 | save_private_key_rsa1(const char *filename, const char *passphrase, | 66 | key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, |
67 | RSA *key, const char *comment) | 67 | const char *comment) |
68 | { | 68 | { |
69 | Buffer buffer, encrypted; | 69 | Buffer buffer, encrypted; |
70 | char buf[100], *cp; | 70 | char buf[100], *cp; |
@@ -100,10 +100,10 @@ save_private_key_rsa1(const char *filename, const char *passphrase, | |||
100 | * will be stored in plain text, and storing them also in encrypted | 100 | * will be stored in plain text, and storing them also in encrypted |
101 | * format would just give known plaintext). | 101 | * format would just give known plaintext). |
102 | */ | 102 | */ |
103 | buffer_put_bignum(&buffer, key->d); | 103 | buffer_put_bignum(&buffer, key->rsa->d); |
104 | buffer_put_bignum(&buffer, key->iqmp); | 104 | buffer_put_bignum(&buffer, key->rsa->iqmp); |
105 | buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */ | 105 | buffer_put_bignum(&buffer, key->rsa->q); /* reverse from SSL p */ |
106 | buffer_put_bignum(&buffer, key->p); /* reverse from SSL q */ | 106 | buffer_put_bignum(&buffer, key->rsa->p); /* reverse from SSL q */ |
107 | 107 | ||
108 | /* Pad the part to be encrypted until its size is a multiple of 8. */ | 108 | /* Pad the part to be encrypted until its size is a multiple of 8. */ |
109 | while (buffer_len(&buffer) % 8 != 0) | 109 | while (buffer_len(&buffer) % 8 != 0) |
@@ -122,9 +122,9 @@ save_private_key_rsa1(const char *filename, const char *passphrase, | |||
122 | buffer_put_int(&encrypted, 0); /* For future extension */ | 122 | buffer_put_int(&encrypted, 0); /* For future extension */ |
123 | 123 | ||
124 | /* Store public key. This will be in plain text. */ | 124 | /* Store public key. This will be in plain text. */ |
125 | buffer_put_int(&encrypted, BN_num_bits(key->n)); | 125 | buffer_put_int(&encrypted, BN_num_bits(key->rsa->n)); |
126 | buffer_put_bignum(&encrypted, key->n); | 126 | buffer_put_bignum(&encrypted, key->rsa->n); |
127 | buffer_put_bignum(&encrypted, key->e); | 127 | buffer_put_bignum(&encrypted, key->rsa->e); |
128 | buffer_put_string(&encrypted, comment, strlen(comment)); | 128 | buffer_put_string(&encrypted, comment, strlen(comment)); |
129 | 129 | ||
130 | /* Allocate space for the private part of the key in the buffer. */ | 130 | /* Allocate space for the private part of the key in the buffer. */ |
@@ -156,10 +156,10 @@ save_private_key_rsa1(const char *filename, const char *passphrase, | |||
156 | return 1; | 156 | return 1; |
157 | } | 157 | } |
158 | 158 | ||
159 | /* save SSH2 key in OpenSSL PEM format */ | 159 | /* save SSH v2 key in OpenSSL PEM format */ |
160 | int | 160 | int |
161 | save_private_key_ssh2(const char *filename, const char *_passphrase, | 161 | key_save_private_pem(Key *key, const char *filename, const char *_passphrase, |
162 | Key *key, const char *comment) | 162 | const char *comment) |
163 | { | 163 | { |
164 | FILE *fp; | 164 | FILE *fp; |
165 | int fd; | 165 | int fd; |
@@ -199,16 +199,18 @@ save_private_key_ssh2(const char *filename, const char *_passphrase, | |||
199 | } | 199 | } |
200 | 200 | ||
201 | int | 201 | int |
202 | save_private_key(const char *filename, const char *passphrase, Key *key, | 202 | key_save_private(Key *key, const char *filename, const char *passphrase, |
203 | const char *comment) | 203 | const char *comment) |
204 | { | 204 | { |
205 | switch (key->type) { | 205 | switch (key->type) { |
206 | case KEY_RSA1: | 206 | case KEY_RSA1: |
207 | return save_private_key_rsa1(filename, passphrase, key->rsa, comment); | 207 | return key_save_private_rsa1(key, filename, passphrase, |
208 | comment); | ||
208 | break; | 209 | break; |
209 | case KEY_DSA: | 210 | case KEY_DSA: |
210 | case KEY_RSA: | 211 | case KEY_RSA: |
211 | return save_private_key_ssh2(filename, passphrase, key, comment); | 212 | return key_save_private_pem(key, filename, passphrase, |
213 | comment); | ||
212 | break; | 214 | break; |
213 | default: | 215 | default: |
214 | break; | 216 | break; |
@@ -217,22 +219,20 @@ save_private_key(const char *filename, const char *passphrase, Key *key, | |||
217 | } | 219 | } |
218 | 220 | ||
219 | /* | 221 | /* |
220 | * Loads the public part of the key file. Returns 0 if an error was | 222 | * Loads the public part of the ssh v1 key file. Returns NULL if an error was |
221 | * encountered (the file does not exist or is not readable), and non-zero | 223 | * encountered (the file does not exist or is not readable), and the key |
222 | * otherwise. | 224 | * otherwise. |
223 | */ | 225 | */ |
224 | 226 | ||
225 | int | 227 | Key * |
226 | load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) | 228 | key_load_public_rsa1(int fd, const char *filename, char **commentp) |
227 | { | 229 | { |
228 | int fd, i; | ||
229 | off_t len; | ||
230 | Buffer buffer; | 230 | Buffer buffer; |
231 | Key *pub; | ||
231 | char *cp; | 232 | char *cp; |
233 | int i; | ||
234 | off_t len; | ||
232 | 235 | ||
233 | fd = open(filename, O_RDONLY); | ||
234 | if (fd < 0) | ||
235 | return 0; | ||
236 | len = lseek(fd, (off_t) 0, SEEK_END); | 236 | len = lseek(fd, (off_t) 0, SEEK_END); |
237 | lseek(fd, (off_t) 0, SEEK_SET); | 237 | lseek(fd, (off_t) 0, SEEK_SET); |
238 | 238 | ||
@@ -243,16 +243,14 @@ load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) | |||
243 | debug("Read from key file %.200s failed: %.100s", filename, | 243 | debug("Read from key file %.200s failed: %.100s", filename, |
244 | strerror(errno)); | 244 | strerror(errno)); |
245 | buffer_free(&buffer); | 245 | buffer_free(&buffer); |
246 | close(fd); | 246 | return NULL; |
247 | return 0; | ||
248 | } | 247 | } |
249 | close(fd); | ||
250 | 248 | ||
251 | /* Check that it is at least big enough to contain the ID string. */ | 249 | /* Check that it is at least big enough to contain the ID string. */ |
252 | if (len < sizeof(authfile_id_string)) { | 250 | if (len < sizeof(authfile_id_string)) { |
253 | debug3("Bad RSA1 key file %.200s.", filename); | 251 | debug3("Bad RSA1 key file %.200s.", filename); |
254 | buffer_free(&buffer); | 252 | buffer_free(&buffer); |
255 | return 0; | 253 | return NULL; |
256 | } | 254 | } |
257 | /* | 255 | /* |
258 | * Make sure it begins with the id string. Consume the id string | 256 | * Make sure it begins with the id string. Consume the id string |
@@ -262,7 +260,7 @@ load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) | |||
262 | if (buffer_get_char(&buffer) != authfile_id_string[i]) { | 260 | if (buffer_get_char(&buffer) != authfile_id_string[i]) { |
263 | debug3("Bad RSA1 key file %.200s.", filename); | 261 | debug3("Bad RSA1 key file %.200s.", filename); |
264 | buffer_free(&buffer); | 262 | buffer_free(&buffer); |
265 | return 0; | 263 | return NULL; |
266 | } | 264 | } |
267 | /* Skip cipher type and reserved data. */ | 265 | /* Skip cipher type and reserved data. */ |
268 | (void) buffer_get_char(&buffer); /* cipher type */ | 266 | (void) buffer_get_char(&buffer); /* cipher type */ |
@@ -270,37 +268,33 @@ load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) | |||
270 | 268 | ||
271 | /* Read the public key from the buffer. */ | 269 | /* Read the public key from the buffer. */ |
272 | buffer_get_int(&buffer); | 270 | buffer_get_int(&buffer); |
273 | /* XXX alloc */ | 271 | pub = key_new(KEY_RSA1); |
274 | if (pub->n == NULL) | 272 | buffer_get_bignum(&buffer, pub->rsa->n); |
275 | pub->n = BN_new(); | 273 | buffer_get_bignum(&buffer, pub->rsa->e); |
276 | buffer_get_bignum(&buffer, pub->n); | 274 | if (commentp) |
277 | /* XXX alloc */ | 275 | *commentp = buffer_get_string(&buffer, NULL); |
278 | if (pub->e == NULL) | ||
279 | pub->e = BN_new(); | ||
280 | buffer_get_bignum(&buffer, pub->e); | ||
281 | if (comment_return) | ||
282 | *comment_return = buffer_get_string(&buffer, NULL); | ||
283 | /* The encrypted private part is not parsed by this function. */ | 276 | /* The encrypted private part is not parsed by this function. */ |
284 | 277 | ||
285 | buffer_free(&buffer); | 278 | buffer_free(&buffer); |
286 | 279 | return pub; | |
287 | return 1; | ||
288 | } | 280 | } |
289 | 281 | ||
290 | /* load public key from private-key file */ | 282 | /* load public key from private-key file, works only for SSH v1 */ |
291 | int | 283 | Key * |
292 | load_public_key(const char *filename, Key * key, char **comment_return) | 284 | key_load_public_type(int type, const char *filename, char **commentp) |
293 | { | 285 | { |
294 | switch (key->type) { | 286 | Key *pub; |
295 | case KEY_RSA1: | 287 | int fd; |
296 | return load_public_key_rsa(filename, key->rsa, comment_return); | 288 | |
297 | break; | 289 | if (type == KEY_RSA1) { |
298 | case KEY_DSA: | 290 | fd = open(filename, O_RDONLY); |
299 | case KEY_RSA: | 291 | if (fd < 0) |
300 | default: | 292 | return NULL; |
301 | break; | 293 | pub = key_load_public_rsa1(fd, filename, commentp); |
294 | close(fd); | ||
295 | return pub; | ||
302 | } | 296 | } |
303 | return 0; | 297 | return NULL; |
304 | } | 298 | } |
305 | 299 | ||
306 | /* | 300 | /* |
@@ -310,9 +304,9 @@ load_public_key(const char *filename, Key * key, char **comment_return) | |||
310 | * Assumes we are called under uid of the owner of the file. | 304 | * Assumes we are called under uid of the owner of the file. |
311 | */ | 305 | */ |
312 | 306 | ||
313 | int | 307 | Key * |
314 | load_private_key_rsa1(int fd, const char *filename, | 308 | key_load_private_rsa1(int fd, const char *filename, const char *passphrase, |
315 | const char *passphrase, RSA * prv, char **comment_return) | 309 | char **commentp) |
316 | { | 310 | { |
317 | int i, check1, check2, cipher_type; | 311 | int i, check1, check2, cipher_type; |
318 | off_t len; | 312 | off_t len; |
@@ -322,6 +316,7 @@ load_private_key_rsa1(int fd, const char *filename, | |||
322 | Cipher *cipher; | 316 | Cipher *cipher; |
323 | BN_CTX *ctx; | 317 | BN_CTX *ctx; |
324 | BIGNUM *aux; | 318 | BIGNUM *aux; |
319 | Key *prv = NULL; | ||
325 | 320 | ||
326 | len = lseek(fd, (off_t) 0, SEEK_END); | 321 | len = lseek(fd, (off_t) 0, SEEK_END); |
327 | lseek(fd, (off_t) 0, SEEK_SET); | 322 | lseek(fd, (off_t) 0, SEEK_SET); |
@@ -334,7 +329,7 @@ load_private_key_rsa1(int fd, const char *filename, | |||
334 | strerror(errno)); | 329 | strerror(errno)); |
335 | buffer_free(&buffer); | 330 | buffer_free(&buffer); |
336 | close(fd); | 331 | close(fd); |
337 | return 0; | 332 | return NULL; |
338 | } | 333 | } |
339 | 334 | ||
340 | /* Check that it is at least big enough to contain the ID string. */ | 335 | /* Check that it is at least big enough to contain the ID string. */ |
@@ -342,7 +337,7 @@ load_private_key_rsa1(int fd, const char *filename, | |||
342 | debug3("Bad RSA1 key file %.200s.", filename); | 337 | debug3("Bad RSA1 key file %.200s.", filename); |
343 | buffer_free(&buffer); | 338 | buffer_free(&buffer); |
344 | close(fd); | 339 | close(fd); |
345 | return 0; | 340 | return NULL; |
346 | } | 341 | } |
347 | /* | 342 | /* |
348 | * Make sure it begins with the id string. Consume the id string | 343 | * Make sure it begins with the id string. Consume the id string |
@@ -353,7 +348,7 @@ load_private_key_rsa1(int fd, const char *filename, | |||
353 | debug3("Bad RSA1 key file %.200s.", filename); | 348 | debug3("Bad RSA1 key file %.200s.", filename); |
354 | buffer_free(&buffer); | 349 | buffer_free(&buffer); |
355 | close(fd); | 350 | close(fd); |
356 | return 0; | 351 | return NULL; |
357 | } | 352 | } |
358 | 353 | ||
359 | /* Read cipher type. */ | 354 | /* Read cipher type. */ |
@@ -362,12 +357,12 @@ load_private_key_rsa1(int fd, const char *filename, | |||
362 | 357 | ||
363 | /* Read the public key from the buffer. */ | 358 | /* Read the public key from the buffer. */ |
364 | buffer_get_int(&buffer); | 359 | buffer_get_int(&buffer); |
365 | prv->n = BN_new(); | 360 | prv = key_new_private(KEY_RSA1); |
366 | buffer_get_bignum(&buffer, prv->n); | 361 | |
367 | prv->e = BN_new(); | 362 | buffer_get_bignum(&buffer, prv->rsa->n); |
368 | buffer_get_bignum(&buffer, prv->e); | 363 | buffer_get_bignum(&buffer, prv->rsa->e); |
369 | if (comment_return) | 364 | if (commentp) |
370 | *comment_return = buffer_get_string(&buffer, NULL); | 365 | *commentp = buffer_get_string(&buffer, NULL); |
371 | else | 366 | else |
372 | xfree(buffer_get_string(&buffer, NULL)); | 367 | xfree(buffer_get_string(&buffer, NULL)); |
373 | 368 | ||
@@ -395,93 +390,81 @@ load_private_key_rsa1(int fd, const char *filename, | |||
395 | if (check1 != buffer_get_char(&decrypted) || | 390 | if (check1 != buffer_get_char(&decrypted) || |
396 | check2 != buffer_get_char(&decrypted)) { | 391 | check2 != buffer_get_char(&decrypted)) { |
397 | if (strcmp(passphrase, "") != 0) | 392 | if (strcmp(passphrase, "") != 0) |
398 | debug("Bad passphrase supplied for key file %.200s.", filename); | 393 | debug("Bad passphrase supplied for key file %.200s.", |
394 | filename); | ||
399 | /* Bad passphrase. */ | 395 | /* Bad passphrase. */ |
400 | buffer_free(&decrypted); | 396 | buffer_free(&decrypted); |
401 | fail: | 397 | goto fail; |
402 | BN_clear_free(prv->n); | ||
403 | prv->n = NULL; | ||
404 | BN_clear_free(prv->e); | ||
405 | prv->e = NULL; | ||
406 | if (comment_return) | ||
407 | xfree(*comment_return); | ||
408 | close(fd); | ||
409 | return 0; | ||
410 | } | 398 | } |
411 | /* Read the rest of the private key. */ | 399 | /* Read the rest of the private key. */ |
412 | prv->d = BN_new(); | 400 | buffer_get_bignum(&decrypted, prv->rsa->d); |
413 | buffer_get_bignum(&decrypted, prv->d); | 401 | buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */ |
414 | prv->iqmp = BN_new(); | 402 | /* in SSL and SSH v1 p and q are exchanged */ |
415 | buffer_get_bignum(&decrypted, prv->iqmp); /* u */ | 403 | buffer_get_bignum(&decrypted, prv->rsa->q); /* p */ |
416 | /* in SSL and SSH p and q are exchanged */ | 404 | buffer_get_bignum(&decrypted, prv->rsa->p); /* q */ |
417 | prv->q = BN_new(); | ||
418 | buffer_get_bignum(&decrypted, prv->q); /* p */ | ||
419 | prv->p = BN_new(); | ||
420 | buffer_get_bignum(&decrypted, prv->p); /* q */ | ||
421 | 405 | ||
406 | /* calculate p-1 and q-1 */ | ||
422 | ctx = BN_CTX_new(); | 407 | ctx = BN_CTX_new(); |
423 | aux = BN_new(); | 408 | aux = BN_new(); |
424 | 409 | ||
425 | BN_sub(aux, prv->q, BN_value_one()); | 410 | BN_sub(aux, prv->rsa->q, BN_value_one()); |
426 | prv->dmq1 = BN_new(); | 411 | BN_mod(prv->rsa->dmq1, prv->rsa->d, aux, ctx); |
427 | BN_mod(prv->dmq1, prv->d, aux, ctx); | ||
428 | 412 | ||
429 | BN_sub(aux, prv->p, BN_value_one()); | 413 | BN_sub(aux, prv->rsa->p, BN_value_one()); |
430 | prv->dmp1 = BN_new(); | 414 | BN_mod(prv->rsa->dmp1, prv->rsa->d, aux, ctx); |
431 | BN_mod(prv->dmp1, prv->d, aux, ctx); | ||
432 | 415 | ||
433 | BN_clear_free(aux); | 416 | BN_clear_free(aux); |
434 | BN_CTX_free(ctx); | 417 | BN_CTX_free(ctx); |
435 | 418 | ||
436 | buffer_free(&decrypted); | 419 | buffer_free(&decrypted); |
437 | close(fd); | 420 | close(fd); |
438 | return 1; | 421 | return prv; |
422 | |||
423 | fail: | ||
424 | if (commentp) | ||
425 | xfree(*commentp); | ||
426 | close(fd); | ||
427 | key_free(prv); | ||
428 | return NULL; | ||
439 | } | 429 | } |
440 | 430 | ||
441 | int | 431 | Key * |
442 | load_private_key_ssh2(int fd, const char *passphrase, Key *k, char **comment_return) | 432 | key_load_private_pem(int fd, int type, const char *passphrase, |
433 | char **commentp) | ||
443 | { | 434 | { |
444 | FILE *fp; | 435 | FILE *fp; |
445 | int success = 0; | ||
446 | EVP_PKEY *pk = NULL; | 436 | EVP_PKEY *pk = NULL; |
437 | Key *prv = NULL; | ||
447 | char *name = "<no key>"; | 438 | char *name = "<no key>"; |
448 | 439 | ||
449 | fp = fdopen(fd, "r"); | 440 | fp = fdopen(fd, "r"); |
450 | if (fp == NULL) { | 441 | if (fp == NULL) { |
451 | error("fdopen failed"); | 442 | error("fdopen failed"); |
452 | close(fd); | 443 | close(fd); |
453 | return 0; | 444 | return NULL; |
454 | } | 445 | } |
455 | pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); | 446 | pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); |
456 | if (pk == NULL) { | 447 | if (pk == NULL) { |
457 | debug("PEM_read_PrivateKey failed"); | 448 | debug("PEM_read_PrivateKey failed"); |
458 | (void)ERR_get_error(); | 449 | (void)ERR_get_error(); |
459 | } else if (pk->type == EVP_PKEY_RSA) { | 450 | } else if (pk->type == EVP_PKEY_RSA && |
460 | /* replace k->rsa with loaded key */ | 451 | (type == KEY_UNSPEC||type==KEY_RSA)) { |
461 | if (k->type == KEY_RSA || k->type == KEY_UNSPEC) { | 452 | prv = key_new(KEY_UNSPEC); |
462 | if (k->rsa != NULL) | 453 | prv->rsa = EVP_PKEY_get1_RSA(pk); |
463 | RSA_free(k->rsa); | 454 | prv->type = KEY_RSA; |
464 | k->rsa = EVP_PKEY_get1_RSA(pk); | 455 | name = "rsa w/o comment"; |
465 | k->type = KEY_RSA; | ||
466 | name = "rsa w/o comment"; | ||
467 | success = 1; | ||
468 | #ifdef DEBUG_PK | 456 | #ifdef DEBUG_PK |
469 | RSA_print_fp(stderr, k->rsa, 8); | 457 | RSA_print_fp(stderr, prv->rsa, 8); |
470 | #endif | 458 | #endif |
471 | } | 459 | } else if (pk->type == EVP_PKEY_DSA && |
472 | } else if (pk->type == EVP_PKEY_DSA) { | 460 | (type == KEY_UNSPEC||type==KEY_DSA)) { |
473 | /* replace k->dsa with loaded key */ | 461 | prv = key_new(KEY_UNSPEC); |
474 | if (k->type == KEY_DSA || k->type == KEY_UNSPEC) { | 462 | prv->dsa = EVP_PKEY_get1_DSA(pk); |
475 | if (k->dsa != NULL) | 463 | prv->type = KEY_DSA; |
476 | DSA_free(k->dsa); | 464 | name = "dsa w/o comment"; |
477 | k->dsa = EVP_PKEY_get1_DSA(pk); | ||
478 | k->type = KEY_DSA; | ||
479 | name = "dsa w/o comment"; | ||
480 | #ifdef DEBUG_PK | 465 | #ifdef DEBUG_PK |
481 | DSA_print_fp(stderr, k->dsa, 8); | 466 | DSA_print_fp(stderr, prv->dsa, 8); |
482 | #endif | 467 | #endif |
483 | success = 1; | ||
484 | } | ||
485 | } else { | 468 | } else { |
486 | error("PEM_read_PrivateKey: mismatch or " | 469 | error("PEM_read_PrivateKey: mismatch or " |
487 | "unknown EVP_PKEY save_type %d", pk->save_type); | 470 | "unknown EVP_PKEY save_type %d", pk->save_type); |
@@ -489,24 +472,18 @@ load_private_key_ssh2(int fd, const char *passphrase, Key *k, char **comment_ret | |||
489 | fclose(fp); | 472 | fclose(fp); |
490 | if (pk != NULL) | 473 | if (pk != NULL) |
491 | EVP_PKEY_free(pk); | 474 | EVP_PKEY_free(pk); |
492 | if (success && comment_return) | 475 | if (prv != NULL && commentp) |
493 | *comment_return = xstrdup(name); | 476 | *commentp = xstrdup(name); |
494 | debug("read SSH2 private key done: name %s success %d", name, success); | 477 | debug("read PEM private key done: type %s", |
495 | return success; | 478 | prv ? key_type(prv) : "<unknown>"); |
479 | return prv; | ||
496 | } | 480 | } |
497 | 481 | ||
498 | int | 482 | int |
499 | load_private_key(const char *filename, const char *passphrase, Key *key, | 483 | key_perm_ok(int fd, const char *filename) |
500 | char **comment_return) | ||
501 | { | 484 | { |
502 | int fd; | ||
503 | int ret = 0; | ||
504 | struct stat st; | 485 | struct stat st; |
505 | 486 | ||
506 | fd = open(filename, O_RDONLY); | ||
507 | if (fd < 0) | ||
508 | return 0; | ||
509 | |||
510 | /* check owner and modes */ | 487 | /* check owner and modes */ |
511 | #ifdef HAVE_CYGWIN | 488 | #ifdef HAVE_CYGWIN |
512 | if (check_ntsec(filename)) | 489 | if (check_ntsec(filename)) |
@@ -521,40 +498,78 @@ load_private_key(const char *filename, const char *passphrase, Key *key, | |||
521 | error("Bad ownership or mode(0%3.3o) for '%s'.", | 498 | error("Bad ownership or mode(0%3.3o) for '%s'.", |
522 | st.st_mode & 0777, filename); | 499 | st.st_mode & 0777, filename); |
523 | error("It is recommended that your private key files are NOT accessible by others."); | 500 | error("It is recommended that your private key files are NOT accessible by others."); |
501 | error("This private key will be ignored."); | ||
524 | return 0; | 502 | return 0; |
525 | } | 503 | } |
526 | switch (key->type) { | 504 | return 1; |
527 | case KEY_RSA1: | 505 | } |
528 | if (key->rsa->e != NULL) { | ||
529 | BN_clear_free(key->rsa->e); | ||
530 | key->rsa->e = NULL; | ||
531 | } | ||
532 | if (key->rsa->n != NULL) { | ||
533 | BN_clear_free(key->rsa->n); | ||
534 | key->rsa->n = NULL; | ||
535 | } | ||
536 | ret = load_private_key_rsa1(fd, filename, passphrase, | ||
537 | key->rsa, comment_return); /* closes fd */ | ||
538 | 506 | ||
507 | Key * | ||
508 | key_load_private_type(int type, const char *filename, const char *passphrase, | ||
509 | char **commentp) | ||
510 | { | ||
511 | int fd; | ||
512 | |||
513 | fd = open(filename, O_RDONLY); | ||
514 | if (fd < 0) | ||
515 | return NULL; | ||
516 | if (!key_perm_ok(fd, filename)) { | ||
517 | debug("bad permissions: ignore key: %s", filename); | ||
518 | close(fd); | ||
519 | return NULL; | ||
520 | } | ||
521 | switch (type) { | ||
522 | case KEY_RSA1: | ||
523 | return key_load_private_rsa1(fd, filename, passphrase, | ||
524 | commentp); | ||
525 | /* closes fd */ | ||
539 | break; | 526 | break; |
540 | case KEY_DSA: | 527 | case KEY_DSA: |
541 | case KEY_RSA: | 528 | case KEY_RSA: |
542 | case KEY_UNSPEC: | 529 | case KEY_UNSPEC: |
543 | ret = load_private_key_ssh2(fd, passphrase, key, | 530 | return key_load_private_pem(fd, type, passphrase, commentp); |
544 | comment_return); /* closes fd */ | 531 | /* closes fd */ |
545 | break; | 532 | break; |
546 | default: | 533 | default: |
547 | close(fd); | 534 | close(fd); |
548 | break; | 535 | break; |
549 | } | 536 | } |
550 | return ret; | 537 | return NULL; |
538 | } | ||
539 | |||
540 | Key * | ||
541 | key_load_private(const char *filename, const char *passphrase, | ||
542 | char **commentp) | ||
543 | { | ||
544 | Key *pub; | ||
545 | int fd; | ||
546 | |||
547 | fd = open(filename, O_RDONLY); | ||
548 | if (fd < 0) | ||
549 | return NULL; | ||
550 | if (!key_perm_ok(fd, filename)) { | ||
551 | debug("bad permissions: ignore key: %s", filename); | ||
552 | close(fd); | ||
553 | return NULL; | ||
554 | } | ||
555 | pub = key_load_public_rsa1(fd, filename, commentp); | ||
556 | lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ | ||
557 | if (pub == NULL) { | ||
558 | /* closes fd */ | ||
559 | return key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL); | ||
560 | } else { | ||
561 | /* it's a SSH v1 key if the public key part is readable */ | ||
562 | key_free(pub); | ||
563 | /* closes fd */ | ||
564 | return key_load_private_rsa1(fd, filename, passphrase, NULL); | ||
565 | } | ||
551 | } | 566 | } |
552 | 567 | ||
553 | int | 568 | int |
554 | do_load_public_key(const char *filename, Key *k, char **commentp) | 569 | key_try_load_public(Key *k, const char *filename, char **commentp) |
555 | { | 570 | { |
556 | FILE *f; | 571 | FILE *f; |
557 | char line[1024]; | 572 | char line[4096]; |
558 | char *cp; | 573 | char *cp; |
559 | 574 | ||
560 | f = fopen(filename, "r"); | 575 | f = fopen(filename, "r"); |
@@ -585,19 +600,23 @@ do_load_public_key(const char *filename, Key *k, char **commentp) | |||
585 | return 0; | 600 | return 0; |
586 | } | 601 | } |
587 | 602 | ||
588 | /* load public key from pubkey file */ | 603 | /* load public key from ssh v1 private or any pubkey file */ |
589 | int | 604 | Key * |
590 | try_load_public_key(const char *filename, Key *k, char **commentp) | 605 | key_load_public(const char *filename, char **commentp) |
591 | { | 606 | { |
592 | char pub[MAXPATHLEN]; | 607 | Key *pub; |
593 | 608 | char file[MAXPATHLEN]; | |
594 | if (do_load_public_key(filename, k, commentp) == 1) | 609 | |
595 | return 1; | 610 | pub = key_load_public_type(KEY_RSA1, filename, commentp); |
596 | if (strlcpy(pub, filename, sizeof pub) >= MAXPATHLEN) | 611 | if (pub != NULL) |
597 | return 0; | 612 | return pub; |
598 | if (strlcat(pub, ".pub", sizeof pub) >= MAXPATHLEN) | 613 | pub = key_new(KEY_UNSPEC); |
599 | return 0; | 614 | if (key_try_load_public(pub, filename, commentp) == 1) |
600 | if (do_load_public_key(pub, k, commentp) == 1) | 615 | return pub; |
601 | return 1; | 616 | if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && |
602 | return 0; | 617 | (strlcat(file, ".pub", sizeof file) < sizeof(file)) && |
618 | (key_try_load_public(pub, file, commentp) == 1)) | ||
619 | return pub; | ||
620 | key_free(pub); | ||
621 | return NULL; | ||
603 | } | 622 | } |
diff --git a/authfile.h b/authfile.h index 525b4aa5b..da90cd913 100644 --- a/authfile.h +++ b/authfile.h | |||
@@ -2,7 +2,6 @@ | |||
2 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 2 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
5 | * Functions to interface with the SSH_AUTHENTICATION_FD socket. | ||
6 | * | 5 | * |
7 | * As far as I am concerned, the code I have written for this software | 6 | * As far as I am concerned, the code I have written for this software |
8 | * can be used freely for any purpose. Any derived versions of this | 7 | * can be used freely for any purpose. Any derived versions of this |
@@ -11,41 +10,27 @@ | |||
11 | * called by a name other than "ssh" or "Secure Shell". | 10 | * called by a name other than "ssh" or "Secure Shell". |
12 | */ | 11 | */ |
13 | 12 | ||
14 | /* $OpenBSD: authfile.h,v 1.5 2000/10/16 09:38:44 djm Exp $ */ | 13 | /* $OpenBSD: authfile.h,v 1.6 2001/03/26 08:07:08 markus Exp $ */ |
15 | 14 | ||
16 | #ifndef AUTHFILE_H | 15 | #ifndef AUTHFILE_H |
17 | #define AUTHFILE_H | 16 | #define AUTHFILE_H |
18 | 17 | ||
19 | |||
20 | /* | ||
21 | * Saves the authentication (private) key in a file, encrypting it with | ||
22 | * passphrase. | ||
23 | * For RSA keys: The identification of the file (lowest 64 bits of n) | ||
24 | * will precede the key to provide identification of the key without | ||
25 | * needing a passphrase. | ||
26 | */ | ||
27 | int | 18 | int |
28 | save_private_key(const char *filename, const char *passphrase, | 19 | key_save_private(Key *key, const char *filename, const char *passphrase, |
29 | Key * private_key, const char *comment); | 20 | const char *comment); |
30 | 21 | ||
31 | /* | 22 | Key * |
32 | * Loads the public part of the key file (public key and comment). Returns 0 | 23 | key_load_public(const char *filename, char **commentp); |
33 | * if an error occurred; zero if the public key was successfully read. The | ||
34 | * comment of the key is returned in comment_return if it is non-NULL; the | ||
35 | * caller must free the value with xfree. | ||
36 | */ | ||
37 | int load_public_key(const char *filename, Key * pub, char **comment_return); | ||
38 | int try_load_public_key(const char *filename, Key * pub, char **comment_return); | ||
39 | 24 | ||
40 | /* | 25 | Key * |
41 | * Loads the private key from the file. Returns 0 if an error is encountered | 26 | key_load_public_type(int type, const char *filename, char **commentp); |
42 | * (file does not exist or is not readable, or passphrase is bad). This | 27 | |
43 | * initializes the private key. The comment of the key is returned in | 28 | Key * |
44 | * comment_return if it is non-NULL; the caller must free the value with | 29 | key_load_private(const char *filename, const char *passphrase, |
45 | * xfree. | 30 | char **commentp); |
46 | */ | 31 | |
47 | int | 32 | Key * |
48 | load_private_key(const char *filename, const char *passphrase, | 33 | key_load_private_type(int type, const char *filename, const char *passphrase, |
49 | Key * private_key, char **comment_return); | 34 | char **commentp); |
50 | 35 | ||
51 | #endif | 36 | #endif |
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "includes.h" | 37 | #include "includes.h" |
38 | RCSID("$OpenBSD: ssh-add.c,v 1.30 2001/03/12 22:02:02 markus Exp $"); | 38 | RCSID("$OpenBSD: ssh-add.c,v 1.31 2001/03/26 08:07:08 markus Exp $"); |
39 | 39 | ||
40 | #include <openssl/evp.h> | 40 | #include <openssl/evp.h> |
41 | 41 | ||
@@ -61,14 +61,10 @@ delete_file(AuthenticationConnection *ac, const char *filename) | |||
61 | Key *public; | 61 | Key *public; |
62 | char *comment; | 62 | char *comment; |
63 | 63 | ||
64 | public = key_new(KEY_RSA1); | 64 | public = key_load_public(filename, &comment); |
65 | if (!load_public_key(filename, public, &comment)) { | 65 | if (public == NULL) { |
66 | key_free(public); | 66 | printf("Bad key file %s\n", filename); |
67 | public = key_new(KEY_UNSPEC); | 67 | return; |
68 | if (!try_load_public_key(filename, public, &comment)) { | ||
69 | printf("Bad key file %s\n", filename); | ||
70 | return; | ||
71 | } | ||
72 | } | 68 | } |
73 | if (ssh_remove_identity(ac, public)) | 69 | if (ssh_remove_identity(ac, public)) |
74 | fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); | 70 | fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); |
@@ -139,30 +135,15 @@ void | |||
139 | add_file(AuthenticationConnection *ac, const char *filename) | 135 | add_file(AuthenticationConnection *ac, const char *filename) |
140 | { | 136 | { |
141 | struct stat st; | 137 | struct stat st; |
142 | Key *public; | ||
143 | Key *private; | 138 | Key *private; |
144 | char *saved_comment, *comment, *askpass = NULL; | 139 | char *comment, *askpass = NULL, *pass; |
145 | char buf[1024], msg[1024]; | 140 | char buf[1024], msg[1024]; |
146 | int success; | ||
147 | int interactive = isatty(STDIN_FILENO); | 141 | int interactive = isatty(STDIN_FILENO); |
148 | int type = KEY_RSA1; | ||
149 | 142 | ||
150 | if (stat(filename, &st) < 0) { | 143 | if (stat(filename, &st) < 0) { |
151 | perror(filename); | 144 | perror(filename); |
152 | exit(1); | 145 | exit(1); |
153 | } | 146 | } |
154 | /* | ||
155 | * try to load the public key. right now this only works for RSA, | ||
156 | * since DSA keys are fully encrypted | ||
157 | */ | ||
158 | public = key_new(KEY_RSA1); | ||
159 | if (!load_public_key(filename, public, &saved_comment)) { | ||
160 | /* ok, so we will assume this is 'some' key */ | ||
161 | type = KEY_UNSPEC; | ||
162 | saved_comment = xstrdup(filename); | ||
163 | } | ||
164 | key_free(public); | ||
165 | |||
166 | if (!interactive && getenv("DISPLAY")) { | 147 | if (!interactive && getenv("DISPLAY")) { |
167 | if (getenv(SSH_ASKPASS_ENV)) | 148 | if (getenv(SSH_ASKPASS_ENV)) |
168 | askpass = getenv(SSH_ASKPASS_ENV); | 149 | askpass = getenv(SSH_ASKPASS_ENV); |
@@ -171,17 +152,17 @@ add_file(AuthenticationConnection *ac, const char *filename) | |||
171 | } | 152 | } |
172 | 153 | ||
173 | /* At first, try empty passphrase */ | 154 | /* At first, try empty passphrase */ |
174 | private = key_new(type); | 155 | private = key_load_private(filename, "", &comment); |
175 | success = load_private_key(filename, "", private, &comment); | 156 | if (comment == NULL) |
176 | if (!success) { | 157 | comment = xstrdup(filename); |
158 | if (private == NULL) { | ||
177 | printf("Need passphrase for %.200s\n", filename); | 159 | printf("Need passphrase for %.200s\n", filename); |
178 | if (!interactive && askpass == NULL) { | 160 | if (!interactive && askpass == NULL) { |
179 | xfree(saved_comment); | 161 | xfree(comment); |
180 | return; | 162 | return; |
181 | } | 163 | } |
182 | snprintf(msg, sizeof msg, "Enter passphrase for %.200s", saved_comment); | 164 | snprintf(msg, sizeof msg, "Enter passphrase for %.200s", comment); |
183 | for (;;) { | 165 | for (;;) { |
184 | char *pass; | ||
185 | if (interactive) { | 166 | if (interactive) { |
186 | snprintf(buf, sizeof buf, "%s: ", msg); | 167 | snprintf(buf, sizeof buf, "%s: ", msg); |
187 | pass = read_passphrase(buf, 1); | 168 | pass = read_passphrase(buf, 1); |
@@ -190,24 +171,23 @@ add_file(AuthenticationConnection *ac, const char *filename) | |||
190 | } | 171 | } |
191 | if (strcmp(pass, "") == 0) { | 172 | if (strcmp(pass, "") == 0) { |
192 | xfree(pass); | 173 | xfree(pass); |
193 | xfree(saved_comment); | 174 | xfree(comment); |
194 | return; | 175 | return; |
195 | } | 176 | } |
196 | success = load_private_key(filename, pass, private, &comment); | 177 | private = key_load_private(filename, pass, &comment); |
197 | memset(pass, 0, strlen(pass)); | 178 | memset(pass, 0, strlen(pass)); |
198 | xfree(pass); | 179 | xfree(pass); |
199 | if (success) | 180 | if (private != NULL) |
200 | break; | 181 | break; |
201 | strlcpy(msg, "Bad passphrase, try again", sizeof msg); | 182 | strlcpy(msg, "Bad passphrase, try again", sizeof msg); |
202 | } | 183 | } |
203 | } | 184 | } |
204 | xfree(comment); | 185 | if (ssh_add_identity(ac, private, comment)) |
205 | if (ssh_add_identity(ac, private, saved_comment)) | 186 | fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); |
206 | fprintf(stderr, "Identity added: %s (%s)\n", filename, saved_comment); | ||
207 | else | 187 | else |
208 | fprintf(stderr, "Could not add identity: %s\n", filename); | 188 | fprintf(stderr, "Could not add identity: %s\n", filename); |
189 | xfree(comment); | ||
209 | key_free(private); | 190 | key_free(private); |
210 | xfree(saved_comment); | ||
211 | } | 191 | } |
212 | 192 | ||
213 | void | 193 | void |
diff --git a/ssh-keygen.c b/ssh-keygen.c index 7d04dd6c1..b3074e8de 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$OpenBSD: ssh-keygen.c,v 1.51 2001/03/21 14:20:45 jakob Exp $"); | 15 | RCSID("$OpenBSD: ssh-keygen.c,v 1.52 2001/03/26 08:07:09 markus Exp $"); |
16 | 16 | ||
17 | #include <openssl/evp.h> | 17 | #include <openssl/evp.h> |
18 | #include <openssl/pem.h> | 18 | #include <openssl/pem.h> |
@@ -111,19 +111,20 @@ ask_filename(struct passwd *pw, const char *prompt) | |||
111 | have_identity = 1; | 111 | have_identity = 1; |
112 | } | 112 | } |
113 | 113 | ||
114 | int | 114 | Key * |
115 | try_load_key(char *filename, Key *k) | 115 | try_load_pem_key(char *filename) |
116 | { | 116 | { |
117 | int success = 1; | 117 | char *pass; |
118 | if (!load_private_key(filename, "", k, NULL)) { | 118 | Key *prv; |
119 | char *pass = read_passphrase("Enter passphrase: ", 1); | 119 | |
120 | if (!load_private_key(filename, pass, k, NULL)) { | 120 | prv = key_load_private(filename, "", NULL); |
121 | success = 0; | 121 | if (prv == NULL) { |
122 | } | 122 | pass = read_passphrase("Enter passphrase: ", 1); |
123 | prv = key_load_private(filename, pass, NULL); | ||
123 | memset(pass, 0, strlen(pass)); | 124 | memset(pass, 0, strlen(pass)); |
124 | xfree(pass); | 125 | xfree(pass); |
125 | } | 126 | } |
126 | return success; | 127 | return prv; |
127 | } | 128 | } |
128 | 129 | ||
129 | #define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" | 130 | #define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" |
@@ -134,7 +135,7 @@ try_load_key(char *filename, Key *k) | |||
134 | void | 135 | void |
135 | do_convert_to_ssh2(struct passwd *pw) | 136 | do_convert_to_ssh2(struct passwd *pw) |
136 | { | 137 | { |
137 | Key *k; | 138 | Key *prv; |
138 | int len; | 139 | int len; |
139 | u_char *blob; | 140 | u_char *blob; |
140 | struct stat st; | 141 | struct stat st; |
@@ -145,20 +146,20 @@ do_convert_to_ssh2(struct passwd *pw) | |||
145 | perror(identity_file); | 146 | perror(identity_file); |
146 | exit(1); | 147 | exit(1); |
147 | } | 148 | } |
148 | k = key_new(KEY_UNSPEC); | 149 | prv = try_load_pem_key(identity_file); |
149 | if (!try_load_key(identity_file, k)) { | 150 | if (prv == NULL) { |
150 | fprintf(stderr, "load failed\n"); | 151 | fprintf(stderr, "load failed\n"); |
151 | exit(1); | 152 | exit(1); |
152 | } | 153 | } |
153 | key_to_blob(k, &blob, &len); | 154 | key_to_blob(prv, &blob, &len); |
154 | fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); | 155 | fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); |
155 | fprintf(stdout, | 156 | fprintf(stdout, |
156 | "Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n", | 157 | "Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n", |
157 | key_size(k), key_type(k), | 158 | key_size(prv), key_type(prv), |
158 | pw->pw_name, hostname); | 159 | pw->pw_name, hostname); |
159 | dump_base64(stdout, blob, len); | 160 | dump_base64(stdout, blob, len); |
160 | fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); | 161 | fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); |
161 | key_free(k); | 162 | key_free(prv); |
162 | xfree(blob); | 163 | xfree(blob); |
163 | exit(0); | 164 | exit(0); |
164 | } | 165 | } |
@@ -302,7 +303,7 @@ do_convert_from_ssh2(struct passwd *pw) | |||
302 | void | 303 | void |
303 | do_print_public(struct passwd *pw) | 304 | do_print_public(struct passwd *pw) |
304 | { | 305 | { |
305 | Key *k; | 306 | Key *prv; |
306 | struct stat st; | 307 | struct stat st; |
307 | 308 | ||
308 | if (!have_identity) | 309 | if (!have_identity) |
@@ -311,14 +312,14 @@ do_print_public(struct passwd *pw) | |||
311 | perror(identity_file); | 312 | perror(identity_file); |
312 | exit(1); | 313 | exit(1); |
313 | } | 314 | } |
314 | k = key_new(KEY_UNSPEC); | 315 | prv = try_load_pem_key(identity_file); |
315 | if (!try_load_key(identity_file, k)) { | 316 | if (prv == NULL) { |
316 | fprintf(stderr, "load failed\n"); | 317 | fprintf(stderr, "load failed\n"); |
317 | exit(1); | 318 | exit(1); |
318 | } | 319 | } |
319 | if (!key_write(k, stdout)) | 320 | if (!key_write(prv, stdout)) |
320 | fprintf(stderr, "key_write failed"); | 321 | fprintf(stderr, "key_write failed"); |
321 | key_free(k); | 322 | key_free(prv); |
322 | fprintf(stdout, "\n"); | 323 | fprintf(stdout, "\n"); |
323 | exit(0); | 324 | exit(0); |
324 | } | 325 | } |
@@ -329,11 +330,11 @@ do_fingerprint(struct passwd *pw) | |||
329 | FILE *f; | 330 | FILE *f; |
330 | Key *public; | 331 | Key *public; |
331 | char *comment = NULL, *cp, *ep, line[16*1024], *fp; | 332 | char *comment = NULL, *cp, *ep, line[16*1024], *fp; |
332 | int i, skip = 0, num = 1, invalid = 1, success = 0, rep, type; | 333 | int i, skip = 0, num = 1, invalid = 1, rep, fptype; |
333 | struct stat st; | 334 | struct stat st; |
334 | 335 | ||
335 | type = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; | 336 | fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; |
336 | rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; | 337 | rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; |
337 | 338 | ||
338 | if (!have_identity) | 339 | if (!have_identity) |
339 | ask_filename(pw, "Enter file in which the key is"); | 340 | ask_filename(pw, "Enter file in which the key is"); |
@@ -341,26 +342,17 @@ do_fingerprint(struct passwd *pw) | |||
341 | perror(identity_file); | 342 | perror(identity_file); |
342 | exit(1); | 343 | exit(1); |
343 | } | 344 | } |
344 | public = key_new(KEY_RSA1); | 345 | public = key_load_public(identity_file, &comment); |
345 | if (load_public_key(identity_file, public, &comment)) { | 346 | if (public != NULL) { |
346 | success = 1; | 347 | fp = key_fingerprint(public, fptype, rep); |
347 | } else { | 348 | printf("%d %s %s\n", key_size(public), fp, comment); |
348 | key_free(public); | ||
349 | public = key_new(KEY_UNSPEC); | ||
350 | if (try_load_public_key(identity_file, public, &comment)) | ||
351 | success = 1; | ||
352 | else | ||
353 | debug("try_load_public_key KEY_UNSPEC failed"); | ||
354 | } | ||
355 | if (success) { | ||
356 | fp = key_fingerprint(public, type, rep); | ||
357 | printf("%d %s %s\n", key_size(public), | ||
358 | fp, comment); | ||
359 | key_free(public); | 349 | key_free(public); |
360 | xfree(comment); | 350 | xfree(comment); |
361 | xfree(fp); | 351 | xfree(fp); |
362 | exit(0); | 352 | exit(0); |
363 | } | 353 | } |
354 | if (comment) | ||
355 | xfree(comment); | ||
364 | 356 | ||
365 | f = fopen(identity_file, "r"); | 357 | f = fopen(identity_file, "r"); |
366 | if (f != NULL) { | 358 | if (f != NULL) { |
@@ -409,15 +401,15 @@ do_fingerprint(struct passwd *pw) | |||
409 | } | 401 | } |
410 | } | 402 | } |
411 | comment = *cp ? cp : comment; | 403 | comment = *cp ? cp : comment; |
412 | fp = key_fingerprint(public, type, rep); | 404 | fp = key_fingerprint(public, fptype, rep); |
413 | printf("%d %s %s\n", key_size(public), fp, | 405 | printf("%d %s %s\n", key_size(public), fp, |
414 | comment ? comment : "no comment"); | 406 | comment ? comment : "no comment"); |
415 | xfree(fp); | 407 | xfree(fp); |
408 | key_free(public); | ||
416 | invalid = 0; | 409 | invalid = 0; |
417 | } | 410 | } |
418 | fclose(f); | 411 | fclose(f); |
419 | } | 412 | } |
420 | key_free(public); | ||
421 | if (invalid) { | 413 | if (invalid) { |
422 | printf("%s is not a valid key file.\n", identity_file); | 414 | printf("%s is not a valid key file.\n", identity_file); |
423 | exit(1); | 415 | exit(1); |
@@ -436,8 +428,6 @@ do_change_passphrase(struct passwd *pw) | |||
436 | char *old_passphrase, *passphrase1, *passphrase2; | 428 | char *old_passphrase, *passphrase1, *passphrase2; |
437 | struct stat st; | 429 | struct stat st; |
438 | Key *private; | 430 | Key *private; |
439 | Key *public; | ||
440 | int type = KEY_RSA1; | ||
441 | 431 | ||
442 | if (!have_identity) | 432 | if (!have_identity) |
443 | ask_filename(pw, "Enter file in which the key is"); | 433 | ask_filename(pw, "Enter file in which the key is"); |
@@ -445,28 +435,20 @@ do_change_passphrase(struct passwd *pw) | |||
445 | perror(identity_file); | 435 | perror(identity_file); |
446 | exit(1); | 436 | exit(1); |
447 | } | 437 | } |
448 | public = key_new(type); | ||
449 | if (!load_public_key(identity_file, public, NULL)) { | ||
450 | type = KEY_UNSPEC; | ||
451 | } else { | ||
452 | /* Clear the public key since we are just about to load the whole file. */ | ||
453 | key_free(public); | ||
454 | } | ||
455 | /* Try to load the file with empty passphrase. */ | 438 | /* Try to load the file with empty passphrase. */ |
456 | private = key_new(type); | 439 | private = key_load_private(identity_file, "", &comment); |
457 | if (!load_private_key(identity_file, "", private, &comment)) { | 440 | if (private == NULL) { |
458 | if (identity_passphrase) | 441 | if (identity_passphrase) |
459 | old_passphrase = xstrdup(identity_passphrase); | 442 | old_passphrase = xstrdup(identity_passphrase); |
460 | else | 443 | else |
461 | old_passphrase = read_passphrase("Enter old passphrase: ", 1); | 444 | old_passphrase = read_passphrase("Enter old passphrase: ", 1); |
462 | if (!load_private_key(identity_file, old_passphrase, private, &comment)) { | 445 | private = key_load_private(identity_file, old_passphrase , &comment); |
463 | memset(old_passphrase, 0, strlen(old_passphrase)); | 446 | memset(old_passphrase, 0, strlen(old_passphrase)); |
464 | xfree(old_passphrase); | 447 | xfree(old_passphrase); |
448 | if (private == NULL) { | ||
465 | printf("Bad passphrase.\n"); | 449 | printf("Bad passphrase.\n"); |
466 | exit(1); | 450 | exit(1); |
467 | } | 451 | } |
468 | memset(old_passphrase, 0, strlen(old_passphrase)); | ||
469 | xfree(old_passphrase); | ||
470 | } | 452 | } |
471 | printf("Key has comment '%s'\n", comment); | 453 | printf("Key has comment '%s'\n", comment); |
472 | 454 | ||
@@ -494,7 +476,7 @@ do_change_passphrase(struct passwd *pw) | |||
494 | } | 476 | } |
495 | 477 | ||
496 | /* Save the file using the new passphrase. */ | 478 | /* Save the file using the new passphrase. */ |
497 | if (!save_private_key(identity_file, passphrase1, private, comment)) { | 479 | if (!key_save_private(private, identity_file, passphrase1, comment)) { |
498 | printf("Saving the key failed: %s: %s.\n", | 480 | printf("Saving the key failed: %s: %s.\n", |
499 | identity_file, strerror(errno)); | 481 | identity_file, strerror(errno)); |
500 | memset(passphrase1, 0, strlen(passphrase1)); | 482 | memset(passphrase1, 0, strlen(passphrase1)); |
@@ -520,7 +502,8 @@ void | |||
520 | do_change_comment(struct passwd *pw) | 502 | do_change_comment(struct passwd *pw) |
521 | { | 503 | { |
522 | char new_comment[1024], *comment, *passphrase; | 504 | char new_comment[1024], *comment, *passphrase; |
523 | Key *private, *public; | 505 | Key *private; |
506 | Key *public; | ||
524 | struct stat st; | 507 | struct stat st; |
525 | FILE *f; | 508 | FILE *f; |
526 | int fd; | 509 | int fd; |
@@ -531,21 +514,8 @@ do_change_comment(struct passwd *pw) | |||
531 | perror(identity_file); | 514 | perror(identity_file); |
532 | exit(1); | 515 | exit(1); |
533 | } | 516 | } |
534 | /* | 517 | private = key_load_private(identity_file, "", &comment); |
535 | * Try to load the public key from the file the verify that it is | 518 | if (private == NULL) { |
536 | * readable and of the proper format. | ||
537 | */ | ||
538 | public = key_new(KEY_RSA1); | ||
539 | if (!load_public_key(identity_file, public, NULL)) { | ||
540 | printf("%s is not a valid key file.\n", identity_file); | ||
541 | printf("Comments are only supported in RSA1 keys\n"); | ||
542 | exit(1); | ||
543 | } | ||
544 | |||
545 | private = key_new(KEY_RSA1); | ||
546 | if (load_private_key(identity_file, "", private, &comment)) | ||
547 | passphrase = xstrdup(""); | ||
548 | else { | ||
549 | if (identity_passphrase) | 519 | if (identity_passphrase) |
550 | passphrase = xstrdup(identity_passphrase); | 520 | passphrase = xstrdup(identity_passphrase); |
551 | else if (identity_new_passphrase) | 521 | else if (identity_new_passphrase) |
@@ -553,13 +523,21 @@ do_change_comment(struct passwd *pw) | |||
553 | else | 523 | else |
554 | passphrase = read_passphrase("Enter passphrase: ", 1); | 524 | passphrase = read_passphrase("Enter passphrase: ", 1); |
555 | /* Try to load using the passphrase. */ | 525 | /* Try to load using the passphrase. */ |
556 | if (!load_private_key(identity_file, passphrase, private, &comment)) { | 526 | private = key_load_private(identity_file, passphrase, &comment); |
527 | if (private == NULL) { | ||
557 | memset(passphrase, 0, strlen(passphrase)); | 528 | memset(passphrase, 0, strlen(passphrase)); |
558 | xfree(passphrase); | 529 | xfree(passphrase); |
559 | printf("Bad passphrase.\n"); | 530 | printf("Bad passphrase.\n"); |
560 | exit(1); | 531 | exit(1); |
561 | } | 532 | } |
533 | } else { | ||
534 | passphrase = xstrdup(""); | ||
562 | } | 535 | } |
536 | if (private->type != KEY_RSA1) { | ||
537 | fprintf(stderr, "Comments are only supported for RSA1 keys.\n"); | ||
538 | key_free(private); | ||
539 | exit(1); | ||
540 | } | ||
563 | printf("Key now has comment '%s'\n", comment); | 541 | printf("Key now has comment '%s'\n", comment); |
564 | 542 | ||
565 | if (identity_comment) { | 543 | if (identity_comment) { |
@@ -577,7 +555,7 @@ do_change_comment(struct passwd *pw) | |||
577 | } | 555 | } |
578 | 556 | ||
579 | /* Save the file using the new passphrase. */ | 557 | /* Save the file using the new passphrase. */ |
580 | if (!save_private_key(identity_file, passphrase, private, new_comment)) { | 558 | if (!key_save_private(private, identity_file, passphrase, new_comment)) { |
581 | printf("Saving the key failed: %s: %s.\n", | 559 | printf("Saving the key failed: %s: %s.\n", |
582 | identity_file, strerror(errno)); | 560 | identity_file, strerror(errno)); |
583 | memset(passphrase, 0, strlen(passphrase)); | 561 | memset(passphrase, 0, strlen(passphrase)); |
@@ -588,6 +566,7 @@ do_change_comment(struct passwd *pw) | |||
588 | } | 566 | } |
589 | memset(passphrase, 0, strlen(passphrase)); | 567 | memset(passphrase, 0, strlen(passphrase)); |
590 | xfree(passphrase); | 568 | xfree(passphrase); |
569 | public = key_from_private(private); | ||
591 | key_free(private); | 570 | key_free(private); |
592 | 571 | ||
593 | strlcat(identity_file, ".pub", sizeof(identity_file)); | 572 | strlcat(identity_file, ".pub", sizeof(identity_file)); |
@@ -823,7 +802,7 @@ passphrase_again: | |||
823 | } | 802 | } |
824 | 803 | ||
825 | /* Save the key with the given passphrase and comment. */ | 804 | /* Save the key with the given passphrase and comment. */ |
826 | if (!save_private_key(identity_file, passphrase1, private, comment)) { | 805 | if (!key_save_private(private, identity_file, passphrase1, comment)) { |
827 | printf("Saving the key failed: %s: %s.\n", | 806 | printf("Saving the key failed: %s: %s.\n", |
828 | identity_file, strerror(errno)); | 807 | identity_file, strerror(errno)); |
829 | memset(passphrase1, 0, strlen(passphrase1)); | 808 | memset(passphrase1, 0, strlen(passphrase1)); |
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: ssh.c,v 1.104 2001/03/08 21:42:32 markus Exp $"); | 42 | RCSID("$OpenBSD: ssh.c,v 1.105 2001/03/26 08:07:09 markus Exp $"); |
43 | 43 | ||
44 | #include <openssl/evp.h> | 44 | #include <openssl/evp.h> |
45 | #include <openssl/err.h> | 45 | #include <openssl/err.h> |
@@ -130,11 +130,8 @@ struct sockaddr_storage hostaddr; | |||
130 | */ | 130 | */ |
131 | volatile int received_window_change_signal = 0; | 131 | volatile int received_window_change_signal = 0; |
132 | 132 | ||
133 | /* Flag indicating whether we have a valid host private key loaded. */ | ||
134 | int host_private_key_loaded = 0; | ||
135 | |||
136 | /* Host private key. */ | 133 | /* Host private key. */ |
137 | RSA *host_private_key = NULL; | 134 | Key *host_private_key = NULL; |
138 | 135 | ||
139 | /* Original real UID. */ | 136 | /* Original real UID. */ |
140 | uid_t original_real_uid; | 137 | uid_t original_real_uid; |
@@ -631,12 +628,8 @@ main(int ac, char **av) | |||
631 | * privileges, because the file is only readable by root. | 628 | * privileges, because the file is only readable by root. |
632 | */ | 629 | */ |
633 | if (ok && (options.protocol & SSH_PROTO_1)) { | 630 | if (ok && (options.protocol & SSH_PROTO_1)) { |
634 | Key k; | 631 | host_private_key = key_load_private_type(KEY_RSA1, |
635 | host_private_key = RSA_new(); | 632 | _PATH_HOST_KEY_FILE, "", NULL); |
636 | k.type = KEY_RSA1; | ||
637 | k.rsa = host_private_key; | ||
638 | if (load_private_key(_PATH_HOST_KEY_FILE, "", &k, NULL)) | ||
639 | host_private_key_loaded = 1; | ||
640 | } | 633 | } |
641 | /* | 634 | /* |
642 | * Get rid of any extra privileges that we may have. We will no | 635 | * Get rid of any extra privileges that we may have. We will no |
@@ -695,12 +688,12 @@ main(int ac, char **av) | |||
695 | tilde_expand_filename(options.user_hostfile2, original_real_uid); | 688 | tilde_expand_filename(options.user_hostfile2, original_real_uid); |
696 | 689 | ||
697 | /* Log into the remote system. This never returns if the login fails. */ | 690 | /* Log into the remote system. This never returns if the login fails. */ |
698 | ssh_login(host_private_key_loaded, host_private_key, | 691 | ssh_login(host_private_key, host, (struct sockaddr *)&hostaddr, |
699 | host, (struct sockaddr *)&hostaddr, original_real_uid); | 692 | original_real_uid); |
700 | 693 | ||
701 | /* We no longer need the host private key. Clear it now. */ | 694 | /* We no longer need the host private key. Clear it now. */ |
702 | if (host_private_key_loaded) | 695 | if (host_private_key != NULL) |
703 | RSA_free(host_private_key); /* Destroys contents safely */ | 696 | key_free(host_private_key); /* Destroys contents safely */ |
704 | 697 | ||
705 | exit_status = compat20 ? ssh_session2() : ssh_session(); | 698 | exit_status = compat20 ? ssh_session2() : ssh_session(); |
706 | packet_close(); | 699 | packet_close(); |
@@ -1074,26 +1067,6 @@ ssh_session2(void) | |||
1074 | return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id); | 1067 | return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id); |
1075 | } | 1068 | } |
1076 | 1069 | ||
1077 | int | ||
1078 | guess_identity_file_type(const char *filename) | ||
1079 | { | ||
1080 | struct stat st; | ||
1081 | Key *public; | ||
1082 | int type = KEY_RSA1; /* default */ | ||
1083 | |||
1084 | if (stat(filename, &st) < 0) { | ||
1085 | /* ignore this key */ | ||
1086 | return KEY_UNSPEC; | ||
1087 | } | ||
1088 | public = key_new(type); | ||
1089 | if (!load_public_key(filename, public, NULL)) { | ||
1090 | /* ok, so we will assume this is 'some' key */ | ||
1091 | type = KEY_UNSPEC; | ||
1092 | } | ||
1093 | key_free(public); | ||
1094 | return type; | ||
1095 | } | ||
1096 | |||
1097 | void | 1070 | void |
1098 | load_public_identity_files(void) | 1071 | load_public_identity_files(void) |
1099 | { | 1072 | { |
@@ -1104,16 +1077,7 @@ load_public_identity_files(void) | |||
1104 | for (i = 0; i < options.num_identity_files; i++) { | 1077 | for (i = 0; i < options.num_identity_files; i++) { |
1105 | filename = tilde_expand_filename(options.identity_files[i], | 1078 | filename = tilde_expand_filename(options.identity_files[i], |
1106 | original_real_uid); | 1079 | original_real_uid); |
1107 | public = key_new(KEY_RSA1); | 1080 | public = key_load_public(filename, NULL); |
1108 | if (!load_public_key(filename, public, NULL)) { | ||
1109 | key_free(public); | ||
1110 | public = key_new(KEY_UNSPEC); | ||
1111 | if (!try_load_public_key(filename, public, NULL)) { | ||
1112 | debug("unknown identity file %s", filename); | ||
1113 | key_free(public); | ||
1114 | public = NULL; | ||
1115 | } | ||
1116 | } | ||
1117 | debug("identity file %s type %d", filename, | 1081 | debug("identity file %s type %d", filename, |
1118 | public ? public->type : -1); | 1082 | public ? public->type : -1); |
1119 | xfree(options.identity_files[i]); | 1083 | xfree(options.identity_files[i]); |
diff --git a/sshconnect.c b/sshconnect.c index d82be89e9..d4f510b11 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include "includes.h" | 15 | #include "includes.h" |
16 | RCSID("$OpenBSD: sshconnect.c,v 1.100 2001/03/12 22:02:02 markus Exp $"); | 16 | RCSID("$OpenBSD: sshconnect.c,v 1.101 2001/03/26 08:07:09 markus Exp $"); |
17 | 17 | ||
18 | #include <openssl/bn.h> | 18 | #include <openssl/bn.h> |
19 | 19 | ||
@@ -738,7 +738,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, | |||
738 | * This function does not require super-user privileges. | 738 | * This function does not require super-user privileges. |
739 | */ | 739 | */ |
740 | void | 740 | void |
741 | ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, | 741 | ssh_login(Key *own_host_key, const char *orighost, |
742 | struct sockaddr *hostaddr, uid_t original_real_uid) | 742 | struct sockaddr *hostaddr, uid_t original_real_uid) |
743 | { | 743 | { |
744 | struct passwd *pw; | 744 | struct passwd *pw; |
@@ -771,7 +771,7 @@ ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, | |||
771 | ssh_userauth2(server_user, host); | 771 | ssh_userauth2(server_user, host); |
772 | } else { | 772 | } else { |
773 | ssh_kex(host, hostaddr); | 773 | ssh_kex(host, hostaddr); |
774 | ssh_userauth(local_user, server_user, host, host_key_valid, own_host_key); | 774 | ssh_userauth(local_user, server_user, host, own_host_key); |
775 | } | 775 | } |
776 | } | 776 | } |
777 | 777 | ||
diff --git a/sshconnect.h b/sshconnect.h index 4edd72f2e..3a71d9c2b 100644 --- a/sshconnect.h +++ b/sshconnect.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.h,v 1.6 2001/02/15 23:19:59 markus Exp $ */ | 1 | /* $OpenBSD: sshconnect.h,v 1.7 2001/03/26 08:07:09 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
@@ -50,7 +50,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
50 | */ | 50 | */ |
51 | 51 | ||
52 | void | 52 | void |
53 | ssh_login(int host_key_valid, RSA * host_key, const char *host, | 53 | ssh_login(Key *host_key, const char *host, |
54 | struct sockaddr * hostaddr, uid_t original_real_uid); | 54 | struct sockaddr * hostaddr, uid_t original_real_uid); |
55 | 55 | ||
56 | 56 | ||
@@ -61,7 +61,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, | |||
61 | void ssh_kex(char *host, struct sockaddr *hostaddr); | 61 | void ssh_kex(char *host, struct sockaddr *hostaddr); |
62 | void | 62 | void |
63 | ssh_userauth(const char * local_user, const char * server_user, char *host, | 63 | ssh_userauth(const char * local_user, const char * server_user, char *host, |
64 | int host_key_valid, RSA *own_host_key); | 64 | Key *own_host_key); |
65 | 65 | ||
66 | void ssh_kex2(char *host, struct sockaddr *hostaddr); | 66 | void ssh_kex2(char *host, struct sockaddr *hostaddr); |
67 | void ssh_userauth2(const char *server_user, char *host); | 67 | void ssh_userauth2(const char *server_user, char *host); |
diff --git a/sshconnect1.c b/sshconnect1.c index 3d45ac5a2..3ec5ecc51 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.28 2001/03/08 21:42:33 markus Exp $"); | 16 | RCSID("$OpenBSD: sshconnect1.c,v 1.29 2001/03/26 08:07:09 markus Exp $"); |
17 | 17 | ||
18 | #include <openssl/bn.h> | 18 | #include <openssl/bn.h> |
19 | #include <openssl/evp.h> | 19 | #include <openssl/evp.h> |
@@ -211,9 +211,9 @@ try_rsa_authentication(const char *authfile) | |||
211 | int plen, clen; | 211 | int plen, clen; |
212 | 212 | ||
213 | /* Try to load identification for the authentication key. */ | 213 | /* Try to load identification for the authentication key. */ |
214 | public = key_new(KEY_RSA1); | 214 | /* XXKEYLOAD */ |
215 | if (!load_public_key(authfile, public, &comment)) { | 215 | public = key_load_public_type(KEY_RSA1, authfile, &comment); |
216 | key_free(public); | 216 | if (public == NULL) { |
217 | /* Could not load it. Fail. */ | 217 | /* Could not load it. Fail. */ |
218 | return 0; | 218 | return 0; |
219 | } | 219 | } |
@@ -252,12 +252,12 @@ try_rsa_authentication(const char *authfile) | |||
252 | 252 | ||
253 | debug("Received RSA challenge from server."); | 253 | debug("Received RSA challenge from server."); |
254 | 254 | ||
255 | private = key_new(KEY_RSA1); | ||
256 | /* | 255 | /* |
257 | * Load the private key. Try first with empty passphrase; if it | 256 | * Load the private key. Try first with empty passphrase; if it |
258 | * fails, ask for a passphrase. | 257 | * fails, ask for a passphrase. |
259 | */ | 258 | */ |
260 | if (!load_private_key(authfile, "", private, NULL)) { | 259 | private = key_load_private_type(KEY_RSA1, authfile, "", NULL); |
260 | if (private == NULL) { | ||
261 | char buf[300]; | 261 | char buf[300]; |
262 | snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", | 262 | snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", |
263 | comment); | 263 | comment); |
@@ -270,7 +270,8 @@ try_rsa_authentication(const char *authfile) | |||
270 | } | 270 | } |
271 | 271 | ||
272 | /* Load the authentication file using the pasphrase. */ | 272 | /* Load the authentication file using the pasphrase. */ |
273 | if (!load_private_key(authfile, passphrase, private, NULL)) { | 273 | private = key_load_private_type(KEY_RSA1, authfile, passphrase, NULL); |
274 | if (private == NULL) { | ||
274 | memset(passphrase, 0, strlen(passphrase)); | 275 | memset(passphrase, 0, strlen(passphrase)); |
275 | xfree(passphrase); | 276 | xfree(passphrase); |
276 | error("Bad passphrase."); | 277 | error("Bad passphrase."); |
@@ -285,7 +286,6 @@ try_rsa_authentication(const char *authfile) | |||
285 | /* Expect the server to reject it... */ | 286 | /* Expect the server to reject it... */ |
286 | packet_read_expect(&plen, SSH_SMSG_FAILURE); | 287 | packet_read_expect(&plen, SSH_SMSG_FAILURE); |
287 | xfree(comment); | 288 | xfree(comment); |
288 | key_free(private); | ||
289 | BN_clear_free(challenge); | 289 | BN_clear_free(challenge); |
290 | return 0; | 290 | return 0; |
291 | } | 291 | } |
@@ -322,7 +322,7 @@ try_rsa_authentication(const char *authfile) | |||
322 | * authentication and RSA host authentication. | 322 | * authentication and RSA host authentication. |
323 | */ | 323 | */ |
324 | int | 324 | int |
325 | try_rhosts_rsa_authentication(const char *local_user, RSA * host_key) | 325 | try_rhosts_rsa_authentication(const char *local_user, Key * host_key) |
326 | { | 326 | { |
327 | int type; | 327 | int type; |
328 | BIGNUM *challenge; | 328 | BIGNUM *challenge; |
@@ -333,9 +333,9 @@ try_rhosts_rsa_authentication(const char *local_user, RSA * host_key) | |||
333 | /* Tell the server that we are willing to authenticate using this key. */ | 333 | /* Tell the server that we are willing to authenticate using this key. */ |
334 | packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); | 334 | packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); |
335 | packet_put_string(local_user, strlen(local_user)); | 335 | packet_put_string(local_user, strlen(local_user)); |
336 | packet_put_int(BN_num_bits(host_key->n)); | 336 | packet_put_int(BN_num_bits(host_key->rsa->n)); |
337 | packet_put_bignum(host_key->e); | 337 | packet_put_bignum(host_key->rsa->e); |
338 | packet_put_bignum(host_key->n); | 338 | packet_put_bignum(host_key->rsa->n); |
339 | packet_send(); | 339 | packet_send(); |
340 | packet_write_wait(); | 340 | packet_write_wait(); |
341 | 341 | ||
@@ -361,7 +361,7 @@ try_rhosts_rsa_authentication(const char *local_user, RSA * host_key) | |||
361 | debug("Received RSA challenge for host key from server."); | 361 | debug("Received RSA challenge for host key from server."); |
362 | 362 | ||
363 | /* Compute a response to the challenge. */ | 363 | /* Compute a response to the challenge. */ |
364 | respond_to_rsa_challenge(challenge, host_key); | 364 | respond_to_rsa_challenge(challenge, host_key->rsa); |
365 | 365 | ||
366 | /* We no longer need the challenge. */ | 366 | /* We no longer need the challenge. */ |
367 | BN_clear_free(challenge); | 367 | BN_clear_free(challenge); |
@@ -915,7 +915,7 @@ ssh_userauth( | |||
915 | const char *local_user, | 915 | const char *local_user, |
916 | const char *server_user, | 916 | const char *server_user, |
917 | char *host, | 917 | char *host, |
918 | int host_key_valid, RSA *own_host_key) | 918 | Key *own_host_key) |
919 | { | 919 | { |
920 | int i, type; | 920 | int i, type; |
921 | int payload_len; | 921 | int payload_len; |
@@ -1000,7 +1000,7 @@ ssh_userauth( | |||
1000 | * authentication. | 1000 | * authentication. |
1001 | */ | 1001 | */ |
1002 | if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && | 1002 | if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && |
1003 | options.rhosts_rsa_authentication && host_key_valid) { | 1003 | options.rhosts_rsa_authentication && own_host_key != NULL) { |
1004 | if (try_rhosts_rsa_authentication(local_user, own_host_key)) | 1004 | if (try_rhosts_rsa_authentication(local_user, own_host_key)) |
1005 | return; | 1005 | return; |
1006 | } | 1006 | } |
diff --git a/sshconnect2.c b/sshconnect2.c index 86f3bb9b2..f636fb3d9 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.55 2001/03/23 11:04:07 djm Exp $"); | 26 | RCSID("$OpenBSD: sshconnect2.c,v 1.56 2001/03/26 08:07:09 markus Exp $"); |
27 | 27 | ||
28 | #include <openssl/bn.h> | 28 | #include <openssl/bn.h> |
29 | #include <openssl/md5.h> | 29 | #include <openssl/md5.h> |
@@ -901,26 +901,24 @@ load_identity_file(char *filename) | |||
901 | { | 901 | { |
902 | Key *private; | 902 | Key *private; |
903 | char prompt[300], *passphrase; | 903 | char prompt[300], *passphrase; |
904 | int success = 0, quit, i; | 904 | int quit, i; |
905 | struct stat st; | 905 | struct stat st; |
906 | 906 | ||
907 | if (stat(filename, &st) < 0) { | 907 | if (stat(filename, &st) < 0) { |
908 | debug3("no such identity: %s", filename); | 908 | debug3("no such identity: %s", filename); |
909 | return NULL; | 909 | return NULL; |
910 | } | 910 | } |
911 | private = key_new(KEY_UNSPEC); | 911 | private = key_load_private_type(KEY_UNSPEC, filename, "", NULL); |
912 | if (!load_private_key(filename, "", private, NULL)) { | 912 | if (private == NULL) { |
913 | if (options.batch_mode) { | 913 | if (options.batch_mode) |
914 | key_free(private); | ||
915 | return NULL; | 914 | return NULL; |
916 | } | ||
917 | snprintf(prompt, sizeof prompt, | 915 | snprintf(prompt, sizeof prompt, |
918 | "Enter passphrase for key '%.100s': ", filename); | 916 | "Enter passphrase for key '%.100s': ", filename); |
919 | for (i = 0; i < options.number_of_password_prompts; i++) { | 917 | for (i = 0; i < options.number_of_password_prompts; i++) { |
920 | passphrase = read_passphrase(prompt, 0); | 918 | passphrase = read_passphrase(prompt, 0); |
921 | if (strcmp(passphrase, "") != 0) { | 919 | if (strcmp(passphrase, "") != 0) { |
922 | success = load_private_key(filename, | 920 | private = key_load_private_type(KEY_UNSPEC, filename, |
923 | passphrase, private, NULL); | 921 | passphrase, NULL); |
924 | quit = 0; | 922 | quit = 0; |
925 | } else { | 923 | } else { |
926 | debug2("no passphrase given, try next key"); | 924 | debug2("no passphrase given, try next key"); |
@@ -928,14 +926,10 @@ load_identity_file(char *filename) | |||
928 | } | 926 | } |
929 | memset(passphrase, 0, strlen(passphrase)); | 927 | memset(passphrase, 0, strlen(passphrase)); |
930 | xfree(passphrase); | 928 | xfree(passphrase); |
931 | if (success || quit) | 929 | if (private != NULL || quit) |
932 | break; | 930 | break; |
933 | debug2("bad passphrase given, try again..."); | 931 | debug2("bad passphrase given, try again..."); |
934 | } | 932 | } |
935 | if (!success) { | ||
936 | key_free(private); | ||
937 | return NULL; | ||
938 | } | ||
939 | } | 933 | } |
940 | return private; | 934 | return private; |
941 | } | 935 | } |
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: sshd.c,v 1.178 2001/03/23 14:28:32 markus Exp $"); | 43 | RCSID("$OpenBSD: sshd.c,v 1.179 2001/03/26 08:07:09 markus Exp $"); |
44 | 44 | ||
45 | #include <openssl/dh.h> | 45 | #include <openssl/dh.h> |
46 | #include <openssl/bn.h> | 46 | #include <openssl/bn.h> |
@@ -454,39 +454,6 @@ destroy_sensitive_data(void) | |||
454 | sensitive_data.ssh1_host_key = NULL; | 454 | sensitive_data.ssh1_host_key = NULL; |
455 | memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); | 455 | memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); |
456 | } | 456 | } |
457 | Key * | ||
458 | load_private_key_autodetect(const char *filename) | ||
459 | { | ||
460 | struct stat st; | ||
461 | int type; | ||
462 | Key *public, *private; | ||
463 | |||
464 | if (stat(filename, &st) < 0) { | ||
465 | perror(filename); | ||
466 | return NULL; | ||
467 | } | ||
468 | /* | ||
469 | * try to load the public key. right now this only works for RSA1, | ||
470 | * since SSH2 keys are fully encrypted | ||
471 | */ | ||
472 | type = KEY_RSA1; | ||
473 | public = key_new(type); | ||
474 | if (!load_public_key(filename, public, NULL)) { | ||
475 | /* ok, so we will assume this is 'some' key */ | ||
476 | type = KEY_UNSPEC; | ||
477 | } | ||
478 | key_free(public); | ||
479 | |||
480 | /* Ok, try key with empty passphrase */ | ||
481 | private = key_new(type); | ||
482 | if (load_private_key(filename, "", private, NULL)) { | ||
483 | debug("load_private_key_autodetect: type %d %s", | ||
484 | private->type, key_type(private)); | ||
485 | return private; | ||
486 | } | ||
487 | key_free(private); | ||
488 | return NULL; | ||
489 | } | ||
490 | 457 | ||
491 | char * | 458 | char * |
492 | list_hostkey_types(void) | 459 | list_hostkey_types(void) |
@@ -579,6 +546,7 @@ main(int ac, char **av) | |||
579 | int listen_sock, maxfd; | 546 | int listen_sock, maxfd; |
580 | int startup_p[2]; | 547 | int startup_p[2]; |
581 | int startups = 0; | 548 | int startups = 0; |
549 | Key *key; | ||
582 | int ret, key_used = 0; | 550 | int ret, key_used = 0; |
583 | 551 | ||
584 | __progname = get_progname(av[0]); | 552 | __progname = get_progname(av[0]); |
@@ -716,10 +684,12 @@ main(int ac, char **av) | |||
716 | sensitive_data.have_ssh2_key = 0; | 684 | sensitive_data.have_ssh2_key = 0; |
717 | 685 | ||
718 | for(i = 0; i < options.num_host_key_files; i++) { | 686 | for(i = 0; i < options.num_host_key_files; i++) { |
719 | Key *key = load_private_key_autodetect(options.host_key_files[i]); | 687 | key = key_load_private(options.host_key_files[i], "", NULL); |
688 | sensitive_data.host_keys[i] = key; | ||
720 | if (key == NULL) { | 689 | if (key == NULL) { |
721 | error("Could not load host key: %.200s: %.100s", | 690 | error("Could not load host key: %.200s: %.100s", |
722 | options.host_key_files[i], strerror(errno)); | 691 | options.host_key_files[i], strerror(errno)); |
692 | sensitive_data.host_keys[i] = NULL; | ||
723 | continue; | 693 | continue; |
724 | } | 694 | } |
725 | switch(key->type){ | 695 | switch(key->type){ |
@@ -732,7 +702,8 @@ main(int ac, char **av) | |||
732 | sensitive_data.have_ssh2_key = 1; | 702 | sensitive_data.have_ssh2_key = 1; |
733 | break; | 703 | break; |
734 | } | 704 | } |
735 | sensitive_data.host_keys[i] = key; | 705 | debug("private host key: #%d type %d %s", i, key->type, |
706 | key_type(key)); | ||
736 | } | 707 | } |
737 | if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { | 708 | if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { |
738 | log("Disabling protocol version 1. Could not load host key"); | 709 | log("Disabling protocol version 1. Could not load host key"); |