|
|
1b2890 |
From 03b04ddac162c7b7fa3c57eadccc5a583a00d291 Mon Sep 17 00:00:00 2001
|
|
|
1b2890 |
From: Emilia Kasper <emilia@openssl.org>
|
|
|
1b2890 |
Date: Wed, 2 Jul 2014 19:02:33 +0200
|
|
|
1b2890 |
Subject: [PATCH] Fix OID handling:
|
|
|
1b2890 |
|
|
|
1b2890 |
- Upon parsing, reject OIDs with invalid base-128 encoding.
|
|
|
1b2890 |
- Always NUL-terminate the destination buffer in OBJ_obj2txt printing function.
|
|
|
1b2890 |
|
|
|
1b2890 |
CVE-2014-3508
|
|
|
1b2890 |
|
|
|
1b2890 |
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
|
|
|
1b2890 |
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
|
|
|
1b2890 |
Reviewed-by: Tim Hudson <tjh@openssl.org>
|
|
|
1b2890 |
---
|
|
|
1b2890 |
crypto/asn1/a_object.c | 30 +++++++++++++++++++++---------
|
|
|
1b2890 |
crypto/objects/obj_dat.c | 16 +++++++++-------
|
|
|
1b2890 |
2 files changed, 30 insertions(+), 16 deletions(-)
|
|
|
1b2890 |
|
|
|
1b2890 |
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c
|
|
|
1b2890 |
index 3978c91..77b2768 100644
|
|
|
1b2890 |
--- a/crypto/asn1/a_object.c
|
|
|
1b2890 |
+++ b/crypto/asn1/a_object.c
|
|
|
1b2890 |
@@ -283,17 +283,29 @@ err:
|
|
|
1b2890 |
ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
|
|
|
1b2890 |
return(NULL);
|
|
|
1b2890 |
}
|
|
|
1b2890 |
+
|
|
|
1b2890 |
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
|
|
1b2890 |
long len)
|
|
|
1b2890 |
{
|
|
|
1b2890 |
ASN1_OBJECT *ret=NULL;
|
|
|
1b2890 |
const unsigned char *p;
|
|
|
1b2890 |
unsigned char *data;
|
|
|
1b2890 |
- int i;
|
|
|
1b2890 |
- /* Sanity check OID encoding: can't have leading 0x80 in
|
|
|
1b2890 |
- * subidentifiers, see: X.690 8.19.2
|
|
|
1b2890 |
+ int i, length;
|
|
|
1b2890 |
+
|
|
|
1b2890 |
+ /* Sanity check OID encoding.
|
|
|
1b2890 |
+ * Need at least one content octet.
|
|
|
1b2890 |
+ * MSB must be clear in the last octet.
|
|
|
1b2890 |
+ * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
|
|
|
1b2890 |
*/
|
|
|
1b2890 |
- for (i = 0, p = *pp; i < len; i++, p++)
|
|
|
1b2890 |
+ if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
|
|
|
1b2890 |
+ p[len - 1] & 0x80)
|
|
|
1b2890 |
+ {
|
|
|
1b2890 |
+ ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
|
|
|
1b2890 |
+ return NULL;
|
|
|
1b2890 |
+ }
|
|
|
1b2890 |
+ /* Now 0 < len <= INT_MAX, so the cast is safe. */
|
|
|
1b2890 |
+ length = (int)len;
|
|
|
1b2890 |
+ for (i = 0; i < length; i++, p++)
|
|
|
1b2890 |
{
|
|
|
1b2890 |
if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
|
|
|
1b2890 |
{
|
|
|
1b2890 |
@@ -316,23 +328,23 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
|
|
1b2890 |
data = (unsigned char *)ret->data;
|
|
|
1b2890 |
ret->data = NULL;
|
|
|
1b2890 |
/* once detached we can change it */
|
|
|
1b2890 |
- if ((data == NULL) || (ret->length < len))
|
|
|
1b2890 |
+ if ((data == NULL) || (ret->length < length))
|
|
|
1b2890 |
{
|
|
|
1b2890 |
ret->length=0;
|
|
|
1b2890 |
if (data != NULL) OPENSSL_free(data);
|
|
|
1b2890 |
- data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
|
|
|
1b2890 |
+ data=(unsigned char *)OPENSSL_malloc(length);
|
|
|
1b2890 |
if (data == NULL)
|
|
|
1b2890 |
{ i=ERR_R_MALLOC_FAILURE; goto err; }
|
|
|
1b2890 |
ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
|
|
1b2890 |
}
|
|
|
1b2890 |
- memcpy(data,p,(int)len);
|
|
|
1b2890 |
+ memcpy(data,p,length);
|
|
|
1b2890 |
/* reattach data to object, after which it remains const */
|
|
|
1b2890 |
ret->data =data;
|
|
|
1b2890 |
- ret->length=(int)len;
|
|
|
1b2890 |
+ ret->length=length;
|
|
|
1b2890 |
ret->sn=NULL;
|
|
|
1b2890 |
ret->ln=NULL;
|
|
|
1b2890 |
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
|
|
|
1b2890 |
- p+=len;
|
|
|
1b2890 |
+ p+=length;
|
|
|
1b2890 |
|
|
|
1b2890 |
if (a != NULL) (*a)=ret;
|
|
|
1b2890 |
*pp=p;
|
|
|
1b2890 |
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
|
|
|
1b2890 |
index 8a342ba..0b2f442 100644
|
|
|
1b2890 |
--- a/crypto/objects/obj_dat.c
|
|
|
1b2890 |
+++ b/crypto/objects/obj_dat.c
|
|
|
1b2890 |
@@ -471,11 +471,12 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
|
|
|
1b2890 |
const unsigned char *p;
|
|
|
1b2890 |
char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
|
|
|
1b2890 |
|
|
|
1b2890 |
- if ((a == NULL) || (a->data == NULL)) {
|
|
|
1b2890 |
- buf[0]='\0';
|
|
|
1b2890 |
- return(0);
|
|
|
1b2890 |
- }
|
|
|
1b2890 |
+ /* Ensure that, at every state, |buf| is NUL-terminated. */
|
|
|
1b2890 |
+ if (buf && buf_len > 0)
|
|
|
1b2890 |
+ buf[0] = '\0';
|
|
|
1b2890 |
|
|
|
1b2890 |
+ if ((a == NULL) || (a->data == NULL))
|
|
|
1b2890 |
+ return(0);
|
|
|
1b2890 |
|
|
|
1b2890 |
if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
|
|
|
1b2890 |
{
|
|
|
1b2890 |
@@ -554,9 +555,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
|
|
|
1b2890 |
i=(int)(l/40);
|
|
|
1b2890 |
l-=(long)(i*40);
|
|
|
1b2890 |
}
|
|
|
1b2890 |
- if (buf && (buf_len > 0))
|
|
|
1b2890 |
+ if (buf && (buf_len > 1))
|
|
|
1b2890 |
{
|
|
|
1b2890 |
*buf++ = i + '0';
|
|
|
1b2890 |
+ *buf = '\0';
|
|
|
1b2890 |
buf_len--;
|
|
|
1b2890 |
}
|
|
|
1b2890 |
n++;
|
|
|
1b2890 |
@@ -571,9 +573,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
|
|
|
1b2890 |
i = strlen(bndec);
|
|
|
1b2890 |
if (buf)
|
|
|
1b2890 |
{
|
|
|
1b2890 |
- if (buf_len > 0)
|
|
|
1b2890 |
+ if (buf_len > 1)
|
|
|
1b2890 |
{
|
|
|
1b2890 |
*buf++ = '.';
|
|
|
1b2890 |
+ *buf = '\0';
|
|
|
1b2890 |
buf_len--;
|
|
|
1b2890 |
}
|
|
|
1b2890 |
BUF_strlcpy(buf,bndec,buf_len);
|
|
|
1b2890 |
@@ -807,4 +810,3 @@ err:
|
|
|
1b2890 |
OPENSSL_free(buf);
|
|
|
1b2890 |
return(ok);
|
|
|
1b2890 |
}
|
|
|
1b2890 |
-
|
|
|
1b2890 |
--
|
|
|
1b2890 |
1.8.3.1
|
|
|
1b2890 |
|