diff options
author | David Benjamin <davidben@chromium.org> | 2015-01-12 04:26:34 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2015-01-15 00:50:20 +0300 |
commit | d83c1884fde18931987ba917d15b1ee8c11a4acc (patch) | |
tree | e6c8ddda32f415fd8e9a0235fd7f6e849b363eac /crypto | |
parent | 1716b3d172e6e97f113576fa9bc834288b4b4402 (diff) |
Return error when a bit string indicates an invalid amount of bits left
(Imported from upstream's 5a1e8c67a90aead86ccc2dda324e8f897d1a044d)
Change-Id: Idfba7eb8244c1926e7921119767cb32605a74202
Reviewed-on: https://boringssl-review.googlesource.com/2836
Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/asn1/a_bitstr.c | 22 | ||||
-rw-r--r-- | crypto/asn1/asn1_error.c | 1 |
2 files changed, 16 insertions, 7 deletions
diff --git a/crypto/asn1/a_bitstr.c b/crypto/asn1/a_bitstr.c index 4917bdaf..50384555 100644 --- a/crypto/asn1/a_bitstr.c +++ b/crypto/asn1/a_bitstr.c @@ -118,11 +118,12 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, ASN1_BIT_STRING *ret=NULL; const unsigned char *p; unsigned char *s; - int i; + int padding; if (len < 1) { - i=ASN1_R_STRING_TOO_SHORT; + OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING, + ASN1_R_STRING_TOO_SHORT); goto err; } @@ -134,23 +135,31 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, ret=(*a); p= *pp; - i= *(p++); + padding = *(p++); + if (padding > 7) + { + OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING, + ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + goto err; + } + /* We do this to preserve the settings. If we modify * the settings, via the _set_bit function, we will recalculate * on output */ ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */ - ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */ + ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|padding); /* set */ if (len-- > 1) /* using one because of the bits left byte */ { s=(unsigned char *)OPENSSL_malloc((int)len); if (s == NULL) { - i=ERR_R_MALLOC_FAILURE; + OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING, + ERR_R_MALLOC_FAILURE); goto err; } memcpy(s,p,(int)len); - s[len-1]&=(0xff<<i); + s[len-1]&=(0xff<<padding); p+=len; } else @@ -164,7 +173,6 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, *pp=p; return(ret); err: - OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING, i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) M_ASN1_BIT_STRING_free(ret); return(NULL); diff --git a/crypto/asn1/asn1_error.c b/crypto/asn1/asn1_error.c index 87a7b645..5e9fcaa6 100644 --- a/crypto/asn1/asn1_error.c +++ b/crypto/asn1/asn1_error.c @@ -130,6 +130,7 @@ const ERR_STRING_DATA ASN1_error_string_data[] = { {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_TIME_VALUE), "ILLEGAL_TIME_VALUE"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INTEGER_NOT_ASCII_FORMAT), "INTEGER_NOT_ASCII_FORMAT"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG), "INTEGER_TOO_LARGE_FOR_LONG"}, + {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_BIT_STRING_BITS_LEFT), "INVALID_BIT_STRING_BITS_LEFT"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_BMPSTRING_LENGTH), "INVALID_BMPSTRING_LENGTH"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_DIGIT), "INVALID_DIGIT"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_MIME_TYPE), "INVALID_MIME_TYPE"}, |