PSK PRF correction.
[openssl.git] / ssl / s3_lib.c
index ab19eebaea792eeaa5cb42947867cd718d7e5c84..527ec1f9469ca119d1e889b70b53b2dacd7898c7 100644 (file)
 #include <stdio.h>
 #include <openssl/objects.h>
 #include "ssl_locl.h"
-#include "kssl_lcl.h"
 #include <openssl/md5.h>
 #ifndef OPENSSL_NO_DH
 # include <openssl/dh.h>
 #endif
+#include <openssl/rand.h>
 
 const char ssl3_version_str[] = "SSLv3" OPENSSL_VERSION_PTEXT;
 
-#define SSL3_NUM_CIPHERS        (sizeof(ssl3_ciphers)/sizeof(SSL_CIPHER))
+#define SSL3_NUM_CIPHERS        OSSL_NELEM(ssl3_ciphers)
 
 /* list of available SSLv3 ciphers (sorted by id) */
 OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
@@ -330,7 +330,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
 /* The DH ciphers */
 /* Cipher 0B */
     {
-     1,
+     0,
      SSL3_TXT_DH_DSS_DES_40_CBC_SHA,
      SSL3_CK_DH_DSS_DES_40_CBC_SHA,
      SSL_kDHd,
@@ -378,7 +378,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
 
 /* Cipher 0E */
     {
-     1,
+     0,
      SSL3_TXT_DH_RSA_DES_40_CBC_SHA,
      SSL3_CK_DH_RSA_DES_40_CBC_SHA,
      SSL_kDHr,
@@ -601,233 +601,6 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
      168,
      },
 
-#ifndef OPENSSL_NO_KRB5
-/* The Kerberos ciphers*/
-/* Cipher 1E */
-    {
-     1,
-     SSL3_TXT_KRB5_DES_64_CBC_SHA,
-     SSL3_CK_KRB5_DES_64_CBC_SHA,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_DES,
-     SSL_SHA1,
-     SSL_SSLV3,
-     SSL_NOT_EXP | SSL_LOW,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     56,
-     56,
-     },
-
-/* Cipher 1F */
-    {
-     1,
-     SSL3_TXT_KRB5_DES_192_CBC3_SHA,
-     SSL3_CK_KRB5_DES_192_CBC3_SHA,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_3DES,
-     SSL_SHA1,
-     SSL_SSLV3,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     112,
-     168,
-     },
-
-/* Cipher 20 */
-    {
-     1,
-     SSL3_TXT_KRB5_RC4_128_SHA,
-     SSL3_CK_KRB5_RC4_128_SHA,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_RC4,
-     SSL_SHA1,
-     SSL_SSLV3,
-     SSL_NOT_EXP | SSL_MEDIUM,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     128,
-     128,
-     },
-
-/* Cipher 21 */
-    {
-     1,
-     SSL3_TXT_KRB5_IDEA_128_CBC_SHA,
-     SSL3_CK_KRB5_IDEA_128_CBC_SHA,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_IDEA,
-     SSL_SHA1,
-     SSL_SSLV3,
-     SSL_NOT_EXP | SSL_MEDIUM,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     128,
-     128,
-     },
-
-/* Cipher 22 */
-    {
-     1,
-     SSL3_TXT_KRB5_DES_64_CBC_MD5,
-     SSL3_CK_KRB5_DES_64_CBC_MD5,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_DES,
-     SSL_MD5,
-     SSL_SSLV3,
-     SSL_NOT_EXP | SSL_LOW,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     56,
-     56,
-     },
-
-/* Cipher 23 */
-    {
-     1,
-     SSL3_TXT_KRB5_DES_192_CBC3_MD5,
-     SSL3_CK_KRB5_DES_192_CBC3_MD5,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_3DES,
-     SSL_MD5,
-     SSL_SSLV3,
-     SSL_NOT_EXP | SSL_HIGH,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     112,
-     168,
-     },
-
-/* Cipher 24 */
-    {
-     1,
-     SSL3_TXT_KRB5_RC4_128_MD5,
-     SSL3_CK_KRB5_RC4_128_MD5,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_RC4,
-     SSL_MD5,
-     SSL_SSLV3,
-     SSL_NOT_EXP | SSL_MEDIUM,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     128,
-     128,
-     },
-
-/* Cipher 25 */
-    {
-     1,
-     SSL3_TXT_KRB5_IDEA_128_CBC_MD5,
-     SSL3_CK_KRB5_IDEA_128_CBC_MD5,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_IDEA,
-     SSL_MD5,
-     SSL_SSLV3,
-     SSL_NOT_EXP | SSL_MEDIUM,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     128,
-     128,
-     },
-
-/* Cipher 26 */
-    {
-     1,
-     SSL3_TXT_KRB5_DES_40_CBC_SHA,
-     SSL3_CK_KRB5_DES_40_CBC_SHA,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_DES,
-     SSL_SHA1,
-     SSL_SSLV3,
-     SSL_EXPORT | SSL_EXP40,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     40,
-     56,
-     },
-
-/* Cipher 27 */
-    {
-     1,
-     SSL3_TXT_KRB5_RC2_40_CBC_SHA,
-     SSL3_CK_KRB5_RC2_40_CBC_SHA,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_RC2,
-     SSL_SHA1,
-     SSL_SSLV3,
-     SSL_EXPORT | SSL_EXP40,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     40,
-     128,
-     },
-
-/* Cipher 28 */
-    {
-     1,
-     SSL3_TXT_KRB5_RC4_40_SHA,
-     SSL3_CK_KRB5_RC4_40_SHA,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_RC4,
-     SSL_SHA1,
-     SSL_SSLV3,
-     SSL_EXPORT | SSL_EXP40,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     40,
-     128,
-     },
-
-/* Cipher 29 */
-    {
-     1,
-     SSL3_TXT_KRB5_DES_40_CBC_MD5,
-     SSL3_CK_KRB5_DES_40_CBC_MD5,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_DES,
-     SSL_MD5,
-     SSL_SSLV3,
-     SSL_EXPORT | SSL_EXP40,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     40,
-     56,
-     },
-
-/* Cipher 2A */
-    {
-     1,
-     SSL3_TXT_KRB5_RC2_40_CBC_MD5,
-     SSL3_CK_KRB5_RC2_40_CBC_MD5,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_RC2,
-     SSL_MD5,
-     SSL_SSLV3,
-     SSL_EXPORT | SSL_EXP40,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     40,
-     128,
-     },
-
-/* Cipher 2B */
-    {
-     1,
-     SSL3_TXT_KRB5_RC4_40_MD5,
-     SSL3_CK_KRB5_RC4_40_MD5,
-     SSL_kKRB5,
-     SSL_aKRB5,
-     SSL_RC4,
-     SSL_MD5,
-     SSL_SSLV3,
-     SSL_EXPORT | SSL_EXP40,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     40,
-     128,
-     },
-#endif                          /* OPENSSL_NO_KRB5 */
-
 /* New AES ciphersuites */
 /* Cipher 2F */
     {
@@ -1212,88 +985,6 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
      },
 #endif                          /* OPENSSL_NO_CAMELLIA */
 
-#if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES
-    /* Cipher 62 */
-    {
-     1,
-     TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA,
-     TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA,
-     SSL_kRSA,
-     SSL_aRSA,
-     SSL_DES,
-     SSL_SHA1,
-     SSL_TLSV1,
-     SSL_EXPORT | SSL_EXP56,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     56,
-     56,
-     },
-
-    /* Cipher 63 */
-    {
-     1,
-     TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
-     TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
-     SSL_kDHE,
-     SSL_aDSS,
-     SSL_DES,
-     SSL_SHA1,
-     SSL_TLSV1,
-     SSL_EXPORT | SSL_EXP56,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     56,
-     56,
-     },
-
-    /* Cipher 64 */
-    {
-     1,
-     TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA,
-     TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA,
-     SSL_kRSA,
-     SSL_aRSA,
-     SSL_RC4,
-     SSL_SHA1,
-     SSL_TLSV1,
-     SSL_EXPORT | SSL_EXP56,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     56,
-     128,
-     },
-
-    /* Cipher 65 */
-    {
-     1,
-     TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
-     TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
-     SSL_kDHE,
-     SSL_aDSS,
-     SSL_RC4,
-     SSL_SHA1,
-     SSL_TLSV1,
-     SSL_EXPORT | SSL_EXP56,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     56,
-     128,
-     },
-
-    /* Cipher 66 */
-    {
-     1,
-     TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA,
-     TLS1_CK_DHE_DSS_WITH_RC4_128_SHA,
-     SSL_kDHE,
-     SSL_aDSS,
-     SSL_RC4,
-     SSL_SHA1,
-     SSL_TLSV1,
-     SSL_NOT_EXP | SSL_MEDIUM,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
-     128,
-     128,
-     },
-#endif
-
     /* TLS v1.2 ciphersuites */
     /* Cipher 67 */
     {
@@ -1921,20 +1612,39 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
      256,
      256,
      },
-#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+#ifndef OPENSSL_NO_PSK
+    /* Cipher A8 */
     {
      1,
-     "SCSV",
-     SSL3_CK_SCSV,
-     0,
-     0,
-     0,
-     0,
-     0,
-     0,
-     0,
-     0,
-     0},
+     TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_PSK_WITH_AES_128_GCM_SHA256,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     SSL_TLSV1_2,
+     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+
+    /* Cipher A9 */
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_PSK_WITH_AES_256_GCM_SHA384,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     SSL_TLSV1_2,
+     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+
 #endif
 
 #ifndef OPENSSL_NO_CAMELLIA
@@ -2133,7 +1843,24 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
      },
 #endif
 
