ssl/s3_srvr.c: Fix typo introduced via 69f682374868b.
[openssl.git] / ssl / s3_srvr.c
index f31b76a96ab9f1e4c19c7b208782af94cbc013e7..7a399673b1d6b4f1c4c1fc0cd11fb7c4f75c25bf 100644 (file)
  * OTHERWISE.
  */
 
-#define REUSE_CIPHER_BUG
-#define NETSCAPE_HANG_BUG
 
 #include <stdio.h>
 #include "ssl_locl.h"
@@ -228,13 +226,11 @@ int ssl3_accept(SSL *s)
 
     /* init things to blank */
     s->in_handshake++;
-    if (!SSL_in_init(s) || SSL_in_before(s))
-        SSL_clear(s);
-
-    if (s->cert == NULL) {
-        SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_NO_CERTIFICATE_SET);
-        return (-1);
+    if (!SSL_in_init(s) || SSL_in_before(s)) {
+        if (!SSL_clear(s))
+            return -1;
     }
+
 #ifndef OPENSSL_NO_HEARTBEATS
     /*
      * If we're awaiting a HeartbeatResponse, pretend we already got and
@@ -542,12 +538,7 @@ int ssl3_accept(SSL *s)
                 ret = ssl3_send_certificate_request(s);
                 if (ret <= 0)
                     goto end;
-#ifndef NETSCAPE_HANG_BUG
                 s->state = SSL3_ST_SW_SRVR_DONE_A;
-#else
-                s->state = SSL3_ST_SW_FLUSH;
-                s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
-#endif
                 s->init_num = 0;
             }
             break;
@@ -891,7 +882,10 @@ int ssl3_send_hello_request(SSL *s)
 {
 
     if (s->state == SSL3_ST_SW_HELLO_REQ_A) {
-        ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0);
+        if (!ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0)) {
+            SSLerr(SSL_F_SSL3_SEND_HELLO_REQUEST, ERR_R_INTERNAL_ERROR);
+            return -1;
+        }
         s->state = SSL3_ST_SW_HELLO_REQ_B;
     }
 
@@ -937,6 +931,16 @@ int ssl3_get_client_hello(SSL *s)
     s->first_packet = 0;
     d = p = (unsigned char *)s->init_msg;
 
+    /*
+     * 2 bytes for client version, SSL3_RANDOM_SIZE bytes for random, 1 byte
+     * for session id length
+     */
+    if (n < 2 + SSL3_RANDOM_SIZE + 1) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+        goto f_err;
+    }
+
     /*
      * use version from inside client hello, not from record header (may
      * differ: see RFC 2246, Appendix E, second paragraph)
@@ -969,6 +973,12 @@ int ssl3_get_client_hello(SSL *s)
         unsigned int session_length, cookie_length;
 
         session_length = *(p + SSL3_RANDOM_SIZE);
+
+        if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+            goto f_err;
+        }
         cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1);
 
         if (cookie_length == 0)
@@ -982,6 +992,12 @@ int ssl3_get_client_hello(SSL *s)
     /* get the session-id */
     j = *(p++);
 
+    if (p + j > d + n) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+        goto f_err;
+    }
+
     s->hit = 0;
     /*
      * Versions before 0.9.7 always allow clients to resume sessions in
@@ -1026,8 +1042,19 @@ int ssl3_get_client_hello(SSL *s)
 
     if (SSL_IS_DTLS(s)) {
         /* cookie stuff */
+        if (p + 1 > d + n) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+            goto f_err;
+        }
         cookie_len = *(p++);
 
+        if (p + cookie_len > d + n) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+            goto f_err;
+        }
+
         /*
          * The ClientHello may contain a cookie even if the
          * HelloVerify message has not been sent--make sure that it
@@ -1093,27 +1120,33 @@ int ssl3_get_client_hello(SSL *s)
         }
     }
 
+    if (p + 2 > d + n) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+        goto f_err;
+    }
     n2s(p, i);
-    if ((i == 0) && (j != 0)) {
-        /* we need a cipher if we are not resuming a session */
+
+    if (i == 0) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED);
         goto f_err;
     }
