Move client construction of ClientHello extensions into new framework
authorMatt Caswell <matt@openssl.org>
Fri, 25 Nov 2016 16:28:02 +0000 (16:28 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 8 Dec 2016 17:18:30 +0000 (17:18 +0000)
Perl changes reviewed by Richard Levitte. Non-perl changes reviewed by Rich
Salz

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
include/openssl/ssl.h
ssl/ssl_err.c
ssl/ssl_locl.h
ssl/statem/extensions.c
ssl/statem/extensions_clnt.c
ssl/statem/extensions_srvr.c
ssl/statem/statem_clnt.c
ssl/statem/statem_locl.h
ssl/t1_lib.c

index 81826a3431816471c7a6d4ec56fe0aa30e0c19d6..2a9d0de6c80e7846bda770ce56330b6c3b572769 100644 (file)
@@ -2265,9 +2265,26 @@ int ERR_load_SSL_strings(void);
 # define SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE             407
 # define SSL_F_TLS_CONSTRUCT_CKE_RSA                      409
 # define SSL_F_TLS_CONSTRUCT_CKE_SRP                      410
+# define SSL_F_TLS_CONSTRUCT_CLIENT_ALPN                  466
 # define SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE           355
+# define SSL_F_TLS_CONSTRUCT_CLIENT_EC_PT_FORMATS         467
+# define SSL_F_TLS_CONSTRUCT_CLIENT_EMS                   468
+# define SSL_F_TLS_CONSTRUCT_CLIENT_ETM                   469
 # define SSL_F_TLS_CONSTRUCT_CLIENT_HELLO                 356
 # define SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE          357
+# define SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE             470
+# define SSL_F_TLS_CONSTRUCT_CLIENT_NPN                   471
+# define SSL_F_TLS_CONSTRUCT_CLIENT_PADDING               472
+# define SSL_F_TLS_CONSTRUCT_CLIENT_RENEGOTIATE           473
+# define SSL_F_TLS_CONSTRUCT_CLIENT_SCT                   474
+# define SSL_F_TLS_CONSTRUCT_CLIENT_SERVER_NAME           475
+# define SSL_F_TLS_CONSTRUCT_CLIENT_SESSION_TICKET        476
+# define SSL_F_TLS_CONSTRUCT_CLIENT_SIG_ALGS              477
+# define SSL_F_TLS_CONSTRUCT_CLIENT_SRP                   478
+# define SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST        479
+# define SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS      480
+# define SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS    481
+# define SSL_F_TLS_CONSTRUCT_CLIENT_USE_SRTP              482
 # define SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY                358
 # define SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS         443
 # define SSL_F_TLS_CONSTRUCT_EXTENSIONS                   447
index 3523682c3a1d98386959eb4b3de78427b156f473..ce74d4497e5cc27732a8ee40e15f963234424bac 100644 (file)
@@ -265,12 +265,40 @@ static ERR_STRING_DATA SSL_str_functs[] = {
      "tls_construct_cke_psk_preamble"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_RSA), "tls_construct_cke_rsa"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_SRP), "tls_construct_cke_srp"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_ALPN), "tls_construct_client_alpn"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE),
      "tls_construct_client_certificate"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_EC_PT_FORMATS),
+     "tls_construct_client_ec_pt_formats"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_EMS), "tls_construct_client_ems"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_ETM), "tls_construct_client_etm"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO),
      "tls_construct_client_hello"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE),
      "tls_construct_client_key_exchange"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE),
+     "tls_construct_client_key_share"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_NPN), "tls_construct_client_npn"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_PADDING),
+     "tls_construct_client_padding"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_RENEGOTIATE),
+     "tls_construct_client_renegotiate"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SCT), "tls_construct_client_sct"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SERVER_NAME),
+     "tls_construct_client_server_name"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SESSION_TICKET),
+     "tls_construct_client_session_ticket"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SIG_ALGS),
+     "tls_construct_client_sig_algs"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SRP), "tls_construct_client_srp"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST),
+     "tls_construct_client_status_request"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS),
+     "tls_construct_client_supported_groups"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS),
+     "tls_construct_client_supported_versions"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_USE_SRTP),
+     "tls_construct_client_use_srtp"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY),
      "tls_construct_client_verify"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS),
index 178a5d0690bdc3df13e806a7ad8e9606c834a23b..e068fd102ef9a2951556e5bb3a94b2ea2963c83e 100644 (file)
@@ -2077,12 +2077,10 @@ __owur int tls_curve_allowed(SSL *s, const unsigned char *curve, int op);
 __owur  int tls1_get_curvelist(SSL *s, int sess, const unsigned char **pcurves,
                                size_t *num_curves);
 
-__owur int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al);
 void ssl_set_default_md(SSL *s);
 __owur int tls1_set_server_sigalgs(SSL *s);
 __owur int ssl_check_clienthello_tlsext_late(SSL *s, int *al);
 __owur int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt);
-__owur int ssl_prepare_clienthello_tlsext(SSL *s);
 __owur RAW_EXTENSION *tls_get_extension_by_type(RAW_EXTENSION *exts,
                                                 size_t numexts,
                                                 unsigned int type);
index 8aba3218aa3814d0cdf650414501400ec992983b..68e278c3e243f4b553267c35bc36842dd0870567 100644 (file)
@@ -36,7 +36,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_renegotiate,
         tls_parse_server_renegotiate,
         tls_construct_server_renegotiate,
-        NULL,
+        tls_construct_client_renegotiate,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_SSL3_ALLOWED
         | EXT_TLS1_2_AND_BELOW_ONLY
     },
@@ -45,7 +45,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_server_name,
         tls_parse_server_server_name,
         tls_construct_server_server_name,
-        NULL,
+        tls_construct_client_server_name,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
         | EXT_TLS1_3_ENCRYPTED_EXTENSIONS
     },
