Commit e72040c1 authored by Richard Levitte's avatar Richard Levitte Committed by Rich Salz
Browse files

Remove heartbeat support

parent 349d1cfd
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
     https://www.akkadia.org/drepper/SHA-crypt.txt
     [Richard Levitte]
  *) Heartbeat support has been removed; the ABI is changed for now.
     [Richard Levitte, Rich Salz]
 Changes between 1.1.0b and 1.1.0c [xx XXX xxxx]
  *) ChaCha20/Poly1305 heap-buffer-overflow
+0 −3
Original line number Diff line number Diff line
@@ -333,9 +333,6 @@
                   available if the GOST algorithms are also available through
                   loading an externally supplied engine.

  enable-heartbeats
                   Build support for DTLS heartbeats.

  no-hw-padlock
                   Don't build the padlock engine.

+0 −168
Original line number Diff line number Diff line
@@ -378,12 +378,6 @@ int dtls1_handle_timeout(SSL *s)
    if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
        s->d1->timeout.read_timeouts = 1;
    }
#ifndef OPENSSL_NO_HEARTBEATS
    if (s->tlsext_hb_pending) {
        s->tlsext_hb_pending = 0;
        return dtls1_heartbeat(s);
    }
#endif

    dtls1_start_timer(s);
    return dtls1_retransmit_buffered_messages(s);
@@ -859,168 +853,6 @@ static int dtls1_handshake_write(SSL *s)
    return dtls1_do_write(s, SSL3_RT_HANDSHAKE);
}

#ifndef OPENSSL_NO_HEARTBEATS

# define HEARTBEAT_SIZE(payload, padding) ( \
    1 /* heartbeat type */ + \
    2 /* heartbeat length */ + \
    (payload) + (padding))

# define HEARTBEAT_SIZE_STD(payload) HEARTBEAT_SIZE(payload, 16)

int dtls1_process_heartbeat(SSL *s, unsigned char *p, size_t length)
{
    unsigned char *pl;
    unsigned short hbtype;
    unsigned int payload;
    unsigned int padding = 16;  /* Use minimum padding */
    size_t written;

    if (s->msg_callback)
        s->msg_callback(0, s->version, DTLS1_RT_HEARTBEAT,
                        p, length, s, s->msg_callback_arg);

    /* Read type and payload length */
    if (HEARTBEAT_SIZE_STD(0) > length)
        return 0;               /* silently discard */
    if (length > SSL3_RT_MAX_PLAIN_LENGTH)
        return 0;               /* silently discard per RFC 6520 sec. 4 */

    hbtype = *p++;
    n2s(p, payload);
    if (HEARTBEAT_SIZE_STD(payload) > length)
        return 0;               /* silently discard per RFC 6520 sec. 4 */
    pl = p;

    if (hbtype == TLS1_HB_REQUEST) {
        unsigned char *buffer, *bp;
        size_t write_length = HEARTBEAT_SIZE(payload, padding);
        int r;

        if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
            return 0;

        /* Allocate memory for the response. */
        buffer = OPENSSL_malloc(write_length);
        if (buffer == NULL)
            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 = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buffer, write_length,
                              &written);

        if (r > 0 && s->msg_callback)
            s->msg_callback(1, s->version, DTLS1_RT_HEARTBEAT,
                            buffer, write_length, s, s->msg_callback_arg);

        OPENSSL_free(buffer);

        if (r <= 0)
            return -1;
    } 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) {
            dtls1_stop_timer(s);
            s->tlsext_hb_seq++;
            s->tlsext_hb_pending = 0;
        }
    }

    return 0;
}

int dtls1_heartbeat(SSL *s)
{
    unsigned char *buf, *p;
    int ret = -1;
    size_t payload = 18;  /* Sequence number + random bytes */
    size_t padding = 16;  /* Use minimum padding */
    size_t size, written;

    /* Only send if peer supports and accepts HB requests... */
    if (!(s->tlsext_heartbeat & SSL_DTLSEXT_HB_ENABLED) ||
        s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_SEND_REQUESTS) {
        SSLerr(SSL_F_DTLS1_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_DTLS1_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_DTLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
        return -1;
    }

    /*-
     * Create HeartBeat message, we just use a sequence number
     * as payload to distinguish different messages and add
     * some random stuff.
     */
    size = HEARTBEAT_SIZE(payload, padding);
    buf = OPENSSL_malloc(size);
    if (buf == NULL) {
        SSLerr(SSL_F_DTLS1_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_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    p += 16;
    /* Random padding */
    if (RAND_bytes(p, padding) <= 0) {
        SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
        goto err;
    }

    ret = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buf, size, &written);
    if (ret > 0) {
        if (s->msg_callback)
            s->msg_callback(1, s->version, DTLS1_RT_HEARTBEAT,
                            buf, size, s, s->msg_callback_arg);

        dtls1_start_timer(s);
        s->tlsext_hb_pending = 1;
    }

 err:
    OPENSSL_free(buf);

    return ret;
}
#endif

int dtls1_shutdown(SSL *s)
{
    int ret;
+0 −15
Original line number Diff line number Diff line
@@ -575,21 +575,6 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
            dest = s->rlayer.d->alert_fragment;
            dest_len = &s->rlayer.d->alert_fragment_len;
        }
#ifndef OPENSSL_NO_HEARTBEATS
        else if (SSL3_RECORD_get_type(rr) == DTLS1_RT_HEARTBEAT) {
            /* We allow a 0 return */
            if (dtls1_process_heartbeat(s, SSL3_RECORD_get_data(rr),
                                        SSL3_RECORD_get_length(rr)) < 0) {
                return -1;
            }
            /* Exit and notify application to read again */
            SSL3_RECORD_set_length(rr, 0);
            s->rwstate = SSL_READING;
            BIO_clear_retry_flags(SSL_get_rbio(s));
            BIO_set_retry_read(SSL_get_rbio(s));
            return -1;
        }
#endif
        /* else it's a CCS message, or application data or wrong */
        else if (SSL3_RECORD_get_type(rr) != SSL3_RT_CHANGE_CIPHER_SPEC) {
            /*
+0 −15
Original line number Diff line number Diff line
@@ -3049,23 +3049,8 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)

#ifndef OPENSSL_NO_HEARTBEATS
    case SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT:
        if (SSL_IS_DTLS(s))
            ret = dtls1_heartbeat(s);
        break;

    case SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING:
        if (SSL_IS_DTLS(s))
            ret = s->tlsext_hb_pending;
        break;

    case SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS:
        if (SSL_IS_DTLS(s)) {
            if (larg)
                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_DONT_RECV_REQUESTS;
            else
                s->tlsext_heartbeat &= ~SSL_DTLSEXT_HB_DONT_RECV_REQUESTS;
            ret = 1;
        }
        break;
#endif

Loading