Skip to content

Commit ffa4da4

Browse files
author
cameronrich
committed
Fix in asn1_get_printable string
Buffer overflow vulnerability in proc.c Possible double memory release on invalid certificates. git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@221 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
1 parent 1378f8a commit ffa4da4

File tree

5 files changed

+29
-17
lines changed

5 files changed

+29
-17
lines changed

crypto/crypto_misc.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,13 +348,15 @@ EXP_FUNC int STDCALL base64_decode(const char *in, int len,
348348

349349
y = t = 0;
350350
}
351+
352+
if (z >= *outlen) /* check that we don't go past the output buffer */
353+
goto error;
351354
}
352355

353356
if (y != 0)
354357
goto error;
355358

356-
if (outlen)
357-
*outlen = z;
359+
*outlen = z;
358360
ret = 0;
359361

360362
error:

httpd/proc.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ static int procheadelem(struct connstruct *cn, char *buf)
152152
else if (strcasecmp(buf, "Authorization:") == 0 &&
153153
strncmp(value, "Basic ", 6) == 0)
154154
{
155-
int size;
155+
int size = sizeof(cn->authorization);
156156
if (base64_decode(&value[6], strlen(&value[6]),
157157
(uint8_t *)cn->authorization, &size))
158158
cn->authorization[0] = 0; /* error */
@@ -1051,7 +1051,8 @@ static int check_digest(char *salt, const char *msg_passwd)
10511051
{
10521052
uint8_t b256_salt[MAXREQUESTLENGTH];
10531053
uint8_t real_passwd[MD5_SIZE];
1054-
int salt_size;
1054+
int salt_size = sizeof(b256_salt);
1055+
int password_size = sizeof(real_passwd);
10551056
char *b64_passwd;
10561057
uint8_t md5_result[MD5_SIZE];
10571058
MD5_CTX ctx;
@@ -1064,7 +1065,8 @@ static int check_digest(char *salt, const char *msg_passwd)
10641065
if (base64_decode(salt, strlen(salt), b256_salt, &salt_size))
10651066
return -1;
10661067

1067-
if (base64_decode(b64_passwd, strlen(b64_passwd), real_passwd, NULL))
1068+
if (base64_decode(b64_passwd, strlen(b64_passwd), real_passwd,
1069+
&password_size))
10681070
return -1;
10691071

10701072
/* very simple MD5 crypt algorithm, but then the salt we use is large */

ssl/asn1.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,19 +288,20 @@ static int asn1_get_oid_x520(const uint8_t *buf, int *offset)
288288
static int asn1_get_printable_str(const uint8_t *buf, int *offset, char **str)
289289
{
290290
int len = X509_NOT_OK;
291+
int asn1_type = buf[*offset];
291292

292293
/* some certs have this awful crud in them for some reason */
293-
if (buf[*offset] != ASN1_PRINTABLE_STR &&
294-
buf[*offset] != ASN1_PRINTABLE_STR2 &&
295-
buf[*offset] != ASN1_TELETEX_STR &&
296-
buf[*offset] != ASN1_IA5_STR &&
297-
buf[*offset] != ASN1_UNICODE_STR)
294+
if (buf[asn1_type] != ASN1_PRINTABLE_STR &&
295+
buf[asn1_type] != ASN1_PRINTABLE_STR2 &&
296+
buf[asn1_type] != ASN1_TELETEX_STR &&
297+
buf[asn1_type] != ASN1_IA5_STR &&
298+
buf[asn1_type] != ASN1_UNICODE_STR)
298299
goto end_pnt_str;
299300

300301
(*offset)++;
301302
len = get_asn1_length(buf, offset);
302303

303-
if (buf[*offset - 1] == ASN1_UNICODE_STR)
304+
if (buf[asn1_type - 1] == ASN1_UNICODE_STR)
304305
{
305306
int i;
306307
*str = (char *)malloc(len/2+1); /* allow for null */
@@ -330,7 +331,7 @@ int asn1_name(const uint8_t *cert, int *offset, char *dn[])
330331
{
331332
int ret = X509_NOT_OK;
332333
int dn_type;
333-
char *tmp = NULL;
334+
char *tmp;
334335

335336
if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
336337
goto end_name;
@@ -343,6 +344,8 @@ int asn1_name(const uint8_t *cert, int *offset, char *dn[])
343344
(dn_type = asn1_get_oid_x520(cert, offset)) < 0)
344345
goto end_name;
345346

347+
tmp = NULL;
348+
346349
if (asn1_get_printable_str(cert, offset, &tmp) < 0)
347350
{
348351
free(tmp);

ssl/loader.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ static int pem_decrypt(const char *where, const char *end,
259259

260260
/* turn base64 into binary */
261261
pem_size = (int)(end-start);
262+
ssl_obj->len = sizeof(ssl_obj->buf);
262263
if (base64_decode(start, pem_size, ssl_obj->buf, &ssl_obj->len) != 0)
263264
goto error;
264265

@@ -326,11 +327,15 @@ static int new_pem_obj(SSL_CTX *ssl_ctx, int is_cacert, char *where,
326327
goto error;
327328
}
328329
}
329-
else if (base64_decode(start, pem_size,
330-
ssl_obj->buf, &ssl_obj->len) != 0)
330+
else
331331
{
332-
ret = SSL_ERROR_BAD_CERTIFICATE;
333-
goto error;
332+
ssl_obj->len = pem_size;
333+
if (base64_decode(start, pem_size,
334+
ssl_obj->buf, &ssl_obj->len) != 0)
335+
{
336+
ret = SSL_ERROR_BAD_CERTIFICATE;
337+
goto error;
338+
}
334339
}
335340

336341
switch (i)

0 commit comments

Comments
 (0)