@@ -55,7 +55,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_srp,
         NULL,
         NULL,
-        NULL,
+        tls_construct_client_srp,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
 #endif
@@ -65,7 +65,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_ec_pt_formats,
         tls_parse_server_ec_pt_formats,
         tls_construct_server_ec_pt_formats,
-        NULL,
+        tls_construct_client_ec_pt_formats,
         EXT_CLIENT_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
     {
@@ -73,7 +73,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_supported_groups,
         NULL,
         NULL /* TODO(TLS1.3): Need to add this */,
-        NULL,
+        tls_construct_client_supported_groups,
         EXT_CLIENT_HELLO
         | EXT_TLS1_3_ENCRYPTED_EXTENSIONS
     },
@@ -83,7 +83,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_session_ticket,
         tls_parse_server_session_ticket,
         tls_construct_server_session_ticket,
-        NULL,
+        tls_construct_client_session_ticket,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
     {
@@ -91,25 +91,27 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_sig_algs,
         NULL,
         NULL,
-        NULL,
+        tls_construct_client_sig_algs,
         EXT_CLIENT_HELLO
     },
+#ifndef OPENSSL_NO_OCSP
     {
         TLSEXT_TYPE_status_request,
         tls_parse_client_status_request,
         tls_parse_server_status_request,
         tls_construct_server_status_request,
-        NULL,
+        tls_construct_client_status_request,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
         | EXT_TLS1_3_CERTIFICATE
     },
+#endif
 #ifndef OPENSSL_NO_NEXTPROTONEG
     {
         TLSEXT_TYPE_next_proto_neg,
         tls_parse_client_npn,
         tls_parse_server_npn,
         tls_construct_server_next_proto_neg,
-        NULL,
+        tls_construct_client_npn,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
 #endif
@@ -118,7 +120,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_alpn,
         tls_parse_server_alpn,
         tls_construct_server_alpn,
-        NULL,
+        tls_construct_client_alpn,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
         | EXT_TLS1_3_ENCRYPTED_EXTENSIONS
     },
@@ -128,7 +130,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_use_srtp,
         tls_parse_server_use_srtp,
         tls_construct_server_use_srtp,
-        NULL,
+        tls_construct_client_use_srtp,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
         | EXT_TLS1_3_ENCRYPTED_EXTENSIONS | EXT_DTLS_ONLY
     },
@@ -138,7 +140,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_etm,
         tls_parse_server_etm,
         tls_construct_server_etm,
-        NULL,
+        tls_construct_client_etm,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
 #ifndef OPENSSL_NO_CT
@@ -152,7 +154,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         NULL,
         tls_parse_server_sct,
         NULL,
-        NULL,
+        tls_construct_client_sct,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
         | EXT_TLS1_3_CERTIFICATE
     },
@@ -162,7 +164,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_parse_client_ems,
         tls_parse_server_ems,
         tls_construct_server_ems,
-        NULL,
+        tls_construct_client_ems,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
     {
@@ -171,24 +173,15 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         NULL,
         NULL,
         NULL,
-        NULL,
-        EXT_CLIENT_HELLO | EXT_TLS_IMPLEMENTATION_ONLY
-    },
-    {
-        TLSEXT_TYPE_padding,
-        /* We send this, but don't read it */
-        NULL,
-        NULL,
-        NULL,
-        NULL,
-        EXT_CLIENT_HELLO
+        tls_construct_client_supported_versions,
+        EXT_CLIENT_HELLO | EXT_TLS_IMPLEMENTATION_ONLY | EXT_TLS1_3_ONLY
     },
     {
         TLSEXT_TYPE_key_share,
         tls_parse_client_key_share,
         tls_parse_server_key_share,
         tls_construct_server_key_share,
-        NULL,
+        tls_construct_client_key_share,
         EXT_CLIENT_HELLO | EXT_TLS1_3_SERVER_HELLO
         | EXT_TLS1_3_HELLO_RETRY_REQUEST | EXT_TLS_IMPLEMENTATION_ONLY
         | EXT_TLS1_3_ONLY
@@ -204,6 +197,16 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_construct_server_cryptopro_bug,
         NULL,
         EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
+    },
+    {
+        /* Last in the list because it must be added as the last extension */
+        TLSEXT_TYPE_padding,
+        /* We send this, but don't read it */
+        NULL,
+        NULL,
+        NULL,
+        tls_construct_client_padding,
+        EXT_CLIENT_HELLO
     }
 };
 