-#ifndef OPENSSL_NO_ECDH
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+    /* Cipher FF */
+    {
+     1,
+     "SCSV",
+     SSL3_CK_SCSV,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0},
+#endif
+
+#ifndef OPENSSL_NO_EC
     /* Cipher C001 */
     {
      1,
@@ -2533,7 +2260,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
      256,
      256,
      },
-#endif                          /* OPENSSL_NO_ECDH */
+#endif                          /* OPENSSL_NO_EC */
 
 #ifndef OPENSSL_NO_SRP
     /* Cipher C01A */
@@ -2680,7 +2407,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
      256,
      },
 #endif                          /* OPENSSL_NO_SRP */
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
 
     /* HMAC based TLS v1.2 ciphersuites from RFC5289 */
 
@@ -3055,7 +2782,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
      256,
      256},
 # endif                         /* OPENSSL_NO_CAMELLIA */
-#endif                          /* OPENSSL_NO_ECDH */
+#endif                          /* OPENSSL_NO_EC */
 
 #ifdef TEMP_GOST_TLS
 /* Cipher FF00 */
@@ -3160,22 +2887,15 @@ const SSL_CIPHER *ssl3_get_cipher(unsigned int u)
         return (NULL);
 }
 
-int ssl3_pending(const SSL *s)
-{
-    if (s->rstate == SSL_ST_READ_BODY)
-        return 0;
-
-    return (s->s3->rrec.type ==
-            SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length : 0;
-}
-
-void ssl3_set_handshake_header(SSL *s, int htype, unsigned long len)
+int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len)
 {
     unsigned char *p = (unsigned char *)s->init_buf->data;
     *(p++) = htype;
     l2n3(len, p);
     s->init_num = (int)len + SSL3_HM_HEADER_LENGTH;
     s->init_off = 0;
+
+     return 1;
 }
 
 int ssl3_handshake_write(SSL *s)
