Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / boringssl / src / ssl / t1_lib.c
index 8e77ef2..eccf875 100644 (file)
 static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
                                const unsigned char *sess_id, int sesslen,
                                SSL_SESSION **psess);
-static int ssl_check_clienthello_tlsext_early(SSL *s);
-int ssl_check_serverhello_tlsext(SSL *s);
+static int ssl_check_clienthello_tlsext(SSL *s);
+static int ssl_check_serverhello_tlsext(SSL *s);
 
 SSL3_ENC_METHOD TLSv1_enc_data={
        tls1_enc,
@@ -182,35 +182,6 @@ SSL3_ENC_METHOD TLSv1_2_enc_data={
        ssl3_handshake_write
        };
 
-long tls1_default_timeout(void)
-       {
-       /* 2 hours, the 24 hours mentioned in the TLSv1 spec
-        * is way too long for http, the cache would over fill */
-       return(60*60*2);
-       }
-
-int tls1_new(SSL *s)
-       {
-       if (!ssl3_new(s)) return(0);
-       s->method->ssl_clear(s);
-       return(1);
-       }
-
-void tls1_free(SSL *s)
-       {
-       if (s->tlsext_session_ticket)
-               {
-               OPENSSL_free(s->tlsext_session_ticket);
-               }
-       ssl3_free(s);
-       }
-
-void tls1_clear(SSL *s)
-       {
-       ssl3_clear(s);
-       s->version = s->method->version;
-       }
-
 static int compare_uint16_t(const void *p1, const void *p2)
        {
        uint16_t u1 = *((const uint16_t*)p1);
@@ -320,7 +291,7 @@ char ssl_early_callback_init(struct ssl_early_callback_ctx *ctx)
        ctx->session_id_len = CBS_len(&session_id);
 
        /* Skip past DTLS cookie */
-       if (ctx->ssl->version == DTLS1_VERSION || ctx->ssl->version == DTLS1_BAD_VER)
+       if (SSL_IS_DTLS(ctx->ssl))
                {
                CBS cookie;
 
@@ -394,9 +365,8 @@ SSL_early_callback_ctx_extension_get(const struct ssl_early_callback_ctx *ctx,
        return 0;
        }
 
-#ifndef OPENSSL_NO_EC
 
-static int nid_list[] =
+static const int nid_list[] =
        {
                NID_sect163k1, /* sect163k1 (1) */
                NID_sect163r1, /* sect163r1 (2) */
@@ -440,12 +410,6 @@ static const uint16_t eccurves_default[] =
                25, /* secp521r1 (25) */
        };
 
-static const uint16_t suiteb_curves[] =
-       {
-               TLSEXT_curve_P_256,
-               TLSEXT_curve_P_384,
-       };
-
 int tls1_ec_curve_id2nid(uint16_t curve_id)
        {
        /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
@@ -480,27 +444,9 @@ static void tls1_get_curvelist(SSL *s, int get_client_curves,
                *out_curve_ids_len = s->session->tlsext_ellipticcurvelist_length;
                return;
                }
-       /* For Suite B mode only include P-256, P-384 */
-       switch (tls1_suiteb(s))
-               {
-       case SSL_CERT_FLAG_SUITEB_128_LOS:
-               *out_curve_ids = suiteb_curves;
-               *out_curve_ids_len = sizeof(suiteb_curves) / sizeof(suiteb_curves[0]);
-               break;
-
-       case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
-               *out_curve_ids = suiteb_curves;
-               *out_curve_ids_len = 1;
-               break;
 
-       case SSL_CERT_FLAG_SUITEB_192_LOS:
-               *out_curve_ids = suiteb_curves + 1;
-               *out_curve_ids_len = 1;
-               break;
-       default:
-               *out_curve_ids = s->tlsext_ellipticcurvelist;
-               *out_curve_ids_len = s->tlsext_ellipticcurvelist_length;
-               }
+       *out_curve_ids = s->tlsext_ellipticcurvelist;
+       *out_curve_ids_len = s->tlsext_ellipticcurvelist_length;
        if (!*out_curve_ids)
                {
                *out_curve_ids = eccurves_default;
@@ -521,23 +467,6 @@ int tls1_check_curve(SSL *s, CBS *cbs, uint16_t *out_curve_id)
                !CBS_get_u16(cbs, &curve_id))
                return 0;
 
-       /* Check curve matches Suite B preferences */
-       if (tls1_suiteb(s))
-               {
-               unsigned long cid = s->s3->tmp.new_cipher->id;
-               if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
-                       {
-                       if (curve_id != TLSEXT_curve_P_256)
-                               return 0;
-                       }
-               else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
-                       {
-                       if (curve_id != TLSEXT_curve_P_384)
-                               return 0;
-                       }
-               else    /* Should never happen */
-                       return 0;
-               }
        tls1_get_curvelist(s, 0, &curves, &curves_len);
        for (i = 0; i < curves_len; i++)
                {
@@ -559,22 +488,7 @@ int tls1_get_shared_curve(SSL *s)
        if (s->server == 0)
                return NID_undef;
 
-       if (tls1_suiteb(s))
-               {
-               /* For Suite B ciphersuite determines curve: we
-                * already know these are acceptable due to previous
-                * checks.
-                */
-               unsigned long cid = s->s3->tmp.new_cipher->id;
-               if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
-                       return NID_X9_62_prime256v1; /* P-256 */
-               if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
-                       return NID_secp384r1; /* P-384 */
-               /* Should never happen */
-               return NID_undef;
-               }
-
-       /* If not Suite B just return first preference shared curve */
+       /* Return first preference shared curve */
        tls1_get_curvelist(s, !!(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE),
                                &supp, &supplen);
        tls1_get_curvelist(s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE),
@@ -726,11 +640,7 @@ static void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
        else
                {
                *pformats = ecformats_default;
-               /* For Suite B we don't support char2 fields */
-               if (tls1_suiteb(s))
-                       *pformatslen = sizeof(ecformats_default) - 1;
-               else
-                       *pformatslen = sizeof(ecformats_default);
+               *pformatslen = sizeof(ecformats_default);
                }
        }
 
@@ -759,38 +669,7 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
        /* Can't check curve_id for client certs as we don't have a
         * supported curves extension.
         */
-       rv = tls1_check_ec_key(s, s->server ? &curve_id : NULL, &comp_id);
-       if (!rv)
-               return 0;
-       /* Special case for suite B. We *MUST* sign using SHA256+P-256 or
-        * SHA384+P-384, adjust digest if necessary.
-        */
-       if (set_ee_md && tls1_suiteb(s))
-               {
-               int check_md;
-               size_t i;
-               CERT *c = s->cert;
-               /* Check to see we have necessary signing algorithm */
-               if (curve_id == TLSEXT_curve_P_256)
-                       check_md = NID_ecdsa_with_SHA256;
-               else if (curve_id == TLSEXT_curve_P_384)
-                       check_md = NID_ecdsa_with_SHA384;
-               else
-                       return 0; /* Should never happen */
-               for (i = 0; i < c->shared_sigalgslen; i++)
-                       if (check_md == c->shared_sigalgs[i].signandhash_nid)
-                               break;
-               if (i == c->shared_sigalgslen)
-                       return 0;
-               if (set_ee_md == 2)
-                       {
-                       if (check_md == NID_ecdsa_with_SHA256)
-                               c->pkeys[SSL_PKEY_ECC].digest = EVP_sha256();
-                       else
-                               c->pkeys[SSL_PKEY_ECC].digest = EVP_sha384();
-                       }
-               }
-       return rv;
+       return tls1_check_ec_key(s, s->server ? &curve_id : NULL, &comp_id);
        }
 /* Check EC temporary key is compatible with client extensions */
 int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
@@ -802,38 +681,6 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
        if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL)
                return 1;
 #endif
-       /* If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384,
-        * no other curves permitted.
-        */
-       if (tls1_suiteb(s))
-               {
-               /* Curve to check determined by ciphersuite */
-               if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
-                       curve_id = TLSEXT_curve_P_256;
-               else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
-                       curve_id = TLSEXT_curve_P_384;
-               else
-                       return 0;
-               /* Check this curve is acceptable */
-               if (!tls1_check_ec_key(s, &curve_id, NULL))
-                       return 0;
-               /* If auto or setting curve from callback assume OK */
-               if (s->cert->ecdh_tmp_auto || s->cert->ecdh_tmp_cb)
-                       return 1;
-               /* Otherwise check curve is acceptable */
-               else 
-                       {
-                       uint16_t curve_tmp;
-                       if (!ec)
-                               return 0;
-                       if (!tls1_curve_params_from_ec_key(&curve_tmp, NULL, ec))
-                               return 0;
-                       if (curve_tmp == curve_id)
-                               return 1;
-                       return 0;
-                       }
-                       
-               }
        if (s->cert->ecdh_tmp_auto)
                {
                /* Need a shared curve */
@@ -856,14 +703,6 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
 #endif
        }
 
-#else
-
-static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
-       {
-       return 1;
-       }
-
-#endif /* OPENSSL_NO_EC */
 
 
 /* List of supported signature algorithms and hashes. Should make this
@@ -872,59 +711,21 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
 
 #define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
 
-#ifdef OPENSSL_NO_DSA
-#define tlsext_sigalg_dsa(md) /* */
-#else
-#define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
-#endif
-
-#ifdef OPENSSL_NO_ECDSA
-#define tlsext_sigalg_ecdsa(md) /* */
-#else
 #define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
-#endif
 
 #define tlsext_sigalg(md) \
                tlsext_sigalg_rsa(md) \
-               tlsext_sigalg_dsa(md) \
                tlsext_sigalg_ecdsa(md)
 
-static unsigned char tls12_sigalgs[] = {
+static const uint8_t tls12_sigalgs[] = {
        tlsext_sigalg(TLSEXT_hash_sha512)
        tlsext_sigalg(TLSEXT_hash_sha384)
        tlsext_sigalg(TLSEXT_hash_sha256)
        tlsext_sigalg(TLSEXT_hash_sha224)
-#ifndef OPENSSL_NO_SHA
        tlsext_sigalg(TLSEXT_hash_sha1)
-#endif
-};
-#ifndef OPENSSL_NO_ECDSA
-static unsigned char suiteb_sigalgs[] = {
-       tlsext_sigalg_ecdsa(TLSEXT_hash_sha256)
-       tlsext_sigalg_ecdsa(TLSEXT_hash_sha384)
 };
-#endif
 size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs)
        {
-       /* If Suite B mode use Suite B sigalgs only, ignore any other
-        * preferences.
-        */
-#ifndef OPENSSL_NO_EC
-       switch (tls1_suiteb(s))
-               {
-       case SSL_CERT_FLAG_SUITEB_128_LOS:
-               *psigs = suiteb_sigalgs;
-               return sizeof(suiteb_sigalgs);
-
-       case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
-               *psigs = suiteb_sigalgs;
-               return 2;
-
-       case SSL_CERT_FLAG_SUITEB_192_LOS:
-               *psigs = suiteb_sigalgs + 2;
-               return 2;
-               }
-#endif
        /* If server use client authentication sigalgs if not NULL */
        if (s->server && s->cert->client_sigalgs)
                {
@@ -977,7 +778,6 @@ int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert,
                *out_alert = SSL_AD_ILLEGAL_PARAMETER;
                return 0;
                }
-#ifndef OPENSSL_NO_EC
        if (pkey->type == EVP_PKEY_EC)
                {
                uint16_t curve_id;
@@ -994,40 +794,7 @@ int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert,
                        *out_alert = SSL_AD_ILLEGAL_PARAMETER;
                        return 0;
                        }
-               /* If Suite B only P-384+SHA384 or P-256+SHA-256 allowed */
-               if (tls1_suiteb(s))
-                       {
-                       if (curve_id == TLSEXT_curve_P_256)
-                               {
-                               if (hash != TLSEXT_hash_sha256)
-                                       {
-                                       OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_ILLEGAL_SUITEB_DIGEST);
-                                       *out_alert = SSL_AD_ILLEGAL_PARAMETER;
-                                       return 0;
-                                       }
-                               }
-                       else if (curve_id == TLSEXT_curve_P_384)
-                               {
-                               if (hash != TLSEXT_hash_sha384)
-                                       {
-                                       OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_ILLEGAL_SUITEB_DIGEST);
-                                       *out_alert = SSL_AD_ILLEGAL_PARAMETER;
-                                       return 0;
-                                       }
-                               }
-                       else
-                               {
-                               *out_alert = SSL_AD_ILLEGAL_PARAMETER;
-                               return 0;
-                               }
-                       }
-               }
-       else if (tls1_suiteb(s))
-               {
-               *out_alert = SSL_AD_ILLEGAL_PARAMETER;
-               return 0;
                }
