Move client parsing of ServerHello extensions into new framework
authorMatt Caswell <matt@openssl.org>
Fri, 25 Nov 2016 12:34:29 +0000 (12:34 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 8 Dec 2016 17:18:25 +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>
12 files changed:
include/openssl/ssl.h
ssl/build.info
ssl/d1_srtp.c
ssl/ssl_err.c
ssl/ssl_locl.h
ssl/statem/extensions.c
ssl/statem/extensions_clnt.c [new file with mode: 0644]
ssl/statem/extensions_srvr.c
ssl/statem/statem_locl.h
ssl/statem/statem_srvr.c
ssl/t1_lib.c
ssl/t1_reneg.c [deleted file]

index 98313af..81826a3 100644 (file)
@@ -2297,6 +2297,9 @@ int ERR_load_SSL_strings(void);
 # define SSL_F_TLS_PARSE_CLIENT_KEY_SHARE                 445
 # define SSL_F_TLS_PARSE_CLIENT_RENEGOTIATE               448
 # define SSL_F_TLS_PARSE_CLIENT_USE_SRTP                  446
+# define SSL_F_TLS_PARSE_SERVER_KEY_SHARE                 463
+# define SSL_F_TLS_PARSE_SERVER_RENEGOTIATE               464
+# define SSL_F_TLS_PARSE_SERVER_USE_SRTP                  465
 # define SSL_F_TLS_POST_PROCESS_CLIENT_HELLO              378
 # define SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE       384
 # define SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE             360
index fb2265e..f13c11f 100644 (file)
@@ -3,13 +3,13 @@ SOURCE[../libssl]=\
         pqueue.c packet.c \
         statem/statem_srvr.c statem/statem_clnt.c  s3_lib.c  s3_enc.c record/rec_layer_s3.c \
         statem/statem_lib.c statem/extensions.c statem/extensions_srvr.c \
-        s3_cbc.c s3_msg.c \
+        statem/extensions_clnt.c s3_cbc.c s3_msg.c \
         methods.c   t1_lib.c  t1_enc.c tls13_enc.c t1_ext.c \
         d1_lib.c  record/rec_layer_d1.c d1_msg.c \
         statem/statem_dtls.c d1_srtp.c \
         ssl_lib.c ssl_cert.c ssl_sess.c \
         ssl_ciph.c ssl_stat.c ssl_rsa.c \
         ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c  ssl_mcnf.c \
-        bio_ssl.c ssl_err.c t1_reneg.c tls_srp.c t1_trce.c ssl_utst.c \
+        bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \
         record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \
         statem/statem.c record/ssl3_record_tls13.c
index e99fd45..ff8f0c5 100644 (file)
@@ -136,61 +136,4 @@ SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s)
 {
     return s->srtp_profile;
 }
-
-int ssl_parse_serverhello_use_srtp_ext(SSL *s, PACKET *pkt, int *al)
-{
-    unsigned int id, ct, mki;
-    int i;
-
-    STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
-    SRTP_PROTECTION_PROFILE *prof;
-
-    if (!PACKET_get_net_2(pkt, &ct)
-        || ct != 2 || !PACKET_get_net_2(pkt, &id)
-        || !PACKET_get_1(pkt, &mki)
-        || PACKET_remaining(pkt) != 0) {
-        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
-               SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
-        *al = SSL_AD_DECODE_ERROR;
-        return 1;
-    }
-
-    if (mki != 0) {
-        /* Must be no MKI, since we never offer one */
-        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
-               SSL_R_BAD_SRTP_MKI_VALUE);
-        *al = SSL_AD_ILLEGAL_PARAMETER;
-        return 1;
-    }
-
-    clnt = SSL_get_srtp_profiles(s);
-
-    /* Throw an error if the server gave us an unsolicited extension */
-    if (clnt == NULL) {
-        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
-               SSL_R_NO_SRTP_PROFILES);
-        *al = SSL_AD_DECODE_ERROR;
-        return 1;
-    }
-
-    /*
-     * Check to see if the server gave us something we support (and
-     * presumably offered)
-     */
-    for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) {
-        prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
-
-        if (prof->id == id) {
-            s->srtp_profile = prof;
-            *al = 0;
-            return 0;
-        }
-    }
-
-    SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
-           SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
-    *al = SSL_AD_DECODE_ERROR;
-    return 1;
-}
-
 #endif
index 2539d6e..3523682 100644 (file)
@@ -319,6 +319,11 @@ static ERR_STRING_DATA SSL_str_functs[] = {
     {ERR_FUNC(SSL_F_TLS_PARSE_CLIENT_RENEGOTIATE),
      "tls_parse_client_renegotiate"},
     {ERR_FUNC(SSL_F_TLS_PARSE_CLIENT_USE_SRTP), "tls_parse_client_use_srtp"},
+    {ERR_FUNC(SSL_F_TLS_PARSE_SERVER_KEY_SHARE),
+     "tls_parse_server_key_share"},
+    {ERR_FUNC(SSL_F_TLS_PARSE_SERVER_RENEGOTIATE),
+     "tls_parse_server_renegotiate"},
+    {ERR_FUNC(SSL_F_TLS_PARSE_SERVER_USE_SRTP), "tls_parse_server_use_srtp"},
     {ERR_FUNC(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO),
      "tls_post_process_client_hello"},
     {ERR_FUNC(SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE),
index 926c6c6..178a5d0 100644 (file)
@@ -2117,7 +2117,6 @@ __owur int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *ex,
 
 __owur EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md);
 void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
-__owur int ssl_parse_serverhello_renegotiate_ext(SSL *s, PACKET *pkt, int *al);
 __owur long ssl_get_algorithm2(SSL *s);
 __owur int tls12_copy_sigalgs(SSL *s, WPACKET *pkt,
                               const unsigned char *psig, size_t psiglen);
@@ -2129,8 +2128,6 @@ __owur int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
 void ssl_set_client_disabled(SSL *s);
 __owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op);
 
-__owur int ssl_parse_serverhello_use_srtp_ext(SSL *s, PACKET *pkt, int *al);
-
 __owur int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen,
                                  size_t *hashlen);
 __owur const EVP_MD *ssl_md(int idx);
index 898b9b9..8aba321 100644 (file)
 typedef struct {
     /* The ID for the extension */
     unsigned int type;
-    int (*server_parse)(SSL *s, PACKET *pkt, int *al);
-    int (*client_parse)(SSL *s, PACKET *pkt, int *al);
-    int (*server_construct)(SSL *s, WPACKET *pkt, int *al);
-    int (*client_construct)(SSL *s, WPACKET *pkt, int *al);
+    /* Parse extension received by server from client */
+    int (*parse_client_ext)(SSL *s, PACKET *pkt, int *al);
+    /* Parse extension received by client from server */
+    int (*parse_server_ext)(SSL *s, PACKET *pkt, int *al);
+    /* Construct extension sent by server */
+    int (*construct_server_ext)(SSL *s, WPACKET *pkt, int *al);
+    /* Construct extension sent by client */
+    int (*construct_client_ext)(SSL *s, WPACKET *pkt, int *al);
     unsigned int context;
 } EXTENSION_DEFINITION;
 