@@ -3187,16 +2907,14 @@ int ssl3_new(SSL *s)
 {
     SSL3_STATE *s3;
 
-    if ((s3 = OPENSSL_malloc(sizeof *s3)) == NULL)
+    if ((s3 = OPENSSL_malloc(sizeof(*s3))) == NULL)
         goto err;
-    memset(s3, 0, sizeof *s3);
-    memset(s3->rrec.seq_num, 0, sizeof(s3->rrec.seq_num));
-    memset(s3->wrec.seq_num, 0, sizeof(s3->wrec.seq_num));
-
+    memset(s3, 0, sizeof(*s3));
     s->s3 = s3;
-
+    
 #ifndef OPENSSL_NO_SRP
-    SSL_SRP_CTX_init(s);
+    if (!SSL_SRP_CTX_init(s))
+          goto err;
 #endif
     s->method->ssl_clear(s);
     return (1);
@@ -3210,113 +2928,88 @@ void ssl3_free(SSL *s)
         return;
 
     ssl3_cleanup_key_block(s);
-    if (s->s3->rbuf.buf != NULL)
-        ssl3_release_read_buffer(s);
-    if (s->s3->wbuf.buf != NULL)
-        ssl3_release_write_buffer(s);
-    if (s->s3->rrec.comp != NULL)
-        OPENSSL_free(s->s3->rrec.comp);
+
+#ifndef OPENSSL_NO_RSA
+    RSA_free(s->s3->peer_rsa_tmp);
+#endif
 #ifndef OPENSSL_NO_DH
-    if (s->s3->tmp.dh != NULL)
-        DH_free(s->s3->tmp.dh);
+    DH_free(s->s3->tmp.dh);
+    DH_free(s->s3->peer_dh_tmp);
 #endif
-#ifndef OPENSSL_NO_ECDH
-    if (s->s3->tmp.ecdh != NULL)
-        EC_KEY_free(s->s3->tmp.ecdh);
+#ifndef OPENSSL_NO_EC
+    EC_KEY_free(s->s3->tmp.ecdh);
+    EC_KEY_free(s->s3->peer_ecdh_tmp);
 #endif
 
-    if (s->s3->tmp.ca_names != NULL)
-        sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
-    if (s->s3->handshake_buffer) {
-        BIO_free(s->s3->handshake_buffer);
-    }
-    if (s->s3->handshake_dgst)
-        ssl3_free_digest_list(s);
-#ifndef OPENSSL_NO_TLSEXT
-    if (s->s3->alpn_selected)
-        OPENSSL_free(s->s3->alpn_selected);
-#endif
+    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+    OPENSSL_free(s->s3->tmp.ciphers_raw);
+    OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
+    ssl3_free_digest_list(s);
+    OPENSSL_free(s->s3->alpn_selected);
 
 #ifndef OPENSSL_NO_SRP
     SSL_SRP_CTX_free(s);
 #endif
-    OPENSSL_cleanse(s->s3, sizeof *s->s3);
-    OPENSSL_free(s->s3);
+    OPENSSL_clear_free(s->s3, sizeof(*s->s3));
     s->s3 = NULL;
 }
 
 void ssl3_clear(SSL *s)
 {
-    unsigned char *rp, *wp;
-    size_t rlen, wlen;
     int init_extra;
 
     ssl3_cleanup_key_block(s);
-    if (s->s3->tmp.ca_names != NULL)
-        sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+    OPENSSL_free(s->s3->tmp.ciphers_raw);
+    s->s3->tmp.ciphers_raw = NULL;
+    OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
+    s->s3->tmp.pms = NULL;
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
+    s->s3->tmp.peer_sigalgs = NULL;
 
-    if (s->s3->rrec.comp != NULL) {
-        OPENSSL_free(s->s3->rrec.comp);
-        s->s3->rrec.comp = NULL;
-    }
-#ifndef OPENSSL_NO_DH
-    if (s->s3->tmp.dh != NULL) {
-        DH_free(s->s3->tmp.dh);
-        s->s3->tmp.dh = NULL;
-    }
+#ifndef OPENSSL_NO_RSA
+    RSA_free(s->s3->peer_rsa_tmp);
+    s->s3->peer_rsa_tmp = NULL;
 #endif
-#ifndef OPENSSL_NO_ECDH
-    if (s->s3->tmp.ecdh != NULL) {
-        EC_KEY_free(s->s3->tmp.ecdh);
-        s->s3->tmp.ecdh = NULL;
-    }
+
+#ifndef OPENSSL_NO_DH
+    DH_free(s->s3->tmp.dh);
+    s->s3->tmp.dh = NULL;
+    DH_free(s->s3->peer_dh_tmp);
+    s->s3->peer_dh_tmp = NULL;
 #endif
-#ifndef OPENSSL_NO_TLSEXT
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
+    EC_KEY_free(s->s3->tmp.ecdh);
+    s->s3->tmp.ecdh = NULL;
+    EC_KEY_free(s->s3->peer_ecdh_tmp);
+    s->s3->peer_ecdh_tmp = NULL;
     s->s3->is_probably_safari = 0;
-# endif                         /* !OPENSSL_NO_EC */
-#endif                          /* !OPENSSL_NO_TLSEXT */
+#endif                         /* !OPENSSL_NO_EC */
 
-    rp = s->s3->rbuf.buf;
-    wp = s->s3->wbuf.buf;
-    rlen = s->s3->rbuf.len;
-    wlen = s->s3->wbuf.len;
     init_extra = s->s3->init_extra;
-    if (s->s3->handshake_buffer) {
-        BIO_free(s->s3->handshake_buffer);
-        s->s3->handshake_buffer = NULL;
-    }
-    if (s->s3->handshake_dgst) {
-        ssl3_free_digest_list(s);
-    }
-#if !defined(OPENSSL_NO_TLSEXT)
+    ssl3_free_digest_list(s);
+
     if (s->s3->alpn_selected) {
-        free(s->s3->alpn_selected);
+        OPENSSL_free(s->s3->alpn_selected);
         s->s3->alpn_selected = NULL;
     }
-#endif
-    memset(s->s3, 0, sizeof *s->s3);
-    s->s3->rbuf.buf = rp;
-    s->s3->wbuf.buf = wp;
-    s->s3->rbuf.len = rlen;
-    s->s3->wbuf.len = wlen;
+
+    memset(s->s3, 0, sizeof(*s->s3));
     s->s3->init_extra = init_extra;
 
     ssl_free_wbio_buffer(s);
 
-    s->packet_length = 0;
     s->s3->renegotiate = 0;
     s->s3->total_renegotiations = 0;
     s->s3->num_renegotiations = 0;
     s->s3->in_read_app_data = 0;
     s->version = SSL3_VERSION;
 
-#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-    if (s->next_proto_negotiated) {
-        OPENSSL_free(s->next_proto_negotiated);
-        s->next_proto_negotiated = NULL;
-        s->next_proto_negotiated_len = 0;
-    }
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    OPENSSL_free(s->next_proto_negotiated);
+    s->next_proto_negotiated = NULL;
+    s->next_proto_negotiated_len = 0;
 #endif
 }
 
