Move ServerHello extension construction into the new extensions framework
authorMatt Caswell <matt@openssl.org>
Fri, 25 Nov 2016 10:22:02 +0000 (10:22 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 8 Dec 2016 17:18:12 +0000 (17:18 +0000)
This lays the foundation for a later move to have the extensions built and
placed into the correct message for TLSv1.3 (e.g. ServerHello or
EncryptedExtensions).

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_srvr.c
ssl/statem/statem_locl.h
ssl/statem/statem_srvr.c
ssl/t1_lib.c
ssl/t1_reneg.c

index 95b53925ac89df47eb24e980e3a69db09fd9ec0c..b8e2188651745c33a0672360b368d189077f483d 100644 (file)
@@ -2275,10 +2275,22 @@ int ERR_load_SSL_strings(void);
 # define SSL_F_TLS_CONSTRUCT_HELLO_REQUEST                373
 # define SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET           428
 # define SSL_F_TLS_CONSTRUCT_NEXT_PROTO                   426
+# define SSL_F_TLS_CONSTRUCT_SERVER_ALPN                  451
 # define SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE           374
+# define SSL_F_TLS_CONSTRUCT_SERVER_CRYPTOPRO_BUG         452
 # define SSL_F_TLS_CONSTRUCT_SERVER_DONE                  375
+# define SSL_F_TLS_CONSTRUCT_SERVER_EC_PT_FORMATS         453
+# define SSL_F_TLS_CONSTRUCT_SERVER_EMS                   454
+# define SSL_F_TLS_CONSTRUCT_SERVER_ETM                   455
 # define SSL_F_TLS_CONSTRUCT_SERVER_HELLO                 376
 # define SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE          377
+# define SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE             456
+# define SSL_F_TLS_CONSTRUCT_SERVER_NEXT_PROTO_NEG        457
+# define SSL_F_TLS_CONSTRUCT_SERVER_RENEGOTIATE           458
+# define SSL_F_TLS_CONSTRUCT_SERVER_SERVER_NAME           459
+# define SSL_F_TLS_CONSTRUCT_SERVER_SESSION_TICKET        460
+# define SSL_F_TLS_CONSTRUCT_SERVER_STATUS_REQUEST        461
+# define SSL_F_TLS_CONSTRUCT_SERVER_USE_SRTP              462
 # define SSL_F_TLS_GET_MESSAGE_BODY                       351
 # define SSL_F_TLS_GET_MESSAGE_HEADER                     387
 # define SSL_F_TLS_PARSE_CLIENTHELLO_KEY_SHARE            445
index b5b9857ebd9a769064e41a64246ef14f04f63edc..af87a349a55a213f50d860f70a3dd1a054cfe2d9 100644 (file)
@@ -282,13 +282,34 @@ static ERR_STRING_DATA SSL_str_functs[] = {
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET),
      "tls_construct_new_session_ticket"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_NEXT_PROTO), "tls_construct_next_proto"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_ALPN), "tls_construct_server_alpn"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE),
      "tls_construct_server_certificate"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_CRYPTOPRO_BUG),
+     "tls_construct_server_cryptopro_bug"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_DONE), "tls_construct_server_done"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_EC_PT_FORMATS),
+     "tls_construct_server_ec_pt_formats"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_EMS), "tls_construct_server_ems"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_ETM), "tls_construct_server_etm"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_HELLO),
      "tls_construct_server_hello"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE),
      "tls_construct_server_key_exchange"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE),
