Check EVP errors for handshake digests.
authorDr. Stephen Henson <steve@openssl.org>
Sat, 14 Dec 2013 13:55:48 +0000 (13:55 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 18 Dec 2013 13:29:07 +0000 (13:29 +0000)
Partial mitigation of PR#3200
(cherry picked from commit 0294b2be5f4c11e60620c0018674ff0e17b14238)

ssl/s3_both.c
ssl/s3_pkt.c
ssl/t1_enc.c

index 76258b3c5cf81c6e0949e07514c14c4f78fed2f9..8de149aaa6330d5f6c48e441faaddd6b237a0192 100644 (file)
@@ -160,6 +160,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
 
                i=s->method->ssl3_enc->final_finish_mac(s,
                        sender,slen,s->s3->tmp.finish_md);
+               if (i == 0)
+                       return 0;
                s->s3->tmp.finish_md_len = i;
                memcpy(p, s->s3->tmp.finish_md, i);
                l=i;
index 33286b84d2dc4d6b37e212e78d5e5b581c02108b..a6fd3bf12e5c1930ebb8be305b83c86200de9d8c 100644 (file)
@@ -1563,8 +1563,14 @@ int ssl3_do_change_cipher_spec(SSL *s)
                slen=s->method->ssl3_enc->client_finished_label_len;
                }
 
-       s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
+       i = s->method->ssl3_enc->final_finish_mac(s,
                sender,slen,s->s3->tmp.peer_finish_md);
+       if (i == 0)
+               {
+               SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
+               return 0;
+               }
+       s->s3->tmp.peer_finish_md_len = i;
 
        return(1);
        }
index 7155fd06bc48e2632784d76babda1f46e1a1bed6..acc5f213636ef92d00a852111be528655fc5c464 100644 (file)
@@ -939,18 +939,19 @@ int tls1_final_finish_mac(SSL *s,
                if (mask & ssl_get_algorithm2(s))
                        {
                        int hashsize = EVP_MD_size(md);
-                       if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
+                       EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
+                       if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
                                {
                                /* internal error: 'buf' is too small for this cipersuite! */
                                err = 1;
                                }
                        else
                                {
-                               EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
-                               EVP_DigestFinal_ex(&ctx,q,&i);
-                               if (i != (unsigned int)hashsize) /* can't really happen */
+                               if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
+                                       !EVP_DigestFinal_ex(&ctx,q,&i) ||
+                                       (i != (unsigned int)hashsize))
                                        err = 1;
-                               q+=i;
+                               q+=hashsize;
                                }
                        }
                }