@@ -3334,22 +3027,6 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 {
     int ret = 0;
 
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA)
-    if (
-# ifndef OPENSSL_NO_RSA
-           cmd == SSL_CTRL_SET_TMP_RSA || cmd == SSL_CTRL_SET_TMP_RSA_CB ||
-# endif
-# ifndef OPENSSL_NO_DSA
-           cmd == SSL_CTRL_SET_TMP_DH || cmd == SSL_CTRL_SET_TMP_DH_CB ||
-# endif
-           0) {
-        if (!ssl_cert_inst(&s->cert)) {
-            SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE);
-            return (0);
-        }
-    }
-#endif
-
     switch (cmd) {
     case SSL_CTRL_GET_SESSION_REUSED:
         ret = s->hit;
@@ -3388,8 +3065,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
                 SSLerr(SSL_F_SSL3_CTRL, ERR_R_RSA_LIB);
                 return (ret);
             }
-            if (s->cert->rsa_tmp != NULL)
-                RSA_free(s->cert->rsa_tmp);
+            RSA_free(s->cert->rsa_tmp);
             s->cert->rsa_tmp = rsa;
             ret = 1;
         }
@@ -3424,8 +3100,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
                     return (ret);
                 }
             }
-            if (s->cert->dh_tmp != NULL)
-                DH_free(s->cert->dh_tmp);
+            DH_free(s->cert->dh_tmp);
             s->cert->dh_tmp = dh;
             ret = 1;
         }