@@ -457,6 +460,7 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
 {
     size_t loop;
     int addcustom = 0;
+    int min_version, max_version = 0, reason;
 
     /*
      * Normally if something goes wrong during construction its an internal
@@ -477,6 +481,35 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
         return 0;
     }
 
+    if ((context & EXT_CLIENT_HELLO) != 0) {
+        reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
+        if (reason != 0) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, reason);
+            return 0;
+        }
+    }
+
+    /* Add custom extensions first */
+    if ((context & EXT_CLIENT_HELLO) != 0) {
+        custom_ext_init(&s->cert->cli_ext);
+        addcustom = 1;
+    } else if ((context & EXT_TLS1_2_SERVER_HELLO) != 0) {
+        /*
+         * We already initialised the custom extensions during ClientHello
+         * parsing.
+         * 
+         * TODO(TLS1.3): We're going to need a new custom extension mechanism
+         * for TLS1.3, so that custom extensions can specify which of the
+         * multiple message they wish to add themselves to.
+         */
+        addcustom = 1;
+    }
+
+    if (addcustom && !custom_ext_add(s, s->server, pkt, al)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
     for (loop = 0; loop < OSSL_NELEM(ext_defs); loop++) {
         int (*construct)(SSL *s, WPACKET *pkt, int *al);
 
@@ -499,6 +532,9 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
                 || (!SSL_IS_TLS13(s)
                     && (ext_defs[loop].context & EXT_TLS1_3_ONLY) != 0
                     && (context & EXT_CLIENT_HELLO) == 0)
+                || ((ext_defs[loop].context & EXT_TLS1_3_ONLY) != 0
+                    && (context & EXT_CLIENT_HELLO) != 0
+                    && (SSL_IS_DTLS(s) || max_version < TLS1_3_VERSION))
                 || construct == NULL)
             continue;
 
@@ -506,27 +542,6 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
             return 0;
     }
 
-    /* Add custom extensions */
-    if ((context & EXT_CLIENT_HELLO) != 0) {
-        custom_ext_init(&s->cert->cli_ext);
-        addcustom = 1;
-    } else if ((context & EXT_TLS1_2_SERVER_HELLO) != 0) {
-        /*
-         * We already initialised the custom extensions during ClientHello
-         * parsing.
-         * 
-         * TODO(TLS1.3): We're going to need a new custom extension mechanism
-         * for TLS1.3, so that custom extensions can specify which of the
-         * multiple message they wish to add themselves to.
-         */
-        addcustom = 1;
-    }
-
-    if (addcustom && !custom_ext_add(s, s->server, pkt, al)) {
-        SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
     if (!WPACKET_close(pkt)) {
         SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, ERR_R_INTERNAL_ERROR);
         return 0;
index f51a2de04122026bc6979d80aeaf8afade91eebb..93f4f02b49be42fa673dfe7b9c415d4a43156cfb 100644 (file)
@@ -8,9 +8,604 @@
  */
 
 #include <assert.h>
+#include <openssl/ocsp.h>
 #include "../ssl_locl.h"
 #include "statem_locl.h"
 
+int tls_construct_client_renegotiate(SSL *s, WPACKET *pkt, int *al)
+{
+    /* Add RI if renegotiating */
+    if (!s->renegotiate)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate)
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_sub_memcpy_u8(pkt, s->s3->previous_client_finished,
+                               s->s3->previous_client_finished_len)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_RENEGOTIATE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_client_server_name(SSL *s, WPACKET *pkt, int *al)
+{
+    if (s->tlsext_hostname == NULL)
+        return 1;
+
+    /* Add TLS extension servername to the Client Hello message */
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
+               /* Sub-packet for server_name extension */
+            || !WPACKET_start_sub_packet_u16(pkt)
+               /* Sub-packet for servername list (always 1 hostname)*/
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_put_bytes_u8(pkt, TLSEXT_NAMETYPE_host_name)
+            || !WPACKET_sub_memcpy_u16(pkt, s->tlsext_hostname,
+                                       strlen(s->tlsext_hostname))
+            || !WPACKET_close(pkt)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SERVER_NAME, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_SRP
+int tls_construct_client_srp(SSL *s, WPACKET *pkt, int *al)
+{
+    /* Add SRP username if there is one */
+    if (s->srp_ctx.login == NULL)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_srp)
+               /* Sub-packet for SRP extension */
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_start_sub_packet_u8(pkt)
+               /* login must not be zero...internal error if so */
+            || !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)
+            || !WPACKET_memcpy(pkt, s->srp_ctx.login,
+                               strlen(s->srp_ctx.login))
+            || !WPACKET_close(pkt)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SRP, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+static int use_ecc(SSL *s)
+{
+    int using_ecc = 0;
+    int i;
+    unsigned long alg_k, alg_a;
+    STACK_OF(SSL_CIPHER) *cipher_stack = NULL;
+
+    /* See if we support any ECC ciphersuites */
+    if (s->version == SSL3_VERSION)
+        return 0;
+
+
+    cipher_stack = SSL_get_ciphers(s);
+
+    for (i = 0; i < sk_SSL_CIPHER_num(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_kECDHEPSK))
+            || (alg_a & SSL_aECDSA)
+            || c->min_tls >= TLS1_3_VERSION) {
+            using_ecc = 1;
+            break;
+        }
+    }
+
+    return using_ecc;
+}
+
+int tls_construct_client_ec_pt_formats(SSL *s, WPACKET *pkt, int *al)
+{
+    const unsigned char *pformats;
+    size_t num_formats;
+
+    if (!use_ecc(s))
+        return 1;
+
+    /* Add TLS extension ECPointFormats to the ClientHello message */
+
+    tls1_get_formatlist(s, &pformats, &num_formats);
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
+               /* Sub-packet for formats extension */
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+
+int tls_construct_client_supported_groups(SSL *s, WPACKET *pkt, int *al)
+{
+    const unsigned char *pcurves = NULL, *pcurvestmp;
+    size_t num_curves = 0, i;
+
+    if (!use_ecc(s))
+        return 1;
+
+    /*
+     * Add TLS extension supported_groups to the ClientHello message
+     */
+    /* TODO(TLS1.3): Add support for DHE groups */
+    pcurves = s->tlsext_supportedgroupslist;
+    if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS,
+               ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    pcurvestmp = pcurves;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_groups)
+               /* Sub-packet for supported_groups extension */
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_start_sub_packet_u16(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS,
+               ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    /* Copy curve ID if supported */
+    for (i = 0; i < num_curves; i++, pcurvestmp += 2) {
+        if (tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) {
+            if (!WPACKET_put_bytes_u8(pkt, pcurvestmp[0])
+                || !WPACKET_put_bytes_u8(pkt, pcurvestmp[1])) {
+                    SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS,
+                           ERR_R_INTERNAL_ERROR);
+                    return 0;
+                }
+        }
+    }
+    if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS,
+               ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+#endif
+
+int tls_construct_client_session_ticket(SSL *s, WPACKET *pkt, int *al)
+{
+    size_t ticklen;
+
+    if (!tls_use_ticket(s))
+        return 1;
+
+    if (!s->new_session && s->session != NULL
+            && s->session->tlsext_tick != NULL) {
+        ticklen = s->session->tlsext_ticklen;
+    } else if (s->session && s->tlsext_session_ticket != NULL
+               && s->tlsext_session_ticket->data != NULL) {
+        ticklen = s->tlsext_session_ticket->length;
+        s->session->tlsext_tick = OPENSSL_malloc(ticklen);
+        if (s->session->tlsext_tick == NULL) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SESSION_TICKET,
+                   ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+        memcpy(s->session->tlsext_tick,
+               s->tlsext_session_ticket->data, ticklen);
+        s->session->tlsext_ticklen = ticklen;
+    } else {
+        ticklen = 0;
+    }
+
+    if (ticklen == 0 && s->tlsext_session_ticket != NULL &&
+            s->tlsext_session_ticket->data == NULL)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
+            || !WPACKET_sub_memcpy_u16(pkt, s->session->tlsext_tick, ticklen)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_client_sig_algs(SSL *s, WPACKET *pkt, int *al)
+{
+    size_t salglen;
+    const unsigned char *salg;
+
+    if (!SSL_CLIENT_USE_SIGALGS(s))
+        return 1;
+
+    salglen = tls12_get_psigalgs(s, &salg);
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signature_algorithms)
+               /* Sub-packet for sig-algs extension */
+            || !WPACKET_start_sub_packet_u16(pkt)
+               /* Sub-packet for the actual list */
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !tls12_copy_sigalgs(s, pkt, salg, salglen)
+            || !WPACKET_close(pkt)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SIG_ALGS, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_OCSP
+int tls_construct_client_status_request(SSL *s, WPACKET *pkt, int *al)
+{
+    int i;
+
+    if (s->tlsext_status_type != TLSEXT_STATUSTYPE_ocsp)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
+               /* Sub-packet for status request extension */
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_put_bytes_u8(pkt, TLSEXT_STATUSTYPE_ocsp)
+               /* Sub-packet for the ids */
+            || !WPACKET_start_sub_packet_u16(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
+        unsigned char *idbytes;
+        int idlen;
+        OCSP_RESPID *id;
+
+        id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
+        idlen = i2d_OCSP_RESPID(id, NULL);
+        if (idlen <= 0
+                   /* Sub-packet for an individual id */
+                || !WPACKET_sub_allocate_bytes_u16(pkt, idlen, &idbytes)
+                || i2d_OCSP_RESPID(id, &idbytes) != idlen) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST,
+                   ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+    }
+    if (!WPACKET_close(pkt)
+            || !WPACKET_start_sub_packet_u16(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    if (s->tlsext_ocsp_exts) {
+        unsigned char *extbytes;
+        int extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
+
+        if (extlen < 0) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST,
+                   ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+        if (!WPACKET_allocate_bytes(pkt, extlen, &extbytes)
+                || i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &extbytes)
+                   != extlen) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST,
+                   ERR_R_INTERNAL_ERROR);
+            return 0;
+       }
+    }
+    if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+#endif
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+int tls_construct_client_npn(SSL *s, WPACKET *pkt, int *al)
+{
+    if (s->ctx->next_proto_select_cb == NULL || s->s3->tmp.finish_md_len != 0)
+        return 1;
+
+    /*
+     * The client advertises an empty extension to indicate its support
+     * for Next Protocol Negotiation
+     */
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
+            || !WPACKET_put_bytes_u16(pkt, 0)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_NPN, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+#endif
+
+int tls_construct_client_alpn(SSL *s, WPACKET *pkt, int *al)
+{
+    s->s3->alpn_sent = 0;
+
+    /*
+     * finish_md_len is non-zero during a renegotiation, so
+     * this avoids sending ALPN during the renegotiation
+     */
+    if (s->alpn_client_proto_list == NULL || s->s3->tmp.finish_md_len != 0)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt,
+                TLSEXT_TYPE_application_layer_protocol_negotiation)
+               /* Sub-packet ALPN extension */
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_sub_memcpy_u16(pkt, s->alpn_client_proto_list,
+                                       s->alpn_client_proto_list_len)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_ALPN, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    s->s3->alpn_sent = 1;
+
+    return 1;
+}
+
+
+#ifndef OPENSSL_NO_SRTP
+int tls_construct_client_use_srtp(SSL *s, WPACKET *pkt, int *al)
+{
+    STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s);
+    SRTP_PROTECTION_PROFILE *prof;
+    int i, ct;
+
+    if (clnt == NULL)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
+               /* Sub-packet for SRTP extension */
+            || !WPACKET_start_sub_packet_u16(pkt)
+               /* Sub-packet for the protection profile list */
+            || !WPACKET_start_sub_packet_u16(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_USE_SRTP, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    ct = sk_SRTP_PROTECTION_PROFILE_num(clnt);
+    for (i = 0; i < ct; i++) {
+        prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
+        if (prof == NULL || !WPACKET_put_bytes_u16(pkt, prof->id)) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_USE_SRTP, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+    }
+    if (!WPACKET_close(pkt)
+               /* Add an empty use_mki value */
+            || !WPACKET_put_bytes_u8(pkt, 0)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_USE_SRTP, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+#endif
+
+int tls_construct_client_etm(SSL *s, WPACKET *pkt, int *al)
+{
+    if (s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
+            || !WPACKET_put_bytes_u16(pkt, 0)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_ETM, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_CT
+int tls_construct_client_sct(SSL *s, WPACKET *pkt, int *al)
+{
+    if (s->ct_validation_callback == NULL)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signed_certificate_timestamp)
+            || !WPACKET_put_bytes_u16(pkt, 0)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SCT, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+#endif
+
+int tls_construct_client_ems(SSL *s, WPACKET *pkt, int *al)
+{
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
+            || !WPACKET_put_bytes_u16(pkt, 0)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_EMS, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_client_supported_versions(SSL *s, WPACKET *pkt, int *al)
+{
+    int currv, min_version, max_version, reason;
+
+    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_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS,
+               ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
+    if (reason != 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS, reason);
+        return 0;
+    }
+
+    /*
+     * TODO(TLS1.3): There is some discussion on the TLS list as to wheter
+     * we should include versions <TLS1.2. For the moment we do. To be
+     * reviewed later.
+     */
+    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_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS,
+                       ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
+        } else if (!WPACKET_put_bytes_u16(pkt, currv)) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS,
+                   ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+    }
+    if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS,
+               ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+
+int tls_construct_client_key_share(SSL *s, WPACKET *pkt, int *al)
+{
+    size_t i, sharessent = 0, num_curves = 0;
+    const unsigned char *pcurves = NULL;
+
+    /* key_share extension */
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
+               /* Extension data sub-packet */
+            || !WPACKET_start_sub_packet_u16(pkt)
+               /* KeyShare list sub-packet */
+            || !WPACKET_start_sub_packet_u16(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    pcurves = s->tlsext_supportedgroupslist;
+    if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    /*
+     * TODO(TLS1.3): Make the number of key_shares sent configurable. For
+     * now, just send one
+     */
+    for (i = 0; i < num_curves && sharessent < 1; i++, pcurves += 2) {
+        unsigned char *encodedPoint = NULL;
+        unsigned int curve_id = 0;
+        EVP_PKEY *key_share_key = NULL;
+        size_t encodedlen;
+
+        if (!tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED))
+            continue;
+
+        if (s->s3->tmp.pkey != NULL) {
+            /* Shouldn't happen! */
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+
+        /* Generate a key for this key_share */
+        curve_id = (pcurves[0] << 8) | pcurves[1];
+        key_share_key = ssl_generate_pkey_curve(curve_id);
+        if (key_share_key == NULL) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_EVP_LIB);
+            return 0;
+        }
+
+        /* Encode the public key. */
+        encodedlen = EVP_PKEY_get1_tls_encodedpoint(key_share_key,
+                                                    &encodedPoint);
+        if (encodedlen == 0) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_EC_LIB);
+            EVP_PKEY_free(key_share_key);
+            return 0;
+        }
+
+        /* Create KeyShareEntry */
+        if (!WPACKET_put_bytes_u16(pkt, curve_id)
+                || !WPACKET_sub_memcpy_u16(pkt, encodedPoint, encodedlen)) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+            EVP_PKEY_free(key_share_key);
+            OPENSSL_free(encodedPoint);
+            return 0;
+        }
+
+        /*
+         * TODO(TLS1.3): When changing to send more than one key_share we're
+         * going to need to be able to save more than one EVP_PKEY. For now
+         * we reuse the existing tmp.pkey
+         */
+        s->s3->group_id = curve_id;
+        s->s3->tmp.pkey = key_share_key;
+        sharessent++;
+        OPENSSL_free(encodedPoint);
+    }
+
+    if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_client_padding(SSL *s, WPACKET *pkt, int *al)
+{
+    unsigned char *padbytes;
+    size_t hlen;
+
+    if ((s->options & SSL_OP_TLSEXT_PADDING) == 0)
+        return 1;
+
+    /*
+     * Add padding to workaround bugs in F5 terminators. See
+     * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
+     * code works out the length of all existing extensions it MUST always
+     * appear last.
+     */
+    if (!WPACKET_get_total_written(pkt, &hlen)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_PADDING, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    if (hlen > 0xff && hlen < 0x200) {
+        hlen = 0x200 - hlen;
+        if (hlen >= 4)
+            hlen -= 4;
+        else
+            hlen = 0;
+
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_padding)
+                || !WPACKET_sub_allocate_bytes_u16(pkt, hlen, &padbytes)) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_PADDING, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+        memset(padbytes, 0, hlen);
+    }
+
+    return 1;
+}
+
 /*
  * Parse the server's renegotiation binding and abort if it's not right
  */
@@ -147,6 +742,7 @@ int tls_parse_server_session_ticket(SSL *s, PACKET *pkt, int *al)
     return 1;
 }
 