+     "tls_construct_server_key_share"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_NEXT_PROTO_NEG),
+     "tls_construct_server_next_proto_neg"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_RENEGOTIATE),
+     "tls_construct_server_renegotiate"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_SERVER_NAME),
+     "tls_construct_server_server_name"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_SESSION_TICKET),
+     "tls_construct_server_session_ticket"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_STATUS_REQUEST),
+     "tls_construct_server_status_request"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_USE_SRTP),
+     "tls_construct_server_use_srtp"},
     {ERR_FUNC(SSL_F_TLS_GET_MESSAGE_BODY), "tls_get_message_body"},
     {ERR_FUNC(SSL_F_TLS_GET_MESSAGE_HEADER), "tls_get_message_header"},
     {ERR_FUNC(SSL_F_TLS_PARSE_CLIENTHELLO_KEY_SHARE),
index 5821968bd8fe1008587d3faf37b91fdc5e45643a..926c6c6396d7cc00c07b5bd27749184262e3f317 100644 (file)
@@ -2064,6 +2064,8 @@ __owur int tls1_set_groups(unsigned char **pext, size_t *pextlen,
                            int *curves, size_t ncurves);
 __owur int tls1_set_groups_list(unsigned char **pext, size_t *pextlen,
                                 const char *str);
+void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
+                         size_t *num_formats);
 __owur int tls1_check_ec_tmp_key(SSL *s, unsigned long id);
 __owur EVP_PKEY *ssl_generate_pkey_curve(int id);
 #  endif                        /* OPENSSL_NO_EC */
@@ -2076,18 +2078,17 @@ __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);
-__owur int ssl_add_serverhello_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 int ssl_prepare_serverhello_tlsext(SSL *s);
 __owur RAW_EXTENSION *tls_get_extension_by_type(RAW_EXTENSION *exts,
                                                 size_t numexts,
                                                 unsigned int type);
 __owur int tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
                                       SSL_SESSION **ret);
+__owur int tls_use_ticket(SSL *s);
 
 __owur int tls12_get_sigandhash(WPACKET *pkt, const EVP_PKEY *pk,
                                 const EVP_MD *md);
@@ -2116,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_add_serverhello_renegotiate_ext(SSL *s, WPACKET *pkt);
 __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,
index 8bea0746e11156057b367a7eb932263c01e7c920..0b82ad7ea7eff2f1c54f3e4219f061194d1a2b89 100644 (file)
@@ -31,7 +31,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_renegotiate,
         tls_parse_clienthello_renegotiate,
         NULL,
-        NULL,
+        tls_construct_server_renegotiate,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_SSL3_ALLOWED
         | EXT_TLS1_2_AND_BELOW_ONLY
@@ -40,7 +40,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_server_name,
         tls_parse_clienthello_server_name,
         NULL,
-        NULL,
+        tls_construct_server_server_name,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
         | /*EXT_TLS1_3_ENCRYPTED_EXTENSIONS*/EXT_TLS1_3_SERVER_HELLO
@@ -60,7 +60,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_ec_point_formats,
         tls_parse_clienthello_ec_pt_formats,
         NULL,
-        NULL,
+        tls_construct_server_ec_pt_formats,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
@@ -68,7 +68,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_supported_groups,
         tls_parse_clienthello_supported_groups,
         NULL,
-        NULL,
+        NULL /* TODO(TLS1.3): Need to add this */,
         NULL,
         EXT_CLIENT_HELLO
         | /*EXT_TLS1_3_ENCRYPTED_EXTENSIONS*/EXT_TLS1_3_SERVER_HELLO
@@ -78,7 +78,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_session_ticket,
         tls_parse_clienthello_session_ticket,
         NULL,
-        NULL,
+        tls_construct_server_session_ticket,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
@@ -94,7 +94,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_status_request,
         tls_parse_clienthello_status_request,
         NULL,
-        NULL,
+        tls_construct_server_status_request,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
         | /*EXT_TLS1_3_CERTIFICATE*/EXT_TLS1_3_SERVER_HELLO
@@ -104,7 +104,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_next_proto_neg,
         tls_parse_clienthello_npn,
         NULL,
-        NULL,
+        tls_construct_server_next_proto_neg,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
@@ -113,25 +113,27 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_application_layer_protocol_negotiation,
         tls_parse_clienthello_alpn,
         NULL,
-        NULL,
+        tls_construct_server_alpn,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
         | /*EXT_TLS1_3_ENCRYPTED_EXTENSIONS*/EXT_TLS1_3_SERVER_HELLO
     },