@@ -3439,7 +3114,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         s->cert->dh_tmp_auto = larg;
         return 1;
 #endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
     case SSL_CTRL_SET_TMP_ECDH:
         {
             EC_KEY *ecdh = NULL;
@@ -3460,8 +3135,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
                     return (ret);
                 }
             }
-            if (s->cert->ecdh_tmp != NULL)
-                EC_KEY_free(s->cert->ecdh_tmp);
+            EC_KEY_free(s->cert->ecdh_tmp);
             s->cert->ecdh_tmp = ecdh;
             ret = 1;
         }
@@ -3471,12 +3145,10 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
             SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return (ret);
         }
-#endif                          /* !OPENSSL_NO_ECDH */
-#ifndef OPENSSL_NO_TLSEXT
+#endif                          /* !OPENSSL_NO_EC */
     case SSL_CTRL_SET_TLSEXT_HOSTNAME:
         if (larg == TLSEXT_NAMETYPE_host_name) {
-            if (s->tlsext_hostname != NULL)
-                OPENSSL_free(s->tlsext_hostname);
+            OPENSSL_free(s->tlsext_hostname);
             s->tlsext_hostname = NULL;
 
             ret = 1;
@@ -3530,14 +3202,13 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         return s->tlsext_ocsp_resplen;
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP:
-        if (s->tlsext_ocsp_resp)
-            OPENSSL_free(s->tlsext_ocsp_resp);
+        OPENSSL_free(s->tlsext_ocsp_resp);
         s->tlsext_ocsp_resp = parg;
         s->tlsext_ocsp_resplen = larg;
         ret = 1;
         break;
 
-# ifndef OPENSSL_NO_HEARTBEATS
+#ifndef OPENSSL_NO_HEARTBEATS
     case SSL_CTRL_TLS_EXT_SEND_HEARTBEAT:
         if (SSL_IS_DTLS(s))
             ret = dtls1_heartbeat(s);
@@ -3556,9 +3227,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
             s->tlsext_heartbeat &= ~SSL_TLSEXT_HB_DONT_RECV_REQUESTS;
         ret = 1;
         break;
-# endif
-
-#endif                          /* !OPENSSL_NO_TLSEXT */
+#endif
 
     case SSL_CTRL_CHAIN:
         if (larg)
@@ -3640,7 +3309,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
     case SSL_CTRL_GET_SHARED_CURVE:
         return tls1_shared_curve(s, larg);
 
-# ifndef OPENSSL_NO_ECDH
+# ifndef OPENSSL_NO_EC
     case SSL_CTRL_SET_ECDH_AUTO:
         s->cert->ecdh_tmp_auto = larg;
         return 1;
@@ -3689,9 +3358,9 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 
     case SSL_CTRL_GET_PEER_SIGNATURE_NID:
         if (SSL_USE_SIGALGS(s)) {
-            if (s->session && s->session->sess_cert) {
+            if (s->session) {
                 const EVP_MD *sig;
-                sig = s->session->sess_cert->peer_key->digest;
+                sig = s->s3->tmp.peer_md;
                 if (sig) {
                     *(int *)parg = EVP_MD_type(sig);
                     return 1;
@@ -3704,32 +3373,29 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
             return 0;
 
     case SSL_CTRL_GET_SERVER_TMP_KEY:
-        if (s->server || !s->session || !s->session->sess_cert)
+        if (s->server || !s->session)
             return 0;
         else {
-            SESS_CERT *sc;
             EVP_PKEY *ptmp;
             int rv = 0;
-            sc = s->session->sess_cert;
-#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDH)
-            if (!sc->peer_rsa_tmp && !sc->peer_dh_tmp && !sc->peer_ecdh_tmp)
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC)
+            if (!s->s3->peer_rsa_tmp && !s->s3->peer_dh_tmp && !s->s3->peer_ecdh_tmp)
                 return 0;
 #endif
             ptmp = EVP_PKEY_new();
             if (!ptmp)
                 return 0;
-            if (0) ;
 #ifndef OPENSSL_NO_RSA
-            else if (sc->peer_rsa_tmp)
-                rv = EVP_PKEY_set1_RSA(ptmp, sc->peer_rsa_tmp);
+            else if (s->s3->peer_rsa_tmp)
+                rv = EVP_PKEY_set1_RSA(ptmp, s->s3->peer_rsa_tmp);
 #endif
 #ifndef OPENSSL_NO_DH
-            else if (sc->peer_dh_tmp)
-                rv = EVP_PKEY_set1_DH(ptmp, sc->peer_dh_tmp);
+            else if (s->s3->peer_dh_tmp)
+                rv = EVP_PKEY_set1_DH(ptmp, s->s3->peer_dh_tmp);
 #endif
-#ifndef OPENSSL_NO_ECDH
-            else if (sc->peer_ecdh_tmp)
-                rv = EVP_PKEY_set1_EC_KEY(ptmp, sc->peer_ecdh_tmp);
+#ifndef OPENSSL_NO_EC
+            else if (s->s3->peer_ecdh_tmp)
+                rv = EVP_PKEY_set1_EC_KEY(ptmp, s->s3->peer_ecdh_tmp);
 #endif
             if (rv) {
                 *(EVP_PKEY **)parg = ptmp;
@@ -3762,9 +3428,9 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
          * Apparently we're using a version-flexible SSL_METHOD (not at its
          * highest protocol version).
          */
-        if (s->ctx->method->version == SSLv23_method()->version) {
+        if (s->ctx->method->version == TLS_method()->version) {
 #if TLS_MAX_VERSION != TLS1_2_VERSION
-# error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION.
+# error Code needs update for TLS_method() support beyond TLS1_2_VERSION.
 #endif
             if (!(s->options & SSL_OP_NO_TLSv1_2))
                 return s->version == TLS1_2_VERSION;
@@ -3787,22 +3453,6 @@ long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
 {
     int ret = 0;
 
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA)
-    if (
-# ifndef OPENSSL_NO_RSA
-           cmd == SSL_CTRL_SET_TMP_RSA_CB ||
-# endif
-# ifndef OPENSSL_NO_DSA
-           cmd == SSL_CTRL_SET_TMP_DH_CB ||
-# endif
-           0) {
-        if (!ssl_cert_inst(&s->cert)) {
-            SSLerr(SSL_F_SSL3_CALLBACK_CTRL, ERR_R_MALLOC_FAILURE);
-            return (0);
-        }
-    }
-#endif
-
     switch (cmd) {
 #ifndef OPENSSL_NO_RSA
     case SSL_CTRL_SET_TMP_RSA_CB:
@@ -3818,19 +3468,18 @@ long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
         }
         break;
 #endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
     case SSL_CTRL_SET_TMP_ECDH_CB:
         {
             s->cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp;
         }
         break;
 #endif
-#ifndef OPENSSL_NO_TLSEXT
     case SSL_CTRL_SET_TLSEXT_DEBUG_CB:
         s->tlsext_debug_cb = (void (*)(SSL *, int, int,
                                        unsigned char *, int, void *))fp;
         break;
-#endif
+
     case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
         {
             s->not_resumable_session_cb = (int (*)(SSL *, int))fp;
@@ -3877,8 +3526,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
                 SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_RSA_LIB);
                 return (0);
             } else {
-                if (cert->rsa_tmp != NULL)
-                    RSA_free(cert->rsa_tmp);
+                RSA_free(cert->rsa_tmp);
                 cert->rsa_tmp = rsa;
                 return (1);
             }
@@ -3912,8 +3560,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
                     return 0;
                 }
             }
-            if (cert->dh_tmp != NULL)
-                DH_free(cert->dh_tmp);
+            DH_free(cert->dh_tmp);
             cert->dh_tmp = new;
             return 1;
         }
@@ -3929,7 +3576,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
         ctx->cert->dh_tmp_auto = larg;
         return 1;
 #endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
     case SSL_CTRL_SET_TMP_ECDH:
         {
             EC_KEY *ecdh = NULL;
@@ -3951,9 +3598,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
                 }
             }
 
-            if (cert->ecdh_tmp != NULL) {
-                EC_KEY_free(cert->ecdh_tmp);
-            }
+            EC_KEY_free(cert->ecdh_tmp);
             cert->ecdh_tmp = ecdh;
             return 1;
         }
@@ -3963,8 +3608,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
             SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return (0);
         }