@@ -30,7 +34,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     {
         TLSEXT_TYPE_renegotiate,
         tls_parse_client_renegotiate,
-        NULL,
+        tls_parse_server_renegotiate,
         tls_construct_server_renegotiate,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_SSL3_ALLOWED
@@ -39,11 +43,11 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     {
         TLSEXT_TYPE_server_name,
         tls_parse_client_server_name,
-        NULL,
+        tls_parse_server_server_name,
         tls_construct_server_server_name,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
-        | /*EXT_TLS1_3_ENCRYPTED_EXTENSIONS*/EXT_TLS1_3_SERVER_HELLO
+        | EXT_TLS1_3_ENCRYPTED_EXTENSIONS
     },
 #ifndef OPENSSL_NO_SRP
     {
@@ -59,7 +63,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     {
         TLSEXT_TYPE_ec_point_formats,
         tls_parse_client_ec_pt_formats,
-        NULL,
+        tls_parse_server_ec_pt_formats,
         tls_construct_server_ec_pt_formats,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
@@ -71,13 +75,13 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         NULL /* TODO(TLS1.3): Need to add this */,
         NULL,
         EXT_CLIENT_HELLO
-        | /*EXT_TLS1_3_ENCRYPTED_EXTENSIONS*/EXT_TLS1_3_SERVER_HELLO
+        | EXT_TLS1_3_ENCRYPTED_EXTENSIONS
     },
 #endif
     {
         TLSEXT_TYPE_session_ticket,
         tls_parse_client_session_ticket,
-        NULL,
+        tls_parse_server_session_ticket,
         tls_construct_server_session_ticket,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
@@ -93,17 +97,17 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     {
         TLSEXT_TYPE_status_request,
         tls_parse_client_status_request,
-        NULL,
+        tls_parse_server_status_request,
         tls_construct_server_status_request,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
-        | /*EXT_TLS1_3_CERTIFICATE*/EXT_TLS1_3_SERVER_HELLO
+        | EXT_TLS1_3_CERTIFICATE
     },
 #ifndef OPENSSL_NO_NEXTPROTONEG
     {
         TLSEXT_TYPE_next_proto_neg,
         tls_parse_client_npn,
-        NULL,
+        tls_parse_server_npn,
         tls_construct_server_next_proto_neg,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
@@ -112,17 +116,17 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     {
         TLSEXT_TYPE_application_layer_protocol_negotiation,
         tls_parse_client_alpn,
-        NULL,
+        tls_parse_server_alpn,
         tls_construct_server_alpn,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
-        | /*EXT_TLS1_3_ENCRYPTED_EXTENSIONS*/EXT_TLS1_3_SERVER_HELLO
+        | EXT_TLS1_3_ENCRYPTED_EXTENSIONS
     },
 #ifndef OPENSSL_NO_SRTP
     {
         TLSEXT_TYPE_use_srtp,
         tls_parse_client_use_srtp,
-        NULL,
+        tls_parse_server_use_srtp,
         tls_construct_server_use_srtp,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
@@ -132,11 +136,12 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     {
         TLSEXT_TYPE_encrypt_then_mac,
         tls_parse_client_etm,
-        NULL,
+        tls_parse_server_etm,
         tls_construct_server_etm,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
+#ifndef OPENSSL_NO_CT
     {
         TLSEXT_TYPE_signed_certificate_timestamp,
         /*
@@ -145,16 +150,17 @@ static const EXTENSION_DEFINITION ext_defs[] = {
          * cannot override built in ones.
          */
         NULL,
-        NULL,
+        tls_parse_server_sct,
         NULL,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
-        | /*EXT_TLS1_3_CERTIFICATE*/EXT_TLS1_3_SERVER_HELLO
+        | EXT_TLS1_3_CERTIFICATE
     },
+#endif
     {
         TLSEXT_TYPE_extended_master_secret,
         tls_parse_client_ems,
-        NULL,
+        tls_parse_server_ems,
         tls_construct_server_ems,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
@@ -180,7 +186,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     {
         TLSEXT_TYPE_key_share,
         tls_parse_client_key_share,
-        NULL,
+        tls_parse_server_key_share,
         tls_construct_server_key_share,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_3_SERVER_HELLO
@@ -277,7 +283,7 @@ static int find_extension_definition(SSL *s, unsigned int type,
 
 /*
  * Gather a list of all the extensions from the data in |packet]. |context|
- * tells us which message this extension is for. The raw extension data is
+ * tells us which message this extension is for. Ttls_parse_server_ec_pt_formatshe raw extension data is
  * stored in |*res| with the number of found extensions in |*numfound|. In the
  * event of an error the alert type to use is stored in |*ad|. We don't actually
  * process the content of the extensions yet, except to check their types.
@@ -288,10 +294,7 @@ static int find_extension_definition(SSL *s, unsigned int type,
  * types, and 0 if the extensions contain duplicates, could not be successfully
  * parsed, or an internal error occurred.
  */
-/*
- * TODO(TLS1.3): Refactor ServerHello extension parsing to use this and then
- * remove tls1_check_duplicate_extensions()
- */
+
 int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context,
                            RAW_EXTENSION **res, size_t *numfound, int *ad)
 {
@@ -376,7 +379,7 @@ int tls_parse_all_extensions(SSL *s, int context, RAW_EXTENSION *exts,
         int (*parser)(SSL *s, PACKET *pkt, int *al) = NULL;
 
         if (s->tlsext_debug_cb)
-            s->tlsext_debug_cb(s, 0, currext->type,
+            s->tlsext_debug_cb(s, !s->server, currext->type,
                                PACKET_data(&currext->data),
                                PACKET_remaining(&currext->data),
                                s->tlsext_debug_arg);
@@ -389,7 +392,8 @@ int tls_parse_all_extensions(SSL *s, int context, RAW_EXTENSION *exts,
 
         parser = NULL;
         if (find_extension_definition(s, currext->type, &extdef)) {
-            parser = s->server ? extdef->server_parse : extdef->client_parse;
+            parser = s->server ? extdef->parse_client_ext
+                               : extdef->parse_server_ext;
 
             /* Check if extension is defined for our protocol. If not, skip */
             if ((SSL_IS_DTLS(s)
@@ -480,8 +484,8 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
         if ((ext_defs[loop].context & context) == 0)
             continue;
 
-        construct = s->server ? ext_defs[loop].server_construct
-                              : ext_defs[loop].client_construct;
+        construct = s->server ? ext_defs[loop].construct_server_ext
+                              : ext_defs[loop].construct_client_ext;
 
         /* Check if this extension is defined for our protocol. If not, skip */
         if ((SSL_IS_DTLS(s)
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
new file mode 100644 (file)
index 0000000..f51a2de
--- /dev/null
@@ -0,0 +1,608 @@
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <assert.h>
+#include "../ssl_locl.h"
+#include "statem_locl.h"
+
+/*
+ * Parse the server's renegotiation binding and abort if it's not right
+ */
+int tls_parse_server_renegotiate(SSL *s, PACKET *pkt, int *al)
+{
+    size_t expected_len = s->s3->previous_client_finished_len
+        + s->s3->previous_server_finished_len;
+    size_t ilen;
+    const unsigned char *data;
+
+    /* Check for logic errors */
+    assert(expected_len == 0 || s->s3->previous_client_finished_len != 0);
+    assert(expected_len == 0 || s->s3->previous_server_finished_len != 0);
+
+    /* Parse the length byte */
+    if (!PACKET_get_1_len(pkt, &ilen)) {
+        SSLerr(SSL_F_TLS_PARSE_SERVER_RENEGOTIATE,
+               SSL_R_RENEGOTIATION_ENCODING_ERR);
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+    }
+
+    /* Consistency check */
+    if (PACKET_remaining(pkt) != ilen) {
+        SSLerr(SSL_F_TLS_PARSE_SERVER_RENEGOTIATE,
+               SSL_R_RENEGOTIATION_ENCODING_ERR);
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+    }
+
+    /* Check that the extension matches */
+    if (ilen != expected_len) {
+        SSLerr(SSL_F_TLS_PARSE_SERVER_RENEGOTIATE,
+               SSL_R_RENEGOTIATION_MISMATCH);
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        return 0;
+    }
+
+    if (!PACKET_get_bytes(pkt, &data, s->s3->previous_client_finished_len)
+        || memcmp(data, s->s3->previous_client_finished,
+                  s->s3->previous_client_finished_len) != 0) {
+        SSLerr(SSL_F_TLS_PARSE_SERVER_RENEGOTIATE,
+               SSL_R_RENEGOTIATION_MISMATCH);
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        return 0;
+    }
+
+    if (!PACKET_get_bytes(pkt, &data, s->s3->previous_server_finished_len)
+        || memcmp(data, s->s3->previous_server_finished,
+                  s->s3->previous_server_finished_len) != 0) {
+        SSLerr(SSL_F_TLS_PARSE_SERVER_RENEGOTIATE,
+               SSL_R_RENEGOTIATION_MISMATCH);
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+    }
+    s->s3->send_connection_binding = 1;
+
+    return 1;
+}
+
+int tls_parse_server_server_name(SSL *s, PACKET *pkt, int *al)
+{
+    if (s->tlsext_hostname == NULL || PACKET_remaining(pkt) > 0) {
+        *al = SSL_AD_UNRECOGNIZED_NAME;
+        return 0;
+    }
+
+    if (!s->hit) {
+        if (s->session->tlsext_hostname != NULL) {
+            *al = SSL_AD_INTERNAL_ERROR;
+            return 0;
+        }
+        s->session->tlsext_hostname = OPENSSL_strdup(s->tlsext_hostname);
+        if (s->session->tlsext_hostname == NULL) {
+            *al = SSL_AD_INTERNAL_ERROR;
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_EC
+int tls_parse_server_ec_pt_formats(SSL *s, PACKET *pkt, int *al)
+{
+    unsigned int ecpointformatlist_length;
+    PACKET ecptformatlist;
+
+    if (!PACKET_as_length_prefixed_1(pkt, &ecptformatlist)) {
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+    if (!s->hit) {
+        ecpointformatlist_length = PACKET_remaining(&ecptformatlist);
+        s->session->tlsext_ecpointformatlist_length = 0;
+
+        OPENSSL_free(s->session->tlsext_ecpointformatlist);
+        s->session->tlsext_ecpointformatlist =
+             OPENSSL_malloc(ecpointformatlist_length);
+        if (s->session->tlsext_ecpointformatlist == NULL) {
+            *al = SSL_AD_INTERNAL_ERROR;
+            return 0;
+        }
+
+        s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+
+        if (!PACKET_copy_bytes(&ecptformatlist,
+                               s->session->tlsext_ecpointformatlist,
+                               ecpointformatlist_length)) {
+            *al = SSL_AD_INTERNAL_ERROR;
+            return 0;
+        }
+    }
+
+    return 1;
+}
+#endif
+
+int tls_parse_server_session_ticket(SSL *s, PACKET *pkt, int *al)
+{
+    if (s->tls_session_ticket_ext_cb &&
+        !s->tls_session_ticket_ext_cb(s, PACKET_data(pkt),
+                                      PACKET_remaining(pkt),
+                                      s->tls_session_ticket_ext_cb_arg)) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        return 0;
+    }
+    if (!tls_use_ticket(s) || PACKET_remaining(pkt) > 0) {
+        *al = SSL_AD_UNSUPPORTED_EXTENSION;
+        return 0;
+    }
+    s->tlsext_ticket_expected = 1;
+
+    return 1;
+}
+
+int tls_parse_server_status_request(SSL *s, PACKET *pkt, int *al)
+{
+    /*
+     * MUST be empty and only sent if we've requested a status
+     * request message.
+     */
+    if (s->tlsext_status_type == -1 || PACKET_remaining(pkt) > 0) {
+        *al = SSL_AD_UNSUPPORTED_EXTENSION;
+        return 0;
+    }
+    /* Set flag to expect CertificateStatus message */
+    s->tlsext_status_expected = 1;
+
+    return 1;
+}
+
+
+#ifndef OPENSSL_NO_CT
+int tls_parse_server_sct(SSL *s, PACKET *pkt, int *al)
+{
+    /*
+     * Only take it if we asked for it - i.e if there is no CT validation
+     * callback set, then a custom extension MAY be processing it, so we
+     * need to let control continue to flow to that.
+     */
+    if (s->ct_validation_callback != NULL) {
+        size_t size = PACKET_remaining(pkt);
+
+        /* Simply copy it off for later processing */
+        if (s->tlsext_scts != NULL) {
+            OPENSSL_free(s->tlsext_scts);
+            s->tlsext_scts = NULL;
+        }
+        s->tlsext_scts_len = size;
+        if (size > 0) {
+            s->tlsext_scts = OPENSSL_malloc(size);
+            if (s->tlsext_scts == NULL
+                    || !PACKET_copy_bytes(pkt, s->tlsext_scts, size)) {
+                *al = SSL_AD_INTERNAL_ERROR;
+                return 0;
+            }
+        }
+    } else {
+        if (custom_ext_parse(s, 0, TLSEXT_TYPE_signed_certificate_timestamp,
+                             PACKET_data(pkt), PACKET_remaining(pkt), al) <= 0)
+            return 0;
+    }
+
+    return 1;
+}
+#endif
+
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/*
+ * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
+ * elements of zero length are allowed and the set of elements must exactly
+ * fill the length of the block. Returns 1 on success or 0 on failure.
+ */
+static int ssl_next_proto_validate(PACKET *pkt)
+{
+    PACKET tmp_protocol;
+
+    while (PACKET_remaining(pkt)) {
+        if (!PACKET_get_length_prefixed_1(pkt, &tmp_protocol)
+            || PACKET_remaining(&tmp_protocol) == 0)
+            return 0;
+    }
+
+    return 1;
+}
+
+int tls_parse_server_npn(SSL *s, PACKET *pkt, int *al)
+{
+    unsigned char *selected;
+    unsigned char selected_len;
+    PACKET tmppkt;
+
+    if (s->s3->tmp.finish_md_len != 0)
+        return 1;
+
+    /* We must have requested it. */
+    if (s->ctx->next_proto_select_cb == NULL) {
+        *al = SSL_AD_UNSUPPORTED_EXTENSION;
+        return 0;
+    }
+    /* The data must be valid */
+    tmppkt = *pkt;
+    if (!ssl_next_proto_validate(&tmppkt)) {
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+    if (s->ctx->next_proto_select_cb(s, &selected, &selected_len,
+                                     PACKET_data(pkt),
+                                     PACKET_remaining(pkt),
+                                     s->ctx->next_proto_select_cb_arg) !=
+             SSL_TLSEXT_ERR_OK) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        return 0;
+    }
+    /*
+     * Could be non-NULL if server has sent multiple NPN extensions in
+     * a single Serverhello
+     */
+    OPENSSL_free(s->next_proto_negotiated);
+    s->next_proto_negotiated = OPENSSL_malloc(selected_len);
+    if (s->next_proto_negotiated == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        return 0;
+    }
+
+    memcpy(s->next_proto_negotiated, selected, selected_len);
+    s->next_proto_negotiated_len = selected_len;
+    s->s3->next_proto_neg_seen = 1;
+
+    return 1;
+}
+#endif
+
+int tls_parse_server_alpn(SSL *s, PACKET *pkt, int *al)
+{
+    size_t len;
+
+    /* We must have requested it. */
+    if (!s->s3->alpn_sent) {
+        *al = SSL_AD_UNSUPPORTED_EXTENSION;
+        return 0;
+    }
+    /*-
+     * The extension data consists of:
+     *   uint16 list_length
+     *   uint8 proto_length;
+     *   uint8 proto[proto_length];
+     */
+    if (!PACKET_get_net_2_len(pkt, &len)
+        || PACKET_remaining(pkt) != len || !PACKET_get_1_len(pkt, &len)
+        || PACKET_remaining(pkt) != len) {
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+    OPENSSL_free(s->s3->alpn_selected);
+    s->s3->alpn_selected = OPENSSL_malloc(len);
+    if (s->s3->alpn_selected == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        return 0;
+    }
+    if (!PACKET_copy_bytes(pkt, s->s3->alpn_selected, len)) {
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+    s->s3->alpn_selected_len = len;
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_SRTP
+int tls_parse_server_use_srtp(SSL *s, PACKET *pkt, int *al)
+{
+    unsigned int id, ct, mki;
+    int i;
+    STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
+    SRTP_PROTECTION_PROFILE *prof;
+
+    if (!PACKET_get_net_2(pkt, &ct)
+        || ct != 2 || !PACKET_get_net_2(pkt, &id)
+        || !PACKET_get_1(pkt, &mki)
+        || PACKET_remaining(pkt) != 0) {
+        SSLerr(SSL_F_TLS_PARSE_SERVER_USE_SRTP,
+               SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+
+    if (mki != 0) {
+        /* Must be no MKI, since we never offer one */
+        SSLerr(SSL_F_TLS_PARSE_SERVER_USE_SRTP, SSL_R_BAD_SRTP_MKI_VALUE);
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+    }
+
+    clnt = SSL_get_srtp_profiles(s);
+
+    /* Throw an error if the server gave us an unsolicited extension */
+    if (clnt == NULL) {
+        SSLerr(SSL_F_TLS_PARSE_SERVER_USE_SRTP, SSL_R_NO_SRTP_PROFILES);
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+
+    /*
+     * Check to see if the server gave us something we support (and
+     * presumably offered)
+     */
+    for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) {
+        prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
+
+        if (prof->id == id) {
+            s->srtp_profile = prof;
+            *al = 0;
+            return 1;
+        }
+    }
+
+    SSLerr(SSL_F_TLS_PARSE_SERVER_USE_SRTP,
+           SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+    *al = SSL_AD_DECODE_ERROR;
+    return 0;
+}
+#endif
+
+int tls_parse_server_etm(SSL *s, PACKET *pkt, int *al)
+{
+    /* Ignore if inappropriate ciphersuite */
+    if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)
+            && s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
+            && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
+        s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
+
+    return 1;
+}
+
+int tls_parse_server_ems(SSL *s, PACKET *pkt, int *al)
+{
+    s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
+    if (!s->hit)
+        s->session->flags |= SSL_SESS_FLAG_EXTMS;
+
+    return 1;
+}
+
+int tls_parse_server_key_share(SSL *s, PACKET *pkt, int *al)
+{
+    unsigned int group_id;
+    PACKET encoded_pt;
+    EVP_PKEY *ckey = s->s3->tmp.pkey, *skey = NULL;
+
+    /* Sanity check */
+    if (ckey == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PARSE_SERVER_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    if (!PACKET_get_net_2(pkt, &group_id)) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PARSE_SERVER_KEY_SHARE, SSL_R_LENGTH_MISMATCH);
+        return 0;
+    }
+
+    if (group_id != s->s3->group_id) {
+        /*
+         * This isn't for the group that we sent in the original
+         * key_share!
+         */
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PARSE_SERVER_KEY_SHARE, SSL_R_BAD_KEY_SHARE);
+        return 0;
+    }
+
+    if (!PACKET_as_length_prefixed_2(pkt, &encoded_pt)
+            || PACKET_remaining(&encoded_pt) == 0) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PARSE_SERVER_KEY_SHARE, SSL_R_LENGTH_MISMATCH);
+        return 0;
+    }
+
+    skey = ssl_generate_pkey(ckey);
+    if (skey == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PARSE_SERVER_KEY_SHARE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt),
+                                        PACKET_remaining(&encoded_pt))) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PARSE_SERVER_KEY_SHARE, SSL_R_BAD_ECPOINT);
+        return 0;
+    }
+
+    if (ssl_derive(s, ckey, skey, 1) == 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PARSE_SERVER_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+        EVP_PKEY_free(skey);
+        return 0;
+    }
+    EVP_PKEY_free(skey);
+
+    return 1;
+}
+
+static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
+{
+    size_t num_extensions = 0;
+    RAW_EXTENSION *extensions = NULL;
+    PACKET extpkt;
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    s->s3->next_proto_neg_seen = 0;
+#endif
+    s->tlsext_ticket_expected = 0;
+
+    OPENSSL_free(s->s3->alpn_selected);
+    s->s3->alpn_selected = NULL;
+
+    s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
+
+    s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
+
+    if (!PACKET_as_length_prefixed_2(pkt, &extpkt)) {
+        /* Extensions block may be completely absent in SSLv3 */
+        if (s->version != SSL3_VERSION || PACKET_remaining(pkt) != 0) {
+            *al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, SSL_R_BAD_LENGTH);
+            return 0;
+        }
+        PACKET_null_init(&extpkt);
+    }
+
+    /*
+     * TODO(TLS1.3): We give multiple contexts for now until we're ready to
+     * give something more specific
+     */
+
+    if (!tls_collect_extensions(s, &extpkt, EXT_TLS1_2_SERVER_HELLO
+                                            | EXT_TLS1_3_SERVER_HELLO
+                                            | EXT_TLS1_3_ENCRYPTED_EXTENSIONS
+                                            | EXT_TLS1_3_CERTIFICATE,
+                                &extensions, &num_extensions, al))
+        return 0;
+
+    /*
+     * Determine if we need to see RI. Strictly speaking if we want to avoid
+     * an attack we should *always* see RI even on initial server hello
+     * because the client doesn't see any renegotiation during an attack.
+     * However this would mean we could not connect to any server which
+     * doesn't support RI so for the immediate future tolerate RI absence
+     */
+    if (!(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
+            && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)
+            && tls_get_extension_by_type(extensions, num_extensions,
+                                         TLSEXT_TYPE_renegotiate) == NULL) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
+               SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+        return 0;
+    }
+
+    if (!tls_parse_all_extensions(s, EXT_TLS1_2_SERVER_HELLO
+                                     | EXT_TLS1_3_SERVER_HELLO
+                                     | EXT_TLS1_3_ENCRYPTED_EXTENSIONS
+                                     | EXT_TLS1_3_CERTIFICATE,
+                                  extensions, num_extensions, al))
+        return 0;
+
+    if (s->hit) {
+        /*
+         * Check extended master secret extension is consistent with
+         * original session.
+         */
+        if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) !=
+            !(s->session->flags & SSL_SESS_FLAG_EXTMS)) {
+            *al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, SSL_R_INCONSISTENT_EXTMS);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+static int ssl_check_serverhello_tlsext(SSL *s)
+{
+    int ret = SSL_TLSEXT_ERR_NOACK;
+    int al = SSL_AD_UNRECOGNIZED_NAME;
+
+#ifndef OPENSSL_NO_EC
+    /*
+     * If we are client and using an elliptic curve cryptography cipher
+     * suite, then if server returns an EC point formats lists extension it
+     * must contain uncompressed.
+     */
+    unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+    unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+    if ((s->tlsext_ecpointformatlist != NULL)
+        && (s->tlsext_ecpointformatlist_length > 0)
+        && (s->session->tlsext_ecpointformatlist != NULL)
+        && (s->session->tlsext_ecpointformatlist_length > 0)
+        && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA))) {
+        /* we are using an ECC cipher */
+        size_t i;
+        unsigned char *list;
+        int found_uncompressed = 0;
+        list = s->session->tlsext_ecpointformatlist;
+        for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) {
+            if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) {
+                found_uncompressed = 1;
+                break;
+            }
+        }
+        if (!found_uncompressed) {
+            SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,
+                   SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
+            return -1;
+        }
+    }
+    ret = SSL_TLSEXT_ERR_OK;
+#endif                          /* OPENSSL_NO_EC */
+
+    if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
+        ret =
+            s->ctx->tlsext_servername_callback(s, &al,
+                                               s->ctx->tlsext_servername_arg);
+    else if (s->initial_ctx != NULL
+             && s->initial_ctx->tlsext_servername_callback != 0)
+        ret =
+            s->initial_ctx->tlsext_servername_callback(s, &al,
+                                                       s->
+                                                       initial_ctx->tlsext_servername_arg);
+
+    /*
+     * Ensure we get sensible values passed to tlsext_status_cb in the event
+     * that we don't receive a status message
+     */
+    OPENSSL_free(s->tlsext_ocsp_resp);
+    s->tlsext_ocsp_resp = NULL;
+    s->tlsext_ocsp_resplen = 0;
+
+    switch (ret) {
+    case SSL_TLSEXT_ERR_ALERT_FATAL:
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        return -1;
+
+    case SSL_TLSEXT_ERR_ALERT_WARNING:
+        ssl3_send_alert(s, SSL3_AL_WARNING, al);
+        return 1;
+
+    case SSL_TLSEXT_ERR_NOACK:
+        s->servername_done = 0;
+    default:
+        return 1;
+    }
+}
+
+int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt)
+{
+    int al = -1;
+    if (s->version < SSL3_VERSION)
+        return 1;
+    if (ssl_scan_serverhello_tlsext(s, pkt, &al) <= 0) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        return 0;
+    }
+
+    if (ssl_check_serverhello_tlsext(s) <= 0) {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT);
+        return 0;
+    }
+    return 1;
+}
index 7a69f68..e090421 100644 (file)
@@ -648,6 +648,138 @@ int tls_parse_client_ems(SSL *s, PACKET *pkt, int *al)
     return 1;
 }
 
+#ifndef OPENSSL_NO_EC
+/*-
+ * ssl_check_for_safari attempts to fingerprint Safari using OS X
+ * SecureTransport using the TLS extension block in |hello|.
+ * Safari, since 10.6, sends exactly these extensions, in this order:
+ *   SNI,
+ *   elliptic_curves
+ *   ec_point_formats
+ *
+ * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
+ * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
+ * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
+ * 10.8..10.8.3 (which don't work).
+ */
+static void ssl_check_for_safari(SSL *s, const CLIENTHELLO_MSG *hello)
+{
+    unsigned int type;
+    PACKET sni, tmppkt;
+    size_t ext_len;
+
+    static const unsigned char kSafariExtensionsBlock[] = {
+        0x00, 0x0a,             /* elliptic_curves extension */
+        0x00, 0x08,             /* 8 bytes */
+        0x00, 0x06,             /* 6 bytes of curve ids */
+        0x00, 0x17,             /* P-256 */
+        0x00, 0x18,             /* P-384 */
+        0x00, 0x19,             /* P-521 */
+
+        0x00, 0x0b,             /* ec_point_formats */
+        0x00, 0x02,             /* 2 bytes */
+        0x01,                   /* 1 point format */
+        0x00,                   /* uncompressed */
+        /* The following is only present in TLS 1.2 */
+        0x00, 0x0d,             /* signature_algorithms */
+        0x00, 0x0c,             /* 12 bytes */
+        0x00, 0x0a,             /* 10 bytes */
+        0x05, 0x01,             /* SHA-384/RSA */
+        0x04, 0x01,             /* SHA-256/RSA */
+        0x02, 0x01,             /* SHA-1/RSA */
+        0x04, 0x03,             /* SHA-256/ECDSA */
+        0x02, 0x03,             /* SHA-1/ECDSA */
+    };
+
+    /* Length of the common prefix (first two extensions). */
+    static const size_t kSafariCommonExtensionsLength = 18;
+
+    tmppkt = hello->extensions;
+
+    if (!PACKET_forward(&tmppkt, 2)
+        || !PACKET_get_net_2(&tmppkt, &type)
+        || !PACKET_get_length_prefixed_2(&tmppkt, &sni)) {
+        return;
+    }
+
+    if (type != TLSEXT_TYPE_server_name)
+        return;
+
+    ext_len = TLS1_get_client_version(s) >= TLS1_2_VERSION ?
+        sizeof(kSafariExtensionsBlock) : kSafariCommonExtensionsLength;
+
+    s->s3->is_probably_safari = PACKET_equal(&tmppkt, kSafariExtensionsBlock,
+                                             ext_len);
+}
+#endif                          /* !OPENSSL_NO_EC */
+
+/*
+ * Process all remaining ClientHello extensions that we collected earlier and
+ * haven't already processed.
+ *
+ * Behaviour upon resumption is extension-specific. If the extension has no
+ * effect during resumption, it is parsed (to verify its format) but otherwise
+ * ignored. Returns 1 on success and 0 on failure. Upon failure, sets |al| to
+ * the appropriate alert.
+ */
+int tls_scan_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello, int *al)
+{
+    /* Reset various flags that might get set by extensions during parsing */
+    s->servername_done = 0;
+    s->tlsext_status_type = -1;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    s->s3->next_proto_neg_seen = 0;
+#endif
+
+    OPENSSL_free(s->s3->alpn_selected);
+    s->s3->alpn_selected = NULL;
+    s->s3->alpn_selected_len = 0;
+    OPENSSL_free(s->s3->alpn_proposed);
+    s->s3->alpn_proposed = NULL;
+    s->s3->alpn_proposed_len = 0;
+
+#ifndef OPENSSL_NO_EC
+    if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
+        ssl_check_for_safari(s, hello);
+#endif                          /* !OPENSSL_NO_EC */
+
+    /* Clear any signature algorithms extension received */
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
+    s->s3->tmp.peer_sigalgs = NULL;
+    s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
+
+#ifndef OPENSSL_NO_SRP
+    OPENSSL_free(s->srp_ctx.login);
+    s->srp_ctx.login = NULL;
+#endif
+
+    s->srtp_profile = NULL;
+
+    /*
+     * We process the supported_groups extension first so that is done before
+     * we get to key_share which needs to use the information in it.
+     */
+    if (!tls_parse_extension(s, TLSEXT_TYPE_supported_groups, EXT_CLIENT_HELLO,
+                             hello->pre_proc_exts, hello->num_extensions, al)) {
+        return 0;
+    }
+
+    /* Need RI if renegotiating */
+    if (s->renegotiate
+            && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)
+            && tls_get_extension_by_type(hello->pre_proc_exts,
+                                         hello->num_extensions,
+                                         TLSEXT_TYPE_renegotiate) == NULL) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_SCAN_CLIENTHELLO_TLSEXT,
+               SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+        return 0;
+    }
+
+    return tls_parse_all_extensions(s, EXT_CLIENT_HELLO, hello->pre_proc_exts,
+                                    hello->num_extensions, al);
+}
+
 /*
  * Process the ALPN extension in a ClientHello.
  * al: a pointer to the alert value to send in the event of a failure.
index 53fd0f0..88c40f5 100644 (file)
@@ -180,6 +180,8 @@ int tls_parse_client_etm(SSL *s, PACKET *pkt, int *al);
 int tls_parse_client_key_share(SSL *s, PACKET *pkt, int *al);
 int tls_parse_client_ems(SSL *s, PACKET *pkt, int *al);
 
+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);
 int tls_construct_server_ec_pt_formats(SSL *s, WPACKET *pkt, int *al);
@@ -191,10 +193,32 @@ int tls_construct_server_use_srtp(SSL *s, WPACKET *pkt, int *al);
 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);
-
 /*
  * Not in public headers as this is not an official extension. Only used when
  * SSL_OP_CRYPTOPRO_TLSEXT_BUG is set.
  */
 #define TLSEXT_TYPE_cryptopro_bug      0xfde8
 int tls_construct_server_cryptopro_bug(SSL *s, WPACKET *pkt, int *al);
+
+/* Client Extension processing */
+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);
+int tls_parse_server_status_request(SSL *s, PACKET *pkt, int *al);
+#ifndef OPENSSL_NO_CT
+int tls_parse_server_sct(SSL *s, PACKET *pkt, int *al);
+#endif
+#ifndef OPENSSL_NO_NEXTPROTONEG
+int tls_parse_server_npn(SSL *s, PACKET *pkt, int *al);
+#endif
+int tls_parse_server_alpn(SSL *s, PACKET *pkt, int *al);
+#ifndef OPENSSL_NO_SRTP
+int tls_parse_server_use_srtp(SSL *s, PACKET *pkt, int *al);
+#endif
+int tls_parse_server_etm(SSL *s, PACKET *pkt, int *al);
+int tls_parse_server_ems(SSL *s, PACKET *pkt, int *al);
+int tls_parse_server_key_share(SSL *s, PACKET *pkt, int *al);
+int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt);
index cc4b8c3..14fa0ed 100644 (file)
@@ -1062,138 +1062,6 @@ int dtls_construct_hello_verify_request(SSL *s, WPACKET *pkt)
     return 1;
 }
 
-#ifndef OPENSSL_NO_EC
-/*-
- * ssl_check_for_safari attempts to fingerprint Safari using OS X
- * SecureTransport using the TLS extension block in |hello|.
- * Safari, since 10.6, sends exactly these extensions, in this order:
- *   SNI,
- *   elliptic_curves
- *   ec_point_formats
- *
- * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
- * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
- * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
- * 10.8..10.8.3 (which don't work).
- */
-static void ssl_check_for_safari(SSL *s, const CLIENTHELLO_MSG *hello)
-{
-    unsigned int type;
-    PACKET sni, tmppkt;
-    size_t ext_len;
-
-    static const unsigned char kSafariExtensionsBlock[] = {
-        0x00, 0x0a,             /* elliptic_curves extension */
-        0x00, 0x08,             /* 8 bytes */
-        0x00, 0x06,             /* 6 bytes of curve ids */
-        0x00, 0x17,             /* P-256 */
-        0x00, 0x18,             /* P-384 */
-        0x00, 0x19,             /* P-521 */
-
-        0x00, 0x0b,             /* ec_point_formats */
-        0x00, 0x02,             /* 2 bytes */
-        0x01,                   /* 1 point format */
-        0x00,                   /* uncompressed */
-        /* The following is only present in TLS 1.2 */
-        0x00, 0x0d,             /* signature_algorithms */
-        0x00, 0x0c,             /* 12 bytes */
-        0x00, 0x0a,             /* 10 bytes */
-        0x05, 0x01,             /* SHA-384/RSA */
-        0x04, 0x01,             /* SHA-256/RSA */
-        0x02, 0x01,             /* SHA-1/RSA */
-        0x04, 0x03,             /* SHA-256/ECDSA */
-        0x02, 0x03,             /* SHA-1/ECDSA */
-    };
-
-    /* Length of the common prefix (first two extensions). */
-    static const size_t kSafariCommonExtensionsLength = 18;
-
-    tmppkt = hello->extensions;
-
-    if (!PACKET_forward(&tmppkt, 2)
-        || !PACKET_get_net_2(&tmppkt, &type)
-        || !PACKET_get_length_prefixed_2(&tmppkt, &sni)) {
-        return;
-    }
-
-    if (type != TLSEXT_TYPE_server_name)
-        return;
-
-    ext_len = TLS1_get_client_version(s) >= TLS1_2_VERSION ?
-        sizeof(kSafariExtensionsBlock) : kSafariCommonExtensionsLength;
-
-    s->s3->is_probably_safari = PACKET_equal(&tmppkt, kSafariExtensionsBlock,
-                                             ext_len);
-}
-#endif                          /* !OPENSSL_NO_EC */
-
-/*
- * Process all remaining ClientHello extensions that we collected earlier and
- * haven't already processed.
- *
- * Behaviour upon resumption is extension-specific. If the extension has no
- * effect during resumption, it is parsed (to verify its format) but otherwise
- * ignored. Returns 1 on success and 0 on failure. Upon failure, sets |al| to
- * the appropriate alert.
- */
-static int tls_scan_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello, int *al)
-{
-    /* Reset various flags that might get set by extensions during parsing */
-    s->servername_done = 0;
-    s->tlsext_status_type = -1;
-#ifndef OPENSSL_NO_NEXTPROTONEG
-    s->s3->next_proto_neg_seen = 0;
-#endif
-
-    OPENSSL_free(s->s3->alpn_selected);
-    s->s3->alpn_selected = NULL;
-    s->s3->alpn_selected_len = 0;
-    OPENSSL_free(s->s3->alpn_proposed);
-    s->s3->alpn_proposed = NULL;
-    s->s3->alpn_proposed_len = 0;
-
-#ifndef OPENSSL_NO_EC
-    if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
-        ssl_check_for_safari(s, hello);
-#endif                          /* !OPENSSL_NO_EC */
-
-    /* Clear any signature algorithms extension received */
-    OPENSSL_free(s->s3->tmp.peer_sigalgs);
-    s->s3->tmp.peer_sigalgs = NULL;
-    s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
-
-#ifndef OPENSSL_NO_SRP
-    OPENSSL_free(s->srp_ctx.login);
-    s->srp_ctx.login = NULL;
-#endif
-
-    s->srtp_profile = NULL;
-
-    /*
-     * We process the supported_groups extension first so that is done before
-     * we get to key_share which needs to use the information in it.
-     */
-    if (!tls_parse_extension(s, TLSEXT_TYPE_supported_groups, EXT_CLIENT_HELLO,
-                             hello->pre_proc_exts, hello->num_extensions, al)) {
-        return 0;
-    }
-
-    /* Need RI if renegotiating */
-    if (s->renegotiate
-            && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)
-            && tls_get_extension_by_type(hello->pre_proc_exts,
-                                         hello->num_extensions,
-                                         TLSEXT_TYPE_renegotiate) == NULL) {
-        *al = SSL_AD_HANDSHAKE_FAILURE;
-        SSLerr(SSL_F_TLS_SCAN_CLIENTHELLO_TLSEXT,
-               SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-        return 0;
-    }
-
-    return tls_parse_all_extensions(s, EXT_CLIENT_HELLO, hello->pre_proc_exts,
-                                    hello->num_extensions, al);
-}
-
 /*
  * Check the results of extension parsing. Currently just calls the servername
  * callback. Returns 1 for success or 0 for failure.
@@ -1986,7 +1854,9 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt)
                 */
             || !tls_construct_extensions(s, pkt,
                                          EXT_TLS1_2_SERVER_HELLO
-                                         | EXT_TLS1_3_SERVER_HELLO, &al)) {
+                                         | EXT_TLS1_3_SERVER_HELLO
+                                         | EXT_TLS1_3_ENCRYPTED_EXTENSIONS
+                                         | EXT_TLS1_3_CERTIFICATE, &al)) {
         SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
         goto err;
     }
