Move s->packet and s->packet_length into s->rlayer
[openssl.git] / ssl / t1_lib.c
index 8fb26a4c8d2eac0326e14e61eb9a6b19034e37df..aef0ef6659096a6b60cd98905f5195df46accb3f 100644 (file)
@@ -596,6 +596,8 @@ static int nid_cb(const char *elem, int len, void *arg)
     size_t i;
     int nid;
     char etmp[20];
+    if (elem == NULL)
+        return 0;
     if (narg->nidcnt == MAX_CURVELIST)
         return 0;
     if (len > (int)(sizeof(etmp) - 1))
@@ -704,6 +706,16 @@ static int tls1_check_ec_key(SSL *s,
     for (j = 0; j <= 1; j++) {
         if (!tls1_get_curvelist(s, j, &pcurves, &num_curves))
             return 0;
+        if (j == 1 && num_curves == 0) {
+            /*
+             * If we've not received any curves then skip this check.
+             * RFC 4492 does not require the supported elliptic curves extension
+             * so if it is not sent we can just choose any curve.
+             * It is invalid to send an empty list in the elliptic curves
+             * extension, so num_curves == 0 always means no extension.
+             */
+            break;
+        }
         for (i = 0; i < num_curves; i++, pcurves += 2) {
             if (pcurves[0] == curve_id[0] && pcurves[1] == curve_id[1])
                 break;
@@ -796,7 +808,7 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
     return rv;
 }
 
-# ifndef OPENSSL_NO_ECDH
+# ifndef OPENSSL_NO_EC
 /* Check EC temporary key is compatible with client extensions */
 int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
 {
@@ -861,7 +873,7 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
     return tls1_check_ec_key(s, curve_id, NULL);
 #  endif
 }
-# endif                         /* OPENSSL_NO_ECDH */
+# endif                         /* OPENSSL_NO_EC */
 
 #else
 
@@ -891,9 +903,8 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
 #  define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
 # endif
 
-# ifdef OPENSSL_NO_ECDSA
-#  define tlsext_sigalg_ecdsa(md)
-                                /* */
+# ifdef OPENSSL_NO_EC
+#  define tlsext_sigalg_ecdsa(md) /* */
 # else
 #  define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
 # endif
@@ -904,20 +915,14 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
                 tlsext_sigalg_ecdsa(md)
 
 static const unsigned char tls12_sigalgs[] = {
-# ifndef OPENSSL_NO_SHA512
     tlsext_sigalg(TLSEXT_hash_sha512)
         tlsext_sigalg(TLSEXT_hash_sha384)
-# endif
-# ifndef OPENSSL_NO_SHA256
         tlsext_sigalg(TLSEXT_hash_sha256)
         tlsext_sigalg(TLSEXT_hash_sha224)
-# endif
-# ifndef OPENSSL_NO_SHA
         tlsext_sigalg(TLSEXT_hash_sha1)
-# endif
 };
 
-# ifndef OPENSSL_NO_ECDSA
+# ifndef OPENSSL_NO_EC
 static const unsigned char suiteb_sigalgs[] = {
     tlsext_sigalg_ecdsa(TLSEXT_hash_sha256)
         tlsext_sigalg_ecdsa(TLSEXT_hash_sha384)
@@ -1339,22 +1344,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         s2n(salglen, etmp);
         ret += salglen;
     }
-# ifdef TLSEXT_TYPE_opaque_prf_input
-    if (s->s3->client_opaque_prf_input != NULL) {
-        size_t col = s->s3->client_opaque_prf_input_len;
-
-        if ((long)(limit - ret - 6 - col) < 0)
-            return NULL;
-        if (col > 0xFFFD)       /* can't happen */
-            return NULL;
-
-        s2n(TLSEXT_TYPE_opaque_prf_input, ret);
-        s2n(col + 2, ret);
-        s2n(col, ret);
-        memcpy(ret, s->s3->client_opaque_prf_input, col);
-        ret += col;
-    }
-# endif
 
     if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
         int i;
@@ -1442,7 +1431,11 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
     if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
         int el;
 
-        ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
+        /* Returns 0 on success!! */
+        if (ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
 
         if ((limit - ret - 4 - el) < 0)
             return NULL;
@@ -1465,6 +1458,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
     s2n(TLSEXT_TYPE_encrypt_then_mac, ret);
     s2n(0, ret);
 # endif
+    s2n(TLSEXT_TYPE_extended_master_secret, ret);
+    s2n(0, ret);
 
     /*
      * Add padding to workaround bugs in F5 terminators. See
@@ -1605,29 +1600,16 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         s2n(TLSEXT_TYPE_status_request, ret);
         s2n(0, ret);
     }
-# ifdef TLSEXT_TYPE_opaque_prf_input
-    if (s->s3->server_opaque_prf_input != NULL) {
-        size_t sol = s->s3->server_opaque_prf_input_len;
-
-        if ((long)(limit - ret - 6 - sol) < 0)
-            return NULL;
-        if (sol > 0xFFFD)       /* can't happen */
-            return NULL;
-
-        s2n(TLSEXT_TYPE_opaque_prf_input, ret);
-        s2n(sol + 2, ret);
-        s2n(sol, ret);
-        memcpy(ret, s->s3->server_opaque_prf_input, sol);
-        ret += sol;
-    }
-# endif
 
 # ifndef OPENSSL_NO_SRTP
     if (SSL_IS_DTLS(s) && s->srtp_profile) {
         int el;
 
-        ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
-
+        /* Returns 0 on success!! */
+        if(ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
         if ((limit - ret - 4 - el) < 0)
             return NULL;
 
@@ -1718,6 +1700,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         }
     }
 # endif
+    if (!s->hit && s->session->flags & SSL_SESS_FLAG_EXTMS) {
+        s2n(TLSEXT_TYPE_extended_master_secret, ret);
+        s2n(0, ret);
+    }
 
     if (s->s3->alpn_selected) {
         const unsigned char *selected = s->s3->alpn_selected;
@@ -1953,9 +1939,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
 
         if (data + size > (d + n))
             goto ri_check;
-# if 0
-        fprintf(stderr, "Received extension type %d size %d\n", type, size);
-# endif
         if (s->tlsext_debug_cb)
             s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg);
         if (type == TLSEXT_TYPE_renegotiate) {
@@ -2110,15 +2093,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
                 memcpy(s->session->tlsext_ecpointformatlist, sdata,
                        ecpointformatlist_length);
             }
-#  if 0
-            fprintf(stderr,
-                    "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ",
-                    s->session->tlsext_ecpointformatlist_length);
-            sdata = s->session->tlsext_ecpointformatlist;
-            for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
-                fprintf(stderr, "%i ", *(sdata++));
-            fprintf(stderr, "\n");
-#  endif
         } else if (type == TLSEXT_TYPE_elliptic_curves) {
             unsigned char *sdata = data;
             int ellipticcurvelist_length = (*(sdata++) << 8);
@@ -2147,48 +2121,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
                 memcpy(s->session->tlsext_ellipticcurvelist, sdata,
                        ellipticcurvelist_length);
             }
-#  if 0
-            fprintf(stderr,
-                    "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ",
-                    s->session->tlsext_ellipticcurvelist_length);
-            sdata = s->session->tlsext_ellipticcurvelist;
-            for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
-                fprintf(stderr, "%i ", *(sdata++));
-            fprintf(stderr, "\n");
-#  endif
         }
 # endif                         /* OPENSSL_NO_EC */