-#endif                          /* !OPENSSL_NO_ECDH */
-#ifndef OPENSSL_NO_TLSEXT
+#endif                          /* !OPENSSL_NO_EC */
     case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG:
         ctx->tlsext_servername_arg = parg;
         break;
@@ -3994,11 +3638,10 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
         ctx->tlsext_status_arg = parg;
         return 1;
 
-# ifndef OPENSSL_NO_SRP
+#ifndef OPENSSL_NO_SRP
     case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME:
         ctx->srp_ctx.srp_Mask |= SSL_kSRP;
-        if (ctx->srp_ctx.login != NULL)
-            OPENSSL_free(ctx->srp_ctx.login);
+        OPENSSL_free(ctx->srp_ctx.login);
         ctx->srp_ctx.login = NULL;
         if (parg == NULL)
             break;
@@ -4025,9 +3668,9 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
     case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH:
         ctx->srp_ctx.strength = larg;
         break;
-# endif
+#endif
 
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
     case SSL_CTRL_SET_CURVES:
         return tls1_set_curves(&ctx->tlsext_ellipticcurvelist,
                                &ctx->tlsext_ellipticcurvelist_length,
@@ -4037,12 +3680,10 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
         return tls1_set_curves_list(&ctx->tlsext_ellipticcurvelist,
                                     &ctx->tlsext_ellipticcurvelist_length,
                                     parg);
-#  ifndef OPENSSL_NO_ECDH
     case SSL_CTRL_SET_ECDH_AUTO:
         ctx->cert->ecdh_tmp_auto = larg;
         return 1;
-#  endif
-# endif
+#endif
     case SSL_CTRL_SET_SIGALGS:
         return tls1_set_sigalgs(ctx->cert, parg, larg, 0);
 
@@ -4067,8 +3708,6 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
     case SSL_CTRL_SET_CHAIN_CERT_STORE:
         return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
 
-#endif                          /* !OPENSSL_NO_TLSEXT */
-
         /* A Thawte special :-) */
     case SSL_CTRL_EXTRA_CHAIN_CERT:
         if (ctx->extra_certs == NULL) {
@@ -4086,10 +3725,8 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
         break;
 
     case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS:
-        if (ctx->extra_certs) {
-            sk_X509_pop_free(ctx->extra_certs, X509_free);
-            ctx->extra_certs = NULL;
-        }
+        sk_X509_pop_free(ctx->extra_certs, X509_free);
+        ctx->extra_certs = NULL;
         break;
 
     case SSL_CTRL_CHAIN:
@@ -4141,14 +3778,13 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
         }
         break;
 #endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
     case SSL_CTRL_SET_TMP_ECDH_CB:
         {
             cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp;
         }
         break;
 #endif
-#ifndef OPENSSL_NO_TLSEXT
     case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB:
         ctx->tlsext_servername_callback = (int (*)(SSL *, int *, void *))fp;
         break;
@@ -4164,7 +3800,7 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
                                              HMAC_CTX *, int))fp;
         break;
 
