Remove static ECDH support.
[openssl.git] / ssl / t1_lib.c
index e7d9f64bf981908c16964712d4522822819a7856..522f0e68b175f2af6290765e603ebf019f9f94db 100644 (file)
@@ -1,4 +1,3 @@
-/* ssl/t1_lib.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -208,7 +207,10 @@ void tls1_free(SSL *s)
 void tls1_clear(SSL *s)
 {
     ssl3_clear(s);
-    s->version = s->method->version;
+    if (s->method->version == TLS_ANY_VERSION)
+        s->version = TLS_MAX_VERSION;
+    else
+        s->version = s->method->version;
 }
 
 #ifndef OPENSSL_NO_EC
@@ -786,16 +788,13 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
     unsigned char comp_id, curve_id[2];
     EVP_PKEY *pkey;
     int rv;
-    pkey = X509_get_pubkey(x);
+    pkey = X509_get0_pubkey(x);
     if (!pkey)
         return 0;
     /* If not EC nothing to do */
-    if (pkey->type != EVP_PKEY_EC) {
-        EVP_PKEY_free(pkey);
+    if (EVP_PKEY_id(pkey) != EVP_PKEY_EC)
         return 1;
-    }
-    rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec);
-    EVP_PKEY_free(pkey);
+    rv = tls1_set_ec_id(curve_id, &comp_id, EVP_PKEY_get0_EC_KEY(pkey));
     if (!rv)
         return 0;
     /*
@@ -990,10 +989,10 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
         return 0;
     }
 #ifndef OPENSSL_NO_EC
-    if (pkey->type == EVP_PKEY_EC) {
+    if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
         unsigned char curve_id[2], comp_id;
         /* Check compression and curve matches extensions */
-        if (!tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec))
+        if (!tls1_set_ec_id(curve_id, &comp_id, EVP_PKEY_get0_EC_KEY(pkey)))
             return 0;
         if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) {
             SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
@@ -1073,14 +1072,6 @@ void ssl_set_client_disabled(SSL *s)
     if (s->client_version == SSL3_VERSION)
         s->s3->tmp.mask_ssl |= SSL_TLSV1;
     ssl_set_sig_mask(&s->s3->tmp.mask_a, s, SSL_SECOP_SIGALG_MASK);
-    /*
-     * Disable static DH if we don't include any appropriate signature
-     * algorithms.
-     */
-    if (s->s3->tmp.mask_a & SSL_aRSA)
-        s->s3->tmp.mask_k |= SSL_kECDHr;
-    if (s->s3->tmp.mask_a & SSL_aECDSA)
-        s->s3->tmp.mask_k |= SSL_kECDHe;
 # ifndef OPENSSL_NO_PSK
     /* with PSK there must be client callback set */
     if (!s->psk_client_callback) {
@@ -1127,12 +1118,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
 
         for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
-            SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
+            const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
 
             alg_k = c->algorithm_mkey;
             alg_a = c->algorithm_auth;
-            if ((alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe | SSL_kECDHEPSK)
-                 || (alg_a & SSL_aECDSA))) {
+            if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))
+                 || (alg_a & SSL_aECDSA)) {
                 using_ecc = 1;
                 break;
             }
@@ -1390,20 +1381,22 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
             i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
     }
 #ifndef OPENSSL_NO_HEARTBEATS
-    /* Add Heartbeat extension */
-    if ((limit - ret - 4 - 1) < 0)
-        return NULL;
-    s2n(TLSEXT_TYPE_heartbeat, ret);
-    s2n(1, ret);
-    /*-
-     * Set mode:
-     * 1: peer may send requests
-     * 2: peer not allowed to send requests
-     */
-    if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
-        *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
-    else
-        *(ret++) = SSL_TLSEXT_HB_ENABLED;
+    if (SSL_IS_DTLS(s)) {
+        /* Add Heartbeat extension */
+        if ((limit - ret - 4 - 1) < 0)
+            return NULL;
+        s2n(TLSEXT_TYPE_heartbeat, ret);
+        s2n(1, ret);
+        /*-
+         * Set mode:
+         * 1: peer may send requests
+         * 2: peer not allowed to send requests
+         */
+        if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)
+            *(ret++) = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
+        else
+            *(ret++) = SSL_DTLSEXT_HB_ENABLED;
+    }
 #endif
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
@@ -1506,8 +1499,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
 #ifndef OPENSSL_NO_EC
     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
     unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-    int using_ecc = (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe))
