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:26:10 +0000 (13:26 +0000)
Partial mitigation of PR#3200

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

index ead01c82a14a09aa485b5e56b386b738403c8369..1e5dcab7d30520c00cc60d55d6ebd6e2ae3e6e6c 100644 (file)
@@ -161,6 +161,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);
 
                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);
                p+=i;
                s->s3->tmp.finish_md_len = i;
                memcpy(p, s->s3->tmp.finish_md, i);
                p+=i;
index 804291e27c32b9190dd68c99b8a60acfd64683c7..c4bc4e787da079a0f05eceb2705c1f2bcb9cd956 100644 (file)
@@ -1459,8 +1459,14 @@ int ssl3_do_change_cipher_spec(SSL *s)
                slen=s->method->ssl3_enc->client_finished_label_len;
                }
 
                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);
                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);
        }
 
        return(1);
        }
index 809ad2ee1e53ff3a3a9d824aa448a7b25475d4c3..72015f5aad67c56869ad0484df19eff628eca653 100644 (file)
@@ -915,18 +915,19 @@ int tls1_final_finish_mac(SSL *s,
                if (mask & ssl_get_algorithm2(s))
                        {
                        int hashsize = EVP_MD_size(md);
                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
                                {
                                {
                                /* 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;
                                        err = 1;
-                               q+=i;
+                               q+=hashsize;
                                }
                        }
                }
                                }
                        }
                }