Blame SOURCES/openssl-1.0.1e-cve-2013-6449.patch

2b5643
Use version in SSL_METHOD not SSL structure.
2b5643
2b5643
When deciding whether to use TLS 1.2 PRF and record hash algorithms
2b5643
use the version number in the corresponding SSL_METHOD structure
2b5643
instead of the SSL structure. The SSL structure version is sometimes
2b5643
inaccurate. Note: OpenSSL 1.0.2 and later effectively do this already.
2b5643
(CVE-2013-6449)
2b5643
2b5643
Also preventively check EVP errors for handshake digests.
2b5643
2b5643
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
2b5643
index bf832bb..c4ef273 100644
2b5643
--- a/ssl/s3_lib.c
2b5643
+++ b/ssl/s3_lib.c
2b5643
@@ -4286,7 +4286,7 @@ need to go to SSL_ST_ACCEPT.
2b5643
 long ssl_get_algorithm2(SSL *s)
2b5643
 	{
2b5643
 	long alg2 = s->s3->tmp.new_cipher->algorithm2;
2b5643
-	if (TLS1_get_version(s) >= TLS1_2_VERSION &&
2b5643
+	if (s->method->version == TLS1_2_VERSION &&
2b5643
 	    alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF))
2b5643
 		return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
2b5643
 	return alg2;
2b5643
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
2b5643
index ead01c8..1e5dcab 100644
2b5643
--- a/ssl/s3_both.c
2b5643
+++ b/ssl/s3_both.c
2b5643
@@ -161,6 +161,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
2b5643
 
2b5643
 		i=s->method->ssl3_enc->final_finish_mac(s,
2b5643
 			sender,slen,s->s3->tmp.finish_md);
2b5643
+		if (i == 0)
2b5643
+			return 0;
2b5643
 		s->s3->tmp.finish_md_len = i;
2b5643
 		memcpy(p, s->s3->tmp.finish_md, i);
2b5643
 		p+=i;
2b5643
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
2b5643
index 804291e..c4bc4e7 100644
2b5643
--- a/ssl/s3_pkt.c
2b5643
+++ b/ssl/s3_pkt.c
2b5643
@@ -335,7 +335,7 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
2b5643
 			if (version != s->version)
2b5643
 				{
2b5643
 				SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
2b5643
-                                if ((s->version & 0xFF00) == (version & 0xFF00))
2b5643
+                                if ((s->version & 0xFF00) == (version & 0xFF00) && !s->enc_write_ctx && !s->write_hash)
2b5643
                                 	/* Send back error using their minor version number :-) */
2b5643
 					s->version = (unsigned short)version;
2b5643
 				al=SSL_AD_PROTOCOL_VERSION;
2b5643
@@ -1459,8 +1459,14 @@ int ssl3_do_change_cipher_spec(SSL *s)
2b5643
 		slen=s->method->ssl3_enc->client_finished_label_len;
2b5643
 		}
2b5643
 
2b5643
-	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
2b5643
+	i = s->method->ssl3_enc->final_finish_mac(s,
2b5643
 		sender,slen,s->s3->tmp.peer_finish_md);
2b5643
+	if (i == 0)
2b5643
+		{
2b5643
+		SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
2b5643
+		return 0;
2b5643
+		}
2b5643
+	s->s3->tmp.peer_finish_md_len = i;
2b5643
 
2b5643
 	return(1);
2b5643
 	}
2b5643
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
2b5643
index e5a8b3f..52efed3 100644
2b5643
--- a/ssl/s3_srvr.c
2b5643
+++ b/ssl/s3_srvr.c
2b5643
@@ -958,7 +958,8 @@ int ssl3_get_client_hello(SSL *s)
2b5643
 	    (s->version != DTLS1_VERSION && s->client_version < s->version))
2b5643
 		{
2b5643
 		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
2b5643
-		if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
2b5643
+		if ((s->client_version>>8) == SSL3_VERSION_MAJOR && 
2b5643
+			!s->enc_write_ctx && !s->write_hash)
2b5643
 			{
2b5643
 			/* similar to ssl3_get_record, send alert using remote version number */
2b5643
 			s->version = s->client_version;
2b5643
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
2b5643
index 809ad2e..72015f5 100644
2b5643
--- a/ssl/t1_enc.c
2b5643
+++ b/ssl/t1_enc.c
2b5643
@@ -915,18 +915,19 @@ int tls1_final_finish_mac(SSL *s,
2b5643
 		if (mask & ssl_get_algorithm2(s))
2b5643
 			{
2b5643
 			int hashsize = EVP_MD_size(md);
2b5643
-			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
2b5643
+			EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
2b5643
+			if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
2b5643
 				{
2b5643
 				/* internal error: 'buf' is too small for this cipersuite! */
2b5643
 				err = 1;
2b5643
 				}
2b5643
 			else
2b5643
 				{
2b5643
-				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
2b5643
-				EVP_DigestFinal_ex(&ctx,q,&i);
2b5643
-				if (i != (unsigned int)hashsize) /* can't really happen */
2b5643
+				if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
2b5643
+					!EVP_DigestFinal_ex(&ctx,q,&i) ||
2b5643
+					(i != (unsigned int)hashsize))
2b5643
 					err = 1;
2b5643
-				q+=i;
2b5643
+				q+=hashsize;
2b5643
 				}
2b5643
 			}
2b5643
 		}
2b5643
-- 
2b5643
1.8.3.1
2b5643