-    if ((p + i) >= (d + n)) {
+
+    /* i bytes of cipher data + 1 byte for compression length later */
+    if ((p + i + 1) > (d + n)) {
         /* not enough data */
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
         goto f_err;
     }
-    if ((i > 0) && (ssl_bytes_to_cipher_list(s, p, i, &(ciphers))
-                    == NULL)) {
+    if (ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) == NULL) {
         goto err;
     }
     p += i;
 
     /* If it is a hit, check that the cipher is in the list */
-    if ((s->hit) && (i > 0)) {
+    if (s->hit) {
         j = 0;
         id = s->session->cipher->id;
 
@@ -1239,14 +1272,9 @@ int ssl3_get_client_hello(SSL *s)
             }
 
             s->session->cipher = pref_cipher;
-
-            if (s->cipher_list)
-                sk_SSL_CIPHER_free(s->cipher_list);
-
-            if (s->cipher_list_by_id)
-                sk_SSL_CIPHER_free(s->cipher_list_by_id);
-
+            sk_SSL_CIPHER_free(s->cipher_list);
             s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
+            sk_SSL_CIPHER_free(s->cipher_list_by_id);
             s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
         }
     }
@@ -1338,12 +1366,11 @@ int ssl3_get_client_hello(SSL *s)
 #else
         s->session->compress_meth = (comp == NULL) ? 0 : comp->id;
 #endif
-        if (s->session->ciphers != NULL)
-            sk_SSL_CIPHER_free(s->session->ciphers);
+        sk_SSL_CIPHER_free(s->session->ciphers);
         s->session->ciphers = ciphers;
         if (ciphers == NULL) {
-            al = SSL_AD_ILLEGAL_PARAMETER;
-            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_PASSED);
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
             goto f_err;
         }
         ciphers = NULL;
@@ -1384,29 +1411,7 @@ int ssl3_get_client_hello(SSL *s)
             s->tlsext_ticket_expected = 0;
     } else {
         /* Session-id reuse */
-#ifdef REUSE_CIPHER_BUG
-        STACK_OF(SSL_CIPHER) *sk;
-        SSL_CIPHER *nc = NULL;
-        SSL_CIPHER *ec = NULL;
-
-        if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) {
-            sk = s->session->ciphers;
-            for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
-                c = sk_SSL_CIPHER_value(sk, i);
-                if (c->algorithm_enc & SSL_eNULL)
-                    nc = c;
-                if (SSL_C_IS_EXPORT(c))
-                    ec = c;
-            }
-            if (nc != NULL)
-                s->s3->tmp.new_cipher = nc;
-            else if (ec != NULL)
-                s->s3->tmp.new_cipher = ec;
-            else
-                s->s3->tmp.new_cipher = s->session->cipher;
-        } else
-#endif
-            s->s3->tmp.new_cipher = s->session->cipher;
+        s->s3->tmp.new_cipher = s->session->cipher;
     }
 
     if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) {
@@ -1441,8 +1446,7 @@ int ssl3_get_client_hello(SSL *s)
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
     }
  err:
-    if (ciphers != NULL)
-        sk_SSL_CIPHER_free(ciphers);
+    sk_SSL_CIPHER_free(ciphers);
     return ret < 0 ? -1 : ret;
 }
 
@@ -1529,7 +1533,10 @@ int ssl3_send_server_hello(SSL *s)
 #endif
         /* do the header */
         l = (p - d);
-        ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l);
+        if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l)) {
+            SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+            return -1;
+        }
         s->state = SSL3_ST_SW_SRVR_HELLO_B;
     }
 
@@ -1541,7 +1548,10 @@ int ssl3_send_server_done(SSL *s)
 {
 
     if (s->state == SSL3_ST_SW_SRVR_DONE_A) {
-        ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0);
+        if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) {
+            SSLerr(SSL_F_SSL3_SEND_SERVER_DONE, ERR_R_INTERNAL_ERROR);
+            return -1;
+        }
         s->state = SSL3_ST_SW_SRVR_DONE_B;
     }
 
@@ -1561,7 +1571,7 @@ int ssl3_send_server_key_exchange(SSL *s)
 #ifndef OPENSSL_NO_DH
     DH *dh = NULL, *dhp;
 #endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
     EC_KEY *ecdh = NULL, *ecdhp;
     unsigned char *encodedPoint = NULL;
     int encodedlen = 0;
@@ -1683,7 +1693,7 @@ int ssl3_send_server_key_exchange(SSL *s)
             r[2] = dh->pub_key;
         } else
 #endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
         if (type & SSL_kECDHE) {
             const EC_GROUP *group;
 
@@ -1811,7 +1821,7 @@ int ssl3_send_server_key_exchange(SSL *s)
             r[2] = NULL;
             r[3] = NULL;
         } else
