summaryrefslogtreecommitdiffstats
path: root/crypto/asn1
diff options
context:
space:
mode:
authorDr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>2018-04-26 20:36:41 +0200
committerDr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>2018-05-02 20:37:47 +0200
commitebdeeb363f03848cea5028e63c6be294a34a8426 (patch)
tree9fa597d3272ff9b110d47aef718ecaf46262a75e /crypto/asn1
parentbf87bf45f181fa130af27739f5c38aba88f88cfd (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/6117)
Diffstat (limited to 'crypto/asn1')
-rw-r--r--crypto/asn1/a_strex.c25
-rw-r--r--crypto/asn1/asn1_err.c1
2 files changed, 24 insertions, 2 deletions
diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c
index b91266b3c5..75bc4319c7 100644
--- a/crypto/asn1/a_strex.c
+++ b/crypto/asn1/a_strex.c
@@ -139,7 +139,7 @@ static int do_buf(unsigned char *buf, int buflen,
int type, unsigned short flags, char *quotes, char_io *io_ch,
void *arg)
{
- int i, outlen, len;
+ int i, outlen, len, charwidth;
unsigned short orflags;
unsigned char *p, *q;
unsigned long c;
@@ -147,12 +147,32 @@ static int do_buf(unsigned char *buf, int buflen,
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;
@@ -173,6 +193,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_err.c b/crypto/asn1/asn1_err.c
index 8602c408d9..7068c0c54f 100644
--- a/crypto/asn1/asn1_err.c
+++ b/crypto/asn1/asn1_err.c
@@ -92,6 +92,7 @@ static ERR_STRING_DATA ASN1_str_functs[] = {
{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"},
{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"},
{ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"},
+ {ERR_FUNC(ASN1_F_DO_BUF), "do_buf"},
{ERR_FUNC(ASN1_F_DO_TCREATE), "do_tcreate"},
{ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"},
{ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"},