+#ifndef OPENSSL_NO_OCSP
 int tls_parse_server_status_request(SSL *s, PACKET *pkt, int *al)
 {
     /*
@@ -162,6 +758,7 @@ int tls_parse_server_status_request(SSL *s, PACKET *pkt, int *al)
 
     return 1;
 }
+#endif
 
 
 #ifndef OPENSSL_NO_CT
index e090421ddeb03c590d632c12881a3340f0e29f0f..70898891e2b7585835fc876253f0539dcde15b1c 100644 (file)
@@ -215,13 +215,14 @@ int tls_parse_client_sig_algs(SSL *s, PACKET *pkt, int *al)
     return 1;
 }
 
+#ifndef OPENSSL_NO_OCSP
 int tls_parse_client_status_request(SSL *s, PACKET *pkt, int *al)
 {
     if (!PACKET_get_1(pkt, (unsigned int *)&s->tlsext_status_type)) {
         *al = SSL_AD_DECODE_ERROR;
         return 0;
     }
-#ifndef OPENSSL_NO_OCSP
+
     if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
         const unsigned char *ext_data;
         PACKET responder_id_list, exts;
@@ -297,9 +298,7 @@ int tls_parse_client_status_request(SSL *s, PACKET *pkt, int *al)
                 return 0;
             }
         }
-    } else
-#endif
-    {
+    } else {
         /*
          * We don't know what to do with any other type so ignore it.
          */
@@ -308,6 +307,7 @@ int tls_parse_client_status_request(SSL *s, PACKET *pkt, int *al)
 
     return 1;
 }