-#endif
 
        /* Check signature matches a type we sent */
        sent_sigslen = tls12_get_psigalgs(s, &sent_sigs);
@@ -1068,7 +835,7 @@ void ssl_set_client_disabled(SSL *s)
        CERT *c = s->cert;
        const unsigned char *sigalgs;
        size_t i, sigalgslen;
-       int have_rsa = 0, have_dsa = 0, have_ecdsa = 0;
+       int have_rsa = 0, have_ecdsa = 0;
        c->mask_a = 0;
        c->mask_k = 0;
        /* Don't allow TLS 1.2 only ciphers if we don't suppport them */
@@ -1088,35 +855,21 @@ void ssl_set_client_disabled(SSL *s)
                case TLSEXT_signature_rsa:
                        have_rsa = 1;
                        break;
-#ifndef OPENSSL_NO_DSA
-               case TLSEXT_signature_dsa:
-                       have_dsa = 1;
-                       break;
-#endif
-#ifndef OPENSSL_NO_ECDSA
                case TLSEXT_signature_ecdsa:
                        have_ecdsa = 1;
                        break;
-#endif
                        }
                }
-       /* Disable auth and static DH if we don't include any appropriate
-        * signature algorithms.
+       /* Disable auth if we don't include any appropriate signature
+        * algorithms.
         */
        if (!have_rsa)
                {
                c->mask_a |= SSL_aRSA;
-               c->mask_k |= SSL_kDHr|SSL_kECDHr;
-               }
-       if (!have_dsa)
-               {
-               c->mask_a |= SSL_aDSS;
-               c->mask_k |= SSL_kDHd;
                }
        if (!have_ecdsa)
                {
                c->mask_a |= SSL_aECDSA;
-               c->mask_k |= SSL_kECDHe;
                }
        /* with PSK there must be client callback set */
        if (!s->psk_client_callback)