-#endif                          /* !OPENSSL_NO_ECDH */
+#endif                          /* !OPENSSL_NO_EC */
 #ifndef OPENSSL_NO_PSK
         if (type & SSL_kPSK) {
             /*
@@ -1882,7 +1892,7 @@ int ssl3_send_server_key_exchange(SSL *s)
             p += nr[i];
         }
 
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
         if (type & SSL_kECDHE) {
             /*
              * XXX: For now, we only support named (not generic) curves. In
@@ -1988,7 +1998,11 @@ int ssl3_send_server_key_exchange(SSL *s)
             }
         }
 
-        ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n);
+        if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n)) {
+            al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto f_err;
+        }
     }
 
     s->state = SSL3_ST_SW_KEY_EXCH_B;
@@ -1997,9 +2011,8 @@ int ssl3_send_server_key_exchange(SSL *s)
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
-#ifndef OPENSSL_NO_ECDH
-    if (encodedPoint != NULL)
-        OPENSSL_free(encodedPoint);
+#ifndef OPENSSL_NO_EC
+    OPENSSL_free(encodedPoint);
     BN_CTX_free(bn_ctx);
 #endif
     EVP_MD_CTX_cleanup(&md_ctx);
@@ -2056,43 +2069,20 @@ int ssl3_send_certificate_request(SSL *s)
                     goto err;
                 }
                 p = ssl_handshake_start(s) + n;
-                if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) {
-                    s2n(j, p);
-                    i2d_X509_NAME(name, &p);
-                    n += 2 + j;
-                    nl += 2 + j;
-                } else {
-                    d = p;
-                    i2d_X509_NAME(name, &p);
-                    j -= 2;
-                    s2n(j, d);
-                    j += 2;
-                    n += j;
-                    nl += j;
-                }
+                s2n(j, p);
+                i2d_X509_NAME(name, &p);
+                n += 2 + j;
+                nl += 2 + j;
             }
         }
         /* else no CA names */
         p = ssl_handshake_start(s) + off;
         s2n(nl, p);
 
-        ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n);
-
-#ifdef NETSCAPE_HANG_BUG
-        if (!SSL_IS_DTLS(s)) {
-            if (!BUF_MEM_grow_clean(buf, s->init_num + 4)) {
-                SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, ERR_R_BUF_LIB);
-                goto err;
-            }
-            p = (unsigned char *)s->init_buf->data + s->init_num;
-            /* do the header */
-            *(p++) = SSL3_MT_SERVER_DONE;
-            *(p++) = 0;
-            *(p++) = 0;
-            *(p++) = 0;
-            s->init_num += 4;
+        if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n)) {
+            SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
+            return -1;
         }
-#endif
 
         s->state = SSL3_ST_SW_CERT_REQ_B;
     }
@@ -2121,7 +2111,7 @@ int ssl3_get_client_key_exchange(SSL *s)
     KSSL_ERR kssl_err;
 #endif                          /* OPENSSL_NO_KRB5 */
 
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
     EC_KEY *srvr_ecdh = NULL;
     EVP_PKEY *clnt_pub_pkey = NULL;
     EC_POINT *clnt_ecpoint = NULL;
@@ -2209,10 +2199,7 @@ int ssl3_get_client_key_exchange(SSL *s)
          * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1
          */
 
-        /*
-         * should be RAND_bytes, but we cannot work around a failure.
-         */
-        if (RAND_pseudo_bytes(rand_premaster_secret,
+        if (RAND_bytes(rand_premaster_secret,
                               sizeof(rand_premaster_secret)) <= 0)
             goto err;
         decrypt_len =
@@ -2282,16 +2269,28 @@ int ssl3_get_client_key_exchange(SSL *s)
                                                         sizeof
                                                         (rand_premaster_secret));
         OPENSSL_cleanse(p, sizeof(rand_premaster_secret));
+        if (s->session->master_key_length < 0) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto f_err;
+        }
     } else
 #endif
 #ifndef OPENSSL_NO_DH
     if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd)) {
         int idx = -1;
         EVP_PKEY *skey = NULL;
-        if (n)
+        if (n > 1) {
             n2s(p, i);
-        else
+        } else {
+            if (alg_k & SSL_kDHE) {
+                al = SSL_AD_HANDSHAKE_FAILURE;
+                SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                       SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
+                goto f_err;
+            }
             i = 0;
+        }
         if (n && n != i + 2) {
             if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) {
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
@@ -2367,6 +2366,11 @@ int ssl3_get_client_key_exchange(SSL *s)
                                                         session->master_key,
                                                         p, i);
         OPENSSL_cleanse(p, i);
+        if (s->session->master_key_length < 0) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto f_err;
+        }
         if (dh_clnt)
             return 2;
     } else
