If we're going to return errors (no matter how stupid), then we should
[openssl.git] / ssl / s3_pkt.c
index 07dd4b23d5204b6840c2b01e4af48d449ebafe76..e6c68b339b7b2736a8b49243277107e9876c4ee9 100644 (file)
@@ -412,7 +412,9 @@ printf("\n");
 
        if (!clear)
                {
+               /* !clear => s->read_hash != NULL => mac_size != -1 */
                mac_size=EVP_MD_CTX_size(s->read_hash);
+               OPENSSL_assert(mac_size >= 0);
 
                if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
                        {
@@ -443,7 +445,7 @@ printf("\n");
 #endif
                        }
                i=s->method->ssl3_enc->mac(s,md,0);
-               if (mac == NULL || memcmp(md, mac, mac_size) != 0)
+               if (i < 0 || mac == NULL || memcmp(md, mac, mac_size) != 0)
                        {
                        decryption_failed_or_bad_record_mac = 1;
                        }
@@ -648,7 +650,11 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        if (clear)
                mac_size=0;
        else
+               {
                mac_size=EVP_MD_CTX_size(s->write_hash);
+               if (mac_size < 0)
+                       goto err;
+               }
 
        /* 'create_empty_fragment' is true only when this function calls itself */
        if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done)
@@ -746,7 +752,8 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
 
        if (mac_size != 0)
                {
-               s->method->ssl3_enc->mac(s,&(p[wr->length]),1);
+               if (s->method->ssl3_enc->mac(s,&(p[wr->length]),1) < 0)
+                       goto err;
                wr->length+=mac_size;
                wr->input=p;
                wr->data=p;
@@ -828,8 +835,15 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
                        s->rwstate=SSL_NOTHING;
                        return(s->s3->wpend_ret);
                        }
-               else if (i <= 0)
+               else if (i <= 0) {
+                       if (s->version == DTLS1_VERSION) {
+                               /* For DTLS, just drop it. That's kind of the wh
+ole
+                                  point in using a datagram service */
+                               wb->left = 0;
+                       }
                        return(i);
+               }
                wb->offset+=i;
                wb->left-=i;
                }
@@ -1302,6 +1316,13 @@ int ssl3_do_change_cipher_spec(SSL *s)
 
        if (s->s3->tmp.key_block == NULL)
                {
+               if (s->session == NULL) 
+                       {
+                       /* might happen if dtls1_read_bytes() calls this */
+                       SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);
+                       return (0);
+                       }
+
                s->session->cipher=s->s3->tmp.new_cipher;
                if (!s->method->ssl3_enc->setup_key_block(s)) return(0);
                }