File 0001-Fix-buffer-overrun-in-ASN1_parse.patch of Package openssl

From 697283ba418b21c4c0682d7050264b492e2ea4e2 Mon Sep 17 00:00:00 2001
From: Viktor Dukhovni <openssl-users@dukhovni.org>
Date: Tue, 19 Apr 2016 22:23:24 -0400
Subject: [PATCH] Fix buffer overrun in ASN1_parse().

Backport of commits:

        79c7f74d6cefd5d32fa20e69195ad3de834ce065
	bdcd660e33710079b495cf5cc6a1aaa5d2dcd317

from master.

Reviewed-by: Matt Caswell <matt@openssl.org>
---
 crypto/asn1/asn1_lib.c | 18 +++++++-----------
 crypto/asn1/asn1_par.c | 17 +++++++++++++----
 2 files changed, 20 insertions(+), 15 deletions(-)

Index: openssl-1.0.1i/crypto/asn1/asn1_lib.c
===================================================================
--- openssl-1.0.1i.orig/crypto/asn1/asn1_lib.c	2016-04-28 17:19:12.524562985 +0200
+++ openssl-1.0.1i/crypto/asn1/asn1_lib.c	2016-04-28 17:22:25.536752503 +0200
@@ -62,7 +62,7 @@
 #include <openssl/asn1.h>
 #include <openssl/asn1_mac.h>
 
-static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
+static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,long max);
 static void asn1_put_length(unsigned char **pp, int length);
 const char ASN1_version[]="ASN.1" OPENSSL_VERSION_PTEXT;
 
@@ -129,7 +129,7 @@ int ASN1_get_object(const unsigned char
 		}
 	*ptag=tag;
 	*pclass=xclass;
-	if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
+	if (!asn1_get_length(&p,&inf,plength,max)) goto err;
 
 	if (inf && !(ret & V_ASN1_CONSTRUCTED))
 		goto err;
@@ -154,11 +154,11 @@ err:
 	return(0x80);
 	}
 
-static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, long max)
 	{
 	const unsigned char *p= *pp;
 	unsigned long ret=0;
-	unsigned int i;
+	unsigned long i;
 
 	if (max-- < 1) return(0);
 	if (*p == 0x80)
@@ -173,14 +173,12 @@ static int asn1_get_length(const unsigne
 		i= *p&0x7f;
 		if (*(p++) & 0x80)
 			{
-			if (i > sizeof(long))
+			if (i > sizeof(ret) || max < i)
 				return 0;
-			if (max-- == 0) return(0);
 			while (i-- > 0)
 				{
 				ret<<=8L;
 				ret|= *(p++);
-				if (max-- == 0) return(0);
 				}
 			}
 		else
Index: openssl-1.0.1i/crypto/asn1/asn1_par.c
===================================================================
--- openssl-1.0.1i.orig/crypto/asn1/asn1_par.c	2016-04-28 17:19:12.524562985 +0200
+++ openssl-1.0.1i/crypto/asn1/asn1_par.c	2016-04-28 17:27:44.140999764 +0200
@@ -165,6 +165,7 @@ static int asn1_parse2(BIO *bp, const un
 			goto end;
 		if (j & V_ASN1_CONSTRUCTED)
 			{
+			const unsigned char *sp;
 			ep=p+len;
 			if (BIO_write(bp,"\n",1) <= 0) goto end;
 			if (len > length)
@@ -176,23 +177,33 @@ static int asn1_parse2(BIO *bp, const un
 				}
 			if ((j == 0x21) && (len == 0))
 				{
+				sp = p;
 				for (;;)
 					{
 					r=asn1_parse2(bp,&p,(long)(tot-p),
 						offset+(p - *pp),depth+1,
 						indent,dump);
 					if (r == 0) { ret=0; goto end; }
-					if ((r == 2) || (p >= tot)) break;
+					if ((r == 2) || (p >= tot))
+						{
+						len = p - sp;
+						break;
+						}
 					}
 				}
 			else
+				{
+				long tmp = len;
 				while (p < ep)
 					{
-					r=asn1_parse2(bp,&p,(long)len,
+					sp = p;
+					r=asn1_parse2(bp,&p,tmp,
 						offset+(p - *pp),depth+1,
 						indent,dump);
 					if (r == 0) { ret=0; goto end; }
+					tmp -= p - sp;
 					}
+				}
 			}
 		else if (xclass != 0)
 			{