+#endif
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
 int tls_parse_client_npn(SSL *s, PACKET *pkt, int *al)
@@ -949,6 +949,7 @@ int tls_construct_server_session_ticket(SSL *s, WPACKET *pkt, int *al)
     return 1;
 }
 
+#ifndef OPENSSL_NO_OCSP
 int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al)
 {
     if (!s->tlsext_status_expected)
@@ -962,6 +963,7 @@ int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al)
 
     return 1;
 }
+#endif
 
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
index ec3991d9a16d2c67e79e9561ea322dfee0252b92..cded5b96ec68a4643e8da8a3a61b22055c3a2cea 100644 (file)
@@ -1011,18 +1011,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt)
     }
 
     /* TLS extensions */
-    if (ssl_prepare_clienthello_tlsext(s) <= 0) {
-        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
-        return 0;
-    }
-    if (!WPACKET_start_sub_packet_u16(pkt)
-               /*
-                * If extensions are of zero length then we don't even add the
-                * extensions length bytes
-                */
-            || !WPACKET_set_flags(pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)
-            || !ssl_add_clienthello_tlsext(s, pkt, &al)
-            || !WPACKET_close(pkt)) {
+    if (!tls_construct_extensions(s, pkt, EXT_CLIENT_HELLO, &al)) {
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
         SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
         return 0;
index 88c40f546b4d696b83e765b5ddda29576ce30af3..0ec2353626b9847bee78a904a55387fe77899c21 100644 (file)
@@ -168,7 +168,9 @@ int tls_parse_client_supported_groups(SSL *s, PACKET *pkt, int *al);
 #endif
 int tls_parse_client_session_ticket(SSL *s, PACKET *pkt, int *al);
 int tls_parse_client_sig_algs(SSL *s, PACKET *pkt, int *al);
+#ifndef OPENSSL_NO_OCSP
 int tls_parse_client_status_request(SSL *s, PACKET *pkt, int *al);
+#endif
 #ifndef OPENSSL_NO_NEXTPROTONEG
 int tls_parse_client_npn(SSL *s, PACKET *pkt, int *al);
 #endif
@@ -184,12 +186,20 @@ int tls_scan_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello, int *al);
 
 int tls_construct_server_renegotiate(SSL *s, WPACKET *pkt, int *al);
 int tls_construct_server_server_name(SSL *s, WPACKET *pkt, int *al);
+#ifndef OPENSSL_NO_EC
 int tls_construct_server_ec_pt_formats(SSL *s, WPACKET *pkt, int *al);
+#endif
 int tls_construct_server_session_ticket(SSL *s, WPACKET *pkt, int *al);
+#ifndef OPENSSL_NO_OCSP
 int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al);
