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,
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);
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;
return 0;
}
-#ifndef OPENSSL_NO_EC
-static int nid_list[] =
+static const int nid_list[] =
{
NID_sect163k1, /* sect163k1 (1) */
NID_sect163r1, /* sect163r1 (2) */
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) */
*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;
!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++)
{
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),
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);
}
}
/* 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)
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 */
#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
#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)
{
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
}
-#ifndef OPENSSL_NO_EC
if (pkey->type == EVP_PKEY_EC)
{
uint16_t curve_id;
*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);
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 */
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)
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))
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
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
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)
{
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;
ret += el;
}
-#ifndef OPENSSL_NO_EC
if (using_ecc)
{
/* Add TLS extension ECPointFormats to the ClientHello message */
s2n(curves[i], ret);
}
}
-#endif /* OPENSSL_NO_EC */
#ifdef TLSEXT_TYPE_padding
/* Add padding to workaround bugs in F5 terminators.
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;
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;
ret += el;
}
-#ifndef OPENSSL_NO_EC
if (using_ecc)
{
const unsigned char *plist;
}
/* 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))
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);
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;
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)
s->s3->next_proto_neg_seen = 1;
}
}
-#endif
if (s->s3->alpn_selected)
{
* 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;
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;
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)
{
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)
{
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 ||
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;
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 &&
}
}
- /* 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)
* 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 &&
{
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 &&
!(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 */
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;
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. */
}
return 1;
}
-#endif
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)
{
}
tlsext_servername = 1;
}
-#ifndef OPENSSL_NO_EC
else if (type == TLSEXT_TYPE_ec_point_formats)
{
CBS ec_point_format_list;
}
}
}
-#endif /* OPENSSL_NO_EC */
else if (type == TLSEXT_TYPE_session_ticket)
{
if (s->tls_session_ticket_ext_cb &&
*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;
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;
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))
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);
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.
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;
}
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;
}
}
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},
{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++)
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++)
{
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();
{
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;
}
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;
/* 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;
}
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;
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)
{
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.
{
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;
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)
{
{
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 */