diff options
author | Damien Miller <djm@mindrot.org> | 2011-06-20 14:23:25 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2011-06-20 14:23:25 +1000 |
commit | e7ac2bd42ad16c2e2485331641befedebaebdb46 (patch) | |
tree | 789bfb4c1733e452f07ed4ef8c1107c3e433994b | |
parent | 6029e076b2c58f5a2cb0dce370b1f14912104fcd (diff) |
- markus@cvs.openbsd.org 2011/06/14 22:49:18
[authfile.c]
make sure key_parse_public/private_rsa1() no longer consumes its input
buffer. fixes ssh-add for passphrase-protected ssh1-keys;
noted by naddy@; ok djm@
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | authfile.c | 53 |
2 files changed, 33 insertions, 25 deletions
@@ -4,6 +4,11 @@ | |||
4 | [ssh_config.5] | 4 | [ssh_config.5] |
5 | explain IdentifyFile's semantics a little better, prompted by bz#1898 | 5 | explain IdentifyFile's semantics a little better, prompted by bz#1898 |
6 | ok dtucker jmc | 6 | ok dtucker jmc |
7 | - markus@cvs.openbsd.org 2011/06/14 22:49:18 | ||
8 | [authfile.c] | ||
9 | make sure key_parse_public/private_rsa1() no longer consumes its input | ||
10 | buffer. fixes ssh-add for passphrase-protected ssh1-keys; | ||
11 | noted by naddy@; ok djm@ | ||
7 | 12 | ||
8 | 20110603 | 13 | 20110603 |
9 | - (dtucker) [README version.h contrib/caldera/openssh.spec | 14 | - (dtucker) [README version.h contrib/caldera/openssh.spec |
diff --git a/authfile.c b/authfile.c index 96d2bf338..1d7e53cd1 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: authfile.c,v 1.91 2011/05/23 07:24:57 djm Exp $ */ | 1 | /* $OpenBSD: authfile.c,v 1.92 2011/06/14 22:49:18 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -279,6 +279,7 @@ static Key * | |||
279 | key_parse_public_rsa1(Buffer *blob, char **commentp) | 279 | key_parse_public_rsa1(Buffer *blob, char **commentp) |
280 | { | 280 | { |
281 | Key *pub; | 281 | Key *pub; |
282 | Buffer copy; | ||
282 | 283 | ||
283 | /* Check that it is at least big enough to contain the ID string. */ | 284 | /* Check that it is at least big enough to contain the ID string. */ |
284 | if (buffer_len(blob) < sizeof(authfile_id_string)) { | 285 | if (buffer_len(blob) < sizeof(authfile_id_string)) { |
@@ -295,21 +296,23 @@ key_parse_public_rsa1(Buffer *blob, char **commentp) | |||
295 | debug3("Incorrect RSA1 identifier"); | 296 | debug3("Incorrect RSA1 identifier"); |
296 | return NULL; | 297 | return NULL; |
297 | } | 298 | } |
298 | buffer_consume(blob, sizeof(authfile_id_string)); | 299 | buffer_init(©); |
300 | buffer_append(©, buffer_ptr(blob), buffer_len(blob)); | ||
301 | buffer_consume(©, sizeof(authfile_id_string)); | ||
299 | 302 | ||
300 | /* Skip cipher type and reserved data. */ | 303 | /* Skip cipher type and reserved data. */ |
301 | (void) buffer_get_char(blob); /* cipher type */ | 304 | (void) buffer_get_char(©); /* cipher type */ |
302 | (void) buffer_get_int(blob); /* reserved */ | 305 | (void) buffer_get_int(©); /* reserved */ |
303 | 306 | ||
304 | /* Read the public key from the buffer. */ | 307 | /* Read the public key from the buffer. */ |
305 | (void) buffer_get_int(blob); | 308 | (void) buffer_get_int(©); |
306 | pub = key_new(KEY_RSA1); | 309 | pub = key_new(KEY_RSA1); |
307 | buffer_get_bignum(blob, pub->rsa->n); | 310 | buffer_get_bignum(©, pub->rsa->n); |
308 | buffer_get_bignum(blob, pub->rsa->e); | 311 | buffer_get_bignum(©, pub->rsa->e); |
309 | if (commentp) | 312 | if (commentp) |
310 | *commentp = buffer_get_string(blob, NULL); | 313 | *commentp = buffer_get_string(©, NULL); |
311 | /* The encrypted private part is not parsed by this function. */ | 314 | /* The encrypted private part is not parsed by this function. */ |
312 | buffer_clear(blob); | 315 | buffer_free(©); |
313 | 316 | ||
314 | return pub; | 317 | return pub; |
315 | } | 318 | } |
@@ -420,6 +423,7 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) | |||
420 | CipherContext ciphercontext; | 423 | CipherContext ciphercontext; |
421 | Cipher *cipher; | 424 | Cipher *cipher; |
422 | Key *prv = NULL; | 425 | Key *prv = NULL; |
426 | Buffer copy; | ||
423 | 427 | ||
424 | /* Check that it is at least big enough to contain the ID string. */ | 428 | /* Check that it is at least big enough to contain the ID string. */ |
425 | if (buffer_len(blob) < sizeof(authfile_id_string)) { | 429 | if (buffer_len(blob) < sizeof(authfile_id_string)) { |
@@ -436,41 +440,44 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) | |||
436 | debug3("Incorrect RSA1 identifier"); | 440 | debug3("Incorrect RSA1 identifier"); |
437 | return NULL; | 441 | return NULL; |
438 | } | 442 | } |
439 | buffer_consume(blob, sizeof(authfile_id_string)); | 443 | buffer_init(©); |
444 | buffer_append(©, buffer_ptr(blob), buffer_len(blob)); | ||
445 | buffer_consume(©, sizeof(authfile_id_string)); | ||
440 | 446 | ||
441 | /* Read cipher type. */ | 447 | /* Read cipher type. */ |
442 | cipher_type = buffer_get_char(blob); | 448 | cipher_type = buffer_get_char(©); |
443 | (void) buffer_get_int(blob); /* Reserved data. */ | 449 | (void) buffer_get_int(©); /* Reserved data. */ |
444 | 450 | ||
445 | /* Read the public key from the buffer. */ | 451 | /* Read the public key from the buffer. */ |
446 | (void) buffer_get_int(blob); | 452 | (void) buffer_get_int(©); |
447 | prv = key_new_private(KEY_RSA1); | 453 | prv = key_new_private(KEY_RSA1); |
448 | 454 | ||
449 | buffer_get_bignum(blob, prv->rsa->n); | 455 | buffer_get_bignum(©, prv->rsa->n); |
450 | buffer_get_bignum(blob, prv->rsa->e); | 456 | buffer_get_bignum(©, prv->rsa->e); |
451 | if (commentp) | 457 | if (commentp) |
452 | *commentp = buffer_get_string(blob, NULL); | 458 | *commentp = buffer_get_string(©, NULL); |
453 | else | 459 | else |
454 | (void)buffer_get_string_ptr(blob, NULL); | 460 | (void)buffer_get_string_ptr(©, NULL); |
455 | 461 | ||
456 | /* Check that it is a supported cipher. */ | 462 | /* Check that it is a supported cipher. */ |
457 | cipher = cipher_by_number(cipher_type); | 463 | cipher = cipher_by_number(cipher_type); |
458 | if (cipher == NULL) { | 464 | if (cipher == NULL) { |
459 | debug("Unsupported RSA1 cipher %d", cipher_type); | 465 | debug("Unsupported RSA1 cipher %d", cipher_type); |
466 | buffer_free(©); | ||
460 | goto fail; | 467 | goto fail; |
461 | } | 468 | } |
462 | /* Initialize space for decrypted data. */ | 469 | /* Initialize space for decrypted data. */ |
463 | buffer_init(&decrypted); | 470 | buffer_init(&decrypted); |
464 | cp = buffer_append_space(&decrypted, buffer_len(blob)); | 471 | cp = buffer_append_space(&decrypted, buffer_len(©)); |
465 | 472 | ||
466 | /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ | 473 | /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ |
467 | cipher_set_key_string(&ciphercontext, cipher, passphrase, | 474 | cipher_set_key_string(&ciphercontext, cipher, passphrase, |
468 | CIPHER_DECRYPT); | 475 | CIPHER_DECRYPT); |
469 | cipher_crypt(&ciphercontext, cp, | 476 | cipher_crypt(&ciphercontext, cp, |
470 | buffer_ptr(blob), buffer_len(blob)); | 477 | buffer_ptr(©), buffer_len(©)); |
471 | cipher_cleanup(&ciphercontext); | 478 | cipher_cleanup(&ciphercontext); |
472 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | 479 | memset(&ciphercontext, 0, sizeof(ciphercontext)); |
473 | buffer_clear(blob); | 480 | buffer_free(©); |
474 | 481 | ||
475 | check1 = buffer_get_char(&decrypted); | 482 | check1 = buffer_get_char(&decrypted); |
476 | check2 = buffer_get_char(&decrypted); | 483 | check2 = buffer_get_char(&decrypted); |
@@ -692,13 +699,9 @@ key_parse_private(Buffer *buffer, const char *filename, | |||
692 | const char *passphrase, char **commentp) | 699 | const char *passphrase, char **commentp) |
693 | { | 700 | { |
694 | Key *pub, *prv; | 701 | Key *pub, *prv; |
695 | Buffer pubcopy; | ||
696 | 702 | ||
697 | buffer_init(&pubcopy); | ||
698 | buffer_append(&pubcopy, buffer_ptr(buffer), buffer_len(buffer)); | ||
699 | /* it's a SSH v1 key if the public key part is readable */ | 703 | /* it's a SSH v1 key if the public key part is readable */ |
700 | pub = key_parse_public_rsa1(&pubcopy, commentp); | 704 | pub = key_parse_public_rsa1(buffer, commentp); |
701 | buffer_free(&pubcopy); | ||
702 | if (pub == NULL) { | 705 | if (pub == NULL) { |
703 | prv = key_parse_private_type(buffer, KEY_UNSPEC, | 706 | prv = key_parse_private_type(buffer, KEY_UNSPEC, |
704 | passphrase, NULL); | 707 | passphrase, NULL); |