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 Reviewed-by: Dr. Stephen Henson <steve@openssl.org> Reviewed-by: Kurt Roeckx <kurt@openssl.org> Reviewed-by: Tim Hudson <tjh@openssl.org>
This commit is contained in:
committed by
Matt Caswell
parent
bff5319d90
commit
b9a73f5481
@@ -285,16 +285,28 @@ err:
|
|||||||
ASN1_OBJECT_free(ret);
|
ASN1_OBJECT_free(ret);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
||||||
long len)
|
long len)
|
||||||
{
|
{
|
||||||
ASN1_OBJECT *ret=NULL;
|
ASN1_OBJECT *ret=NULL;
|
||||||
const unsigned char *p;
|
const unsigned char *p;
|
||||||
int i;
|
int i, length;
|
||||||
/* Sanity check OID encoding: can't have leading 0x80 in
|
|
||||||
* subidentifiers, see: X.690 8.19.2
|
/* 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)
|
||||||
|
{
|
||||||
|
ASN1err(ASN1_F_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)))
|
if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
|
||||||
{
|
{
|
||||||
@@ -313,20 +325,20 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
|||||||
else ret=(*a);
|
else ret=(*a);
|
||||||
|
|
||||||
p= *pp;
|
p= *pp;
|
||||||
if ((ret->data == NULL) || (ret->length < len))
|
if ((ret->data == NULL) || (ret->length < length))
|
||||||
{
|
{
|
||||||
if (ret->data != NULL) OPENSSL_free(ret->data);
|
if (ret->data != NULL) OPENSSL_free(ret->data);
|
||||||
ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
|
ret->data=(unsigned char *)OPENSSL_malloc(length);
|
||||||
ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
||||||
if (ret->data == NULL)
|
if (ret->data == NULL)
|
||||||
{ i=ERR_R_MALLOC_FAILURE; goto err; }
|
{ i=ERR_R_MALLOC_FAILURE; goto err; }
|
||||||
}
|
}
|
||||||
memcpy(ret->data,p,(int)len);
|
memcpy(ret->data,p,length);
|
||||||
ret->length=(int)len;
|
ret->length=length;
|
||||||
ret->sn=NULL;
|
ret->sn=NULL;
|
||||||
ret->ln=NULL;
|
ret->ln=NULL;
|
||||||
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
|
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
|
||||||
p+=len;
|
p+=length;
|
||||||
|
|
||||||
if (a != NULL) (*a)=ret;
|
if (a != NULL) (*a)=ret;
|
||||||
*pp=p;
|
*pp=p;
|
||||||
|
|||||||
@@ -444,11 +444,12 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
|
|||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
|
char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
|
||||||
|
|
||||||
if ((a == NULL) || (a->data == NULL)) {
|
/* Ensure that, at every state, |buf| is NUL-terminated. */
|
||||||
buf[0]='\0';
|
if (buf && buf_len > 0)
|
||||||
return(0);
|
buf[0] = '\0';
|
||||||
}
|
|
||||||
|
|
||||||
|
if ((a == NULL) || (a->data == NULL))
|
||||||
|
return(0);
|
||||||
|
|
||||||
if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
|
if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
|
||||||
{
|
{
|
||||||
@@ -527,9 +528,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
|
|||||||
i=(int)(l/40);
|
i=(int)(l/40);
|
||||||
l-=(long)(i*40);
|
l-=(long)(i*40);
|
||||||
}
|
}
|
||||||
if (buf && (buf_len > 0))
|
if (buf && (buf_len > 1))
|
||||||
{
|
{
|
||||||
*buf++ = i + '0';
|
*buf++ = i + '0';
|
||||||
|
*buf = '\0';
|
||||||
buf_len--;
|
buf_len--;
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
@@ -544,9 +546,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
|
|||||||
i = strlen(bndec);
|
i = strlen(bndec);
|
||||||
if (buf)
|
if (buf)
|
||||||
{
|
{
|
||||||
if (buf_len > 0)
|
if (buf_len > 1)
|
||||||
{
|
{
|
||||||
*buf++ = '.';
|
*buf++ = '.';
|
||||||
|
*buf = '\0';
|
||||||
buf_len--;
|
buf_len--;
|
||||||
}
|
}
|
||||||
BUF_strlcpy(buf,bndec,buf_len);
|
BUF_strlcpy(buf,bndec,buf_len);
|
||||||
@@ -786,4 +789,3 @@ err:
|
|||||||
OPENSSL_free(buf);
|
OPENSSL_free(buf);
|
||||||
return(ok);
|
return(ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user