@@ -1135,7 +888,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
        int extdatalen=0;
        unsigned char *ret = buf;
        unsigned char *orig = buf;
-#ifndef OPENSSL_NO_EC
        /* See if we support any ECC ciphersuites */
        int using_ecc = 0;
        if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s))
@@ -1146,19 +898,17 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
 
                for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++)
                        {
-                       SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
+                       const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
 
                        alg_k = c->algorithm_mkey;
                        alg_a = c->algorithm_auth;
-                       if ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)
-                               || (alg_a & SSL_aECDSA)))
+                       if ((alg_k & SSL_kEECDH) || (alg_a & SSL_aECDSA))
                                {
                                using_ecc = 1;
                                break;
                                }
                        }
                }
-#endif
 
        /* don't add extensions for SSLv3 unless doing secure renegotiation */
        if (s->client_version == SSL3_VERSION
@@ -1275,58 +1025,24 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
                ret += salglen;
                }
 
-        /* TODO(fork): we probably want OCSP stapling, but it currently pulls in a lot of code. */
-#if 0
-       if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
+       if (s->ocsp_stapling_enabled)
                {
-               int i;
-               long extlen, idlen, itmp;
-               OCSP_RESPID *id;
+               /* The status_request extension is excessively extensible at
+                * every layer. On the client, only support requesting OCSP
+                * responses with an empty responder_id_list and no
+                * extensions. */
+               if (limit - ret - 4 - 1 - 2 - 2 < 0) return NULL;
 
-               idlen = 0;
-               for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
-                       {
-                       id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
-                       itmp = i2d_OCSP_RESPID(id, NULL);
-                       if (itmp <= 0)
-                               return NULL;
-                       idlen += itmp + 2;
-                       }
-
-               if (s->tlsext_ocsp_exts)
-                       {
-                       extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
-                       if (extlen < 0)
-                               return NULL;
-                       }
-               else
-                       extlen = 0;
-                       
-               if ((long)(limit - ret - 7 - extlen - idlen) < 0) return NULL;
                s2n(TLSEXT_TYPE_status_request, ret);
-               if (extlen + idlen > 0xFFF0)
-                       return NULL;
-               s2n(extlen + idlen + 5, ret);
+               s2n(1 + 2 + 2, ret);
+               /* status_type */
                *(ret++) = TLSEXT_STATUSTYPE_ocsp;
-               s2n(idlen, ret);
-               for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
-                       {
-                       /* save position of id len */
-                       unsigned char *q = ret;
-                       id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
-                       /* skip over id len */
-                       ret += 2;
-                       itmp = i2d_OCSP_RESPID(id, &ret);
-                       /* write id len */
-                       s2n(itmp, q);
-                       }
-               s2n(extlen, ret);
-               if (extlen > 0)
-                       i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
+               /* responder_id_list - empty */
+               s2n(0, ret);
+               /* request_extensions - empty */
+               s2n(0, ret);
                }
-#endif
 