+#ifndef OPENSSL_NO_SRTP
     {
         TLSEXT_TYPE_use_srtp,
         tls_parse_clienthello_use_srtp,
         NULL,
-        NULL,
+        tls_construct_server_use_srtp,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
         | EXT_TLS1_3_ENCRYPTED_EXTENSIONS | EXT_DTLS_ONLY
     },
+#endif
     {
         TLSEXT_TYPE_encrypt_then_mac,
         tls_parse_clienthello_etm,
         NULL,
-        NULL,
+        tls_construct_server_etm,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
@@ -153,7 +155,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_extended_master_secret,
         tls_parse_clienthello_ems,
         NULL,
-        NULL,
+        tls_construct_server_ems,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     },
@@ -179,11 +181,23 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_key_share,
         tls_parse_clienthello_key_share,
         NULL,
-        NULL,
+        tls_construct_server_key_share,
         NULL,
         EXT_CLIENT_HELLO | EXT_TLS1_3_SERVER_HELLO
         | EXT_TLS1_3_HELLO_RETRY_REQUEST | EXT_TLS_IMPLEMENTATION_ONLY
         | EXT_TLS1_3_ONLY
+    },
+    {
+        /*
+         * Special unsolicited ServerHello extension only used when
+         * SSL_OP_CRYPTOPRO_TLSEXT_BUG is set
+         */
+        TLSEXT_TYPE_cryptopro_bug,
+        NULL,
+        NULL,
+        tls_construct_server_cryptopro_bug,
+        NULL,
+        EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
     }
 };
 
@@ -440,15 +454,21 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
     size_t loop;
     int addcustom = 0;
 
+    /*
+     * Normally if something goes wrong during construction its an internal
+     * error. We can always override this later.
+     */
+    *al = SSL_AD_INTERNAL_ERROR;
+
     if (!WPACKET_start_sub_packet_u16(pkt)
                /*
                 * If extensions are of zero length then we don't even add the
-                * extensions length bytes to a ClientHello
+                * extensions length bytes to a ClientHello/ServerHello in SSLv3
                 */
-            || ((context & EXT_CLIENT_HELLO) != 0
+            || ((context & (EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO)) != 0
+               && s->version == SSL3_VERSION
                && !WPACKET_set_flags(pkt,
                                      WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH))) {
-        *al = SSL_AD_INTERNAL_ERROR;
         SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, ERR_R_INTERNAL_ERROR);
         return 0;
     }
@@ -504,7 +524,6 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
     }
 
     if (!WPACKET_close(pkt)) {
-        *al = SSL_AD_INTERNAL_ERROR;
         SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, ERR_R_INTERNAL_ERROR);
         return 0;
     }
index 38a6bef8627dd1097840263dba43e5b02a0cd24a..e313e9aa5c35b69a0d13d42cc1e31a1439dc6f83 100644 (file)
@@ -647,3 +647,373 @@ int tls_parse_clienthello_ems(SSL *s, PACKET *pkt, int *al)
 
     return 1;
 }