-# ifdef TLSEXT_TYPE_opaque_prf_input
-        else if (type == TLSEXT_TYPE_opaque_prf_input) {
-            unsigned char *sdata = data;
-
-            if (size < 2) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
-            n2s(sdata, s->s3->client_opaque_prf_input_len);
-            if (s->s3->client_opaque_prf_input_len != size - 2) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
-
-            if (s->s3->client_opaque_prf_input != NULL) {
-                /* shouldn't really happen */
-                OPENSSL_free(s->s3->client_opaque_prf_input);
-            }
-
-            /* dummy byte just to get non-NULL */
-            if (s->s3->client_opaque_prf_input_len == 0)
-                s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
-            else
-                s->s3->client_opaque_prf_input =
-                    BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
-            if (s->s3->client_opaque_prf_input == NULL) {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-        }
-# endif
         else if (type == TLSEXT_TYPE_session_ticket) {
             if (s->tls_session_ticket_ext_cb &&
                 !s->tls_session_ticket_ext_cb(s, data, size,
@@ -2367,6 +2301,10 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
         else if (type == TLSEXT_TYPE_encrypt_then_mac)
             s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
 # endif
+        else if (type == TLSEXT_TYPE_extended_master_secret) {
+            if (!s->hit)
+                s->session->flags |= SSL_SESS_FLAG_EXTMS;
+        }
         /*
          * If this ClientHello extension was unhandled and this is a
          * nonresumed connection, check whether the extension is a custom
@@ -2519,14 +2457,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
                 memcpy(s->session->tlsext_ecpointformatlist, sdata,
                        ecpointformatlist_length);
             }
-#  if 0
-            fprintf(stderr,
-                    "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
-            sdata = s->session->tlsext_ecpointformatlist;
-            for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
-                fprintf(stderr, "%i ", *(sdata++));
-            fprintf(stderr, "\n");
-#  endif
         }
 # endif                         /* OPENSSL_NO_EC */
 
@@ -2544,38 +2474,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
             }
             s->tlsext_ticket_expected = 1;
         }
-# ifdef TLSEXT_TYPE_opaque_prf_input
-        else if (type == TLSEXT_TYPE_opaque_prf_input) {
-            unsigned char *sdata = data;
-
-            if (size < 2) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
-            n2s(sdata, s->s3->server_opaque_prf_input_len);
-            if (s->s3->server_opaque_prf_input_len != size - 2) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
-
-            if (s->s3->server_opaque_prf_input != NULL) {
-                /* shouldn't really happen */
-                OPENSSL_free(s->s3->server_opaque_prf_input);
-            }
-            if (s->s3->server_opaque_prf_input_len == 0) {
-                /* dummy byte just to get non-NULL */
-                s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
-            } else {
-                s->s3->server_opaque_prf_input =
-                    BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
-            }
-
-            if (s->s3->server_opaque_prf_input == NULL) {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-        }
-# endif
         else if (type == TLSEXT_TYPE_status_request) {
             /*
              * MUST be empty and only sent if we've requested a status
@@ -2693,6 +2591,10 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
                 s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
         }
 # endif
+        else if (type == TLSEXT_TYPE_extended_master_secret) {
+            if (!s->hit)
+                s->session->flags |= SSL_SESS_FLAG_EXTMS;
+        }
         /*
          * If this extension type was not otherwise handled, but matches a
          * custom_cli_ext_record, then send it to the c callback
@@ -2749,51 +2651,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
 int ssl_prepare_clienthello_tlsext(SSL *s)
 {
 
-# ifdef TLSEXT_TYPE_opaque_prf_input
-    {
-        int r = 1;
-
-        if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
-            r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
-                                                         s->
-                                                         ctx->tlsext_opaque_prf_input_callback_arg);
-            if (!r)
-                return -1;
-        }
-
-        if (s->tlsext_opaque_prf_input != NULL) {
-            if (s->s3->client_opaque_prf_input != NULL) {
-                /* shouldn't really happen */
-                OPENSSL_free(s->s3->client_opaque_prf_input);
-            }
-
-            if (s->tlsext_opaque_prf_input_len == 0) {
-                /* dummy byte just to get non-NULL */
-                s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
-            } else {
-                s->s3->client_opaque_prf_input =
-                    BUF_memdup(s->tlsext_opaque_prf_input,
-                               s->tlsext_opaque_prf_input_len);
-            }
-            if (s->s3->client_opaque_prf_input == NULL) {
-                SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
-                       ERR_R_MALLOC_FAILURE);
-                return -1;
-            }
-            s->s3->client_opaque_prf_input_len =
-                s->tlsext_opaque_prf_input_len;
-        }
-
-        if (r == 2)
-            /*
-             * at callback's request, insist on receiving an appropriate
-             * server opaque PRF input
-             */
-            s->s3->server_opaque_prf_input_len =
-                s->tlsext_opaque_prf_input_len;
-    }
-# endif
-
     return 1;
 }
 