-#ifndef OPENSSL_NO_NEXTPROTONEG
        if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len)
                {
                /* The client advertises an emtpy extension to indicate its
@@ -1336,7 +1052,16 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
                s2n(TLSEXT_TYPE_next_proto_neg,ret);
                s2n(0,ret);
                }
-#endif
+
+       if (s->signed_cert_timestamps_enabled && !s->s3->tmp.finish_md_len)
+               {
+               /* The client advertises an empty extension to indicate its support for
+                * certificate timestamps. */
+               if (limit - ret - 4 < 0)
+                       return NULL;
+               s2n(TLSEXT_TYPE_certificate_timestamp,ret);
+               s2n(0,ret);
+               }
 
        if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len)
                {
@@ -1374,7 +1099,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
                 s2n(TLSEXT_TYPE_use_srtp,ret);
                 s2n(el,ret);
 
-                if(ssl_add_clienthello_use_srtp_ext(s, ret, &el, el))
+                if(!ssl_add_clienthello_use_srtp_ext(s, ret, &el, el))
                        {
                        OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
                        return NULL;
@@ -1382,7 +1107,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
                 ret += el;
                 }
 
-#ifndef OPENSSL_NO_EC
        if (using_ecc)
                {
                /* Add TLS extension ECPointFormats to the ClientHello message */
@@ -1432,7 +1156,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
                        s2n(curves[i], ret);
                        }
                }
-#endif /* OPENSSL_NO_EC */
 
 #ifdef TLSEXT_TYPE_padding
        /* Add padding to workaround bugs in F5 terminators.
@@ -1477,15 +1200,11 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
        int extdatalen=0;
        unsigned char *orig = buf;
        unsigned char *ret = buf;
-#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_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA);
+       int using_ecc = (alg_k & SSL_kEECDH) || (alg_a & SSL_aECDSA);
        using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
-#endif
        /* don't add extensions for SSLv3, unless doing secure renegotiation */
        if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
                return orig;
@@ -1493,7 +1212,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
        ret+=2;
        if (ret>=limit) return NULL; /* this really never occurs, but ... */
 
-       if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
+       if (!s->hit && s->should_ack_sni && s->session->tlsext_hostname != NULL)
                { 
                if ((long)(limit - ret - 4) < 0) return NULL; 
 
@@ -1525,7 +1244,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
           ret += el;
         }
 
-#ifndef OPENSSL_NO_EC
        if (using_ecc)
                {
                const unsigned char *plist;
@@ -1551,7 +1269,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
 
                }
        /* Currently the server should not respond with a SupportedCurves extension */
-#endif /* OPENSSL_NO_EC */
 
        if (s->tlsext_ticket_expected
                && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) 
@@ -1561,7 +1278,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
                s2n(0,ret);
                }
 
-       if (s->tlsext_status_expected)
+       if (s->s3->tmp.certificate_status_expected)
                { 
                if ((long)(limit - ret - 4) < 0) return NULL; 
                s2n(TLSEXT_TYPE_status_request,ret);
@@ -1579,7 +1296,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
                 s2n(TLSEXT_TYPE_use_srtp,ret);
                 s2n(el,ret);
 
-                if(ssl_add_serverhello_use_srtp_ext(s, ret, &el, el))
+                if(!ssl_add_serverhello_use_srtp_ext(s, ret, &el, el))
                        {
                        OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
                        return NULL;
@@ -1587,7 +1304,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
                 ret+=el;
                 }
 
-#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)
@@ -1607,7 +1323,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
                        s->s3->next_proto_neg_seen = 1;
                        }
                }
-#endif
 
        if (s->s3->alpn_selected)
                {
@@ -1653,7 +1368,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
  *   returns: 1 on success. */
 static int tls1_alpn_handle_client_hello(SSL *s, CBS *cbs, int *out_alert)
        {
-       CBS protocol_name_list;
+       CBS protocol_name_list, protocol_name_list_copy;
        const unsigned char *selected;
        unsigned char selected_len;
        int r;
@@ -1667,7 +1382,7 @@ static int tls1_alpn_handle_client_hello(SSL *s, CBS *cbs, int *out_alert)
                goto parse_error;
 
        /* Validate the protocol list. */
-       CBS protocol_name_list_copy = protocol_name_list;
+       protocol_name_list_copy = protocol_name_list;
        while (CBS_len(&protocol_name_list_copy) > 0)
                {
                CBS protocol_name;
@@ -1703,11 +1418,9 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert)
        CBS extensions;
        size_t i;
 
-       s->servername_done = 0;
-       s->tlsext_status_type = -1;
-#ifndef OPENSSL_NO_NEXTPROTONEG
+       s->should_ack_sni = 0;
        s->s3->next_proto_neg_seen = 0;
-#endif
+       s->s3->tmp.certificate_status_expected = 0;
 
        if (s->s3->alpn_selected)
                {
@@ -1734,23 +1447,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                s->cert->pkeys[i].valid_flags = 0;
                }
 
-       /* TODO(fork): we probably want OCSP stapling support, but this pulls in
-        * a lot of code. */
-#if 0
-       /* Clear OCSP state. */
-       s->tlsext_status_type = -1;
-       if (s->tlsext_ocsp_ids)
-               {
-               sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
-               s->tlsext_ocsp_ids = NULL;
-               }
-       if (s->tlsext_ocsp_exts)
-               {
-               sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free);
-               s->tlsext_ocsp_exts = NULL;
-               }
-#endif
-
        /* There may be no extensions. */
        if (CBS_len(cbs) == 0)
                {
@@ -1810,6 +1506,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                if (type == TLSEXT_TYPE_server_name)
                        {
                        CBS server_name_list;
+                       char have_seen_host_name = 0;
 
                        if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
                                CBS_len(&server_name_list) < 1 ||
@@ -1836,50 +1533,53 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                                if (name_type != TLSEXT_NAMETYPE_host_name)
                                        continue;
 
+                               if (have_seen_host_name)
+                                       {
+                                       /* The ServerNameList MUST NOT contain
+                                        * more than one name of the same
+                                        * name_type. */
+                                       *out_alert = SSL_AD_DECODE_ERROR;
+                                       return 0;
+                                       }
+
+                               have_seen_host_name = 1;
+
+                               if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
+                                       CBS_len(&host_name) < 1)
+                                       {
+                                       *out_alert = SSL_AD_DECODE_ERROR;
+                                       return 0;
+                                       }
+
+                               if (CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
+                                       CBS_contains_zero_byte(&host_name))
+                                       {
+                                       *out_alert = SSL_AD_UNRECOGNIZED_NAME;
+                                       return 0;
+                                       }
+
                                if (!s->hit)
                                        {
+                                       assert(s->session->tlsext_hostname == NULL);
                                        if (s->session->tlsext_hostname)
                                                {
-                                               /* The ServerNameList MUST NOT
-                                                  contain more than one name of
-                                                  the same name_type. */
+                                               /* This should be impossible. */
                                                *out_alert = SSL_AD_DECODE_ERROR;
                                                return 0;
                                                }
 
-                                       if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
-                                               CBS_len(&host_name) < 1)
-                                               {
-                                               *out_alert = SSL_AD_DECODE_ERROR;
-                                               return 0;
-                                               }
-
-                                       if (CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
-                                               CBS_contains_zero_byte(&host_name))
-                                               {
-                                               *out_alert = SSL_AD_UNRECOGNIZED_NAME;
-                                               return 0;
-                                               }
-
                                        /* Copy the hostname as a string. */
                                        if (!CBS_strdup(&host_name, &s->session->tlsext_hostname))
                                                {
                                                *out_alert = SSL_AD_INTERNAL_ERROR;
                                                return 0;
                                                }
-                                       s->servername_done = 1;
-                                       }
-                               else
-                                       {
-                                       s->servername_done = s->session->tlsext_hostname
-                                               && strlen(s->session->tlsext_hostname) == CBS_len(&host_name)
-                                               && strncmp(s->session->tlsext_hostname,
-                                                       (char *)CBS_data(&host_name), CBS_len(&host_name)) == 0;
+
+                                       s->should_ack_sni = 1;
                                        }
                                }
                        }
 
