Commit 0b9c5da0 authored by Matt Caswell's avatar Matt Caswell
Browse files

Implement length checks as a macro



Replace the various length checks in the extension code with a macro to
simplify the logic.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent a520723f
Loading
Loading
Loading
Loading
+26 −21
Original line number Diff line number Diff line
@@ -132,6 +132,9 @@ static int ssl_check_clienthello_tlsext_early(SSL *s);
int ssl_check_serverhello_tlsext(SSL *s);
#endif

#define CHECKLEN(curr, val, limit) \
    (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val))

SSL3_ENC_METHOD TLSv1_enc_data = {
    tls1_enc,
    tls1_mac,
@@ -1274,7 +1277,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         * + hostname length
         */
        size_str = strlen(s->tlsext_hostname);
        if (ret >= limit || (size_t)(limit - ret) < 9 + size_str)
        if (CHECKLEN(ret, 9 + size_str, limit))
            return NULL;

        /* extension type and length */
@@ -1330,7 +1333,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         * 1 for the srp user identity
         * + srp user identity length
         */
        if (ret >= limit || (size_t)(limit - ret) < 5 + login_len)
        if (CHECKLEN(ret, 5 + login_len, limit))
            return NULL;

        /* fill in the extension */
@@ -1362,7 +1365,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         * 1 byte for the length of the formats
         * + formats length
         */
        if (ret >= limit || (size_t)(limit - ret) < 5 + num_formats)
        if (CHECKLEN(ret, 5 + num_formats, limit))
            return NULL;

        s2n(TLSEXT_TYPE_ec_point_formats, ret);
@@ -1390,7 +1393,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         * 2 bytes for the curve list length
         * + curve list length
         */
        if (ret >= limit || (size_t)(limit - ret) < 6 + curves_list_len)
        if (CHECKLEN(ret, 6 + curves_list_len, limit))
            return NULL;

        s2n(TLSEXT_TYPE_elliptic_curves, ret);
@@ -1423,7 +1426,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         * Check for enough room 2 for extension type, 2 for len rest for
         * ticket
         */
        if (ret >= limit || (size_t)(limit - ret) < 4 + ticklen)
        if (CHECKLEN(ret, 4 + ticklen, limit))
            return NULL;
        s2n(TLSEXT_TYPE_session_ticket, ret);
        s2n(ticklen, ret);
@@ -1445,7 +1448,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         * 2 bytes for the sigalg list length
         * + sigalg list length
         */
        if (ret >= limit || (size_t)(limit - ret) < salglen + 6)
        if (CHECKLEN(ret, salglen + 6, limit))
            return NULL;
        s2n(TLSEXT_TYPE_signature_algorithms, ret);
        s2n(salglen + 2, ret);
@@ -1501,8 +1504,10 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         * 1 byte for OCSP request type
         * 2 bytes for length of ids
         * 2 bytes for length of extensions
         * + length of ids
         * + length of extensions
         */
        if (ret >= limit || (size_t)(limit - ret) < 9 + idlen + extlen)
        if (CHECKLEN(ret, 9 + idlen + extlen, limit))
            return NULL;

        s2n(TLSEXT_TYPE_status_request, ret);
@@ -1531,7 +1536,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
     * 4 bytes for the heartbeat ext type and extension length
     * 1 byte for the mode
     */
    if (ret >= limit || limit - ret < 5)
    if (CHECKLEN(ret, 5, limit))
        return NULL;

    s2n(TLSEXT_TYPE_heartbeat, ret);
@@ -1558,7 +1563,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         * check for enough space.
         * 4 bytes for the NPN ext type and extension length
         */
        if (ret >= limit || limit - ret < 4)
        if (CHECKLEN(ret, 4, limit))
            return NULL;
        s2n(TLSEXT_TYPE_next_proto_neg, ret);
        s2n(0, ret);
@@ -1572,7 +1577,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         * 2 bytes for the ALPN protocol list length
         * + ALPN protocol list length
         */
        if (ret >= limit || limit - ret < 6 + s->alpn_client_proto_list_len)
        if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit))
            return NULL;
        s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
        s2n(2 + s->alpn_client_proto_list_len, ret);