@@ -2532,6 +2536,11 @@ int ssl3_get_client_key_exchange(SSL *s)
                                                         s->
                                                         session->master_key,
                                                         pms, outl);
+        if (s->session->master_key_length < 0) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto f_err;
+        }
 
         if (kssl_ctx->client_princ) {
             size_t len = strlen(kssl_ctx->client_princ);
@@ -2550,7 +2559,7 @@ int ssl3_get_client_key_exchange(SSL *s)
     } else
 #endif                          /* OPENSSL_NO_KRB5 */
 
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
     if (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe)) {
         int ret = 1;
         int field_size = 0;
@@ -2680,6 +2689,11 @@ int ssl3_get_client_key_exchange(SSL *s)
                                                         p, i);
 
         OPENSSL_cleanse(p, i);
+        if (s->session->master_key_length < 0) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto f_err;
+        }
         return (ret);
     } else
 #endif
@@ -2741,16 +2755,14 @@ int ssl3_get_client_key_exchange(SSL *s)
         t += psk_len;
         s2n(psk_len, t);
 
-        if (s->session->psk_identity != NULL)
-            OPENSSL_free(s->session->psk_identity);
+        OPENSSL_free(s->session->psk_identity);
         s->session->psk_identity = BUF_strdup((char *)p);
         if (s->session->psk_identity == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto psk_err;
         }
 
-        if (s->session->psk_identity_hint != NULL)
-            OPENSSL_free(s->session->psk_identity_hint);
+        OPENSSL_free(s->session->psk_identity_hint);
         s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
         if (s->ctx->psk_identity_hint != NULL &&
             s->session->psk_identity_hint == NULL) {
@@ -2764,6 +2776,11 @@ int ssl3_get_client_key_exchange(SSL *s)
                                                         session->master_key,
                                                         psk_or_pre_ms,
                                                         pre_ms_len);
+        if (s->session->master_key_length < 0) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto psk_err;
+        }
         psk_err = 0;
  psk_err:
         OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
@@ -2794,8 +2811,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                    SSL_R_BAD_SRP_PARAMETERS);
             goto f_err;
         }
-        if (s->session->srp_username != NULL)
-            OPENSSL_free(s->session->srp_username);
+        OPENSSL_free(s->session->srp_username);
         s->session->srp_username = BUF_strdup(s->srp_ctx.login);
         if (s->session->srp_username == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
@@ -2865,6 +2881,11 @@ int ssl3_get_client_key_exchange(SSL *s)
                                                         s->
                                                         session->master_key,
                                                         premaster_secret, 32);
+        if (s->session->master_key_length < 0) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto f_err;
+        }
         /* Check if pubkey from client certificate was used */
         if (EVP_PKEY_CTX_ctrl
             (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
@@ -2876,8 +2897,7 @@ int ssl3_get_client_key_exchange(SSL *s)
         EVP_PKEY_CTX_free(pkey_ctx);
         if (ret)
             return ret;
-        else
-            goto err;
+        goto err;
     } else {
         al = SSL_AD_HANDSHAKE_FAILURE;
         SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE);
@@ -2887,14 +2907,13 @@ int ssl3_get_client_key_exchange(SSL *s)
     return (1);
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
-#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP)
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_EC) || defined(OPENSSL_NO_SRP)
  err:
 #endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
     EVP_PKEY_free(clnt_pub_pkey);
     EC_POINT_free(clnt_ecpoint);
-    if (srvr_ecdh != NULL)
-        EC_KEY_free(srvr_ecdh);
+    EC_KEY_free(srvr_ecdh);
     BN_CTX_free(bn_ctx);
 #endif
     return (-1);
@@ -3056,7 +3075,7 @@ int ssl3_get_cert_verify(SSL *s)
         }
     } else
 #endif