index e8019c0..e682912 100644 (file)
@@ -23,7 +23,6 @@
 static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, size_t ticklen,
                               const unsigned char *sess_id, size_t sesslen,
                               SSL_SESSION **psess);
-static int ssl_check_serverhello_tlsext(SSL *s);
 
 SSL3_ENC_METHOD const TLSv1_enc_data = {
     tls1_enc,
@@ -946,81 +945,6 @@ int tls_use_ticket(SSL *s)
     return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
 }
 
-static int compare_uint(const void *p1, const void *p2)
-{
-    unsigned int u1 = *((const unsigned int *)p1);
-    unsigned int u2 = *((const unsigned int *)p2);
-    if (u1 < u2)
-        return -1;
-    else if (u1 > u2)
-        return 1;
-    else
-        return 0;
-}
-
-/*
- * Per http://tools.ietf.org/html/rfc5246#section-7.4.1.4, there may not be
- * more than one extension of the same type in a ClientHello or ServerHello.
- * This function does an initial scan over the extensions block to filter those
- * out. It returns 1 if all extensions are unique, and 0 if the extensions
- * contain duplicates, could not be successfully parsed, or an internal error
- * occurred.
- */
-static int tls1_check_duplicate_extensions(const PACKET *packet)
-{
-    PACKET extensions = *packet;
-    size_t num_extensions = 0, i = 0;
-    unsigned int *extension_types = NULL;
-    int ret = 0;
-
-    /* First pass: count the extensions. */
-    while (PACKET_remaining(&extensions) > 0) {
-        unsigned int type;
-        PACKET extension;
-        if (!PACKET_get_net_2(&extensions, &type) ||
-            !PACKET_get_length_prefixed_2(&extensions, &extension)) {
-            goto done;
-        }
-        num_extensions++;
-    }
-
-    if (num_extensions <= 1)
-        return 1;
-
-    extension_types = OPENSSL_malloc(sizeof(unsigned int) * num_extensions);
-    if (extension_types == NULL) {
-        SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_MALLOC_FAILURE);
-        goto done;
-    }
-
-    /* Second pass: gather the extension types. */
-    extensions = *packet;
-    for (i = 0; i < num_extensions; i++) {
-        PACKET extension;
-        if (!PACKET_get_net_2(&extensions, &extension_types[i]) ||
-            !PACKET_get_length_prefixed_2(&extensions, &extension)) {
-            /* This should not happen. */
-            SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_INTERNAL_ERROR);
-            goto done;
-        }
-    }
-
-    if (PACKET_remaining(&extensions) != 0) {
-        SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_INTERNAL_ERROR);
-        goto done;
-    }
-    /* Sort the extensions and make sure there are no duplicates. */
-    qsort(extension_types, num_extensions, sizeof(unsigned int), compare_uint);
-    for (i = 1; i < num_extensions; i++) {
-        if (extension_types[i - 1] == extension_types[i])
-            goto done;
-    }
-    ret = 1;
- done:
-    OPENSSL_free(extension_types);
-    return ret;
-}
-
 int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al)
 {
 #ifndef OPENSSL_NO_EC
@@ -1512,366 +1436,6 @@ int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al)
     return 1;
 }
 
