diff options
author | Benjamin Kaduk <bkaduk@akamai.com> | 2017-06-09 13:31:11 -0400 |
---|---|---|
committer | Rich Salz <rsalz@openssl.org> | 2017-06-09 13:32:29 -0400 |
commit | 62b0a0dea612e3683c6bd4bef359fceda00238e8 (patch) | |
tree | 46da1e6a25e540698cb6b896440c8f70fffe6d2b /crypto/ct | |
parent | 388d679a4fd8a408e7c7c1867cc974cdc977ae63 (diff) |
Fix memory leaks in CTLOG_new_from_base64
Move the call to ct_base64_decode(), which allocates, until after
the check for NULL output parameter.
Also place a cap on the number of padding characters used to decrement
the output length -- any more than two '='s is not permitted in a
well-formed base64 text. Prior to this change, ct_base64_decode() would
return a length of -1 along with allocated storage for an input of
"====".
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3379)
Diffstat (limited to 'crypto/ct')
-rw-r--r-- | crypto/ct/ct_b64.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/crypto/ct/ct_b64.c b/crypto/ct/ct_b64.c index f0bf3aff29..109ffcdcf2 100644 --- a/crypto/ct/ct_b64.c +++ b/crypto/ct/ct_b64.c @@ -24,7 +24,7 @@ static int ct_base64_decode(const char *in, unsigned char **out) { size_t inlen = strlen(in); - int outlen; + int outlen, i; unsigned char *outbuf = NULL; if (inlen == 0) { @@ -45,9 +45,12 @@ static int ct_base64_decode(const char *in, unsigned char **out) goto err; } - /* Subtract padding bytes from |outlen| */ + /* Subtract padding bytes from |outlen|. Any more than 2 is malformed. */ + i = 0; while (in[--inlen] == '=') { --outlen; + if (++i > 2) + goto err; } *out = outbuf; @@ -132,7 +135,7 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64, int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name) { unsigned char *pkey_der = NULL; - int pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der); + int pkey_der_len; const unsigned char *p; EVP_PKEY *pkey = NULL; @@ -141,7 +144,8 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n return 0; } - if (pkey_der_len <= 0) { + pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der); + if (pkey_der_len < 0) { CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY); return 0; } |