@@ -1592,7 +1597,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         * 4 bytes for the SRTP type and extension length
         * + SRTP profiles length
         */
        if (ret >= limit || limit - ret < 4 + el)
        if (CHECKLEN(ret, 4 + el, limit))
            return NULL;

        s2n(TLSEXT_TYPE_use_srtp, ret);
@@ -1641,7 +1646,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
             * 4 bytes for the padding type and extension length
             * + padding length
             */
            if (ret >= limit || limit - ret < 4 + hlen)
            if (CHECKLEN(ret, 4 + hlen, limit))
                return NULL;
            s2n(TLSEXT_TYPE_padding, ret);
            s2n(hlen, ret);
@@ -1705,7 +1710,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         * 4 bytes for the reneg type and extension length
         * + reneg data length
         */
        if (ret >= limit || limit - ret < 4 + el)
        if (CHECKLEN(ret, 4 + el, limit))
            return NULL;

        s2n(TLSEXT_TYPE_renegotiate, ret);
@@ -1739,7 +1744,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         * 1 byte for the points format list length
         * + length of points format list
         */
        if (ret >= limit || (size_t)(limit - ret) < 5 + plistlen)
        if (CHECKLEN(ret, 5 + plistlen, limit))
            return NULL;

        s2n(TLSEXT_TYPE_ec_point_formats, ret);
@@ -1760,7 +1765,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         * check for enough space.
         * 4 bytes for the Ticket type and extension length
         */
        if (ret >= limit || limit - ret < 4)
        if (CHECKLEN(ret, 4, limit))
            return NULL;
        s2n(TLSEXT_TYPE_session_ticket, ret);
        s2n(0, ret);
@@ -1771,7 +1776,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         * check for enough space.
         * 4 bytes for the Status request type and extension length
         */
        if (ret >= limit || limit - ret < 4)
        if (CHECKLEN(ret, 4, limit))
            return NULL;
        s2n(TLSEXT_TYPE_status_request, ret);
        s2n(0, ret);
@@ -1804,7 +1809,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         * 4 bytes for the SRTP profiles type and extension length
         * + length of the SRTP profiles list
         */
        if (ret >= limit || limit - ret < 4 + el)
        if (CHECKLEN(ret, 4 + el, limit))
            return NULL;

        s2n(TLSEXT_TYPE_use_srtp, ret);
@@ -1831,7 +1836,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
        };

        /* check for enough space. */
        if (ret >= limit || (size_t)(limit - ret) < sizeof(cryptopro_ext))
        if (CHECKLEN(ret, sizeof(cryptopro_ext), limit))
            return NULL;
        memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext));
        ret += sizeof(cryptopro_ext);
@@ -1845,7 +1850,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         * 4 bytes for the Heartbeat type and extension length
         * 1 byte for the mode
         */
        if (ret >= limit || limit - ret < 5)
        if (CHECKLEN(ret, 5, limit))
            return NULL;
        s2n(TLSEXT_TYPE_heartbeat, ret);
        s2n(1, ret);
@@ -1879,7 +1884,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
             * 4 bytes for the NPN type and extension length
             * + length of protocols list
             */
            if (ret >= limit || limit - ret < 4 + npalen)
            if (CHECKLEN(ret, 4 + npalen, limit))
                return NULL;
            s2n(TLSEXT_TYPE_next_proto_neg, ret);
            s2n(npalen, ret);
@@ -1903,7 +1908,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         * 1 byte for selected protocol length
         * + length of the selected protocol
         */
        if (ret >= limit || (size_t)(limit - ret) < 7 + len)
        if (CHECKLEN(ret, 7 + len, limit))
            return NULL;
        s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
        s2n(3 + len, ret);