File openssl-CVE-2014-3508.patch of Package compat-openssl098.29129
commit d9d0f1b52c570f0cc91ac5e8d1eb6a5bce4ba146
Author: Dr. Stephen Henson <steve@openssl.org>
Date: Thu Aug 6 16:32:54 2009 +0000
Reject leading 0x80 in OID subidentifiers.
commit 7ed485bc9fab7609ad06960bf84118ea4c61da3a
Author: Dr. Stephen Henson <steve@openssl.org>
Date: Sun Mar 7 16:40:05 2010 +0000
The OID sanity check was incorrect. It should only disallow *leading* 0x80
values.
commit b9a73f5481fb8d5aac535622759cb0f632f39914
Author: Emilia Kasper <emilia@openssl.org>
Date: Wed Jul 2 19:02:33 2014 +0200
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
diff --git a/apps/x509.c b/apps/x509.c
index d904d34..6a3eef7 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -874,6 +874,7 @@ bad:
else if (text == i)
{
X509_print_ex(out,x,nmflag, certflag);
+ERR_print_errors_fp(stderr);
}
else if (startdate == i)
{
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c
index dc98042..e50501a 100644
--- a/crypto/asn1/a_object.c
+++ b/crypto/asn1/a_object.c
@@ -139,7 +139,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
goto err;
}
- if (!use_bn && l > (ULONG_MAX / 10L))
+ if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
{
use_bn = 1;
if (!bl)
@@ -285,12 +285,35 @@ err:
ASN1_OBJECT_free(ret);
return(NULL);
}
+
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
long len)
{
ASN1_OBJECT *ret=NULL;
const unsigned char *p;
- int i;
+ 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
+ */
+ 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)))
+ {
+ ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
+ return NULL;
+ }
+ }
/* only the ASN1_OBJECTs from the 'table' will have values
* for ->sn or ->ln */
@@ -302,20 +325,20 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
else ret=(*a);
p= *pp;
- if ((ret->data == NULL) || (ret->length < len))
+ if ((ret->data == NULL) || (ret->length < length))
{
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;
if (ret->data == NULL)
{ i=ERR_R_MALLOC_FAILURE; goto err; }
}
- memcpy(ret->data,p,(int)len);
- ret->length=(int)len;
+ memcpy(ret->data,p,length);
+ 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;
diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h
index fb27b04..622aa1d 100644
--- a/crypto/asn1/asn1.h
+++ b/crypto/asn1/asn1.h
@@ -1262,6 +1262,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_INVALID_MIME_TYPE 200
#define ASN1_R_INVALID_MODIFIER 186
#define ASN1_R_INVALID_NUMBER 187
+#define ASN1_R_INVALID_OBJECT_ENCODING 216
#define ASN1_R_INVALID_SEPARATOR 131
#define ASN1_R_INVALID_TIME_FORMAT 132
#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133
diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c
index 5f5de98..3df6212 100644
--- a/crypto/asn1/asn1_err.c
+++ b/crypto/asn1/asn1_err.c
@@ -1,6 +1,6 @@
/* crypto/asn1/asn1_err.c */
/* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -240,6 +240,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
{ERR_REASON(ASN1_R_INVALID_MODIFIER) ,"invalid modifier"},
{ERR_REASON(ASN1_R_INVALID_NUMBER) ,"invalid number"},
+{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING),"invalid object encoding"},
{ERR_REASON(ASN1_R_INVALID_SEPARATOR) ,"invalid separator"},
{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT) ,"invalid time format"},
{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),"invalid universalstring length"},
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
index 7fd7433..cf8cd18 100644
--- a/crypto/objects/obj_dat.c
+++ b/crypto/objects/obj_dat.c
@@ -444,11 +444,12 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
unsigned char *p;
char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
- if ((a == NULL) || (a->data == NULL)) {
- buf[0]='\0';
- return(0);
- }
+ /* Ensure that, at every state, |buf| is NUL-terminated. */
+ if (buf && buf_len > 0)
+ buf[0] = '\0';
+ if ((a == NULL) || (a->data == NULL))
+ return(0);
if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
{
@@ -524,9 +525,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
i=(int)(l/40);
l-=(long)(i*40);
}
- if (buf && (buf_len > 0))
+ if (buf && (buf_len > 1))
{
*buf++ = i + '0';
+ *buf = '\0';
buf_len--;
}
n++;
@@ -541,9 +543,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
i = strlen(bndec);
if (buf)
{
- if (buf_len > 0)
+ if (buf_len > 1)
{
*buf++ = '.';
+ *buf = '\0';
buf_len--;
}
BUF_strlcpy(buf,bndec,buf_len);
@@ -783,4 +786,3 @@ err:
OPENSSL_free(buf);
return(ok);
}
-