@@ -2829,73 +2686,6 @@ static int ssl_check_clienthello_tlsext_early(SSL *s)
                                                        s->
                                                        initial_ctx->tlsext_servername_arg);
 
-# ifdef TLSEXT_TYPE_opaque_prf_input
-    {
-        /*
-         * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we
-         * might be sending an alert in response to the client hello, so this
-         * has to happen here in ssl_check_clienthello_tlsext_early().
-         */
-
-        int r = 1;
-
-        if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
-            r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
-                                                         s->
-                                                         ctx->tlsext_opaque_prf_input_callback_arg);
-            if (!r) {
-                ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-                al = SSL_AD_INTERNAL_ERROR;
-                goto err;
-            }
-        }
-
-        if (s->s3->server_opaque_prf_input != NULL) {
-            /* shouldn't really happen */
-            OPENSSL_free(s->s3->server_opaque_prf_input);
-        }
-        s->s3->server_opaque_prf_input = NULL;
-
-        if (s->tlsext_opaque_prf_input != NULL) {
-            if (s->s3->client_opaque_prf_input != NULL &&
-                s->s3->client_opaque_prf_input_len ==
-                s->tlsext_opaque_prf_input_len) {
-                /*
-                 * can only use this extension if we have a server opaque PRF
-                 * input of the same length as the client opaque PRF input!
-                 */
-
-                if (s->tlsext_opaque_prf_input_len == 0) {
-                    /* dummy byte just to get non-NULL */
-                    s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
-                } else {
-                    s->s3->server_opaque_prf_input =
-                        BUF_memdup(s->tlsext_opaque_prf_input,
-                                   s->tlsext_opaque_prf_input_len);
-                }
-                if (s->s3->server_opaque_prf_input == NULL) {
-                    ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-                    al = SSL_AD_INTERNAL_ERROR;
-                    goto err;
-                }
-                s->s3->server_opaque_prf_input_len =
-                    s->tlsext_opaque_prf_input_len;
-            }
-        }
-
-        if (r == 2 && s->s3->server_opaque_prf_input == NULL) {
-            /*
-             * The callback wants to enforce use of the extension, but we
-             * can't do that with the client opaque PRF input; abort the
-             * handshake.
-             */
-            ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-            al = SSL_AD_HANDSHAKE_FAILURE;
-        }
-    }
-
- err:
-# endif
     switch (ret) {
     case SSL_TLSEXT_ERR_ALERT_FATAL:
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
@@ -2920,6 +2710,7 @@ int tls1_set_server_sigalgs(SSL *s)
     if (s->cert->shared_sigalgs) {
         OPENSSL_free(s->cert->shared_sigalgs);
         s->cert->shared_sigalgs = NULL;
+        s->cert->shared_sigalgslen = 0;
     }
     /* Clear certificate digests and validity flags */
     for (i = 0; i < SSL_PKEY_NUM; i++) {
@@ -3061,32 +2852,6 @@ int ssl_check_serverhello_tlsext(SSL *s)
                                                        s->
                                                        initial_ctx->tlsext_servername_arg);
 
-# ifdef TLSEXT_TYPE_opaque_prf_input
-    if (s->s3->server_opaque_prf_input_len > 0) {
-        /*
-         * This case may indicate that we, as a client, want to insist on
-         * using opaque PRF inputs. So first verify that we really have a
-         * value from the server too.
-         */
-
-        if (s->s3->server_opaque_prf_input == NULL) {
-            ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-            al = SSL_AD_HANDSHAKE_FAILURE;
-        }
-
-        /*
-         * Anytime the server *has* sent an opaque PRF input, we need to
-         * check that we have a client opaque PRF input of the same size.
-         */
-        if (s->s3->client_opaque_prf_input == NULL ||
-            s->s3->client_opaque_prf_input_len !=
-            s->s3->server_opaque_prf_input_len) {
-            ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-            al = SSL_AD_ILLEGAL_PARAMETER;
-        }
-    }
-# endif
-
     /*
      * If we've requested certificate status and we wont get one tell the
      * callback
@@ -3316,7 +3081,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
         if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
             return 2;
         HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
-                     tlsext_tick_md(), NULL);
+                     EVP_sha256(), NULL);
         EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
                            tctx->tlsext_tick_aes_key, etick + 16);
     }
@@ -3460,25 +3225,11 @@ static const tls12_hash_info tls12_md_info[] = {
 # else
     {NID_md5, 64, EVP_md5},
 # endif
-# ifdef OPENSSL_NO_SHA
-    {NID_sha1, 80, 0},
-# else
     {NID_sha1, 80, EVP_sha1},
-# endif
-# ifdef OPENSSL_NO_SHA256
-    {NID_sha224, 112, 0},
-    {NID_sha256, 128, 0},
-# else
     {NID_sha224, 112, EVP_sha224},
     {NID_sha256, 128, EVP_sha256},
-# endif
-# ifdef OPENSSL_NO_SHA512
-    {NID_sha384, 192, 0},
-    {NID_sha512, 256, 0}
-# else
     {NID_sha384, 192, EVP_sha384},
     {NID_sha512, 256, EVP_sha512}
-# endif
 };
 
 static const tls12_hash_info *tls12_get_hash_info(unsigned char hash_alg)
@@ -3512,7 +3263,7 @@ static int tls12_get_pkey_idx(unsigned char sig_alg)
     case TLSEXT_signature_dsa:
         return SSL_PKEY_DSA_SIGN;
 # endif
-# ifndef OPENSSL_NO_ECDSA
+# ifndef OPENSSL_NO_EC
     case TLSEXT_signature_ecdsa:
         return SSL_PKEY_ECC;
 # endif
@@ -3592,7 +3343,7 @@ void ssl_set_sig_mask(unsigned long *pmask_a, SSL *s, int op)
                 have_dsa = 1;
             break;
 # endif
-# ifndef OPENSSL_NO_ECDSA
+# ifndef OPENSSL_NO_EC
         case TLSEXT_signature_ecdsa:
             if (!have_ecdsa && tls12_sigalg_allowed(s, op, sigalgs))
                 have_ecdsa = 1;
@@ -3663,6 +3414,7 @@ static int tls1_set_shared_sigalgs(SSL *s)
     if (c->shared_sigalgs) {
         OPENSSL_free(c->shared_sigalgs);
         c->shared_sigalgs = NULL;
+        c->shared_sigalgslen = 0;
     }
     /* If client use client signature algorithms if not NULL */
     if (!s->server && c->client_sigalgs && !is_suiteb) {
@@ -3685,12 +3437,14 @@ static int tls1_set_shared_sigalgs(SSL *s)
         preflen = c->peer_sigalgslen;
     }
     nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen);
