Additional workaround for PR#2771
[oweals/openssl.git] / ssl / s3_pkt.c
index 5e0cbdc3df57a4f6c91651c3eff8e57a0038d6d6..adf8c387cc0a504801211bfeece83e46b60b5f98 100644 (file)
@@ -664,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);
@@ -736,7 +740,14 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        wr->type=type;
 
        *(p++)=(s->version>>8);
-       *(p++)=s->version&0xff;
+       /* Some servers hang if iniatial client hello is larger than 256
+        * bytes and record version number > TLS 1.0
+        */
+       if (s->state == SSL3_ST_CW_CLNT_HELLO_B
+                               && TLS1_get_version(s) > TLS1_VERSION)
+               *(p++) = 0x1;
+       else
+               *(p++)=s->version&0xff;
 
        /* field where we are to write out packet length */
        plen=p; 
@@ -1070,6 +1081,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)
                        {
@@ -1392,10 +1416,8 @@ err:
 int ssl3_do_change_cipher_spec(SSL *s)
        {
        int i;
-#ifdef OPENSSL_NO_NEXTPROTONEG
        const char *sender;
        int slen;
-#endif
 
        if (s->state & SSL_ST_ACCEPT)
                i=SSL3_CHANGE_CIPHER_SERVER_READ;
@@ -1418,7 +1440,6 @@ int ssl3_do_change_cipher_spec(SSL *s)
        if (!s->method->ssl3_enc->change_cipher_state(s,i))
                return(0);
 
-#ifdef OPENSSL_NO_NEXTPROTONEG
        /* we have to record the message digest at
         * this point so we can get it before we read
         * the finished message */
@@ -1435,7 +1456,6 @@ int ssl3_do_change_cipher_spec(SSL *s)
 
        s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
                sender,slen,s->s3->tmp.peer_finish_md);
-#endif
 
        return(1);
        }