-        || (alg_a & SSL_aECDSA);
+    int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
     using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
 #endif
 
@@ -1638,7 +1630,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
     }
 #ifndef OPENSSL_NO_HEARTBEATS
     /* Add Heartbeat extension if we've received one */
-    if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
+    if (SSL_IS_DTLS(s) && (s->tlsext_heartbeat & SSL_DTLSEXT_HB_ENABLED)) {
         if ((limit - ret - 4 - 1) < 0)
             return NULL;
         s2n(TLSEXT_TYPE_heartbeat, ret);
@@ -1648,10 +1640,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
          * 1: peer may send requests
          * 2: peer not allowed to send requests
          */
-        if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
-            *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
+        if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)
+            *(ret++) = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
         else
-            *(ret++) = SSL_TLSEXT_HB_ENABLED;
+            *(ret++) = SSL_DTLSEXT_HB_ENABLED;
 
     }
 #endif
@@ -1737,7 +1729,7 @@ static int tls1_alpn_handle_client_hello(SSL *s, PACKET *pkt, int *al)
     unsigned int data_len;
     unsigned int proto_len;
     const unsigned char *selected;
-    unsigned char *data;
+    const unsigned char *data;
     unsigned char selected_len;
     int r;
 
@@ -1796,7 +1788,7 @@ static int tls1_alpn_handle_client_hello(SSL *s, PACKET *pkt, int *al)
 static void ssl_check_for_safari(SSL *s, const PACKET *pkt)
 {
     unsigned int type, size;
-    unsigned char *eblock1, *eblock2;
+    const unsigned char *eblock1, *eblock2;
     PACKET tmppkt;
 
     static const unsigned char kSafariExtensionsBlock[] = {
@@ -1867,7 +1859,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
     unsigned int type;
     unsigned int size;
     unsigned int len;
-    unsigned char *data;
+    const unsigned char *data;
     int renegotiate_seen = 0;
 
     s->servername_done = 0;
@@ -1879,8 +1871,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
     OPENSSL_free(s->s3->alpn_selected);
     s->s3->alpn_selected = NULL;
 #ifndef OPENSSL_NO_HEARTBEATS
-    s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
-                             SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
+    s->tlsext_heartbeat &= ~(SSL_DTLSEXT_HB_ENABLED |
+                             SSL_DTLSEXT_HB_DONT_SEND_REQUESTS);
 #endif
 
 #ifndef OPENSSL_NO_EC
@@ -1955,7 +1947,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
  */
 
         else if (type == TLSEXT_TYPE_server_name) {
-            unsigned char *sdata;
+            const unsigned char *sdata;
             unsigned int servname_type;
             unsigned int dsize;
             PACKET ssubpkt;
@@ -2198,7 +2190,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
                 s->tlsext_status_type = -1;
         }
 #ifndef OPENSSL_NO_HEARTBEATS
-        else if (type == TLSEXT_TYPE_heartbeat) {
+        else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_heartbeat) {
             unsigned int hbtype;
 
             if (!PACKET_get_1(&subpkt, &hbtype)
@@ -2208,11 +2200,11 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
             }
             switch (hbtype) {
             case 0x01:         /* Client allows us to send HB requests */
-                s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
                 break;
             case 0x02:         /* Client doesn't accept HB requests */
-                s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
-                s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
                 break;
             default:
                 *al = SSL_AD_ILLEGAL_PARAMETER;
@@ -2357,8 +2349,8 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
     OPENSSL_free(s->s3->alpn_selected);
     s->s3->alpn_selected = NULL;
 #ifndef OPENSSL_NO_HEARTBEATS
-    s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
-                             SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
+    s->tlsext_heartbeat &= ~(SSL_DTLSEXT_HB_ENABLED |
+                             SSL_DTLSEXT_HB_DONT_SEND_REQUESTS);
 #endif
 
 #ifdef TLSEXT_TYPE_encrypt_then_mac
@@ -2376,7 +2368,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
     }
 
     while (PACKET_get_net_2(pkt, &type) && PACKET_get_net_2(pkt, &size)) {
-        unsigned char *data;
+        const unsigned char *data;
         PACKET spkt;
 
         if (!PACKET_get_sub_packet(pkt, &spkt, size)
@@ -2520,7 +2512,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
             s->s3->alpn_selected_len = len;
         }
 #ifndef OPENSSL_NO_HEARTBEATS
-        else if (type == TLSEXT_TYPE_heartbeat) {
+        else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_heartbeat) {
             unsigned int hbtype;
             if (!PACKET_get_1(&spkt, &hbtype)) {
                 *al = SSL_AD_DECODE_ERROR;
@@ -2528,11 +2520,11 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
             }
             switch (hbtype) {
             case 0x01:         /* Server allows us to send HB requests */
-                s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
                 break;
             case 0x02:         /* Server doesn't accept HB requests */
-                s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
-                s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
                 break;
             default:
                 *al = SSL_AD_ILLEGAL_PARAMETER;
@@ -2814,8 +2806,7 @@ int ssl_check_serverhello_tlsext(SSL *s)
         && (s->tlsext_ecpointformatlist_length > 0)
         && (s->session->tlsext_ecpointformatlist != NULL)
         && (s->session->tlsext_ecpointformatlist_length > 0)
-        && ((alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe))
-            || (alg_a & SSL_aECDSA))) {
+        && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA))) {
         /* we are using an ECC cipher */
         size_t i;
         unsigned char *list;
@@ -2847,30 +2838,13 @@ int ssl_check_serverhello_tlsext(SSL *s)
                                                        s->
                                                        initial_ctx->tlsext_servername_arg);
 
+    /*
+     * Ensure we get sensible values passed to tlsext_status_cb in the event
+     * that we don't receive a status message
+     */
     OPENSSL_free(s->tlsext_ocsp_resp);
     s->tlsext_ocsp_resp = NULL;
     s->tlsext_ocsp_resplen = -1;
-    /*
-     * If we've requested certificate status and we wont get one tell the
-     * callback
-     */
-    if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
-        && s->ctx && s->ctx->tlsext_status_cb) {
-        int r;
-        /*
-         * Call callback with resp == NULL and resplen == -1 so callback
-         * knows there is no response
-         */
-        r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
-        if (r == 0) {
-            al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
-            ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-        }
-        if (r < 0) {
-            al = SSL_AD_INTERNAL_ERROR;
-            ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-        }
-    }
 
     switch (ret) {
     case SSL_TLSEXT_ERR_ALERT_FATAL:
@@ -2983,7 +2957,7 @@ int tls_check_serverhello_tlsext_early(SSL *s, const PACKET *ext,
         }
         if (type == TLSEXT_TYPE_session_ticket && use_ticket) {
             int r;
-            unsigned char *etick;
+            const unsigned char *etick;
 
             /* Duplicate extension */
             if (have_ticket != 0) {
@@ -3077,7 +3051,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     int slen, mlen, renew_ticket = 0;
     unsigned char tick_hmac[EVP_MAX_MD_SIZE];
     HMAC_CTX *hctx = NULL;
-    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX *ctx;
     SSL_CTX *tctx = s->initial_ctx;
     /* Need at least keyname + iv + some encrypted data */
     if (eticklen < 48)
@@ -3086,11 +3060,11 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     hctx = HMAC_CTX_new();
     if (hctx == NULL)
         return -2;
-    EVP_CIPHER_CTX_init(&ctx);
+    ctx = EVP_CIPHER_CTX_new();
     if (tctx->tlsext_ticket_key_cb) {
         unsigned char *nctick = (unsigned char *)etick;
         int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
-                                            &ctx, hctx, 0);
+                                            ctx, hctx, 0);
         if (rv < 0)
             return -1;
         if (rv == 0)
@@ -3103,7 +3077,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
             return 2;
         if (HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key, 16,
                          EVP_sha256(), NULL) <= 0
-                || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+                || EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL,
                                       tctx->tlsext_tick_aes_key,
                                       etick + 16) <= 0) {
             goto err;
@@ -3125,26 +3099,27 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     }
     HMAC_CTX_free(hctx);
     if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
-        EVP_CIPHER_CTX_cleanup(&ctx);
+        EVP_CIPHER_CTX_free(ctx);
         return 2;
     }
     /* Attempt to decrypt session data */
     /* Move p after IV to start of encrypted ticket, update length */
