8978637
Use version in SSL_METHOD not SSL structure.
8978637
8978637
When deciding whether to use TLS 1.2 PRF and record hash algorithms
8978637
use the version number in the corresponding SSL_METHOD structure
8978637
instead of the SSL structure. The SSL structure version is sometimes
8978637
inaccurate. Note: OpenSSL 1.0.2 and later effectively do this already.
8978637
(CVE-2013-6449)
8978637
8978637
Also preventively check EVP errors for handshake digests.
8978637
8978637
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
8978637
index bf832bb..c4ef273 100644
8978637
--- a/ssl/s3_lib.c
8978637
+++ b/ssl/s3_lib.c
8978637
@@ -4286,7 +4286,7 @@ need to go to SSL_ST_ACCEPT.
8978637
 long ssl_get_algorithm2(SSL *s)
8978637
 	{
8978637
 	long alg2 = s->s3->tmp.new_cipher->algorithm2;
8978637
-	if (TLS1_get_version(s) >= TLS1_2_VERSION &&
8978637
+	if (s->method->version == TLS1_2_VERSION &&
8978637
 	    alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF))
8978637
 		return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
8978637
 	return alg2;
8978637
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
8978637
index ead01c8..1e5dcab 100644
8978637
--- a/ssl/s3_both.c
8978637
+++ b/ssl/s3_both.c
8978637
@@ -161,6 +161,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
8978637
 
8978637
 		i=s->method->ssl3_enc->final_finish_mac(s,
8978637
 			sender,slen,s->s3->tmp.finish_md);
8978637
+		if (i == 0)
8978637
+			return 0;
8978637
 		s->s3->tmp.finish_md_len = i;
8978637
 		memcpy(p, s->s3->tmp.finish_md, i);
8978637
 		p+=i;
8978637
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
8978637
index 804291e..c4bc4e7 100644
8978637
--- a/ssl/s3_pkt.c
8978637
+++ b/ssl/s3_pkt.c
8978637
@@ -1459,8 +1459,14 @@ int ssl3_do_change_cipher_spec(SSL *s)
8978637
 		slen=s->method->ssl3_enc->client_finished_label_len;
8978637
 		}
8978637
 
8978637
-	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
8978637
+	i = s->method->ssl3_enc->final_finish_mac(s,
8978637
 		sender,slen,s->s3->tmp.peer_finish_md);
8978637
+	if (i == 0)
8978637
+		{
8978637
+		SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
8978637
+		return 0;
8978637
+		}
8978637
+	s->s3->tmp.peer_finish_md_len = i;
8978637
 
8978637
 	return(1);
8978637
 	}
8978637
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
8978637
index 809ad2e..72015f5 100644
8978637
--- a/ssl/t1_enc.c
8978637
+++ b/ssl/t1_enc.c
8978637
@@ -915,18 +915,19 @@ int tls1_final_finish_mac(SSL *s,
8978637
 		if (mask & ssl_get_algorithm2(s))
8978637
 			{
8978637
 			int hashsize = EVP_MD_size(md);
8978637
-			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
8978637
+			EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
8978637
+			if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
8978637
 				{
8978637
 				/* internal error: 'buf' is too small for this cipersuite! */
8978637
 				err = 1;
8978637
 				}
8978637
 			else
8978637
 				{
8978637
-				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
8978637
-				EVP_DigestFinal_ex(&ctx,q,&i);
8978637
-				if (i != (unsigned int)hashsize) /* can't really happen */
8978637
+				if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
8978637
+					!EVP_DigestFinal_ex(&ctx,q,&i) ||
8978637
+					(i != (unsigned int)hashsize))
8978637
 					err = 1;
8978637
-				q+=i;
8978637
+				q+=hashsize;
8978637
 				}
8978637
 			}
8978637
 		}
8978637
-- 
8978637
1.8.3.1
8978637