-    if (!nmatch)
-        return 1;
-    salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
-    if (!salgs)
-        return 0;
-    nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen);
+    if (nmatch) {
+        salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
+        if (!salgs)
+            return 0;
+        nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen);
+    } else {
+        salgs = NULL;
+    }
     c->shared_sigalgs = salgs;
     c->shared_sigalgslen = nmatch;
     return 1;
@@ -3787,7 +3541,7 @@ int tls1_process_sigalgs(SSL *s)
             c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
         }
 # endif
-# ifndef OPENSSL_NO_ECDSA
+# ifndef OPENSSL_NO_EC
         if (!c->pkeys[SSL_PKEY_ECC].digest)
             c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
 # endif
@@ -3838,24 +3592,24 @@ int SSL_get_shared_sigalgs(SSL *s, int idx,
 }
 
 # ifndef OPENSSL_NO_HEARTBEATS
-int tls1_process_heartbeat(SSL *s)
+int tls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length)
 {
-    unsigned char *p = &s->s3->rrec.data[0], *pl;
+    unsigned char *pl;
     unsigned short hbtype;
     unsigned int payload;
     unsigned int padding = 16;  /* Use minimum padding */
 
     if (s->msg_callback)
         s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
-                        &s->s3->rrec.data[0], s->s3->rrec.length,
+                        p, length,
                         s, s->msg_callback_arg);
 
     /* Read type and payload length first */
