Add the ability to send the supported_versions extension
authorMatt Caswell <matt@openssl.org>
Fri, 21 Oct 2016 22:40:52 +0000 (23:40 +0100)
committerMatt Caswell <matt@openssl.org>
Wed, 9 Nov 2016 16:03:08 +0000 (16:03 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
include/openssl/tls1.h
ssl/t1_lib.c

index ba3c413cb06767beeec03af75cc5d246c86ea2c9..f0c61060a35d288901dab9ed130d5ac511464eb4 100644 (file)
@@ -68,6 +68,9 @@ extern "C" {
 # define TLS1_3_VERSION                  0x0304
 # define TLS_MAX_VERSION                 TLS1_3_VERSION
 
+/* TODO(TLS1.3) REMOVE ME: Version indicator for draft -17 */
+# define TLS1_3_VERSION_DRAFT            0x7f11
+
 /* Special value for method supporting multiple versions */
 # define TLS_ANY_VERSION                 0x10000
 
@@ -163,6 +166,9 @@ extern "C" {
 /* ExtensionType value from RFC4507 */
 # define TLSEXT_TYPE_session_ticket              35
 
+/* As defined for TLS1.3 */
+# define TLSEXT_TYPE_supported_versions          43
+
 /* Temporary extension type */
 # define TLSEXT_TYPE_renegotiate                 0xff01
 
index 6598776ef9735c923ca8d5dbbe441a7876e6ca81..515b4e33af5c698789abe19fe64d501f5ab05a87 100644 (file)
@@ -1371,6 +1371,40 @@ int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al)
         return 0;
     }
 
+
+    /* TODO(TLS1.3): Should we add this extension for versions < TLS1.3? */
+    if (!SSL_IS_DTLS(s) && s->version >= TLS1_3_VERSION) {
+        int min_version, max_version, reason, currv;
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions)
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_start_sub_packet_u8(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+        reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
+        if (reason != 0) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, reason);
+            return 0;
+        }
+        for (currv = max_version; currv >= min_version; currv--) {
+            /* TODO(TLS1.3): Remove this first if clause prior to release!! */
+            if (currv == TLS1_3_VERSION) {
+                if (!WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT)) {
+                    SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
+                           ERR_R_INTERNAL_ERROR);
+                    return 0;
+                }
+            } else if (!WPACKET_put_bytes_u16(pkt, currv)) {
+                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
+        }
+        if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+    }
+
     /*
      * Add padding to workaround bugs in F5 terminators. See
      * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this