+#endif
+#ifndef OPENSSL_NO_NEXTPROTONEG
 int tls_construct_server_next_proto_neg(SSL *s, WPACKET *pkt, int *al);
+#endif
 int tls_construct_server_alpn(SSL *s, WPACKET *pkt, int *al);
+#ifndef OPENSSL_NO_SRTP
 int tls_construct_server_use_srtp(SSL *s, WPACKET *pkt, int *al);
+#endif
 int tls_construct_server_etm(SSL *s, WPACKET *pkt, int *al);
 int tls_construct_server_ems(SSL *s, WPACKET *pkt, int *al);
 int tls_construct_server_key_share(SSL *s, WPACKET *pkt, int *al);
@@ -201,13 +211,44 @@ int tls_construct_server_key_share(SSL *s, WPACKET *pkt, int *al);
 int tls_construct_server_cryptopro_bug(SSL *s, WPACKET *pkt, int *al);
 
 /* Client Extension processing */
+int tls_construct_client_renegotiate(SSL *s, WPACKET *pkt, int *al);
+int tls_construct_client_server_name(SSL *s, WPACKET *pkt, int *al);
+#ifndef OPENSSL_NO_SRP
+int tls_construct_client_srp(SSL *s, WPACKET *pkt, int *al);
+#endif
+#ifndef OPENSSL_NO_EC
+int tls_construct_client_ec_pt_formats(SSL *s, WPACKET *pkt, int *al);
+int tls_construct_client_supported_groups(SSL *s, WPACKET *pkt, int *al);
+#endif
+int tls_construct_client_session_ticket(SSL *s, WPACKET *pkt, int *al);
+int tls_construct_client_sig_algs(SSL *s, WPACKET *pkt, int *al);
+#ifndef OPENSSL_NO_OCSP
+int tls_construct_client_status_request(SSL *s, WPACKET *pkt, int *al);
+#endif
+#ifndef OPENSSL_NO_NEXTPROTONEG
+int tls_construct_client_npn(SSL *s, WPACKET *pkt, int *al);
+#endif
+int tls_construct_client_alpn(SSL *s, WPACKET *pkt, int *al);
+#ifndef OPENSSL_NO_SRTP
+int tls_construct_client_use_srtp(SSL *s, WPACKET *pkt, int *al);
+#endif
+int tls_construct_client_etm(SSL *s, WPACKET *pkt, int *al);
+#ifndef OPENSSL_NO_CT
+int tls_construct_client_sct(SSL *s, WPACKET *pkt, int *al);
+#endif
+int tls_construct_client_ems(SSL *s, WPACKET *pkt, int *al);
+int tls_construct_client_supported_versions(SSL *s, WPACKET *pkt, int *al);
+int tls_construct_client_key_share(SSL *s, WPACKET *pkt, int *al);
+int tls_construct_client_padding(SSL *s, WPACKET *pkt, int *al);
 int tls_parse_server_renegotiate(SSL *s, PACKET *pkt, int *al);
 int tls_parse_server_server_name(SSL *s, PACKET *pkt, int *al);
 #ifndef OPENSSL_NO_EC
 int tls_parse_server_ec_pt_formats(SSL *s, PACKET *pkt, int *al);
 #endif
 int tls_parse_server_session_ticket(SSL *s, PACKET *pkt, int *al);
+#ifndef OPENSSL_NO_OCSP
 int tls_parse_server_status_request(SSL *s, PACKET *pkt, int *al);
+#endif
 #ifndef OPENSSL_NO_CT
 int tls_parse_server_sct(SSL *s, PACKET *pkt, int *al);
 #endif