-    if (1 + 2 + 16 > s->s3->rrec.length)
+    if (1 + 2 + 16 > length)
         return 0;               /* silently discard */
     hbtype = *p++;
     n2s(p, payload);
-    if (1 + 2 + payload + 16 > s->s3->rrec.length)
+    if (1 + 2 + payload + 16 > length)
         return 0;               /* silently discard per RFC 6520 sec. 4 */
     pl = p;
 
@@ -3880,7 +3634,10 @@ int tls1_process_heartbeat(SSL *s)
         memcpy(bp, pl, payload);
         bp += payload;
         /* Random padding */
-        RAND_pseudo_bytes(bp, padding);
+        if (RAND_bytes(bp, padding) <= 0) {
+            OPENSSL_free(buffer);
+            return -1;
+        }
 
         r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
                              3 + payload + padding);
@@ -3915,7 +3672,7 @@ int tls1_process_heartbeat(SSL *s)
 int tls1_heartbeat(SSL *s)
 {
     unsigned char *buf, *p;
-    int ret;
+    int ret = -1;
     unsigned int payload = 18;  /* Sequence number + random bytes */
     unsigned int padding = 16;  /* Use minimum padding */
 
@@ -3967,10 +3724,16 @@ int tls1_heartbeat(SSL *s)
     /* Sequence number */
     s2n(s->tlsext_hb_seq, p);
     /* 16 random bytes */
-    RAND_pseudo_bytes(p, 16);
+    if (RAND_bytes(p, 16) <= 0) {
+        SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
     p += 16;
     /* Random padding */
-    RAND_pseudo_bytes(p, padding);
+    if (RAND_bytes(p, padding) <= 0) {
+        SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
 
     ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
     if (ret >= 0) {
@@ -3982,8 +3745,8 @@ int tls1_heartbeat(SSL *s)
         s->tlsext_hb_pending = 1;
     }
 
+ err:
     OPENSSL_free(buf);
-
     return ret;
 }
 # endif
@@ -4001,6 +3764,8 @@ static int sig_cb(const char *elem, int len, void *arg)
     size_t i;
     char etmp[20], *p;
     int sig_alg, hash_alg;
+    if (elem == NULL)
+        return 0;
     if (sarg->sigalgcnt == MAX_SIGALGLEN)
         return 0;
     if (len > (int)(sizeof(etmp) - 1))
@@ -4175,10 +3940,10 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
 # endif
     } else {
         if (!x || !pk)
-            goto end;
+            return 0;
         idx = ssl_cert_type(x, pk);
         if (idx == -1)
-            goto end;
+            return 0;
         cpk = c->pkeys + idx;
         if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
             check_flags = CERT_PKEY_STRICT_FLAGS;