+
+/*
+ * Process the ALPN extension in a ClientHello.
+ * al: a pointer to the alert value to send in the event of a failure.
+ * returns 1 on success, 0 on error.
+ */
+static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
+{
+    const unsigned char *selected = NULL;
+    unsigned char selected_len = 0;
+
+    if (s->ctx->alpn_select_cb != NULL && s->s3->alpn_proposed != NULL) {
+        int r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
+                                       s->s3->alpn_proposed,
+                                       (unsigned int)s->s3->alpn_proposed_len,
+                                       s->ctx->alpn_select_cb_arg);
+
+        if (r == SSL_TLSEXT_ERR_OK) {
+            OPENSSL_free(s->s3->alpn_selected);
+            s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len);
+            if (s->s3->alpn_selected == NULL) {
+                *al = SSL_AD_INTERNAL_ERROR;
+                return 0;
+            }
+            s->s3->alpn_selected_len = selected_len;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+            /* ALPN takes precedence over NPN. */
+            s->s3->next_proto_neg_seen = 0;
+#endif
+        } else {
+            *al = SSL_AD_NO_APPLICATION_PROTOCOL;
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+/*
+ * Upon success, returns 1.
+ * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
+ */
+int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
+{
+    s->tlsext_status_expected = 0;
+
+    /*
+     * If status request then ask callback what to do. Note: this must be
+     * called after servername callbacks in case the certificate has changed,
+     * and must be called after the cipher has been chosen because this may
+     * influence which certificate is sent
+     */
+    if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
+        int ret;
+        CERT_PKEY *certpkey;
+        certpkey = ssl_get_server_send_pkey(s);
+        /* If no certificate can't return certificate status */
+        if (certpkey != NULL) {
+            /*
+             * Set current certificate to one we will use so SSL_get_certificate
+             * et al can pick it up.
+             */
+            s->cert->key = certpkey;
+            ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+            switch (ret) {
+                /* We don't want to send a status request response */
+            case SSL_TLSEXT_ERR_NOACK:
+                s->tlsext_status_expected = 0;
+                break;
+                /* status request response should be sent */
+            case SSL_TLSEXT_ERR_OK:
+                if (s->tlsext_ocsp_resp)
+                    s->tlsext_status_expected = 1;
+                break;
+                /* something bad happened */
+            case SSL_TLSEXT_ERR_ALERT_FATAL:
+            default:
+                *al = SSL_AD_INTERNAL_ERROR;
+                return 0;
+            }
+        }
+    }
+
+    if (!tls1_alpn_handle_client_hello_late(s, al)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+/* Add the server's renegotiation binding */
+int tls_construct_server_renegotiate(SSL *s, WPACKET *pkt, int *al)
+{
+    if (!s->s3->send_connection_binding)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate)
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_start_sub_packet_u8(pkt)
+            || !WPACKET_memcpy(pkt, s->s3->previous_client_finished,
+                               s->s3->previous_client_finished_len)
+            || !WPACKET_memcpy(pkt, s->s3->previous_server_finished,
+                               s->s3->previous_server_finished_len)
+            || !WPACKET_close(pkt)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_RENEGOTIATE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_server_server_name(SSL *s, WPACKET *pkt, int *al)
+{
+    if (s->hit || s->servername_done != 1
+            || s->session->tlsext_hostname == NULL)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
+            || !WPACKET_put_bytes_u16(pkt, 0)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_SERVER_NAME, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_EC
+int tls_construct_server_ec_pt_formats(SSL *s, WPACKET *pkt, int *al)
+{
+    unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+    unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+    int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
+    using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
+    const unsigned char *plist;
+    size_t plistlen;
+
+    if (!using_ecc)
+        return 1;
+
+    tls1_get_formatlist(s, &plist, &plistlen);
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_sub_memcpy_u8(pkt, plist, plistlen)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+#endif
+
+int tls_construct_server_session_ticket(SSL *s, WPACKET *pkt, int *al)
+{
+    if (!s->tlsext_ticket_expected || !tls_use_ticket(s)) {
+        s->tlsext_ticket_expected = 0;
+        return 1;
+    }
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
+            || !WPACKET_put_bytes_u16(pkt, 0)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al)
+{
+    if (!s->tlsext_status_expected)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
+            || !WPACKET_put_bytes_u16(pkt, 0)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_STATUS_REQUEST, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+int tls_construct_server_next_proto_neg(SSL *s, WPACKET *pkt, int *al)
+{
+    const unsigned char *npa;
+    unsigned int npalen;
+    int ret;
+    int next_proto_neg_seen = s->s3->next_proto_neg_seen;
+
+    s->s3->next_proto_neg_seen = 0;
+    if (!next_proto_neg_seen || s->ctx->next_protos_advertised_cb == NULL)
+        return 1;
+
+    ret = s->ctx->next_protos_advertised_cb(s, &npa, &npalen,
+                                      s->ctx->next_protos_advertised_cb_arg);
+    if (ret == SSL_TLSEXT_ERR_OK) {
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
+                || !WPACKET_sub_memcpy_u16(pkt, npa, npalen)) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_NEXT_PROTO_NEG,
+                   ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+        s->s3->next_proto_neg_seen = 1;
+    }
+
+    return 1;
+}
+#endif
+
+int tls_construct_server_alpn(SSL *s, WPACKET *pkt, int *al)
+{
+    if (s->s3->alpn_selected == NULL)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt,
+                TLSEXT_TYPE_application_layer_protocol_negotiation)
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_sub_memcpy_u8(pkt, s->s3->alpn_selected,
+                                      s->s3->alpn_selected_len)
+            || !WPACKET_close(pkt)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_ALPN, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_SRTP
+int tls_construct_server_use_srtp(SSL *s, WPACKET *pkt, int *al)
+{
+    if (s->srtp_profile == NULL)
+        return 1;
+        
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_put_bytes_u16(pkt, 2)
+            || !WPACKET_put_bytes_u16(pkt, s->srtp_profile->id)
+            || !WPACKET_put_bytes_u8(pkt, 0)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_USE_SRTP, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+#endif
+
+int tls_construct_server_etm(SSL *s, WPACKET *pkt, int *al)
+{
+    if ((s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) == 0)
+        return 1;
+
+    /*
+     * Don't use encrypt_then_mac if AEAD or RC4 might want to disable
+     * for other cases too.
+     */
+    if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD
+        || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4
+        || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT
+        || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12) {
+        s->s3->flags &= ~TLS1_FLAGS_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_SERVER_ETM, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_server_ems(SSL *s, WPACKET *pkt, int *al)
+{
+    if ((s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
+            || !WPACKET_put_bytes_u16(pkt, 0)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_EMS, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_server_key_share(SSL *s, WPACKET *pkt, int *al)
+{
+    unsigned char *encodedPoint;
+    size_t encoded_pt_len = 0;
+    EVP_PKEY *ckey = s->s3->peer_tmp, *skey = NULL;
+
+    if (s->hit)
+        return 1;
+
+    if (ckey == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_put_bytes_u16(pkt, s->s3->group_id)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    skey = ssl_generate_pkey(ckey);
+    if (skey == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    /* Generate encoding of server key */
+    encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint);
+    if (encoded_pt_len == 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_EC_LIB);
+        EVP_PKEY_free(skey);
+        return 0;
+    }
+
+    if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+        EVP_PKEY_free(skey);
+        OPENSSL_free(encodedPoint);
+        return 0;
+    }
+    OPENSSL_free(encodedPoint);
+
+    /* This causes the crypto state to be updated based on the derived keys */
+    s->s3->tmp.pkey = skey;
+    if (ssl_derive(s, skey, ckey, 1) == 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_server_cryptopro_bug(SSL *s, WPACKET *pkt, int *al)
+{
+    const unsigned char cryptopro_ext[36] = {
+        0xfd, 0xe8,         /* 65000 */
+        0x00, 0x20,         /* 32 bytes length */
+        0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
+        0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
+        0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
+        0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
+    };
+
+    if (((s->s3->tmp.new_cipher->id & 0xFFFF) != 0x80
+         && (s->s3->tmp.new_cipher->id & 0xFFFF) != 0x81)
+            || (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG) == 0)
+        return 1;
+
+    if (!WPACKET_memcpy(pkt, cryptopro_ext, sizeof(cryptopro_ext))) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_CRYPTOPRO_BUG, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
index c884eab67673ecd7075d540fe47579f7bd40cbfa..7032ab4eb43a78ba7298348cb0b529b9a81b2e52 100644 (file)
@@ -179,3 +179,22 @@ int tls_parse_clienthello_use_srtp(SSL *s, PACKET *pkt, int *al);
 int tls_parse_clienthello_etm(SSL *s, PACKET *pkt, int *al);
 int tls_parse_clienthello_key_share(SSL *s, PACKET *pkt, int *al);
 int tls_parse_clienthello_ems(SSL *s, PACKET *pkt, 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);
+int tls_construct_server_session_ticket(SSL *s, WPACKET *pkt, int *al);
+int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al);
+int tls_construct_server_next_proto_neg(SSL *s, WPACKET *pkt, int *al);
+int tls_construct_server_alpn(SSL *s, WPACKET *pkt, int *al);
+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);
index 773e7326427a021cee682875ea1f7487fc277bef..cc4b8c3153f9b0cb6631b153367d664311561dd6 100644 (file)
@@ -1980,15 +1980,20 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt)
             || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, &len)
             || (!SSL_IS_TLS13(s)
                 && !WPACKET_put_bytes_u8(pkt, compm))
-            || !ssl_prepare_serverhello_tlsext(s)
-            || !ssl_add_serverhello_tlsext(s, pkt, &al)) {
+               /*
+                * TODO(TLS1.3): For now we add all 1.2 and 1.3 extensions. Later
+                * we will do this based on the actual protocol
+                */
+            || !tls_construct_extensions(s, pkt,
+                                         EXT_TLS1_2_SERVER_HELLO
+                                         | EXT_TLS1_3_SERVER_HELLO, &al)) {
         SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
         goto err;
     }
 
     return 1;
  err:
-    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
     return 0;
 }
 
index 1cc481cc4966433ac940fd6bcedc46c5aa51cd0e..e8019c0471c6215f3bf34a2fe66be3918799760e 100644 (file)
@@ -596,8 +596,8 @@ static int tls1_check_ec_key(SSL *s,
     return 1;
 }
 
-static void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
-                                size_t *num_formats)
+void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
+                         size_t *num_formats)
 {
     /*
      * If we have a custom point format list use it otherwise use default
@@ -939,7 +939,7 @@ int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op)
     return !ssl_security(s, op, c->strength_bits, 0, (void *)c);
 }
 
-static int tls_use_ticket(SSL *s)
+int tls_use_ticket(SSL *s)
 {
     if ((s->options & SSL_OP_NO_TICKET) || SSL_IS_TLS13(s))
         return 0;
@@ -1512,289 +1512,6 @@ int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al)
     return 1;
 }
 
-/*
- * Add the key_share extension.
- *
- * Returns 1 on success or 0 on failure.
- */
-static int add_client_key_share_ext(SSL *s, WPACKET *pkt, int *al)
-{
-    unsigned char *encodedPoint;
-    size_t encoded_pt_len = 0;
-    EVP_PKEY *ckey = s->s3->peer_tmp, *skey = NULL;
-
-    if (ckey == NULL) {
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
-            || !WPACKET_start_sub_packet_u16(pkt)
-            || !WPACKET_put_bytes_u16(pkt, s->s3->group_id)) {
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    skey = ssl_generate_pkey(ckey);
-    if (skey == NULL) {
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
-    /* Generate encoding of server key */
-    encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint);
-    if (encoded_pt_len == 0) {
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_EC_LIB);
-        EVP_PKEY_free(skey);
-        return 0;
-    }
-
-    if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len)
-            || !WPACKET_close(pkt)) {
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_INTERNAL_ERROR);
-        EVP_PKEY_free(skey);
-        OPENSSL_free(encodedPoint);
-        return 0;
-    }
-    OPENSSL_free(encodedPoint);
-
-    /* This causes the crypto state to be updated based on the derived keys */
-    s->s3->tmp.pkey = skey;
-    if (ssl_derive(s, skey, ckey, 1) == 0) {
-        *al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    return 1;
-}
-
-int ssl_add_serverhello_tlsext(SSL *s, WPACKET *pkt, int *al)
-{
-#ifndef OPENSSL_NO_NEXTPROTONEG
-    int next_proto_neg_seen;
-#endif
-#ifndef OPENSSL_NO_EC
-    unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
-    unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-    int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
-    using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
-#endif
-
-    if (!WPACKET_start_sub_packet_u16(pkt)
-            || !WPACKET_set_flags(pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)) {
-        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    if (s->s3->send_connection_binding &&
-            !ssl_add_serverhello_renegotiate_ext(s, pkt)) {
-        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    /* Only add RI for SSLv3 */
-    if (s->version == SSL3_VERSION)
-        goto done;
-
-    if (!s->hit && s->servername_done == 1
-            && s->session->tlsext_hostname != NULL) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#ifndef OPENSSL_NO_EC
-    if (using_ecc) {
-        const unsigned char *plist;
-        size_t plistlen;
-        /*
-         * Add TLS extension ECPointFormats to the ServerHello message
-         */
-        tls1_get_formatlist(s, &plist, &plistlen);
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_sub_memcpy_u8(pkt, plist, plistlen)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-    /*
-     * Currently the server should not respond with a SupportedCurves
-     * extension
-     */
-#endif                          /* OPENSSL_NO_EC */
-
-    if (s->tlsext_ticket_expected && tls_use_ticket(s)) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    } else {
-        /*
-         * if we don't add the above TLSEXT, we can't add a session ticket
-         * later
-         */
-        s->tlsext_ticket_expected = 0;
-    }
-
-    if (s->tlsext_status_expected) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#ifndef OPENSSL_NO_SRTP
-    if (SSL_IS_DTLS(s) && s->srtp_profile) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_put_bytes_u16(pkt, 2)
-                || !WPACKET_put_bytes_u16(pkt, s->srtp_profile->id)
-                || !WPACKET_put_bytes_u8(pkt, 0)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
-
-    if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80
-         || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81)
-        && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) {
-        const unsigned char cryptopro_ext[36] = {
-            0xfd, 0xe8,         /* 65000 */
-            0x00, 0x20,         /* 32 bytes length */
-            0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
-            0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
-            0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
-            0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
-        };
-        if (!WPACKET_memcpy(pkt, cryptopro_ext, sizeof(cryptopro_ext))) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-
-#ifndef OPENSSL_NO_NEXTPROTONEG
-    next_proto_neg_seen = s->s3->next_proto_neg_seen;
-    s->s3->next_proto_neg_seen = 0;
-    if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
-        const unsigned char *npa;
-        unsigned int npalen;
-        int r;
-
-        r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen,
-                                              s->
-                                              ctx->next_protos_advertised_cb_arg);
-        if (r == SSL_TLSEXT_ERR_OK) {
-            if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
-                    || !WPACKET_sub_memcpy_u16(pkt, npa, npalen)) {
-                SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-            s->s3->next_proto_neg_seen = 1;
-        }
-    }
-#endif
-
-    if (SSL_IS_TLS13(s) && !s->hit && !add_client_key_share_ext(s, pkt, al))
-        return 0;
-
-    if (!custom_ext_add(s, 1, pkt, al)) {
-        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) {
-        /*
-         * Don't use encrypt_then_mac if AEAD or RC4 might want to disable
-         * for other cases too.
-         */
-        if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD
-            || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4
-            || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT
-            || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12)
-            s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
-        else {
-            if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
-                    || !WPACKET_put_bytes_u16(pkt, 0)) {
-                SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-        }
-    }
-    if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-
-    if (s->s3->alpn_selected != NULL) {
-        if (!WPACKET_put_bytes_u16(pkt,
-                    TLSEXT_TYPE_application_layer_protocol_negotiation)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_sub_memcpy_u8(pkt, s->s3->alpn_selected,
-                                          s->s3->alpn_selected_len)
-                || !WPACKET_close(pkt)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-
- done:
-    if (!WPACKET_close(pkt)) {
-        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-    return 1;
-}
-
-/*
- * Process the ALPN extension in a ClientHello.
- * al: a pointer to the alert value to send in the event of a failure.
- * returns 1 on success, 0 on error.
- */
-static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
-{
-    const unsigned char *selected = NULL;
-    unsigned char selected_len = 0;
-
-    if (s->ctx->alpn_select_cb != NULL && s->s3->alpn_proposed != NULL) {
-        int r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
-                                       s->s3->alpn_proposed,
-                                       (unsigned int)s->s3->alpn_proposed_len,
-                                       s->ctx->alpn_select_cb_arg);
-
-        if (r == SSL_TLSEXT_ERR_OK) {
-            OPENSSL_free(s->s3->alpn_selected);
-            s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len);
-            if (s->s3->alpn_selected == NULL) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            s->s3->alpn_selected_len = selected_len;
-#ifndef OPENSSL_NO_NEXTPROTONEG
-            /* ALPN takes precedence over NPN. */
-            s->s3->next_proto_neg_seen = 0;
-#endif
-        } else {
-            *al = SSL_AD_NO_APPLICATION_PROTOCOL;
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
 #ifndef OPENSSL_NO_NEXTPROTONEG
 /*
  * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
@@ -2161,11 +1878,6 @@ int ssl_prepare_clienthello_tlsext(SSL *s)
     return 1;
 }
 
-int ssl_prepare_serverhello_tlsext(SSL *s)
-{
-    return 1;
-}
-
 /* Initialise digests to default values */
 void ssl_set_default_md(SSL *s)
 {
@@ -2228,58 +1940,6 @@ int tls1_set_server_sigalgs(SSL *s)
     return 0;
 }
 
-/*
- * Upon success, returns 1.
- * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
- */
-int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
-{
-    s->tlsext_status_expected = 0;
-
-    /*
-     * If status request then ask callback what to do. Note: this must be
-     * called after servername callbacks in case the certificate has changed,
-     * and must be called after the cipher has been chosen because this may
-     * influence which certificate is sent
-     */
-    if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
-        int ret;
-        CERT_PKEY *certpkey;
-        certpkey = ssl_get_server_send_pkey(s);
-        /* If no certificate can't return certificate status */
-        if (certpkey != NULL) {
-            /*
-             * Set current certificate to one we will use so SSL_get_certificate
-             * et al can pick it up.
-             */
-            s->cert->key = certpkey;
-            ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
-            switch (ret) {
-                /* We don't want to send a status request response */
-            case SSL_TLSEXT_ERR_NOACK:
-                s->tlsext_status_expected = 0;
-                break;
-                /* status request response should be sent */
-            case SSL_TLSEXT_ERR_OK:
-                if (s->tlsext_ocsp_resp)
-                    s->tlsext_status_expected = 1;
-                break;
-                /* something bad happened */
-            case SSL_TLSEXT_ERR_ALERT_FATAL:
-            default:
-                *al = SSL_AD_INTERNAL_ERROR;
-                return 0;
-            }
-        }
-    }
-
-    if (!tls1_alpn_handle_client_hello_late(s, al)) {
-        return 0;
-    }
-
-    return 1;
-}
-
 int ssl_check_serverhello_tlsext(SSL *s)
 {
     int ret = SSL_TLSEXT_ERR_NOACK;
index 5e9c71eecc592b71f19937689cd7cc9dfffadf8c..4301a38be5b0b85ce6dc2bc4561f42492445100d 100644 (file)
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-/* Add the server's renegotiation binding */
-int ssl_add_serverhello_renegotiate_ext(SSL *s, WPACKET *pkt)
-{
-    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate)
-            || !WPACKET_start_sub_packet_u16(pkt)
-            || !WPACKET_start_sub_packet_u8(pkt)
-            || !WPACKET_memcpy(pkt, s->s3->previous_client_finished,
-                               s->s3->previous_client_finished_len)
-            || !WPACKET_memcpy(pkt, s->s3->previous_server_finished,
-                               s->s3->previous_server_finished_len)
-            || !WPACKET_close(pkt)
-            || !WPACKET_close(pkt))
-        return 0;
-
-    return 1;
-}
-
 /*
  * Parse the server's renegotiation binding and abort if it's not right
  */