-#ifndef OPENSSL_NO_EC
                else if (type == TLSEXT_TYPE_ec_point_formats)
                        {
                        CBS ec_point_format_list;
@@ -1948,7 +1648,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                                s->session->tlsext_ellipticcurvelist_length = num_curves;
                                }
                        }
-#endif /* OPENSSL_NO_EC */
                else if (type == TLSEXT_TYPE_session_ticket)
                        {
                        if (s->tls_session_ticket_ext_cb &&
@@ -2001,120 +1700,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                                }
                        }
 
-                /* TODO(fork): we probably want OCSP stapling support, but this pulls in a lot of code. */
-#if 0
-               else if (type == TLSEXT_TYPE_status_request)
-                       {
-                       uint8_t status_type;
-                       CBS responder_id_list;
-                       CBS request_extensions;
-
-                       if (!CBS_get_u8(&extension, &status_type))
-                               {
-                               *out_alert = SSL_AD_DECODE_ERROR;
-                               return 0;
-                               }
-
-                       /* Only OCSP is supported. */
-                       if (status_type != TLSEXT_STATUSTYPE_ocsp)
-                               continue;
-
-                       s->tlsext_status_type = status_type;
-
-                       /* Extension consists of a responder_id_list and
-                        * request_extensions. */
-                       if (!CBS_get_u16_length_prefixed(&extension, &responder_id_list) ||
-                               !CBS_get_u16_length_prefixed(&extension, &request_extensions) ||
-                               CBS_len(&extension) != 0)
-                               {
-                               *out_alert = SSL_AD_DECODE_ERROR;
-                               return 0;
-                               }
-
-                       if (CBS_len(&responder_id_list) > 0)
-                               {
-                               s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
-                               if (s->tlsext_ocsp_ids == NULL)
-                                       {
-                                       *out_alert = SSL_AD_INTERNAL_ERROR;
-                                       return 0;
-                                       }
-                               }
-
-                       /* Parse out the responder IDs. */
-                       while (CBS_len(&responder_id_list) > 0)
-                               {
-                               CBS responder_id;
-                               OCSP_RESPID *id;
-                               const uint8_t *data;
-
-                               /* Each ResponderID must have size at least 1. */
-                               if (!CBS_get_u16_length_prefixed(&responder_id_list, &responder_id) ||
-                                       CBS_len(&responder_id) < 1)
-                                       {
-                                       *out_alert = SSL_AD_DECODE_ERROR;
-                                       return 0;
-                                       }
-
-                               /* TODO(fork): Add CBS versions of d2i_FOO_BAR. */
-                               data = CBS_data(&responder_id);
-                               id = d2i_OCSP_RESPID(NULL, &data, CBS_len(&responder_id));
-                               if (!id)
-                                       {
-                                       *out_alert = SSL_AD_DECODE_ERROR;
-                                       return 0;
-                                       }
-                               if (!CBS_skip(&responder_id, data - CBS_data(&responder_id)))
-                                       {
-                                       /* This should never happen. */
-                                       *out_alert = SSL_AD_INTERNAL_ERROR;
-                                       OCSP_RESPID_free(id);
-                                       return 0;
-                                       }
-                               if (CBS_len(&responder_id) != 0)
-                                       {
-                                       *out_alert = SSL_AD_DECODE_ERROR;
-                                       OCSP_RESPID_free(id);
-                                       return 0;
-                                       }
-
-                               if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id))
-                                       {
-                                       *out_alert = SSL_AD_INTERNAL_ERROR;
-                                       OCSP_RESPID_free(id);
-                                       return 0;
-                                       }
-                               }
-
-                       /* Parse out request_extensions. */
-                       if (CBS_len(&request_extensions) > 0)
-                               {
-                               const uint8_t *data;
-
-                               data = CBS_data(&request_extensions);
-                               s->tlsext_ocsp_exts = d2i_X509_EXTENSIONS(NULL,
-                                       &data, CBS_len(&request_extensions));
-                               if (s->tlsext_ocsp_exts == NULL)
-                                       {
-                                       *out_alert = SSL_AD_DECODE_ERROR;
-                                       return 0;
-                                       }
-                               if (!CBS_skip(&request_extensions, data - CBS_data(&request_extensions)))
-                                       {
-                                       /* This should never happen. */
-                                       *out_alert = SSL_AD_INTERNAL_ERROR;
-                                       return 0;
-                                       }
-                               if (CBS_len(&request_extensions) != 0)
-                                       {
-                                       *out_alert = SSL_AD_DECODE_ERROR;
-                                       return 0;
-                                       }
-                               }
-                       }
-#endif
-
-#ifndef OPENSSL_NO_NEXTPROTONEG
                else if (type == TLSEXT_TYPE_next_proto_neg &&
                         s->s3->tmp.finish_md_len == 0 &&
                         s->s3->alpn_selected == NULL)
