diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2011-06-14 22:49:19 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2011-06-14 22:49:19 +0000 |
commit | a1a09b596c0616ce46c113367e177885e17943f1 (patch) | |
tree | 4765dba3475f77aec327d1b5f94510529e0726f0 /usr.bin | |
parent | b5cd3f364ec6c9c5253bd0838c98f07c20320833 (diff) |
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@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ssh/authfile.c | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/usr.bin/ssh/authfile.c b/usr.bin/ssh/authfile.c index 325a8e25005..228934ac26e 100644 --- a/usr.bin/ssh/authfile.c +++ b/usr.bin/ssh/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.91 2011/05/23 07:24:57 djm Exp $ */ +/* $OpenBSD: authfile.c,v 1.92 2011/06/14 22:49:18 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -268,6 +268,7 @@ static Key * key_parse_public_rsa1(Buffer *blob, char **commentp) { Key *pub; + Buffer copy; /* Check that it is at least big enough to contain the ID string. */ if (buffer_len(blob) < sizeof(authfile_id_string)) { @@ -284,21 +285,23 @@ key_parse_public_rsa1(Buffer *blob, char **commentp) debug3("Incorrect RSA1 identifier"); return NULL; } - buffer_consume(blob, sizeof(authfile_id_string)); + buffer_init(©); + buffer_append(©, buffer_ptr(blob), buffer_len(blob)); + buffer_consume(©, sizeof(authfile_id_string)); /* Skip cipher type and reserved data. */ - (void) buffer_get_char(blob); /* cipher type */ - (void) buffer_get_int(blob); /* reserved */ + (void) buffer_get_char(©); /* cipher type */ + (void) buffer_get_int(©); /* reserved */ /* Read the public key from the buffer. */ - (void) buffer_get_int(blob); + (void) buffer_get_int(©); pub = key_new(KEY_RSA1); - buffer_get_bignum(blob, pub->rsa->n); - buffer_get_bignum(blob, pub->rsa->e); + buffer_get_bignum(©, pub->rsa->n); + buffer_get_bignum(©, pub->rsa->e); if (commentp) - *commentp = buffer_get_string(blob, NULL); + *commentp = buffer_get_string(©, NULL); /* The encrypted private part is not parsed by this function. */ - buffer_clear(blob); + buffer_free(©); return pub; } @@ -409,6 +412,7 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) CipherContext ciphercontext; Cipher *cipher; Key *prv = NULL; + Buffer copy; /* Check that it is at least big enough to contain the ID string. */ if (buffer_len(blob) < sizeof(authfile_id_string)) { @@ -425,41 +429,44 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) debug3("Incorrect RSA1 identifier"); return NULL; } - buffer_consume(blob, sizeof(authfile_id_string)); + buffer_init(©); + buffer_append(©, buffer_ptr(blob), buffer_len(blob)); + buffer_consume(©, sizeof(authfile_id_string)); /* Read cipher type. */ - cipher_type = buffer_get_char(blob); - (void) buffer_get_int(blob); /* Reserved data. */ + cipher_type = buffer_get_char(©); + (void) buffer_get_int(©); /* Reserved data. */ /* Read the public key from the buffer. */ - (void) buffer_get_int(blob); + (void) buffer_get_int(©); prv = key_new_private(KEY_RSA1); - buffer_get_bignum(blob, prv->rsa->n); - buffer_get_bignum(blob, prv->rsa->e); + buffer_get_bignum(©, prv->rsa->n); + buffer_get_bignum(©, prv->rsa->e); if (commentp) - *commentp = buffer_get_string(blob, NULL); + *commentp = buffer_get_string(©, NULL); else - (void)buffer_get_string_ptr(blob, NULL); + (void)buffer_get_string_ptr(©, NULL); /* Check that it is a supported cipher. */ cipher = cipher_by_number(cipher_type); if (cipher == NULL) { debug("Unsupported RSA1 cipher %d", cipher_type); + buffer_free(©); goto fail; } /* Initialize space for decrypted data. */ buffer_init(&decrypted); - cp = buffer_append_space(&decrypted, buffer_len(blob)); + cp = buffer_append_space(&decrypted, buffer_len(©)); /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_DECRYPT); cipher_crypt(&ciphercontext, cp, - buffer_ptr(blob), buffer_len(blob)); + buffer_ptr(©), buffer_len(©)); cipher_cleanup(&ciphercontext); memset(&ciphercontext, 0, sizeof(ciphercontext)); - buffer_clear(blob); + buffer_free(©); check1 = buffer_get_char(&decrypted); check2 = buffer_get_char(&decrypted); @@ -676,13 +683,9 @@ key_parse_private(Buffer *buffer, const char *filename, const char *passphrase, char **commentp) { Key *pub, *prv; - Buffer pubcopy; - buffer_init(&pubcopy); - buffer_append(&pubcopy, buffer_ptr(buffer), buffer_len(buffer)); /* it's a SSH v1 key if the public key part is readable */ - pub = key_parse_public_rsa1(&pubcopy, commentp); - buffer_free(&pubcopy); + pub = key_parse_public_rsa1(buffer, commentp); if (pub == NULL) { prv = key_parse_private_type(buffer, KEY_UNSPEC, passphrase, NULL); |