Implement length checks as a macro
authorMatt Caswell <matt@openssl.org>
Tue, 25 Oct 2016 10:10:56 +0000 (11:10 +0100)
committerMatt Caswell <matt@openssl.org>
Fri, 28 Oct 2016 08:43:41 +0000 (09:43 +0100)
Replace the various length checks in the extension code with a macro to
simplify the logic.

Reviewed-by: Rich Salz <rsalz@openssl.org>
ssl/t1_lib.c

index 4006aa280bf2858f645a6933add0925691728b9d..69706be608eebb0620031ea00e75fa2c63d1e43c 100644 (file)
@@ -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);