-#ifndef OPENSSL_NO_ECDSA
+#ifndef OPENSSL_NO_EC
     if (pkey->type == EVP_PKEY_EC) {
         j = ECDSA_verify(pkey->save_type,
                          &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
@@ -3101,11 +3120,9 @@ int ssl3_get_cert_verify(SSL *s)
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
     }
  end:
-    if (s->s3->handshake_buffer) {
-        BIO_free(s->s3->handshake_buffer);
-        s->s3->handshake_buffer = NULL;
-        s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE;
-    }
+    BIO_free(s->s3->handshake_buffer);
+    s->s3->handshake_buffer = NULL;
+    s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE;
     EVP_MD_CTX_cleanup(&mctx);
     EVP_PKEY_free(pkey);
     return (ret);
@@ -3158,7 +3175,7 @@ int ssl3_get_client_certificate(SSL *s)
 
     if ((sk = sk_X509_new_null()) == NULL) {
         SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
-        goto err;
+        goto done;
     }
 
     n2l3(p, llen);
@@ -3180,7 +3197,7 @@ int ssl3_get_client_certificate(SSL *s)
         x = d2i_X509(NULL, &p, l);
         if (x == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB);
-            goto err;
+            goto done;
         }
         if (p != (q + l)) {
             al = SSL_AD_DECODE_ERROR;
@@ -3190,7 +3207,7 @@ int ssl3_get_client_certificate(SSL *s)
         }
         if (!sk_X509_push(sk, x)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
-            goto err;
+            goto done;
         }
         x = NULL;
         nc += l + 3;
@@ -3241,8 +3258,7 @@ int ssl3_get_client_certificate(SSL *s)
         EVP_PKEY_free(pkey);
     }
 
-    if (s->session->peer != NULL) /* This should not be needed */
-        X509_free(s->session->peer);
+    X509_free(s->session->peer);
     s->session->peer = sk_X509_shift(sk);
     s->session->verify_result = s->verify_result;
 
@@ -3254,29 +3270,24 @@ int ssl3_get_client_certificate(SSL *s)
         s->session->sess_cert = ssl_sess_cert_new();
         if (s->session->sess_cert == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
-            goto err;
+            goto done;
         }
     }
-    if (s->session->sess_cert->cert_chain != NULL)
-        sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free);
+    sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free);
     s->session->sess_cert->cert_chain = sk;
     /*
      * Inconsistency alert: cert_chain does *not* include the peer's own
      * certificate, while we do include it in s3_clnt.c
      */
-
     sk = NULL;
-
     ret = 1;
-    if (0) {
+    goto done;
+
  f_err:
-        ssl3_send_alert(s, SSL3_AL_FATAL, al);
-    }
- err:
-    if (x != NULL)
-        X509_free(x);
-    if (sk != NULL)
-        sk_X509_pop_free(sk, X509_free);
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ done:
+    X509_free(x);
+    sk_X509_pop_free(sk, X509_free);
     return (ret);
 }
 