-    p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
-    eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
+    p = etick + 16 + EVP_CIPHER_CTX_iv_length(ctx);
+    eticklen -= 16 + EVP_CIPHER_CTX_iv_length(ctx);
     sdec = OPENSSL_malloc(eticklen);
     if (sdec == NULL
-            || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) {
-        EVP_CIPHER_CTX_cleanup(&ctx);
+            || EVP_DecryptUpdate(ctx, sdec, &slen, p, eticklen) <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return -1;
     }
-    if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) {
-        EVP_CIPHER_CTX_cleanup(&ctx);
+    if (EVP_DecryptFinal(ctx, sdec + slen, &mlen) <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         OPENSSL_free(sdec);
         return 2;
     }
     slen += mlen;
-    EVP_CIPHER_CTX_cleanup(&ctx);
+    EVP_CIPHER_CTX_free(ctx);
+    ctx = NULL;
     p = sdec;
 
     sess = d2i_SSL_SESSION(NULL, &p, slen);
@@ -3171,7 +3146,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
      */
     return 2;
 err:
-    EVP_CIPHER_CTX_cleanup(&ctx);
+    EVP_CIPHER_CTX_free(ctx);
     HMAC_CTX_free(hctx);
     return -1;
 }
@@ -3243,7 +3218,7 @@ int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
 
 int tls12_get_sigid(const EVP_PKEY *pk)
 {
-    return tls12_find_id(pk->type, tls12_sig, OSSL_NELEM(tls12_sig));
+    return tls12_find_id(EVP_PKEY_id(pk), tls12_sig, OSSL_NELEM(tls12_sig));
 }
 
 typedef struct {
@@ -3644,160 +3619,6 @@ int SSL_get_shared_sigalgs(SSL *s, int idx,
     return s->cert->shared_sigalgslen;
 }
 
-#ifndef OPENSSL_NO_HEARTBEATS
-int tls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length)
-{
-    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,
-                        p, length,
-                        s, s->msg_callback_arg);
-
-    /* Read type and payload length first */
-    if (1 + 2 + 16 > length)
-        return 0;               /* silently discard */
-    hbtype = *p++;
-    n2s(p, payload);
-    if (1 + 2 + payload + 16 > length)
-        return 0;               /* silently discard per RFC 6520 sec. 4 */
-    pl = p;
-
-    if (hbtype == TLS1_HB_REQUEST) {
-        unsigned char *buffer, *bp;
-        int r;
-
-        /*
-         * Allocate memory for the response, size is 1 bytes message type,
-         * plus 2 bytes payload length, plus payload, plus padding
-         */
-        buffer = OPENSSL_malloc(1 + 2 + payload + padding);
-        if (buffer == NULL) {
-            SSLerr(SSL_F_TLS1_PROCESS_HEARTBEAT, ERR_R_MALLOC_FAILURE);
-            return -1;
-        }
-        bp = buffer;
-
-        /* Enter response type, length and copy payload */
-        *bp++ = TLS1_HB_RESPONSE;
-        s2n(payload, bp);
-        memcpy(bp, pl, payload);
-        bp += payload;
-        /* Random padding */
-        if (RAND_bytes(bp, padding) <= 0) {
-            OPENSSL_free(buffer);
-            return -1;
-        }
-
-        r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
-                             3 + payload + padding);
-
-        if (r >= 0 && s->msg_callback)
-            s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
-                            buffer, 3 + payload + padding,
-                            s, s->msg_callback_arg);
-
-        OPENSSL_free(buffer);
-
-        if (r < 0)
-            return r;
-    } else if (hbtype == TLS1_HB_RESPONSE) {
-        unsigned int seq;
-
-        /*
-         * We only send sequence numbers (2 bytes unsigned int), and 16
-         * random bytes, so we just try to read the sequence number
-         */
-        n2s(pl, seq);
-
-        if (payload == 18 && seq == s->tlsext_hb_seq) {
-            s->tlsext_hb_seq++;
-            s->tlsext_hb_pending = 0;
-        }
-    }
-
-    return 0;
-}
-
-int tls1_heartbeat(SSL *s)
-{
-    unsigned char *buf, *p;
-    int ret = -1;
-    unsigned int payload = 18;  /* Sequence number + random bytes */
-    unsigned int padding = 16;  /* Use minimum padding */
-
-    /* Only send if peer supports and accepts HB requests... */
-    if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
-        s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) {
-        SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
-        return -1;
-    }
-
-    /* ...and there is none in flight yet... */
-    if (s->tlsext_hb_pending) {
-        SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING);
-        return -1;
-    }
-
-    /* ...and no handshake in progress. */
-    if (SSL_in_init(s) || ossl_statem_get_in_handshake(s)) {
-        SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
-        return -1;
-    }
-
-    /*-
-     * Create HeartBeat message, we just use a sequence number
-     * as payload to distuingish different messages and add
-     * some random stuff.
-     *  - Message Type, 1 byte
-     *  - Payload Length, 2 bytes (unsigned int)
-     *  - Payload, the sequence number (2 bytes uint)
-     *  - Payload, random bytes (16 bytes uint)
-     *  - Padding
-     */
-    buf = OPENSSL_malloc(1 + 2 + payload + padding);
-    if (buf == NULL) {
-        SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_MALLOC_FAILURE);
-        return -1;
-    }
-    p = buf;
-    /* Message Type */
-    *p++ = TLS1_HB_REQUEST;
-    /* Payload length (18 bytes here) */
-    s2n(payload, p);
-    /* Sequence number */
-    s2n(s->tlsext_hb_seq, p);
-    /* 16 random bytes */
-    if (RAND_bytes(p, 16) <= 0) {
-        SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
-        goto err;
-    }
-    p += 16;
-    /* Random 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) {
-        if (s->msg_callback)
-            s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
-                            buf, 3 + payload + padding,
-                            s, s->msg_callback_arg);
-
-        s->tlsext_hb_pending = 1;
-    }
-
- err:
-    OPENSSL_free(buf);
-    return ret;
-}
-#endif
-
 #define MAX_SIGALGLEN   (TLSEXT_hash_num * TLSEXT_signature_num * 2)
 
 typedef struct {
@@ -4126,7 +3947,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
     if (!s->server && strict_mode) {
         STACK_OF(X509_NAME) *ca_dn;
         int check_type = 0;
-        switch (pk->type) {
+        switch (EVP_PKEY_id(pk)) {
         case EVP_PKEY_RSA:
             check_type = TLS_CT_RSA_SIGN;
             break;
@@ -4270,13 +4091,17 @@ DH *ssl_get_auto_dh(SSL *s)
 
 static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op)
 {
-    int secbits;
-    EVP_PKEY *pkey = X509_get_pubkey(x);
+    int secbits = -1;
+    EVP_PKEY *pkey = X509_get0_pubkey(x);
     if (pkey) {
+        /*
+         * If no parameters this will return -1 and fail using the default
+         * security callback for any non-zero security level. This will
+         * reject keys which omit parameters but this only affects DSA and
+         * omission of parameters is never (?) done in practice.
+         */
         secbits = EVP_PKEY_security_bits(pkey);
-        EVP_PKEY_free(pkey);
-    } else
-        secbits = -1;
+    }
     if (s)
         return ssl_security(s, op, secbits, 0, x);
     else
@@ -4287,6 +4112,9 @@ static int ssl_security_cert_sig(SSL *s, SSL_CTX *ctx, X509 *x, int op)
 {
     /* Lookup signature algorithm digest */
     int secbits = -1, md_nid = NID_undef, sig_nid;
+    /* Don't check signature if self signed */
+    if ((X509_get_extension_flags(x) & EXFLAG_SS) != 0)
+        return 1;
     sig_nid = X509_get_signature_nid(x);
     if (sig_nid && OBJ_find_sigid_algs(sig_nid, &md_nid, NULL)) {
         const EVP_MD *md;