-#ifndef OPENSSL_NO_NEXTPROTONEG
-/*
- * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
- * elements of zero length are allowed and the set of elements must exactly
- * fill the length of the block.
- */
-static char ssl_next_proto_validate(PACKET *pkt)
-{
-    PACKET tmp_protocol;
-
-    while (PACKET_remaining(pkt)) {
-        if (!PACKET_get_length_prefixed_1(pkt, &tmp_protocol)
-            || PACKET_remaining(&tmp_protocol) == 0)
-            return 0;
-    }
-
-    return 1;
-}
-#endif
-
-static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
-{
-    unsigned int length, type, size;
-    int tlsext_servername = 0;
-    int renegotiate_seen = 0;
-
-#ifndef OPENSSL_NO_NEXTPROTONEG
-    s->s3->next_proto_neg_seen = 0;
-#endif
-    s->tlsext_ticket_expected = 0;
-
-    OPENSSL_free(s->s3->alpn_selected);
-    s->s3->alpn_selected = NULL;
-
-    s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
-
-    s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
-
-    if (!PACKET_get_net_2(pkt, &length))
-        goto ri_check;
-
-    if (PACKET_remaining(pkt) != length) {
-        *al = SSL_AD_DECODE_ERROR;
-        return 0;
-    }
-
-    if (!tls1_check_duplicate_extensions(pkt)) {
-        *al = SSL_AD_DECODE_ERROR;
-        return 0;
-    }
-
-    while (PACKET_get_net_2(pkt, &type) && PACKET_get_net_2(pkt, &size)) {
-        const unsigned char *data;
-        PACKET spkt;
-
-        if (!PACKET_get_sub_packet(pkt, &spkt, size)
-            || !PACKET_peek_bytes(&spkt, &data, size))
-            goto ri_check;
-
-        if (s->tlsext_debug_cb)
-            s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg);
-
-        if (type == TLSEXT_TYPE_renegotiate) {
-            if (!ssl_parse_serverhello_renegotiate_ext(s, &spkt, al))
-                return 0;
-            renegotiate_seen = 1;
-        } else if (s->version == SSL3_VERSION) {
-        } else if (type == TLSEXT_TYPE_server_name) {
-            if (s->tlsext_hostname == NULL || size > 0) {
-                *al = TLS1_AD_UNRECOGNIZED_NAME;
-                return 0;
-            }
-            tlsext_servername = 1;
-        }
-#ifndef OPENSSL_NO_EC
-        else if (type == TLSEXT_TYPE_ec_point_formats) {
-            unsigned int ecpointformatlist_length;
-            if (!PACKET_get_1(&spkt, &ecpointformatlist_length)
-                || ecpointformatlist_length != size - 1) {
-                *al = TLS1_AD_DECODE_ERROR;
-                return 0;
-            }
-            if (!s->hit) {
-                s->session->tlsext_ecpointformatlist_length = 0;
-                OPENSSL_free(s->session->tlsext_ecpointformatlist);
-                if ((s->session->tlsext_ecpointformatlist =
-                     OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
-                    *al = TLS1_AD_INTERNAL_ERROR;
-                    return 0;
-                }
-                s->session->tlsext_ecpointformatlist_length =
-                    ecpointformatlist_length;
-                if (!PACKET_copy_bytes(&spkt,
-                                       s->session->tlsext_ecpointformatlist,
-                                       ecpointformatlist_length)) {
-                    *al = TLS1_AD_DECODE_ERROR;
-                    return 0;
-                }
-
-            }
-        }
-#endif                          /* OPENSSL_NO_EC */
-
-        else if (type == TLSEXT_TYPE_session_ticket) {
-            if (s->tls_session_ticket_ext_cb &&
-                !s->tls_session_ticket_ext_cb(s, data, size,
-                                              s->tls_session_ticket_ext_cb_arg))
-            {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            if (!tls_use_ticket(s) || (size > 0)) {
-                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                return 0;
-            }
-            s->tlsext_ticket_expected = 1;
-        } else if (type == TLSEXT_TYPE_status_request) {
-            /*
-             * MUST be empty and only sent if we've requested a status
-             * request message.
-             */
-            if ((s->tlsext_status_type == -1) || (size > 0)) {
-                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                return 0;
-            }
-            /* Set flag to expect CertificateStatus message */
-            s->tlsext_status_expected = 1;
-        }
-#ifndef OPENSSL_NO_CT
-        /*
-         * Only take it if we asked for it - i.e if there is no CT validation
-         * callback set, then a custom extension MAY be processing it, so we
-         * need to let control continue to flow to that.
-         */
-        else if (type == TLSEXT_TYPE_signed_certificate_timestamp &&
-                 s->ct_validation_callback != NULL) {
-            /* Simply copy it off for later processing */
-            if (s->tlsext_scts != NULL) {
-                OPENSSL_free(s->tlsext_scts);
-                s->tlsext_scts = NULL;
-            }
-            s->tlsext_scts_len = size;
-            if (size > 0) {
-                s->tlsext_scts = OPENSSL_malloc(size);
-                if (s->tlsext_scts == NULL) {
-                    *al = TLS1_AD_INTERNAL_ERROR;
-                    return 0;
-                }
-                memcpy(s->tlsext_scts, data, size);
-            }
-        }
-#endif
-#ifndef OPENSSL_NO_NEXTPROTONEG
-        else if (type == TLSEXT_TYPE_next_proto_neg &&
-                 s->s3->tmp.finish_md_len == 0) {
-            unsigned char *selected;
-            unsigned char selected_len;
-            /* We must have requested it. */
-            if (s->ctx->next_proto_select_cb == NULL) {
-                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                return 0;
-            }
-            /* The data must be valid */
-            if (!ssl_next_proto_validate(&spkt)) {
-                *al = TLS1_AD_DECODE_ERROR;
-                return 0;
-            }
-            if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data,
-                                             size,
-                                             s->
-                                             ctx->next_proto_select_cb_arg) !=
-                SSL_TLSEXT_ERR_OK) {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            /*
-             * Could be non-NULL if server has sent multiple NPN extensions in
-             * a single Serverhello
-             */
-            OPENSSL_free(s->next_proto_negotiated);
-            s->next_proto_negotiated = OPENSSL_malloc(selected_len);
-            if (s->next_proto_negotiated == NULL) {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            memcpy(s->next_proto_negotiated, selected, selected_len);
-            s->next_proto_negotiated_len = selected_len;
-            s->s3->next_proto_neg_seen = 1;
-        }
-#endif
-
-        else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) {
-            unsigned len;
-            /* We must have requested it. */
-            if (!s->s3->alpn_sent) {
-                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                return 0;
-            }
-            /*-
-             * The extension data consists of:
-             *   uint16 list_length
-             *   uint8 proto_length;
-             *   uint8 proto[proto_length];
-             */
-            if (!PACKET_get_net_2(&spkt, &len)
-                || PACKET_remaining(&spkt) != len || !PACKET_get_1(&spkt, &len)
-                || PACKET_remaining(&spkt) != len) {
-                *al = TLS1_AD_DECODE_ERROR;
-                return 0;
-            }
-            OPENSSL_free(s->s3->alpn_selected);
-            s->s3->alpn_selected = OPENSSL_malloc(len);
-            if (s->s3->alpn_selected == NULL) {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            if (!PACKET_copy_bytes(&spkt, s->s3->alpn_selected, len)) {
-                *al = TLS1_AD_DECODE_ERROR;
-                return 0;
-            }
-            s->s3->alpn_selected_len = len;
-        }
-#ifndef OPENSSL_NO_SRTP
-        else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) {
-            if (ssl_parse_serverhello_use_srtp_ext(s, &spkt, al))
-                return 0;
-        }
-#endif
-        else if (type == TLSEXT_TYPE_encrypt_then_mac) {
-            /* Ignore if inappropriate ciphersuite */
-            if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC) &&
-                s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
-                && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
-                s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
-        } else if (type == TLSEXT_TYPE_extended_master_secret &&
-                (SSL_IS_DTLS(s) || !SSL_IS_TLS13(s))) {
-            s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
-            if (!s->hit)
-                s->session->flags |= SSL_SESS_FLAG_EXTMS;
-        } else if (type == TLSEXT_TYPE_key_share
-                && SSL_IS_TLS13(s)) {
-            unsigned int group_id;
-            PACKET encoded_pt;
-            EVP_PKEY *ckey = s->s3->tmp.pkey, *skey = NULL;
-
-            /* Sanity check */
-            if (ckey == NULL) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-
-            if (!PACKET_get_net_2(&spkt, &group_id)) {
-                *al = SSL_AD_HANDSHAKE_FAILURE;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
-                       SSL_R_LENGTH_MISMATCH);
-                return 0;
-            }
-
-            if (group_id != s->s3->group_id) {
-                /*
-                 * This isn't for the group that we sent in the original
-                 * key_share!
-                 */
-                *al = SSL_AD_HANDSHAKE_FAILURE;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
-                       SSL_R_BAD_KEY_SHARE);
-                return 0;
-            }
-
-            if (!PACKET_as_length_prefixed_2(&spkt, &encoded_pt)
-                    || PACKET_remaining(&encoded_pt) == 0) {
-                *al = SSL_AD_DECODE_ERROR;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
-                       SSL_R_LENGTH_MISMATCH);
-                return 0;
-            }
-
-            skey = ssl_generate_pkey(ckey);
-            if (skey == NULL) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, ERR_R_MALLOC_FAILURE);
-                return 0;
-            }
-            if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt),
-                                                PACKET_remaining(&encoded_pt))) {
-                *al = SSL_AD_DECODE_ERROR;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, SSL_R_BAD_ECPOINT);
-                return 0;
-            }
-
-            if (ssl_derive(s, ckey, skey, 1) == 0) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                EVP_PKEY_free(skey);
-                return 0;
-            }
-            EVP_PKEY_free(skey);
-        /*
-         * If this extension type was not otherwise handled, but matches a
-         * custom_cli_ext_record, then send it to the c callback
-         */
-        } else if (custom_ext_parse(s, 0, type, data, size, al) <= 0)
-            return 0;
-    }
-
-    if (PACKET_remaining(pkt) != 0) {
-        *al = SSL_AD_DECODE_ERROR;
-        return 0;
-    }
-
-    if (!s->hit && tlsext_servername == 1) {
-        if (s->tlsext_hostname) {
-            if (s->session->tlsext_hostname == NULL) {
-                s->session->tlsext_hostname =
-                    OPENSSL_strdup(s->tlsext_hostname);
-                if (!s->session->tlsext_hostname) {
-                    *al = SSL_AD_UNRECOGNIZED_NAME;
-                    return 0;
-                }
-            } else {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
-        }
-    }
-
- ri_check:
-
-    /*
-     * Determine if we need to see RI. Strictly speaking if we want to avoid
-     * an attack we should *always* see RI even on initial server hello
-     * because the client doesn't see any renegotiation during an attack.
-     * However this would mean we could not connect to any server which
-     * doesn't support RI so for the immediate future tolerate RI absence
-     */
-    if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
-        && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
-        *al = SSL_AD_HANDSHAKE_FAILURE;
-        SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
-               SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-        return 0;
-    }
-
-    if (s->hit) {
-        /*
-         * Check extended master secret extension is consistent with
-         * original session.
-         */
-        if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) !=
-            !(s->session->flags & SSL_SESS_FLAG_EXTMS)) {
-            *al = SSL_AD_HANDSHAKE_FAILURE;
-            SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, SSL_R_INCONSISTENT_EXTMS);
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
 int ssl_prepare_clienthello_tlsext(SSL *s)
 {
     s->s3->alpn_sent = 0;
@@ -1940,96 +1504,6 @@ int tls1_set_server_sigalgs(SSL *s)
     return 0;
 }
 
