e_aes_cbc_hmac_sha1.c: handle zero-length payload and engage empty frag
[openssl.git] / ssl / s3_pkt.c
index ee103cd2427c403eb15d6b7007df79d167d113ba..ca5412dc2a4c15dfc7e0baf8f0986b8fd6c2a00c 100644 (file)
@@ -247,7 +247,8 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
                if (i <= 0)
                        {
                        rb->left = left;
-                       if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+                       if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
+                           SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
                                if (len+left == 0)
                                        ssl3_release_read_buffer(s);
                        return(i);
@@ -663,10 +664,14 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        if (    (sess == NULL) ||
                (s->enc_write_ctx == NULL) ||
                (EVP_MD_CTX_md(s->write_hash) == NULL))
+               {
+#if 1
+               clear=s->enc_write_ctx?0:1;     /* must be AEAD cipher */
+#else
                clear=1;
-
-       if (clear)
+#endif
                mac_size=0;
+               }
        else
                {
                mac_size=EVP_MD_CTX_size(s->write_hash);
@@ -741,11 +746,19 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        plen=p; 
        p+=2;
        /* Explicit IV length, block ciphers and TLS version 1.1 or later */
-       if (s->enc_write_ctx && s->version >= TLS1_1_VERSION
-               && EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)
+       if (s->enc_write_ctx && s->version >= TLS1_1_VERSION)
                {
-               eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
-               if (eivlen <= 1)
+               int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
+               if (mode == EVP_CIPH_CBC_MODE)
+                       {
+                       eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
+                       if (eivlen <= 1)
+                               eivlen = 0;
+                       }
+               /* Need explicit part of IV for GCM mode */
+               else if (mode == EVP_CIPH_GCM_MODE)
+                       eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
+               else
                        eivlen = 0;
                }
        else 
@@ -866,7 +879,8 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
                        {
                        wb->left=0;
                        wb->offset+=i;
-                       if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+                       if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
+                           SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
                                ssl3_release_write_buffer(s);
                        s->rwstate=SSL_NOTHING;
                        return(s->s3->wpend_ret);
@@ -1060,6 +1074,19 @@ start:
                        dest = s->s3->alert_fragment;
                        dest_len = &s->s3->alert_fragment_len;
                        }
+#ifndef OPENSSL_NO_HEARTBEATS
+               else if (rr->type == TLS1_RT_HEARTBEAT)
+                       {
+                       tls1_process_heartbeat(s);
+
+                       /* Exit and notify application to read again */
+                       rr->length = 0;
+                       s->rwstate=SSL_READING;
+                       BIO_clear_retry_flags(SSL_get_rbio(s));
+                       BIO_set_retry_read(SSL_get_rbio(s));
+                       return(-1);
+                       }
+#endif
 
                if (dest_maxlen > 0)
                        {