Blame SOURCES/openssl-1.0.1e-cve-2015-1789.patch

5c1a6c
diff -up openssl-1.0.1e/crypto/x509/x509_vfy.c.oob-read openssl-1.0.1e/crypto/x509/x509_vfy.c
5c1a6c
--- openssl-1.0.1e/crypto/x509/x509_vfy.c.oob-read	2015-05-25 12:03:41.000000000 +0200
5c1a6c
+++ openssl-1.0.1e/crypto/x509/x509_vfy.c	2015-06-09 15:01:51.688640453 +0200
5c1a6c
@@ -1702,49 +1702,92 @@ int X509_cmp_time(const ASN1_TIME *ctm,
5c1a6c
 	ASN1_TIME atm;
5c1a6c
 	long offset;
5c1a6c
 	char buff1[24],buff2[24],*p;
5c1a6c
-	int i,j;
5c1a6c
+	int i, j, remaining;
5c1a6c
 
5c1a6c
 	p=buff1;
5c1a6c
-	i=ctm->length;
5c1a6c
+	remaining=ctm->length;
5c1a6c
 	str=(char *)ctm->data;
5c1a6c
+	/*
5c1a6c
+	 * Note that the following (historical) code allows much more slack in the
5c1a6c
+	 * time format than RFC5280. In RFC5280, the representation is fixed:
5c1a6c
+	 * UTCTime: YYMMDDHHMMSSZ
5c1a6c
+	 * GeneralizedTime: YYYYMMDDHHMMSSZ
5c1a6c
+	 */
5c1a6c
 	if (ctm->type == V_ASN1_UTCTIME)
5c1a6c
 		{
5c1a6c
-		if ((i < 11) || (i > 17)) return 0;
5c1a6c
+		/* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
5c1a6c
+		int min_length = sizeof("YYMMDDHHMMZ") - 1;
5c1a6c
+		int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
5c1a6c
+		if (remaining < min_length || remaining > max_length)
5c1a6c
+			return 0;
5c1a6c
 		memcpy(p,str,10);
5c1a6c
 		p+=10;
5c1a6c
 		str+=10;
5c1a6c
+		remaining -= 10;
5c1a6c
 		}
5c1a6c
 	else
5c1a6c
 		{
5c1a6c
-		if (i < 13) return 0;
5c1a6c
+		/* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
5c1a6c
+		int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
5c1a6c
+		int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
5c1a6c
+		if (remaining < min_length || remaining > max_length)
5c1a6c
+			return 0;
5c1a6c
 		memcpy(p,str,12);
5c1a6c
 		p+=12;
5c1a6c
 		str+=12;
5c1a6c
+		remaining -= 12;
5c1a6c
 		}
5c1a6c
 
5c1a6c
 	if ((*str == 'Z') || (*str == '-') || (*str == '+'))
5c1a6c
 		{ *(p++)='0'; *(p++)='0'; }
5c1a6c
 	else
5c1a6c
 		{ 
5c1a6c
+		/* SS (seconds) */
5c1a6c
+		if (remaining < 2)
5c1a6c
+			return 0;
5c1a6c
 		*(p++)= *(str++);
5c1a6c
 		*(p++)= *(str++);
5c1a6c
-		/* Skip any fractional seconds... */
5c1a6c
-		if (*str == '.')
5c1a6c
+		remaining -= 2;
5c1a6c
+		/*
5c1a6c
+		 * Skip any (up to three) fractional seconds...
5c1a6c
+		 * TODO(emilia): in RFC5280, fractional seconds are forbidden.
5c1a6c
+		 * Can we just kill them altogether?
5c1a6c
+		 */
5c1a6c
+		if (remaining && *str == '.')
5c1a6c
 			{
5c1a6c
 			str++;
5c1a6c
-			while ((*str >= '0') && (*str <= '9')) str++;
5c1a6c
+			remaining--;
5c1a6c
+			for (i = 0; i < 3 && remaining; i++, str++, remaining--)
5c1a6c
+				{
5c1a6c
+				if (*str < '0' || *str > '9')
5c1a6c
+					break;
5c1a6c
+				}
5c1a6c
 			}
5c1a6c
 		
5c1a6c
 		}
5c1a6c
 	*(p++)='Z';
5c1a6c
 	*(p++)='\0';
5c1a6c
 
5c1a6c
+	/* We now need either a terminating 'Z' or an offset. */
5c1a6c
+	if (!remaining)
5c1a6c
+		return 0;
5c1a6c
 	if (*str == 'Z')
5c1a6c
+		{
5c1a6c
+		if (remaining != 1)
5c1a6c
+			return 0;
5c1a6c
 		offset=0;
5c1a6c
+		}
5c1a6c
 	else
5c1a6c
 		{
5c1a6c
+	        /* (+-)HHMM */
5c1a6c
 		if ((*str != '+') && (*str != '-'))
5c1a6c
 			return 0;
5c1a6c
+		/* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
5c1a6c
+		if (remaining != 5)
5c1a6c
+			return 0;
5c1a6c
+		if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
5c1a6c
+			str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
5c1a6c
+			return 0;
5c1a6c
 		offset=((str[1]-'0')*10+(str[2]-'0'))*60;
5c1a6c
 		offset+=(str[3]-'0')*10+(str[4]-'0');
5c1a6c
 		if (*str == '-')