@@ -2143,7 +1728,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                         * Finished message could have been computed.) */
                        s->s3->next_proto_neg_seen = 1;
                        }
-#endif
 
                else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
                         s->ctx->alpn_select_cb &&
@@ -2151,10 +1735,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                        {
                        if (!tls1_alpn_handle_client_hello(s, &extension, out_alert))
                                return 0;
-#ifndef OPENSSL_NO_NEXTPROTONEG
                        /* ALPN takes precedence over NPN. */
                        s->s3->next_proto_neg_seen = 0;
-#endif
                        }
 
                else if (type == TLSEXT_TYPE_channel_id &&
@@ -2201,7 +1783,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
                {
                *out_alert = SSL_AD_HANDSHAKE_FAILURE;
-               OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+               OPENSSL_PUT_ERROR(SSL, ssl_scan_clienthello_tlsext, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
                return 0;
                }
        /* If no signature algorithms extension set default values */
@@ -2220,7 +1802,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs)
                return 0;
                }
 
-       if (ssl_check_clienthello_tlsext_early(s) <= 0) 
+       if (ssl_check_clienthello_tlsext(s) <= 0)
                {
                OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_tlsext, SSL_R_CLIENTHELLO_TLSEXT);
                return 0;
@@ -2228,7 +1810,6 @@ int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs)
        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. */
@@ -2247,7 +1828,6 @@ static char ssl_next_proto_validate(const CBS *cbs)
                }
        return 1;
        }
-#endif
 
 static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert)
        {
@@ -2255,11 +1835,13 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert)
        int renegotiate_seen = 0;
        CBS extensions;
 
-#ifndef OPENSSL_NO_NEXTPROTONEG
+       /* TODO(davidben): Move all of these to some per-handshake state that
+        * gets systematically reset on a new handshake; perhaps allocate it
+        * fresh each time so it's not even kept around post-handshake. */
        s->s3->next_proto_neg_seen = 0;
-#endif
 
-        s->tlsext_ticket_expected = 0;
+       s->tlsext_ticket_expected = 0;
+       s->s3->tmp.certificate_status_expected = 0;
 
        if (s->s3->alpn_selected)
                {
@@ -2316,7 +1898,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                                }
                        tlsext_servername = 1;
                        }
-#ifndef OPENSSL_NO_EC
                else if (type == TLSEXT_TYPE_ec_point_formats)
                        {
                        CBS ec_point_format_list;
@@ -2339,7 +1920,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                                        }
                                }
                        }
-#endif /* OPENSSL_NO_EC */
                else if (type == TLSEXT_TYPE_session_ticket)
                        {
                        if (s->tls_session_ticket_ext_cb &&
@@ -2367,15 +1947,14 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                                *out_alert = SSL_AD_DECODE_ERROR;
                                return 0;
                                }
-                       if (s->tlsext_status_type == -1)
+                       if (!s->ocsp_stapling_enabled)
                                {
                                *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
                                return 0;
                                }
                        /* Set a flag to expect a CertificateStatus message */
-                       s->tlsext_status_expected = 1;
+                       s->s3->tmp.certificate_status_expected = 1;
                        }
-#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;
@@ -2411,7 +1990,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                s->next_proto_negotiated_len = selected_len;
                s->s3->next_proto_neg_seen = 1;
                }
-#endif
                else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation)
                        {
                        CBS protocol_name_list, protocol_name;
@@ -2463,7 +2041,26 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert)
                        s->s3->tlsext_channel_id_valid = 1;
                        s->s3->tlsext_channel_id_new = 1;
                        }
+               else if (type == TLSEXT_TYPE_certificate_timestamp)
+                       {
+                       if (CBS_len(&extension) == 0)
+                               {
+                               *out_alert = SSL_AD_DECODE_ERROR;
+                               return 0;
+                               }
 
+                       /* Session resumption uses the original session information. */
+                       if (!s->hit)
+                               {
+                               if (!CBS_stow(&extension,
+                                       &s->session->tlsext_signed_cert_timestamp_list,
+                                       &s->session->tlsext_signed_cert_timestamp_list_length))
+                                       {
+                                       *out_alert = SSL_AD_INTERNAL_ERROR;
+                                       return 0;
+                                       }
+                               }
+                       }
                else if (type == TLSEXT_TYPE_renegotiate)
                        {
                        if (!ssl_parse_serverhello_renegotiate_ext(s, &extension, out_alert))
@@ -2530,19 +2127,17 @@ int ssl_prepare_serverhello_tlsext(SSL *s)
        return 1;
        }
 
