diff options
author | Matt Caswell <matt@openssl.org> | 2016-04-27 14:00:37 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-04-28 13:13:09 +0100 |
commit | 8e588e2812f82419fb177e42480b4edffc676070 (patch) | |
tree | b880ed40e79ff50538f3d366b0a1460faf9ed328 /crypto/pem | |
parent | 204cf9406e8f8cd1e3748e69a19e35bf0c224443 (diff) | |
download | openssl-8e588e2812f82419fb177e42480b4edffc676070.tar.gz |
Don't leak memory on error in i2b_PVK
The i2b_PVK function leaked a number of different memory allocations on
error paths (and even some non-error paths).
Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'crypto/pem')
-rw-r--r-- | crypto/pem/pvkfmt.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c index 85ab677a21..e7ee6ddf9c 100644 --- a/crypto/pem/pvkfmt.c +++ b/crypto/pem/pvkfmt.c @@ -807,26 +807,29 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, { int outlen = 24, pklen; unsigned char *p, *salt = NULL; - EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX *cctx = NULL; if (enclevel) outlen += PVK_SALTLEN; pklen = do_i2b(NULL, pk, 0); if (pklen < 0) return -1; outlen += pklen; - if (!out) + if (out == NULL) return outlen; - if (*out) + if (*out != NULL) { p = *out; - else { + } else { p = OPENSSL_malloc(outlen); if (p == NULL) { PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE); return -1; } - *out = p; } + cctx = EVP_CIPHER_CTX_new(); + if (cctx == NULL) + return -1; + write_ledword(&p, MS_PVKMAGIC); write_ledword(&p, 0); if (EVP_PKEY_id(pk) == EVP_PKEY_DSA) @@ -843,9 +846,7 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, p += PVK_SALTLEN; } do_i2b(&p, pk, 0); - if (enclevel == 0) - return outlen; - else { + if (enclevel != 0) { char psbuf[PEM_BUFSIZE]; unsigned char keybuf[20]; int enctmplen, inlen; @@ -871,7 +872,12 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, if (!EVP_DecryptFinal_ex(cctx, p + enctmplen, &enctmplen)) goto error; } + EVP_CIPHER_CTX_free(cctx); + + if (*out == NULL) + *out = p; + return outlen; error: |