File openssl-CVE-2014-3508.patch of Package compat-openssl098.703

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);
 	}
-