-# ifndef OPENSSL_NO_SRP
+#ifndef OPENSSL_NO_SRP
     case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB:
         ctx->srp_ctx.srp_Mask |= SSL_kSRP;
         ctx->srp_ctx.SRP_verify_param_callback = (int (*)(SSL *, void *))fp;
@@ -4179,7 +3815,6 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
         ctx->srp_ctx.SRP_give_srp_client_pwd_callback =
             (char *(*)(SSL *, void *))fp;
         break;
-# endif
 #endif
     case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
         {
@@ -4232,11 +3867,9 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
     SSL_CIPHER *c, *ret = NULL;
     STACK_OF(SSL_CIPHER) *prio, *allow;
     int i, ii, ok;
-    CERT *cert;
     unsigned long alg_k, alg_a, mask_k, mask_a, emask_k, emask_a;
 
     /* Let's see which ciphers we can support */
-    cert = s->cert;
 
 #if 0
     /*
@@ -4281,11 +3914,11 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
         if ((c->algorithm_ssl & SSL_TLSV1_2) && !SSL_USE_TLS1_2_CIPHERS(s))
             continue;
 
-        ssl_set_cert_masks(cert, c);
-        mask_k = cert->mask_k;
-        mask_a = cert->mask_a;
-        emask_k = cert->export_mask_k;
-        emask_a = cert->export_mask_a;
+        ssl_set_masks(s, c);
+        mask_k = s->s3->tmp.mask_k;
+        mask_a = s->s3->tmp.mask_a;
+        emask_k = s->s3->tmp.export_mask_k;
+        emask_a = s->s3->tmp.export_mask_a;
 #ifndef OPENSSL_NO_SRP
         if (s->srp_ctx.srp_Mask & SSL_kSRP) {
             mask_k |= SSL_kSRP;
@@ -4295,25 +3928,12 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
         }
 #endif
 
-#ifdef KSSL_DEBUG
-        /*
-         * fprintf(stderr,"ssl3_choose_cipher %d alg= %lx\n",
-         * i,c->algorithms);
-         */
-#endif                          /* KSSL_DEBUG */
-
         alg_k = c->algorithm_mkey;
         alg_a = c->algorithm_auth;
 
-#ifndef OPENSSL_NO_KRB5
-        if (alg_k & SSL_kKRB5) {
-            if (!kssl_keytab_is_available(s->kssl_ctx))
-                continue;
-        }
-#endif                          /* OPENSSL_NO_KRB5 */
 #ifndef OPENSSL_NO_PSK
         /* with PSK there must be server callback set */
-        if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL)
+        if ((alg_k & SSL_PSK) && s->psk_server_callback == NULL)
             continue;
 #endif                          /* OPENSSL_NO_PSK */
 
@@ -4331,18 +3951,14 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 #endif
         }
 
-#ifndef OPENSSL_NO_TLSEXT
 # ifndef OPENSSL_NO_EC
-#  ifndef OPENSSL_NO_ECDH
         /*
          * if we are considering an ECC cipher suite that uses an ephemeral
          * EC key check it
          */
         if (alg_k & SSL_kECDHE)
             ok = ok && tls1_check_ec_tmp_key(s, c->id);
-#  endif                        /* OPENSSL_NO_ECDH */
 # endif                         /* OPENSSL_NO_EC */
-#endif                          /* OPENSSL_NO_TLSEXT */
 
         if (!ok)
             continue;
@@ -4352,7 +3968,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
             if (!ssl_security(s, SSL_SECOP_CIPHER_SHARED,
                               c->strength_bits, 0, c))
                 continue;
