mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-31 01:35:11 +02:00
upstream commit
don't choke on new-format private keys encrypted with an AEAD cipher; bz#2366, patch from Ron Frederick; ok markus@
This commit is contained in:
parent
f8484dac67
commit
63ebf019be
15
sshkey.c
15
sshkey.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: sshkey.c,v 1.16 2015/04/03 22:17:27 djm Exp $ */
|
/* $OpenBSD: sshkey.c,v 1.18 2015/05/08 03:17:49 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
|
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
|
||||||
@ -3201,7 +3201,7 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
|
|||||||
const u_char *cp;
|
const u_char *cp;
|
||||||
int r = SSH_ERR_INTERNAL_ERROR;
|
int r = SSH_ERR_INTERNAL_ERROR;
|
||||||
size_t encoded_len;
|
size_t encoded_len;
|
||||||
size_t i, keylen = 0, ivlen = 0, slen = 0;
|
size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0;
|
||||||
struct sshbuf *encoded = NULL, *decoded = NULL;
|
struct sshbuf *encoded = NULL, *decoded = NULL;
|
||||||
struct sshbuf *kdf = NULL, *decrypted = NULL;
|
struct sshbuf *kdf = NULL, *decrypted = NULL;
|
||||||
struct sshcipher_ctx ciphercontext;
|
struct sshcipher_ctx ciphercontext;
|
||||||
@ -3311,6 +3311,7 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
|
|||||||
/* setup key */
|
/* setup key */
|
||||||
keylen = cipher_keylen(cipher);
|
keylen = cipher_keylen(cipher);
|
||||||
ivlen = cipher_ivlen(cipher);
|
ivlen = cipher_ivlen(cipher);
|
||||||
|
authlen = cipher_authlen(cipher);
|
||||||
if ((key = calloc(1, keylen + ivlen)) == NULL) {
|
if ((key = calloc(1, keylen + ivlen)) == NULL) {
|
||||||
r = SSH_ERR_ALLOC_FAIL;
|
r = SSH_ERR_ALLOC_FAIL;
|
||||||
goto out;
|
goto out;
|
||||||
@ -3326,19 +3327,25 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check that an appropriate amount of auth data is present */
|
||||||
|
if (sshbuf_len(decoded) < encrypted_len + authlen) {
|
||||||
|
r = SSH_ERR_INVALID_FORMAT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* decrypt private portion of key */
|
/* decrypt private portion of key */
|
||||||
if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 ||
|
if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 ||
|
||||||
(r = cipher_init(&ciphercontext, cipher, key, keylen,
|
(r = cipher_init(&ciphercontext, cipher, key, keylen,
|
||||||
key + keylen, ivlen, 0)) != 0)
|
key + keylen, ivlen, 0)) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
if ((r = cipher_crypt(&ciphercontext, 0, dp, sshbuf_ptr(decoded),
|
if ((r = cipher_crypt(&ciphercontext, 0, dp, sshbuf_ptr(decoded),
|
||||||
sshbuf_len(decoded), 0, cipher_authlen(cipher))) != 0) {
|
encrypted_len, 0, authlen)) != 0) {
|
||||||
/* an integrity error here indicates an incorrect passphrase */
|
/* an integrity error here indicates an incorrect passphrase */
|
||||||
if (r == SSH_ERR_MAC_INVALID)
|
if (r == SSH_ERR_MAC_INVALID)
|
||||||
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
|
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if ((r = sshbuf_consume(decoded, encrypted_len)) != 0)
|
if ((r = sshbuf_consume(decoded, encrypted_len + authlen)) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
/* there should be no trailing data */
|
/* there should be no trailing data */
|
||||||
if (sshbuf_len(decoded) != 0) {
|
if (sshbuf_len(decoded) != 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user