diff options
author | Dr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com> | 2018-04-26 20:36:41 +0200 |
---|---|---|
committer | Dr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com> | 2018-05-02 20:39:25 +0200 |
commit | 7e6c0f56e65af0727d87615342df1272cd017e9f (patch) | |
tree | 9cfaf4284d858dd27b74fc7c008979aa0bd9596a /crypto | |
parent | a96022b3c4d159d1b14f54bd6811fd97a52df636 (diff) |
a_strex.c: prevent out of bound read in do_buf()
which is used for ASN1_STRING_print_ex*() and X509_NAME_print_ex*().
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6118)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/asn1/a_strex.c | 25 | ||||
-rw-r--r-- | crypto/asn1/asn1.h | 6 | ||||
-rw-r--r-- | crypto/asn1/asn1_err.c | 1 |
3 files changed, 28 insertions, 4 deletions
diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c index 95f0416207..65f47a7c22 100644 --- a/crypto/asn1/a_strex.c +++ b/crypto/asn1/a_strex.c @@ -194,18 +194,38 @@ static int do_buf(unsigned char *buf, int buflen, int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg) { - int i, outlen, len; + int i, outlen, len, charwidth; unsigned char orflags, *p, *q; unsigned long c; p = buf; q = buf + buflen; outlen = 0; + charwidth = type & BUF_TYPE_WIDTH_MASK; + + switch (charwidth) { + case 4: + if (buflen & 3) { + ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); + return -1; + } + break; + case 2: + if (buflen & 1) { + ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_BMPSTRING_LENGTH); + return -1; + } + break; + default: + break; + } + while (p != q) { if (p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253; else orflags = 0; - switch (type & BUF_TYPE_WIDTH_MASK) { + + switch (charwidth) { case 4: c = ((unsigned long)*p++) << 24; c |= ((unsigned long)*p++) << 16; @@ -226,6 +246,7 @@ static int do_buf(unsigned char *buf, int buflen, i = UTF8_getc(p, buflen, &c); if (i < 0) return -1; /* Invalid UTF8String */ + buflen -= i; p += i; break; default: diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index 35a2b2aa02..256c531811 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -1164,6 +1164,7 @@ int SMIME_text(BIO *in, BIO *out); * The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. */ + void ERR_load_ASN1_strings(void); /* Error codes for the ASN1 functions. */ @@ -1264,6 +1265,7 @@ void ERR_load_ASN1_strings(void); # define ASN1_F_D2I_X509 156 # define ASN1_F_D2I_X509_CINF 157 # define ASN1_F_D2I_X509_PKEY 159 +# define ASN1_F_DO_BUF 221 # define ASN1_F_I2D_ASN1_BIO_STREAM 211 # define ASN1_F_I2D_ASN1_SET 188 # define ASN1_F_I2D_ASN1_TIME 160 @@ -1414,7 +1416,7 @@ void ERR_load_ASN1_strings(void); # define ASN1_R_WRONG_TAG 168 # define ASN1_R_WRONG_TYPE 169 -#ifdef __cplusplus +# ifdef __cplusplus } -#endif +# endif #endif diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c index cfc1512f9d..c144180836 100644 --- a/crypto/asn1/asn1_err.c +++ b/crypto/asn1/asn1_err.c @@ -166,6 +166,7 @@ static ERR_STRING_DATA ASN1_str_functs[] = { {ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"}, {ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"}, {ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"}, + {ERR_FUNC(ASN1_F_DO_BUF), "DO_BUF"}, {ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"}, {ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"}, {ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"}, |