-#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLSEXT)
+#if !defined(OPENSSL_NO_EC)
             if ((alg_k & SSL_kECDHE) && (alg_a & SSL_aECDSA)
                 && s->s3->is_probably_safari) {
                 if (!ret)
@@ -4428,16 +4044,13 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
     if (!(alg_a & SSL_aDSS))
         p[ret++] = SSL3_CT_DSS_SIGN;
 #endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
     if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->version >= TLS1_VERSION)) {
         if (nostrict || !(alg_a & SSL_aRSA))
             p[ret++] = TLS_CT_RSA_FIXED_ECDH;
         if (nostrict || !(alg_a & SSL_aECDSA))
             p[ret++] = TLS_CT_ECDSA_FIXED_ECDH;
     }
-#endif
-
-#ifndef OPENSSL_NO_ECDSA
     /*
      * ECDSA certs can be used with RSA cipher suites as well so we don't
      * need to check for SSL_kECDH or SSL_kECDHE
@@ -4452,10 +4065,8 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
 
 static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len)
 {
-    if (c->ctypes) {
-        OPENSSL_free(c->ctypes);
-        c->ctypes = NULL;
-    }
+    OPENSSL_free(c->ctypes);
+    c->ctypes = NULL;
     if (!p || !len)
         return 1;
     if (len > 0xff)
@@ -4520,54 +4131,12 @@ int ssl3_shutdown(SSL *s)
 
 int ssl3_write(SSL *s, const void *buf, int len)
 {
-    int ret, n;
-
-#if 0
-    if (s->shutdown & SSL_SEND_SHUTDOWN) {
-        s->rwstate = SSL_NOTHING;
-        return (0);
-    }
-#endif
     clear_sys_error();
     if (s->s3->renegotiate)
         ssl3_renegotiate_check(s);
 
-    /*
-     * This is an experimental flag that sends the last handshake message in
-     * the same packet as the first use data - used to see if it helps the
-     * TCP protocol during session-id reuse
-     */
-    /* The second test is because the buffer may have been removed */
-    if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio)) {
-        /* First time through, we write into the buffer */
-        if (s->s3->delay_buf_pop_ret == 0) {
-            ret = ssl3_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len);
-            if (ret <= 0)
-                return (ret);
-
-            s->s3->delay_buf_pop_ret = ret;
-        }
-
-        s->rwstate = SSL_WRITING;
-        n = BIO_flush(s->wbio);
-        if (n <= 0)
-            return (n);
-        s->rwstate = SSL_NOTHING;
-
-        /* We have flushed the buffer, so remove it */
-        ssl_free_wbio_buffer(s);
-        s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER;
-
-        ret = s->s3->delay_buf_pop_ret;
-        s->s3->delay_buf_pop_ret = 0;
-    } else {
-        ret = s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA,
+    return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA,
                                          buf, len);
-        if (ret <= 0)
-            return (ret);
-    }
-
-    return (ret);
 }
 
 static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
@@ -4627,8 +4196,9 @@ int ssl3_renegotiate_check(SSL *s)
     int ret = 0;
 
     if (s->s3->renegotiate) {
-        if ((s->s3->rbuf.left == 0) &&
-            (s->s3->wbuf.left == 0) && !SSL_in_init(s)) {
+        if (!RECORD_LAYER_read_pending(&s->rlayer)
+            && !RECORD_LAYER_write_pending(&s->rlayer)
+            && !SSL_in_init(s)) {
             /*
              * if we are the server, and we have sent a 'RENEGOTIATE'
              * message, we need to go to SSL_ST_ACCEPT.
@@ -4647,12 +4217,56 @@ int ssl3_renegotiate_check(SSL *s)
 /*
  * If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and
  * handshake macs if required.
+ *
+ * If PSK and using SHA384 for TLS < 1.2 switch to default.
  */
 long ssl_get_algorithm2(SSL *s)
 {
     long alg2 = s->s3->tmp.new_cipher->algorithm2;
-    if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF
-        && alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF))
-        return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
+    if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF) {
+        if (alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF))
+            return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
+    } else if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK) {
+        if (alg2 == (SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384))
+            return SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF;
+    }
     return alg2;
 }
+
+/*
+ * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on
+ * failure, 1 on success.
+ */
+int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len)
+{
+    int send_time = 0;
+
+    if (len < 4)
+        return 0;
+    if (server)
+        send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0;
+    else
+        send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0;
+    if (send_time) {
+        unsigned long Time = (unsigned long)time(NULL);
+        unsigned char *p = result;
+        l2n(Time, p);
+        return RAND_bytes(p, len - 4);
+    } else
+        return RAND_bytes(result, len);
+}
+
+int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
+                               int free_pms)
+{
+    s->session->master_key_length =
+        s->method->ssl3_enc->generate_master_secret(s, s->session->master_key,
+                                                    pms, pmslen);
+    if (free_pms)
+        OPENSSL_clear_free(pms, pmslen);
+    else
+        OPENSSL_cleanse(pms, pmslen);
+    if (s->server == 0)
+        s->s3->tmp.pms = NULL;
+    return s->session->master_key_length >= 0;
+}