-static int ssl_check_clienthello_tlsext_early(SSL *s)
+static int ssl_check_clienthello_tlsext(SSL *s)
        {
        int ret=SSL_TLSEXT_ERR_NOACK;
        int al = SSL_AD_UNRECOGNIZED_NAME;
 
-#ifndef OPENSSL_NO_EC
        /* The handling of the ECPointFormats extension is done elsewhere, namely in 
         * ssl3_choose_cipher in s3_lib.c.
         */
        /* The handling of the EllipticCurves extension is done elsewhere, namely in 
         * ssl3_choose_cipher in s3_lib.c.
         */
-#endif
 
        if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
                ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
@@ -2557,86 +2152,22 @@ static int ssl_check_clienthello_tlsext_early(SSL *s)
 
                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_check_clienthello_tlsext_late(SSL *s)
-       {
-       int ret = SSL_TLSEXT_ERR_OK;
-       int al;
-
-       /* 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 r;
-               CERT_PKEY *certpkey;
-               certpkey = ssl_get_server_send_pkey(s);
-               /* If no certificate can't return certificate status */
-               if (certpkey == NULL)
-                       {
-                       s->tlsext_status_expected = 0;
                        return 1;
-                       }
-               /* Set current certificate to one we will use so
-                * SSL_get_certificate et al can pick it up.
-                */
-               s->cert->key = certpkey;
-               r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
-               switch (r)
-                       {
-                       /* 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;
-                               else
-                                       s->tlsext_status_expected = 0;
-                               break;
-                       /* something bad happened */
-                       case SSL_TLSEXT_ERR_ALERT_FATAL:
-                               ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-                               al = SSL_AD_INTERNAL_ERROR;
-                               goto err;
-                       }
-               }
-       else
-               s->tlsext_status_expected = 0;
-
- err:
-       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->should_ack_sni = 0;
+                       return 1;
 
                default:
                        return 1;
                }
        }
 
-int ssl_check_serverhello_tlsext(SSL *s)
+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.
@@ -2645,7 +2176,7 @@ int ssl_check_serverhello_tlsext(SSL *s)
        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_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA)))
+           ((alg_k & SSL_kEECDH) || (alg_a & SSL_aECDSA)))
                {
                /* we are using an ECC cipher */
                size_t i;
@@ -2662,61 +2193,29 @@ int ssl_check_serverhello_tlsext(SSL *s)
                        }
                if (!found_uncompressed)
                        {
-                       OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
+                       OPENSSL_PUT_ERROR(SSL, 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);
 
-       /* If we've requested certificate status and we wont get one
-        * tell the callback
-        */
-       if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
-                       && s->ctx && s->ctx->tlsext_status_cb)
-               {
-               int r;
-               /* Set resp to NULL, resplen to -1 so callback knows
-                * there is no response.
-                */
-               if (s->tlsext_ocsp_resp)
-                       {
-                       OPENSSL_free(s->tlsext_ocsp_resp);
-                       s->tlsext_ocsp_resp = NULL;
-                       }
-               s->tlsext_ocsp_resplen = -1;
-               r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
-               if (r == 0)
-                       {
-                       al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
-                       ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-                       }
-               if (r < 0)
-                       {
-                       al = SSL_AD_INTERNAL_ERROR;
-                       ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-                       }
-               }
-
        switch (ret)
                {
                case SSL_TLSEXT_ERR_ALERT_FATAL:
-                       ssl3_send_alert(s,SSL3_AL_FATAL,al); 
+                       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;
+                       return 1;
+
+               default:
+                       return 1;
                }
        }
 
@@ -2949,7 +2448,7 @@ typedef struct
        int id;
        } tls12_lookup;
 