@@ -3311,14 +3322,16 @@ int ssl3_send_server_certificate(SSL *s)
 /* send a new session ticket (not necessarily for a new session) */
 int ssl3_send_newsession_ticket(SSL *s)
 {
+    unsigned char *senc = NULL;
+    EVP_CIPHER_CTX ctx;
+    HMAC_CTX hctx;
+
     if (s->state == SSL3_ST_SW_SESSION_TICKET_A) {
-        unsigned char *p, *senc, *macstart;
+        unsigned char *p, *macstart;
         const unsigned char *const_p;
         int len, slen_full, slen;
         SSL_SESSION *sess;
         unsigned int hlen;
-        EVP_CIPHER_CTX ctx;
-        HMAC_CTX hctx;
         SSL_CTX *tctx = s->initial_ctx;
         unsigned char iv[EVP_MAX_IV_LENGTH];
         unsigned char key_name[16];
@@ -3329,32 +3342,38 @@ int ssl3_send_newsession_ticket(SSL *s)
          * Some length values are 16 bits, so forget it if session is too
          * long
          */
-        if (slen_full > 0xFF00)
+        if (slen_full == 0 || slen_full > 0xFF00)
             return -1;
         senc = OPENSSL_malloc(slen_full);
         if (!senc)
             return -1;
+
+        EVP_CIPHER_CTX_init(&ctx);
+        HMAC_CTX_init(&hctx);
+
         p = senc;
-        i2d_SSL_SESSION(s->session, &p);
+        if (!i2d_SSL_SESSION(s->session, &p))
+            goto err;
 
         /*
          * create a fresh copy (not shared with other threads) to clean up
          */
         const_p = senc;
         sess = d2i_SSL_SESSION(NULL, &const_p, slen_full);
-        if (sess == NULL) {
-            OPENSSL_free(senc);
-            return -1;
-        }
+        if (sess == NULL)
+            goto err;
         sess->session_id_length = 0; /* ID is irrelevant for the ticket */
 
         slen = i2d_SSL_SESSION(sess, NULL);
-        if (slen > slen_full) { /* shouldn't ever happen */
-            OPENSSL_free(senc);
-            return -1;
+        if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */
+            SSL_SESSION_free(sess);
+            goto err;
         }
         p = senc;
-        i2d_SSL_SESSION(sess, &p);
+        if (!i2d_SSL_SESSION(sess, &p)) {
+            SSL_SESSION_free(sess);
+            goto err;
+        }
         SSL_SESSION_free(sess);
 
         /*-
@@ -3368,26 +3387,26 @@ int ssl3_send_newsession_ticket(SSL *s)
         if (!BUF_MEM_grow(s->init_buf,
                           SSL_HM_HEADER_LENGTH(s) + 22 + EVP_MAX_IV_LENGTH +
                           EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen))
-            return -1;
+            goto err;
+
         p = ssl_handshake_start(s);
-        EVP_CIPHER_CTX_init(&ctx);
-        HMAC_CTX_init(&hctx);
         /*
          * Initialize HMAC and cipher contexts. If callback present it does
          * all the work otherwise use generated values from parent ctx.
          */
         if (tctx->tlsext_ticket_key_cb) {
             if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
-                                           &hctx, 1) < 0) {
-                OPENSSL_free(senc);
-                return -1;
-            }
+                                           &hctx, 1) < 0)
+                goto err;
         } else {
-            RAND_pseudo_bytes(iv, 16);
-            EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
-                               tctx->tlsext_tick_aes_key, iv);
-            HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
-                         EVP_sha256(), NULL);
+            if (RAND_bytes(iv, 16) <= 0)
+                goto err;
+            if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+                                    tctx->tlsext_tick_aes_key, iv))
+                goto err;
+            if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+                              EVP_sha256(), NULL))
+                goto err;
             memcpy(key_name, tctx->tlsext_tick_key_name, 16);
         }
 
@@ -3408,30 +3427,41 @@ int ssl3_send_newsession_ticket(SSL *s)
         memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
         p += EVP_CIPHER_CTX_iv_length(&ctx);
         /* Encrypt session data */
-        EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
+        if (!EVP_EncryptUpdate(&ctx, p, &len, senc, slen))
+            goto err;
         p += len;
-        EVP_EncryptFinal(&ctx, p, &len);
+        if (!EVP_EncryptFinal(&ctx, p, &len))
+            goto err;
         p += len;
-        EVP_CIPHER_CTX_cleanup(&ctx);
 
-        HMAC_Update(&hctx, macstart, p - macstart);
-        HMAC_Final(&hctx, p, &hlen);
+        if (!HMAC_Update(&hctx, macstart, p - macstart))
+            goto err;
+        if (!HMAC_Final(&hctx, p, &hlen))
+            goto err;
+
+        EVP_CIPHER_CTX_cleanup(&ctx);
         HMAC_CTX_cleanup(&hctx);
 
         p += hlen;
         /* Now write out lengths: p points to end of data written */
         /* Total length */
         len = p - ssl_handshake_start(s);
-        ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len);
         /* Skip ticket lifetime hint */
         p = ssl_handshake_start(s) + 4;
         s2n(len - 6, p);
+        if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len))
+            goto err;
         s->state = SSL3_ST_SW_SESSION_TICKET_B;
         OPENSSL_free(senc);
     }
 
     /* SSL3_ST_SW_SESSION_TICKET_B */
     return ssl_do_write(s);
+ err:
+    OPENSSL_free(senc);
+    EVP_CIPHER_CTX_cleanup(&ctx);
+    HMAC_CTX_cleanup(&hctx);
+    return -1;
 }
 
 int ssl3_send_cert_status(SSL *s)