-int ssl_check_serverhello_tlsext(SSL *s)
-{
-    int ret = SSL_TLSEXT_ERR_NOACK;
-    int al = SSL_AD_UNRECOGNIZED_NAME;
-
-#ifndef OPENSSL_NO_EC
-    /*
-     * If we are client and using an elliptic curve cryptography cipher
-     * suite, then if server returns an EC point formats lists extension it
-     * must contain uncompressed.
-     */
-    unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
-    unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-    if ((s->tlsext_ecpointformatlist != NULL)
-        && (s->tlsext_ecpointformatlist_length > 0)
-        && (s->session->tlsext_ecpointformatlist != NULL)
-        && (s->session->tlsext_ecpointformatlist_length > 0)
-        && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA))) {
-        /* we are using an ECC cipher */
-        size_t i;
-        unsigned char *list;
-        int found_uncompressed = 0;
-        list = s->session->tlsext_ecpointformatlist;
-        for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) {
-            if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) {
-                found_uncompressed = 1;
-                break;
-            }
-        }
-        if (!found_uncompressed) {
-            SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,
-                   SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
-            return -1;
-        }
-    }
-    ret = SSL_TLSEXT_ERR_OK;
-#endif                          /* OPENSSL_NO_EC */
-
-    if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
-        ret =
-            s->ctx->tlsext_servername_callback(s, &al,
-                                               s->ctx->tlsext_servername_arg);
-    else if (s->initial_ctx != NULL
-             && s->initial_ctx->tlsext_servername_callback != 0)
-        ret =
-            s->initial_ctx->tlsext_servername_callback(s, &al,
-                                                       s->
-                                                       initial_ctx->tlsext_servername_arg);
-
-    /*
-     * Ensure we get sensible values passed to tlsext_status_cb in the event
-     * that we don't receive a status message
-     */
-    OPENSSL_free(s->tlsext_ocsp_resp);
-    s->tlsext_ocsp_resp = NULL;
-    s->tlsext_ocsp_resplen = 0;
-
-    switch (ret) {
-    case SSL_TLSEXT_ERR_ALERT_FATAL:
-        ssl3_send_alert(s, SSL3_AL_FATAL, al);
-        return -1;
-
-    case SSL_TLSEXT_ERR_ALERT_WARNING:
-        ssl3_send_alert(s, SSL3_AL_WARNING, al);
-        return 1;
-
-    case SSL_TLSEXT_ERR_NOACK:
-        s->servername_done = 0;
-    default:
-        return 1;
-    }
-}
-
-int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt)
-{
-    int al = -1;
-    if (s->version < SSL3_VERSION)
-        return 1;
-    if (ssl_scan_serverhello_tlsext(s, pkt, &al) <= 0) {
-        ssl3_send_alert(s, SSL3_AL_FATAL, al);
-        return 0;
-    }
-
-    if (ssl_check_serverhello_tlsext(s) <= 0) {
-        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT);
-        return 0;
-    }
-    return 1;
-}
-
 /*
  * Given a list of extensions that we collected earlier, find one of a given
  * type and return it.
diff --git a/ssl/t1_reneg.c b/ssl/t1_reneg.c
deleted file mode 100644 (file)
index 4301a38..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License").  You may not use
- * this file except in compliance with the License.  You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <openssl/objects.h>
-#include "ssl_locl.h"
-
-/*
- * Parse the server's renegotiation binding and abort if it's not right
- */
-int ssl_parse_serverhello_renegotiate_ext(SSL *s, PACKET *pkt, int *al)
-{
-    size_t expected_len = s->s3->previous_client_finished_len
-        + s->s3->previous_server_finished_len;
-    size_t ilen;
-    const unsigned char *data;
-
-    /* Check for logic errors */
-    OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len);
-    OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len);
-
-    /* Parse the length byte */
-    if (!PACKET_get_1_len(pkt, &ilen)) {
-        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
-               SSL_R_RENEGOTIATION_ENCODING_ERR);
-        *al = SSL_AD_ILLEGAL_PARAMETER;
-        return 0;
-    }
-
-    /* Consistency check */
-    if (PACKET_remaining(pkt) != ilen) {
-        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
-               SSL_R_RENEGOTIATION_ENCODING_ERR);
-        *al = SSL_AD_ILLEGAL_PARAMETER;
-        return 0;
-    }
-
-    /* Check that the extension matches */
-    if (ilen != expected_len) {
-        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
-               SSL_R_RENEGOTIATION_MISMATCH);
-        *al = SSL_AD_HANDSHAKE_FAILURE;
-        return 0;
-    }
-
-    if (!PACKET_get_bytes(pkt, &data, s->s3->previous_client_finished_len)
-        || memcmp(data, s->s3->previous_client_finished,
-                  s->s3->previous_client_finished_len) != 0) {
-        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
-               SSL_R_RENEGOTIATION_MISMATCH);
-        *al = SSL_AD_HANDSHAKE_FAILURE;
-        return 0;
-    }
-
-    if (!PACKET_get_bytes(pkt, &data, s->s3->previous_server_finished_len)
-        || memcmp(data, s->s3->previous_server_finished,
-                  s->s3->previous_server_finished_len) != 0) {
-        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
-               SSL_R_RENEGOTIATION_MISMATCH);
-        *al = SSL_AD_ILLEGAL_PARAMETER;
-        return 0;
-    }
-    s->s3->send_connection_binding = 1;
-
-    return 1;
-}