-static tls12_lookup tls12_md[] = {
+static const tls12_lookup tls12_md[] = {
        {NID_md5, TLSEXT_hash_md5},
        {NID_sha1, TLSEXT_hash_sha1},
        {NID_sha224, TLSEXT_hash_sha224},
@@ -2958,13 +2457,12 @@ static tls12_lookup tls12_md[] = {
        {NID_sha512, TLSEXT_hash_sha512}
 };
 
-static tls12_lookup tls12_sig[] = {
+static const tls12_lookup tls12_sig[] = {
        {EVP_PKEY_RSA, TLSEXT_signature_rsa},
-       {EVP_PKEY_DSA, TLSEXT_signature_dsa},
        {EVP_PKEY_EC, TLSEXT_signature_ecdsa}
 };
 
-static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
+static int tls12_find_id(int nid, const tls12_lookup *table, size_t tlen)
        {
        size_t i;
        for (i = 0; i < tlen; i++)
@@ -2975,7 +2473,7 @@ static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
        return -1;
        }
 
-static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
+static int tls12_find_nid(int id, const tls12_lookup *table, size_t tlen)
        {
        size_t i;
        for (i = 0; i < tlen; i++)
@@ -3013,14 +2511,10 @@ const EVP_MD *tls12_get_hash(unsigned char hash_alg)
        {
        switch(hash_alg)
                {
-#ifndef OPENSSL_NO_MD5
                case TLSEXT_hash_md5:
                return EVP_md5();
-#endif
-#ifndef OPENSSL_NO_SHA
                case TLSEXT_hash_sha1:
                return EVP_sha1();
-#endif
                case TLSEXT_hash_sha224:
                return EVP_sha224();
 
@@ -3043,14 +2537,8 @@ static int tls12_get_pkey_idx(unsigned char sig_alg)
                {
        case TLSEXT_signature_rsa:
                return SSL_PKEY_RSA_SIGN;
-#ifndef OPENSSL_NO_DSA
-       case TLSEXT_signature_dsa:
-               return SSL_PKEY_DSA_SIGN;
-#endif
-#ifndef OPENSSL_NO_ECDSA
        case TLSEXT_signature_ecdsa:
                return SSL_PKEY_ECC;
-#endif
                }
        return -1;
        }
@@ -3129,26 +2617,25 @@ static int tls1_set_shared_sigalgs(SSL *s)
        size_t nmatch;
        TLS_SIGALGS *salgs = NULL;
        CERT *c = s->cert;
-       unsigned int is_suiteb = tls1_suiteb(s);
        if (c->shared_sigalgs)
                {
                OPENSSL_free(c->shared_sigalgs);
                c->shared_sigalgs = NULL;
                }
        /* If client use client signature algorithms if not NULL */
-       if (!s->server && c->client_sigalgs && !is_suiteb)
+       if (!s->server && c->client_sigalgs)
                {
                conf = c->client_sigalgs;
                conflen = c->client_sigalgslen;
                }
-       else if (c->conf_sigalgs && !is_suiteb)
+       else if (c->conf_sigalgs)
                {
                conf = c->conf_sigalgs;
                conflen = c->conf_sigalgslen;
                }
        else
                conflen = tls12_get_psigalgs(s, &conf);
-       if(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb)
+       if(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
                {
                pref = conf;
                preflen = conflen;
@@ -3251,19 +2738,13 @@ int tls1_process_sigalgs(SSL *s, const CBS *sigalgs)
                /* Set any remaining keys to default values. NOTE: if alg is
                 * not supported it stays as NULL.
                 */
-#ifndef OPENSSL_NO_DSA
-               if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
-                       c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
-#endif
                if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest)
                        {
                        c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
                        c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
                        }
-#ifndef OPENSSL_NO_ECDSA
                if (!c->pkeys[SSL_PKEY_ECC].digest)
                        c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
-#endif
                }
        return 1;
        }
@@ -3380,75 +2861,6 @@ int tls1_record_handshake_hashes_for_channel_id(SSL *s)
        return 1;
        }
 
-/* TODO(fork): remove */
-#if 0
-#define MAX_SIGALGLEN  (TLSEXT_hash_num * TLSEXT_signature_num * 2)
-
-typedef struct
-       {
-       size_t sigalgcnt;
-       int sigalgs[MAX_SIGALGLEN];
-       } sig_cb_st;
-
-static int sig_cb(const char *elem, int len, void *arg)
-       {
-       sig_cb_st *sarg = arg;
-       size_t i;
-       char etmp[20], *p;
-       int sig_alg, hash_alg;
-       if (sarg->sigalgcnt == MAX_SIGALGLEN)
-               return 0;
-       if (len > (int)(sizeof(etmp) - 1))
-               return 0;
-       memcpy(etmp, elem, len);
-       etmp[len] = 0;
-       p = strchr(etmp, '+');
-       if (!p)
-               return 0;
-       *p = 0;
-       p++;
-       if (!*p)
-               return 0;
-
-       if (!strcmp(etmp, "RSA"))
-               sig_alg = EVP_PKEY_RSA;
-       else if (!strcmp(etmp, "DSA"))
-               sig_alg = EVP_PKEY_DSA;
-       else if (!strcmp(etmp, "ECDSA"))
-               sig_alg = EVP_PKEY_EC;
-       else return 0;
-
-       hash_alg = OBJ_sn2nid(p);
-       if (hash_alg == NID_undef)
-               hash_alg = OBJ_ln2nid(p);
-       if (hash_alg == NID_undef)
-               return 0;
-
-       for (i = 0; i < sarg->sigalgcnt; i+=2)
-               {
-               if (sarg->sigalgs[i] == sig_alg
-                       && sarg->sigalgs[i + 1] == hash_alg)
-                       return 0;
-               }
-       sarg->sigalgs[sarg->sigalgcnt++] = hash_alg;
-       sarg->sigalgs[sarg->sigalgcnt++] = sig_alg;
-       return 1;
-       }
-
-/* Set suppored signature algorithms based on a colon separated list
- * of the form sig+hash e.g. RSA+SHA512:DSA+SHA512 */
-int tls1_set_sigalgs_list(CERT *c, const char *str, int client)
-       {
-       sig_cb_st sig;
-       sig.sigalgcnt = 0;
-       if (!CONF_parse_list(str, ':', 1, sig_cb, &sig))
-               return 0;
-       if (c == NULL)
-               return 1;
-       return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client);
-       }
-#endif
-
 int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
        {
        unsigned char *sigalgs, *sptr;
@@ -3545,7 +2957,6 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
        int check_flags = 0, strict_mode;
        CERT_PKEY *cpk = NULL;
        CERT *c = s->cert;
-       unsigned int suiteb_flags = tls1_suiteb(s);
        /* idx == -1 means checking server chains */
        if (idx != -1)
                {
@@ -3589,21 +3000,6 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
                strict_mode = 1;
                }
 
-       if (suiteb_flags)
-               {
-               int ok;
-               if (check_flags)
-                       check_flags |= CERT_PKEY_SUITEB;
-               ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags);
-               if (ok != X509_V_OK)
-                       {
-                       if (check_flags)
-                               rv |= CERT_PKEY_SUITEB;
-                       else
-                               goto end;
-                       }
-               }
-
        /* Check all signature algorithms are consistent with
         * signature algorithms extension if TLS 1.2 or later
         * and strict mode.
@@ -3621,17 +3017,10 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
                                {       
                        case SSL_PKEY_RSA_ENC:
                        case SSL_PKEY_RSA_SIGN:
-                       case SSL_PKEY_DH_RSA:
                                rsign = TLSEXT_signature_rsa;
                                default_nid = NID_sha1WithRSAEncryption;
                                break;
 
-                       case SSL_PKEY_DSA_SIGN:
-                       case SSL_PKEY_DH_DSA:
-                               rsign = TLSEXT_signature_dsa;
-                               default_nid = NID_dsaWithSHA1;
-                               break;
-
                        case SSL_PKEY_ECC:
                                rsign = TLSEXT_signature_ecdsa;
                                default_nid = NID_ecdsa_with_SHA1;
@@ -3725,21 +3114,9 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
                case EVP_PKEY_RSA:
                        check_type = TLS_CT_RSA_SIGN;
                        break;
-               case EVP_PKEY_DSA:
-                       check_type = TLS_CT_DSS_SIGN;
-                       break;
                case EVP_PKEY_EC:
                        check_type = TLS_CT_ECDSA_SIGN;
                        break;
-               case EVP_PKEY_DH:
-               case EVP_PKEY_DHX:
-                               {
-                               int cert_type = X509_certificate_type(x, pk);
-                               if (cert_type & EVP_PKS_RSA)
-                                       check_type = TLS_CT_RSA_FIXED_DH;
-                               if (cert_type & EVP_PKS_DSA)
-                                       check_type = TLS_CT_DSS_FIXED_DH;
-                               }
                        }
                if (check_type)
                        {
@@ -3820,9 +3197,6 @@ void tls1_set_cert_validity(SSL *s)
        {
        tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC);
        tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN);
-       tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN);
-       tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_RSA);
-       tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_DSA);
        tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC);
        }
 /* User level utiity function to check a chain is suitable */