diff options
author | Emilia Kasper <emilia@openssl.org> | 2014-08-07 04:23:04 +0400 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2014-08-08 01:09:47 +0400 |
commit | 0dccfbc6c7dda409deb1ce88fd21caf50d4f9bde (patch) | |
tree | cbe46a8157e9898457503661d482372b4d26d84a /crypto/asn1 | |
parent | abae631fb9af14c60834c58769ef57979ff35eee (diff) |
Fix OID handling.
- Upon parsing, reject OIDs with invalid base-128 encoding.
- Always NUL-terminate the destination buffer in OBJ_obj2txt printing
function.
CVE-2014-3508
(Imported from upstream's c01618dd822cc724c05eeb52455874ad068ec6a5)
Change-Id: I12bdeeaa700183195e4c2f474f964f8ae7a04549
Reviewed-on: https://boringssl-review.googlesource.com/1440
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'crypto/asn1')
-rw-r--r-- | crypto/asn1/a_object.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c index f2a9e2db..16d5e791 100644 --- a/crypto/asn1/a_object.c +++ b/crypto/asn1/a_object.c @@ -282,17 +282,29 @@ err: OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_OBJECT, i); return(NULL); } + ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long len) { ASN1_OBJECT *ret=NULL; const unsigned char *p; unsigned char *data; - int i; - /* Sanity check OID encoding: can't have leading 0x80 in - * subidentifiers, see: X.690 8.19.2 + int i, length; + + /* Sanity check OID encoding. + * Need at least one content octet. + * MSB must be clear in the last octet. + * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2 */ - for (i = 0, p = *pp; i < len; i++, p++) + if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || + p[len - 1] & 0x80) + { + OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); + return NULL; + } + /* Now 0 < len <= INT_MAX, so the cast is safe. */ + length = (int)len; + for (i = 0; i < length; i++, p++) { if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { @@ -315,23 +327,23 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, data = (unsigned char *)ret->data; ret->data = NULL; /* once detached we can change it */ - if ((data == NULL) || (ret->length < len)) + if ((data == NULL) || (ret->length < length)) { ret->length=0; if (data != NULL) OPENSSL_free(data); - data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); + data=(unsigned char *)OPENSSL_malloc(length); if (data == NULL) { i=ERR_R_MALLOC_FAILURE; goto err; } ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; } - memcpy(data,p,(int)len); + memcpy(data,p,length); /* reattach data to object, after which it remains const */ ret->data =data; - ret->length=(int)len; + ret->length=length; ret->sn=NULL; ret->ln=NULL; /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ - p+=len; + p+=length; if (a != NULL) (*a)=ret; *pp=p; |