summaryrefslogtreecommitdiffstats
path: root/crypto/ct
diff options
context:
space:
mode:
authorBenjamin Kaduk <bkaduk@akamai.com>2017-06-09 13:31:11 -0400
committerRich Salz <rsalz@openssl.org>2017-06-09 13:32:29 -0400
commit62b0a0dea612e3683c6bd4bef359fceda00238e8 (patch)
tree46da1e6a25e540698cb6b896440c8f70fffe6d2b /crypto/ct
parent388d679a4fd8a408e7c7c1867cc974cdc977ae63 (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.c12
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;
}