index e682912b5dbce57d7599d5480b305e6e3b2c5218..a49df18ceb265e339548940bd64af5c758950e70 100644 (file)
@@ -945,503 +945,6 @@ int tls_use_ticket(SSL *s)
     return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
 }
 
-int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al)
-{
-#ifndef OPENSSL_NO_EC
-    const unsigned char *pcurves = NULL;
-    size_t num_curves = 0;
-    int using_ecc = 0;
-    int min_version, max_version, reason;
-
-    /* See if we support any ECC ciphersuites */
-    if ((s->version >= TLS1_VERSION && s->version <= TLS1_3_VERSION)
-            || SSL_IS_DTLS(s)) {
-        int i;
-        unsigned long alg_k, alg_a;
-        STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
-
-        for (i = 0; i < sk_SSL_CIPHER_num(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_kECDHEPSK))
-                || (alg_a & SSL_aECDSA)
-                || c->min_tls >= TLS1_3_VERSION) {
-                using_ecc = 1;
-                break;
-            }
-        }
-    }
-#else
-    if (SSL_IS_TLS13(s)) {
-        /* Shouldn't happen! */
-        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-#endif
-
-    /* Add RI if renegotiating */
-    if (s->renegotiate) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_sub_memcpy_u8(pkt, s->s3->previous_client_finished,
-                                   s->s3->previous_client_finished_len)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-    /* Only add RI for SSLv3 */
-    if (s->client_version == SSL3_VERSION)
-        goto done;
-
-    if (s->tlsext_hostname != NULL) {
-        /* Add TLS extension servername to the Client Hello message */
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
-                   /* Sub-packet for server_name extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                   /* Sub-packet for servername list (always 1 hostname)*/
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_put_bytes_u8(pkt, TLSEXT_NAMETYPE_host_name)
-                || !WPACKET_sub_memcpy_u16(pkt, s->tlsext_hostname,
-                                           strlen(s->tlsext_hostname))
-                || !WPACKET_close(pkt)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#ifndef OPENSSL_NO_SRP
-    /* Add SRP username if there is one */
-    if (s->srp_ctx.login != NULL) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_srp)
-                   /* Sub-packet for SRP extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_start_sub_packet_u8(pkt)
-                   /* login must not be zero...internal error if so */
-                || !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)
-                || !WPACKET_memcpy(pkt, s->srp_ctx.login,
-                                   strlen(s->srp_ctx.login))
-                || !WPACKET_close(pkt)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
-
-#ifndef OPENSSL_NO_EC
-    if (using_ecc) {
-        /*
-         * Add TLS extension ECPointFormats to the ClientHello message
-         */
-        const unsigned char *pformats, *pcurvestmp;
-        size_t num_formats;
-        size_t i;
-
-        tls1_get_formatlist(s, &pformats, &num_formats);
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
-                   /* Sub-packet for formats extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-
-        /*
-         * Add TLS extension supported_groups to the ClientHello message
-         */
-        /* TODO(TLS1.3): Add support for DHE groups */
-        pcurves = s->tlsext_supportedgroupslist;
-        if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        pcurvestmp = pcurves;
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_groups)
-                   /* Sub-packet for supported_groups extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_start_sub_packet_u16(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        /* Copy curve ID if supported */
-        for (i = 0; i < num_curves; i++, pcurvestmp += 2) {
-            if (tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) {
-                if (!WPACKET_put_bytes_u8(pkt, pcurvestmp[0])
-                    || !WPACKET_put_bytes_u8(pkt, pcurvestmp[1])) {
-                        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;
-        }
-    }
-#endif                          /* OPENSSL_NO_EC */
-
-    if (tls_use_ticket(s)) {
-        size_t ticklen;
-        if (!s->new_session && s->session && s->session->tlsext_tick)
-            ticklen = s->session->tlsext_ticklen;
-        else if (s->session && s->tlsext_session_ticket &&
-                 s->tlsext_session_ticket->data) {
-            ticklen = s->tlsext_session_ticket->length;
-            s->session->tlsext_tick = OPENSSL_malloc(ticklen);
-            if (s->session->tlsext_tick == NULL) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-            memcpy(s->session->tlsext_tick,
-                   s->tlsext_session_ticket->data, ticklen);
-            s->session->tlsext_ticklen = ticklen;
-        } else
-            ticklen = 0;
-        if (ticklen == 0 && s->tlsext_session_ticket &&
-            s->tlsext_session_ticket->data == NULL)
-            goto skip_ext;
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
-                || !WPACKET_sub_memcpy_u16(pkt, s->session->tlsext_tick,
-                                           ticklen)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
- skip_ext:
-
-    if (SSL_CLIENT_USE_SIGALGS(s)) {
-        size_t salglen;
-        const unsigned char *salg;
-
-        salglen = tls12_get_psigalgs(s, &salg);
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signature_algorithms)
-                   /* Sub-packet for sig-algs extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                   /* Sub-packet for the actual list */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !tls12_copy_sigalgs(s, pkt, salg, salglen)
-                || !WPACKET_close(pkt)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#ifndef OPENSSL_NO_OCSP
-    if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
-        int i;
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
-                   /* Sub-packet for status request extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_put_bytes_u8(pkt, TLSEXT_STATUSTYPE_ocsp)
-                   /* Sub-packet for the ids */
-                || !WPACKET_start_sub_packet_u16(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
-            unsigned char *idbytes;
-            int idlen;
-            OCSP_RESPID *id;
-
-            id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
-            idlen = i2d_OCSP_RESPID(id, NULL);
-            if (idlen <= 0
-                       /* Sub-packet for an individual id */
-                    || !WPACKET_sub_allocate_bytes_u16(pkt, idlen, &idbytes)
-                    || i2d_OCSP_RESPID(id, &idbytes) != idlen) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-        }
-        if (!WPACKET_close(pkt)
-                || !WPACKET_start_sub_packet_u16(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        if (s->tlsext_ocsp_exts) {
-            unsigned char *extbytes;
-            int extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
-
-            if (extlen < 0) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-            if (!WPACKET_allocate_bytes(pkt, extlen, &extbytes)
-                    || i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &extbytes)
-                       != extlen) {
-                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;
-        }
-    }
-#endif
-
-#ifndef OPENSSL_NO_NEXTPROTONEG
-    if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
-        /*
-         * The client advertises an empty extension to indicate its support
-         * for Next Protocol Negotiation
-         */
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
-
-    /*
-     * finish_md_len is non-zero during a renegotiation, so
-     * this avoids sending ALPN during the renegotiation
-     * (see longer comment below)
-     */
-    if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
-        if (!WPACKET_put_bytes_u16(pkt,
-                    TLSEXT_TYPE_application_layer_protocol_negotiation)
-                   /* Sub-packet ALPN extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_sub_memcpy_u16(pkt, s->alpn_client_proto_list,
-                                           s->alpn_client_proto_list_len)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        s->s3->alpn_sent = 1;
-    }
-#ifndef OPENSSL_NO_SRTP
-    if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
-        STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s);
-        SRTP_PROTECTION_PROFILE *prof;
-        int i, ct;
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
-                   /* Sub-packet for SRTP extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                   /* Sub-packet for the protection profile list */
-                || !WPACKET_start_sub_packet_u16(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        ct = sk_SRTP_PROTECTION_PROFILE_num(clnt);
-        for (i = 0; i < ct; i++) {
-            prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
-            if (prof == NULL || !WPACKET_put_bytes_u16(pkt, prof->id)) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-        }
-        if (!WPACKET_close(pkt)
-                   /* Add an empty use_mki value */
-                || !WPACKET_put_bytes_u8(pkt, 0)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
-    custom_ext_init(&s->cert->cli_ext);
-    /* Add custom TLS Extensions to ClientHello */
-    if (!custom_ext_add(s, 0, pkt, al)) {
-        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
-            || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-
-#ifndef OPENSSL_NO_CT
-    if (s->ct_validation_callback != NULL) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signed_certificate_timestamp)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
-
-    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
-            || !WPACKET_put_bytes_u16(pkt, 0)) {
-        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;
-    }
-
-    /* TLS1.3 specific extensions */
-    if (!SSL_IS_DTLS(s) && max_version >= TLS1_3_VERSION) {
-        int currv;
-        size_t i, sharessent = 0;
-
-        /* TODO(TLS1.3): Should we add this extension for versions < TLS1.3? */
-        /* supported_versions extension */
-        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;
-        }
-
-        /*
-         * TODO(TLS1.3): There is some discussion on the TLS list as to wheter
-         * we should include versions <TLS1.2. For the moment we do. To be
-         * reviewed later.
-         */
-        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;
-        }
-
-
-        /* key_share extension */
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
-                   /* Extension data sub-packet */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                   /* KeyShare list sub-packet */
-                || !WPACKET_start_sub_packet_u16(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-
-        /*
-         * TODO(TLS1.3): Make the number of key_shares sent configurable. For
-         * now, just send one
-         */
-        for (i = 0; i < num_curves && sharessent < 1; i++, pcurves += 2) {
-            unsigned char *encodedPoint = NULL;
-            unsigned int curve_id = 0;
-            EVP_PKEY *key_share_key = NULL;
-            size_t encodedlen;
-
-            if (!tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED))
-                continue;
-
-            if (s->s3->tmp.pkey != NULL) {
-                /* Shouldn't happen! */
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
-                       ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-
-            /* Generate a key for this key_share */
-            curve_id = (pcurves[0] << 8) | pcurves[1];
-            key_share_key = ssl_generate_pkey_curve(curve_id);
-            if (key_share_key == NULL) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_EVP_LIB);
-                return 0;
-            }
-
-            /* Encode the public key. */
-            encodedlen = EVP_PKEY_get1_tls_encodedpoint(key_share_key,
-                                                        &encodedPoint);
-            if (encodedlen == 0) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_EC_LIB);
-                EVP_PKEY_free(key_share_key);
-                return 0;
-            }
-
-            /* Create KeyShareEntry */
-            if (!WPACKET_put_bytes_u16(pkt, curve_id)
-                    || !WPACKET_sub_memcpy_u16(pkt, encodedPoint, encodedlen)) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
-                       ERR_R_INTERNAL_ERROR);
-                EVP_PKEY_free(key_share_key);
-                OPENSSL_free(encodedPoint);
-                return 0;
-            }
-
-            /*
-             * TODO(TLS1.3): When changing to send more than one key_share we're
-             * going to need to be able to save more than one EVP_PKEY. For now
-             * we reuse the existing tmp.pkey
-             */
-            s->s3->group_id = curve_id;
-            s->s3->tmp.pkey = key_share_key;
-            sharessent++;
-            OPENSSL_free(encodedPoint);
-        }
-        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
-     * code works out the length of all existing extensions it MUST always
-     * appear last.
-     */
-    if (s->options & SSL_OP_TLSEXT_PADDING) {
-        unsigned char *padbytes;
-        size_t hlen;
-
-        if (!WPACKET_get_total_written(pkt, &hlen)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-
-        if (hlen > 0xff && hlen < 0x200) {
-            hlen = 0x200 - hlen;
-            if (hlen >= 4)
-                hlen -= 4;
-            else
-                hlen = 0;
-
-            if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_padding)
-                    || !WPACKET_sub_allocate_bytes_u16(pkt, hlen, &padbytes)) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-            memset(padbytes, 0, hlen);
-        }
-    }
-
- done:
-    return 1;
-}
-
-int ssl_prepare_clienthello_tlsext(SSL *s)
-{
-    s->s3->alpn_sent = 0;
-    return 1;
-}
-
 /* Initialise digests to default values */
 void ssl_set_default_md(SSL *s)
 {