-#endif
-}
-
-/*
- * ssl_cipher_disabled - check that a cipher is disabled or not
- * @s: SSL connection that you want to use the cipher on
- * @c: cipher to check
- * @op: Security check that you want to do
- *
- * Returns 1 when it's disabled, 0 when enabled.
- */
-int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op)
-{
- if (c->algorithm_mkey & s->s3->tmp.mask_k
- || c->algorithm_auth & s->s3->tmp.mask_a)
- return 1;
- if (s->s3->tmp.max_ver == 0)
- return 1;
- if (!SSL_IS_DTLS(s) && ((c->min_tls > s->s3->tmp.max_ver)
- || (c->max_tls < s->s3->tmp.min_ver)))
- return 1;
- if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3->tmp.max_ver)
- || DTLS_VERSION_LT(c->max_dtls, s->s3->tmp.min_ver)))
- return 1;
-
- return !ssl_security(s, op, c->strength_bits, 0, (void *)c);
-}
-
-static int tls_use_ticket(SSL *s)
-{
- if (s->options & SSL_OP_NO_TICKET)
- return 0;
- return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
-}
-
-static int compare_uint(const void *p1, const void *p2)
-{
- unsigned int u1 = *((const unsigned int *)p1);
- unsigned int u2 = *((const unsigned int *)p2);
- if (u1 < u2)
- return -1;
- else if (u1 > u2)
- return 1;
- else
- return 0;
-}
-
-/*
- * Per http://tools.ietf.org/html/rfc5246#section-7.4.1.4, there may not be
- * more than one extension of the same type in a ClientHello or ServerHello.
- * This function does an initial scan over the extensions block to filter those
- * out. It returns 1 if all extensions are unique, and 0 if the extensions
- * contain duplicates, could not be successfully parsed, or an internal error
- * occurred.
- */
-static int tls1_check_duplicate_extensions(const PACKET *packet)
-{
- PACKET extensions = *packet;
- size_t num_extensions = 0, i = 0;
- unsigned int *extension_types = NULL;
- int ret = 0;
-
- /* First pass: count the extensions. */
- while (PACKET_remaining(&extensions) > 0) {
- unsigned int type;
- PACKET extension;
- if (!PACKET_get_net_2(&extensions, &type) ||
- !PACKET_get_length_prefixed_2(&extensions, &extension)) {
- goto done;
- }
- num_extensions++;
- }
-
- if (num_extensions <= 1)
- return 1;
-
- extension_types = OPENSSL_malloc(sizeof(unsigned int) * num_extensions);
- if (extension_types == NULL) {
- SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- /* Second pass: gather the extension types. */
- extensions = *packet;
- for (i = 0; i < num_extensions; i++) {
- PACKET extension;
- if (!PACKET_get_net_2(&extensions, &extension_types[i]) ||
- !PACKET_get_length_prefixed_2(&extensions, &extension)) {
- /* This should not happen. */
- SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_INTERNAL_ERROR);
- goto done;
- }
- }
-
- if (PACKET_remaining(&extensions) != 0) {
- SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_INTERNAL_ERROR);
- goto done;
- }
- /* Sort the extensions and make sure there are no duplicates. */
- qsort(extension_types, num_extensions, sizeof(unsigned int), compare_uint);
- for (i = 1; i < num_extensions; i++) {
- if (extension_types[i - 1] == extension_types[i])
- goto done;
- }
- ret = 1;
- done:
- OPENSSL_free(extension_types);
- return ret;
-}
-
-int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al)
-{
-#ifndef OPENSSL_NO_EC
- /* See if we support any ECC ciphersuites */
- int using_ecc = 0;
- if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) {
- int i;
- unsigned long alg_k, alg_a;
- STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
-
- for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
- const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
-
- alg_k = c->algorithm_mkey;
- alg_a = c->algorithm_auth;
- if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))
- || (alg_a & SSL_aECDSA)) {
- using_ecc = 1;
- break;
- }
- }
- }
-#endif
-
- /* Add RI if renegotiating */
- if (s->renegotiate) {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate)
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_sub_memcpy_u8(pkt, s->s3->previous_client_finished,
- s->s3->previous_client_finished_len)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
- /* Only add RI for SSLv3 */
- if (s->client_version == SSL3_VERSION)
- goto done;
-
- if (s->tlsext_hostname != NULL) {
- /* Add TLS extension servername to the Client Hello message */
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
- /* Sub-packet for server_name extension */
- || !WPACKET_start_sub_packet_u16(pkt)
- /* Sub-packet for servername list (always 1 hostname)*/
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_put_bytes_u8(pkt, TLSEXT_NAMETYPE_host_name)
- || !WPACKET_sub_memcpy_u16(pkt, s->tlsext_hostname,
- strlen(s->tlsext_hostname))
- || !WPACKET_close(pkt)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#ifndef OPENSSL_NO_SRP
- /* Add SRP username if there is one */
- if (s->srp_ctx.login != NULL) {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_srp)
- /* Sub-packet for SRP extension */
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_start_sub_packet_u8(pkt)
- /* login must not be zero...internal error if so */
- || !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)
- || !WPACKET_memcpy(pkt, s->srp_ctx.login,
- strlen(s->srp_ctx.login))
- || !WPACKET_close(pkt)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#endif
-
-#ifndef OPENSSL_NO_EC
- if (using_ecc) {
- /*
- * Add TLS extension ECPointFormats to the ClientHello message
- */
- const unsigned char *pcurves, *pformats;
- size_t num_curves, num_formats;
- size_t i;
-
- tls1_get_formatlist(s, &pformats, &num_formats);
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
- /* Sub-packet for formats extension */
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- /*
- * Add TLS extension EllipticCurves to the ClientHello message
- */
- pcurves = s->tlsext_ellipticcurvelist;
- if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_elliptic_curves)
- /* Sub-packet for curves extension */
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_start_sub_packet_u16(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- /* Copy curve ID if supported */
- for (i = 0; i < num_curves; i++, pcurves += 2) {
- if (tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) {
- if (!WPACKET_put_bytes_u8(pkt, pcurves[0])
- || !WPACKET_put_bytes_u8(pkt, pcurves[1])) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
- ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
- }
- if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#endif /* OPENSSL_NO_EC */
-
- if (tls_use_ticket(s)) {
- size_t ticklen;
- if (!s->new_session && s->session && s->session->tlsext_tick)
- ticklen = s->session->tlsext_ticklen;
- else if (s->session && s->tlsext_session_ticket &&
- s->tlsext_session_ticket->data) {
- ticklen = s->tlsext_session_ticket->length;
- s->session->tlsext_tick = OPENSSL_malloc(ticklen);
- if (s->session->tlsext_tick == NULL) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- memcpy(s->session->tlsext_tick,
- s->tlsext_session_ticket->data, ticklen);
- s->session->tlsext_ticklen = ticklen;
- } else
- ticklen = 0;
- if (ticklen == 0 && s->tlsext_session_ticket &&
- s->tlsext_session_ticket->data == NULL)
- goto skip_ext;
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
- || !WPACKET_sub_memcpy_u16(pkt, s->session->tlsext_tick,
- ticklen)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
- skip_ext:
-
- if (SSL_CLIENT_USE_SIGALGS(s)) {
- size_t salglen;
- const unsigned char *salg;
-
- salglen = tls12_get_psigalgs(s, &salg);
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signature_algorithms)
- /* Sub-packet for sig-algs extension */
- || !WPACKET_start_sub_packet_u16(pkt)
- /* Sub-packet for the actual list */
- || !WPACKET_start_sub_packet_u16(pkt)
- || !tls12_copy_sigalgs(s, pkt, salg, salglen)
- || !WPACKET_close(pkt)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#ifndef OPENSSL_NO_OCSP
- if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
- int i;
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
- /* Sub-packet for status request extension */
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_put_bytes_u8(pkt, TLSEXT_STATUSTYPE_ocsp)
- /* Sub-packet for the ids */
- || !WPACKET_start_sub_packet_u16(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
- unsigned char *idbytes;
- int idlen;
- OCSP_RESPID *id;
-
- id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
- idlen = i2d_OCSP_RESPID(id, NULL);
- if (idlen <= 0
- /* Sub-packet for an individual id */
- || !WPACKET_sub_allocate_bytes_u16(pkt, idlen, &idbytes)
- || i2d_OCSP_RESPID(id, &idbytes) != idlen) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
- if (!WPACKET_close(pkt)
- || !WPACKET_start_sub_packet_u16(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- if (s->tlsext_ocsp_exts) {
- unsigned char *extbytes;
- int extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
-
- if (extlen < 0) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- if (!WPACKET_allocate_bytes(pkt, extlen, &extbytes)
- || i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &extbytes)
- != extlen) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
- if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#endif
-#ifndef OPENSSL_NO_HEARTBEATS
- if (SSL_IS_DTLS(s)) {
- unsigned int mode;
-
- /*-
- * Set mode:
- * 1: peer may send requests
- * 2: peer not allowed to send requests
- */
- if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)
- mode = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
- else
- mode = SSL_DTLSEXT_HB_ENABLED;
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_heartbeat)
- /* Sub-packet for Hearbeat extension */
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_put_bytes_u8(pkt, mode)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#endif
-
-#ifndef OPENSSL_NO_NEXTPROTONEG
- if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
- /*
- * The client advertises an empty extension to indicate its support
- * for Next Protocol Negotiation
- */
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
- || !WPACKET_put_bytes_u16(pkt, 0)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#endif
-
- /*
- * finish_md_len is non-zero during a renegotiation, so
- * this avoids sending ALPN during the renegotiation
- * (see longer comment below)
- */
- if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
- if (!WPACKET_put_bytes_u16(pkt,
- TLSEXT_TYPE_application_layer_protocol_negotiation)
- /* Sub-packet ALPN extension */
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_sub_memcpy_u16(pkt, s->alpn_client_proto_list,
- s->alpn_client_proto_list_len)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- s->s3->alpn_sent = 1;
- }
-#ifndef OPENSSL_NO_SRTP
- if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
- STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s);
- SRTP_PROTECTION_PROFILE *prof;
- int i, ct;
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
- /* Sub-packet for SRTP extension */
- || !WPACKET_start_sub_packet_u16(pkt)
- /* Sub-packet for the protection profile list */
- || !WPACKET_start_sub_packet_u16(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- ct = sk_SRTP_PROTECTION_PROFILE_num(clnt);
- for (i = 0; i < ct; i++) {
- prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
- if (prof == NULL || !WPACKET_put_bytes_u16(pkt, prof->id)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
- if (!WPACKET_close(pkt)
- /* Add an empty use_mki value */
- || !WPACKET_put_bytes_u8(pkt, 0)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#endif
- custom_ext_init(&s->cert->cli_ext);
- /* Add custom TLS Extensions to ClientHello */
- if (!custom_ext_add(s, 0, pkt, al)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)) {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
- || !WPACKET_put_bytes_u16(pkt, 0)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-
-#ifndef OPENSSL_NO_CT
- if (s->ct_validation_callback != NULL) {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signed_certificate_timestamp)
- || !WPACKET_put_bytes_u16(pkt, 0)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#endif
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
- || !WPACKET_put_bytes_u16(pkt, 0)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- if (!SSL_IS_DTLS(s) && s->version >= TLS1_3_VERSION) {
- int min_version, max_version, reason, currv;
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions)
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_start_sub_packet_u8(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
- if (reason != 0) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, reason);
- return 0;
- }
- for (currv = max_version; currv >= min_version; currv--) {
- /* TODO(TLS1.3): Remove this first if clause prior to release!! */
- if (currv == TLS1_3_VERSION) {
- if (!WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
- ERR_R_INTERNAL_ERROR);
- return 0;
- }
- } else if (!WPACKET_put_bytes_u16(pkt, currv)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
- if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-
- /*
- * Add padding to workaround bugs in F5 terminators. See
- * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
- * code works out the length of all existing extensions it MUST always
- * appear last.
- */
- if (s->options & SSL_OP_TLSEXT_PADDING) {
- unsigned char *padbytes;
- size_t hlen;
-
- if (!WPACKET_get_total_written(pkt, &hlen)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- if (hlen > 0xff && hlen < 0x200) {
- hlen = 0x200 - hlen;
- if (hlen >= 4)
- hlen -= 4;
- else
- hlen = 0;
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_padding)
- || !WPACKET_sub_allocate_bytes_u16(pkt, hlen, &padbytes)) {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- memset(padbytes, 0, hlen);
- }
- }
-
- done:
- return 1;
-}
-
-int ssl_add_serverhello_tlsext(SSL *s, WPACKET *pkt, int *al)
-{
-#ifndef OPENSSL_NO_NEXTPROTONEG
- int next_proto_neg_seen;
-#endif
-#ifndef OPENSSL_NO_EC
- unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
- using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
-#endif
-
- if (!WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_set_flags(pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- if (s->s3->send_connection_binding &&
- !ssl_add_serverhello_renegotiate_ext(s, pkt)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- /* Only add RI for SSLv3 */
- if (s->version == SSL3_VERSION)
- goto done;
-
- if (!s->hit && s->servername_done == 1
- && s->session->tlsext_hostname != NULL) {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
- || !WPACKET_put_bytes_u16(pkt, 0)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#ifndef OPENSSL_NO_EC
- if (using_ecc) {
- const unsigned char *plist;
- size_t plistlen;
- /*
- * Add TLS extension ECPointFormats to the ServerHello message
- */
- tls1_get_formatlist(s, &plist, &plistlen);
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_sub_memcpy_u8(pkt, plist, plistlen)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
- /*
- * Currently the server should not respond with a SupportedCurves
- * extension
- */
-#endif /* OPENSSL_NO_EC */
-
- if (s->tlsext_ticket_expected && tls_use_ticket(s)) {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
- || !WPACKET_put_bytes_u16(pkt, 0)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- } else {
- /*
- * if we don't add the above TLSEXT, we can't add a session ticket
- * later
- */
- s->tlsext_ticket_expected = 0;
- }
-
- if (s->tlsext_status_expected) {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
- || !WPACKET_put_bytes_u16(pkt, 0)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#ifndef OPENSSL_NO_SRTP
- if (SSL_IS_DTLS(s) && s->srtp_profile) {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_put_bytes_u16(pkt, 2)
- || !WPACKET_put_bytes_u16(pkt, s->srtp_profile->id)
- || !WPACKET_put_bytes_u8(pkt, 0)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#endif
-
- if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80
- || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81)
- && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) {
- const unsigned char cryptopro_ext[36] = {
- 0xfd, 0xe8, /* 65000 */
- 0x00, 0x20, /* 32 bytes length */
- 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
- 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
- 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
- 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
- };
- if (!WPACKET_memcpy(pkt, cryptopro_ext, sizeof(cryptopro_ext))) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-#ifndef OPENSSL_NO_HEARTBEATS
- /* Add Heartbeat extension if we've received one */
- if (SSL_IS_DTLS(s) && (s->tlsext_heartbeat & SSL_DTLSEXT_HB_ENABLED)) {
- unsigned int mode;
- /*-
- * Set mode:
- * 1: peer may send requests
- * 2: peer not allowed to send requests
- */
- if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)
- mode = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
- else
- mode = SSL_DTLSEXT_HB_ENABLED;
-
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_heartbeat)
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_put_bytes_u8(pkt, mode)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- }
-#endif
-
-#ifndef OPENSSL_NO_NEXTPROTONEG
- next_proto_neg_seen = s->s3->next_proto_neg_seen;
- s->s3->next_proto_neg_seen = 0;
- if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
- const unsigned char *npa;
- unsigned int npalen;
- int r;
-
- r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen,
- s->
- ctx->next_protos_advertised_cb_arg);
- if (r == SSL_TLSEXT_ERR_OK) {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
- || !WPACKET_sub_memcpy_u16(pkt, npa, npalen)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- s->s3->next_proto_neg_seen = 1;
- }
- }
-#endif
- if (!custom_ext_add(s, 1, pkt, al)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) {
- /*
- * Don't use encrypt_then_mac if AEAD or RC4 might want to disable
- * for other cases too.
- */
- if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD
- || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4
- || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT
- || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12)
- s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
- else {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
- || !WPACKET_put_bytes_u16(pkt, 0)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
- }
- if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) {
- if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
- || !WPACKET_put_bytes_u16(pkt, 0)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-
- if (s->s3->alpn_selected != NULL) {
- if (!WPACKET_put_bytes_u16(pkt,
- TLSEXT_TYPE_application_layer_protocol_negotiation)
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_start_sub_packet_u16(pkt)
- || !WPACKET_sub_memcpy_u8(pkt, s->s3->alpn_selected,
- s->s3->alpn_selected_len)
- || !WPACKET_close(pkt)
- || !WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- }
-
- done:
- if (!WPACKET_close(pkt)) {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- return 1;
-}
-
-/*
- * Save the ALPN extension in a ClientHello.
- * pkt: the contents of the ALPN extension, not including type and length.
- * al: a pointer to the alert value to send in the event of a failure.
- * returns: 1 on success, 0 on error.
- */
-static int tls1_alpn_handle_client_hello(SSL *s, PACKET *pkt, int *al)
-{
- PACKET protocol_list, save_protocol_list, protocol;
-
- *al = SSL_AD_DECODE_ERROR;
-
- if (!PACKET_as_length_prefixed_2(pkt, &protocol_list)
- || PACKET_remaining(&protocol_list) < 2) {
- return 0;
- }
-
- save_protocol_list = protocol_list;
- do {
- /* Protocol names can't be empty. */
- if (!PACKET_get_length_prefixed_1(&protocol_list, &protocol)
- || PACKET_remaining(&protocol) == 0) {
- return 0;
- }
- } while (PACKET_remaining(&protocol_list) != 0);
-
- if (!PACKET_memdup(&save_protocol_list,
- &s->s3->alpn_proposed, &s->s3->alpn_proposed_len)) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
-
- return 1;
-}
-
-/*
- * Process the ALPN extension in a ClientHello.
- * al: a pointer to the alert value to send in the event of a failure.
- * returns 1 on success, 0 on error.
- */
-static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
-{
- const unsigned char *selected = NULL;
- unsigned char selected_len = 0;
-
- if (s->ctx->alpn_select_cb != NULL && s->s3->alpn_proposed != NULL) {
- int r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
- s->s3->alpn_proposed,
- (unsigned int)s->s3->alpn_proposed_len,
- s->ctx->alpn_select_cb_arg);
-
- if (r == SSL_TLSEXT_ERR_OK) {
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len);
- if (s->s3->alpn_selected == NULL) {
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- s->s3->alpn_selected_len = selected_len;
-#ifndef OPENSSL_NO_NEXTPROTONEG
- /* ALPN takes precedence over NPN. */
- s->s3->next_proto_neg_seen = 0;
-#endif
- } else {
- *al = SSL_AD_NO_APPLICATION_PROTOCOL;
- return 0;
- }
- }
-
- return 1;
-}
-
-#ifndef OPENSSL_NO_EC
-/*-
- * ssl_check_for_safari attempts to fingerprint Safari using OS X
- * SecureTransport using the TLS extension block in |hello|.
- * Safari, since 10.6, sends exactly these extensions, in this order:
- * SNI,
- * elliptic_curves
- * ec_point_formats
- *
- * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
- * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
- * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
- * 10.8..10.8.3 (which don't work).
- */
-static void ssl_check_for_safari(SSL *s, const CLIENTHELLO_MSG *hello)
-{
- unsigned int type;
- PACKET sni, tmppkt;
- size_t ext_len;
-
- static const unsigned char kSafariExtensionsBlock[] = {
- 0x00, 0x0a, /* elliptic_curves extension */
- 0x00, 0x08, /* 8 bytes */
- 0x00, 0x06, /* 6 bytes of curve ids */
- 0x00, 0x17, /* P-256 */
- 0x00, 0x18, /* P-384 */
- 0x00, 0x19, /* P-521 */
-
- 0x00, 0x0b, /* ec_point_formats */
- 0x00, 0x02, /* 2 bytes */
- 0x01, /* 1 point format */
- 0x00, /* uncompressed */
- /* The following is only present in TLS 1.2 */
- 0x00, 0x0d, /* signature_algorithms */
- 0x00, 0x0c, /* 12 bytes */
- 0x00, 0x0a, /* 10 bytes */
- 0x05, 0x01, /* SHA-384/RSA */
- 0x04, 0x01, /* SHA-256/RSA */
- 0x02, 0x01, /* SHA-1/RSA */
- 0x04, 0x03, /* SHA-256/ECDSA */
- 0x02, 0x03, /* SHA-1/ECDSA */
- };
-
- /* Length of the common prefix (first two extensions). */
- static const size_t kSafariCommonExtensionsLength = 18;
-
- tmppkt = hello->extensions;
-
- if (!PACKET_forward(&tmppkt, 2)
- || !PACKET_get_net_2(&tmppkt, &type)
- || !PACKET_get_length_prefixed_2(&tmppkt, &sni)) {
- return;
- }
-
- if (type != TLSEXT_TYPE_server_name)
- return;
-
- ext_len = TLS1_get_client_version(s) >= TLS1_2_VERSION ?
- sizeof(kSafariExtensionsBlock) : kSafariCommonExtensionsLength;
-
- s->s3->is_probably_safari = PACKET_equal(&tmppkt, kSafariExtensionsBlock,
- ext_len);
-}
-#endif /* !OPENSSL_NO_EC */
-
-/*
- * Loop through all remaining ClientHello extensions that we collected earlier
- * and haven't already processed. For each one parse it and update the SSL
- * object as required.
- *
- * Behaviour upon resumption is extension-specific. If the extension has no
- * effect during resumption, it is parsed (to verify its format) but otherwise
- * ignored.
- *
- * Returns 1 on success and 0 on failure.
- * Upon failure, sets |al| to the appropriate alert.
- */
-static int ssl_scan_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello, int *al)
-{
- size_t loop;
- int renegotiate_seen = 0;
-
- *al = SSL_AD_DECODE_ERROR;
- s->servername_done = 0;
- s->tlsext_status_type = -1;
-#ifndef OPENSSL_NO_NEXTPROTONEG
- s->s3->next_proto_neg_seen = 0;
-#endif
-
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = NULL;
- s->s3->alpn_selected_len = 0;
- OPENSSL_free(s->s3->alpn_proposed);
- s->s3->alpn_proposed = NULL;
- s->s3->alpn_proposed_len = 0;
-#ifndef OPENSSL_NO_HEARTBEATS
- s->tlsext_heartbeat &= ~(SSL_DTLSEXT_HB_ENABLED |
- SSL_DTLSEXT_HB_DONT_SEND_REQUESTS);
-#endif
-
-#ifndef OPENSSL_NO_EC
- if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
- ssl_check_for_safari(s, hello);
-#endif /* !OPENSSL_NO_EC */
-
- /* Clear any signature algorithms extension received */
- OPENSSL_free(s->s3->tmp.peer_sigalgs);
- s->s3->tmp.peer_sigalgs = NULL;
- s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
-
-#ifndef OPENSSL_NO_SRP
- OPENSSL_free(s->srp_ctx.login);
- s->srp_ctx.login = NULL;
-#endif
-
- s->srtp_profile = NULL;
-
- /*
- * We parse all extensions to ensure the ClientHello is well-formed but,
- * unless an extension specifies otherwise, we ignore extensions upon
- * resumption.
- */
- for (loop = 0; loop < hello->num_extensions; loop++) {
- RAW_EXTENSION *currext = &hello->pre_proc_exts[loop];
-
- if (s->tlsext_debug_cb)
- s->tlsext_debug_cb(s, 0, currext->type,
- PACKET_data(&currext->data),
- PACKET_remaining(&currext->data),
- s->tlsext_debug_arg);
-
- if (currext->type == TLSEXT_TYPE_renegotiate) {
- if (!ssl_parse_clienthello_renegotiate_ext(s,
- &currext->data, al))
- return 0;
- renegotiate_seen = 1;
- } else if (s->version == SSL3_VERSION) {
- }
-/*-
- * The servername extension is treated as follows:
- *
- * - Only the hostname type is supported with a maximum length of 255.
- * - The servername is rejected if too long or if it contains zeros,
- * in which case an fatal alert is generated.
- * - The servername field is maintained together with the session cache.
- * - When a session is resumed, the servername call back invoked in order
- * to allow the application to position itself to the right context.
- * - The servername is acknowledged if it is new for a session or when
- * it is identical to a previously used for the same session.
- * Applications can control the behaviour. They can at any time
- * set a 'desirable' servername for a new SSL object. This can be the
- * case for example with HTTPS when a Host: header field is received and
- * a renegotiation is requested. In this case, a possible servername
- * presented in the new client hello is only acknowledged if it matches
- * the value of the Host: field.
- * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
- * if they provide for changing an explicit servername context for the
- * session, i.e. when the session has been established with a servername
- * extension.
- * - On session reconnect, the servername extension may be absent.
- *
- */
-
- else if (currext->type == TLSEXT_TYPE_server_name) {
- unsigned int servname_type;
- PACKET sni, hostname;
-
- if (!PACKET_as_length_prefixed_2(&currext->data, &sni)
- /* ServerNameList must be at least 1 byte long. */
- || PACKET_remaining(&sni) == 0) {
- return 0;
- }
-
- /*
- * Although the server_name extension was intended to be
- * extensible to new name types, RFC 4366 defined the
- * syntax inextensibility and OpenSSL 1.0.x parses it as
- * such.
- * RFC 6066 corrected the mistake but adding new name types
- * is nevertheless no longer feasible, so act as if no other
- * SNI types can exist, to simplify parsing.
- *
- * Also note that the RFC permits only one SNI value per type,
- * i.e., we can only have a single hostname.
- */
- if (!PACKET_get_1(&sni, &servname_type)
- || servname_type != TLSEXT_NAMETYPE_host_name
- || !PACKET_as_length_prefixed_2(&sni, &hostname)) {
- return 0;
- }
-
- if (!s->hit) {
- if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) {
- *al = TLS1_AD_UNRECOGNIZED_NAME;
- return 0;
- }
-
- if (PACKET_contains_zero_byte(&hostname)) {
- *al = TLS1_AD_UNRECOGNIZED_NAME;
- return 0;
- }
-
- if (!PACKET_strndup(&hostname, &s->session->tlsext_hostname)) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
-
- s->servername_done = 1;
- } else {
- /*
- * TODO(openssl-team): if the SNI doesn't match, we MUST
- * fall back to a full handshake.
- */
- s->servername_done = s->session->tlsext_hostname
- && PACKET_equal(&hostname, s->session->tlsext_hostname,
- strlen(s->session->tlsext_hostname));
- }
- }
-#ifndef OPENSSL_NO_SRP
- else if (currext->type == TLSEXT_TYPE_srp) {
- PACKET srp_I;
-
- if (!PACKET_as_length_prefixed_1(&currext->data, &srp_I))
- return 0;
-
- if (PACKET_contains_zero_byte(&srp_I))
- return 0;
-
- /*
- * TODO(openssl-team): currently, we re-authenticate the user
- * upon resumption. Instead, we MUST ignore the login.
- */
- if (!PACKET_strndup(&srp_I, &s->srp_ctx.login)) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- }
-#endif
-
-#ifndef OPENSSL_NO_EC
- else if (currext->type == TLSEXT_TYPE_ec_point_formats) {
- PACKET ec_point_format_list;
-
- if (!PACKET_as_length_prefixed_1(&currext->data,
- &ec_point_format_list)
- || PACKET_remaining(&ec_point_format_list) == 0) {
- return 0;
- }
-
- if (!s->hit) {
- if (!PACKET_memdup(&ec_point_format_list,
- &s->session->tlsext_ecpointformatlist,
- &s->
- session->tlsext_ecpointformatlist_length)) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- }
- } else if (currext->type == TLSEXT_TYPE_elliptic_curves) {
- PACKET elliptic_curve_list;
-
- /* Each NamedCurve is 2 bytes and we must have at least 1. */
- if (!PACKET_as_length_prefixed_2(&currext->data,
- &elliptic_curve_list)
- || PACKET_remaining(&elliptic_curve_list) == 0
- || (PACKET_remaining(&elliptic_curve_list) % 2) != 0) {
- return 0;
- }
-
- if (!s->hit) {
- if (!PACKET_memdup(&elliptic_curve_list,
- &s->session->tlsext_ellipticcurvelist,
- &s->
- session->tlsext_ellipticcurvelist_length)) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- }
- }
-#endif /* OPENSSL_NO_EC */
- else if (currext->type == TLSEXT_TYPE_session_ticket) {
- if (s->tls_session_ticket_ext_cb &&
- !s->tls_session_ticket_ext_cb(s,
- PACKET_data(&currext->data),
- PACKET_remaining(&currext->data),
- s->tls_session_ticket_ext_cb_arg)) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- } else if (currext->type == TLSEXT_TYPE_signature_algorithms) {
- PACKET supported_sig_algs;
-
- if (!PACKET_as_length_prefixed_2(&currext->data,
- &supported_sig_algs)
- || (PACKET_remaining(&supported_sig_algs) % 2) != 0
- || PACKET_remaining(&supported_sig_algs) == 0) {
- return 0;
- }
-
- if (!s->hit) {
- if (!tls1_save_sigalgs(s, PACKET_data(&supported_sig_algs),
- PACKET_remaining(&supported_sig_algs))) {
- return 0;
- }
- }
- } else if (currext->type == TLSEXT_TYPE_status_request) {
- if (!PACKET_get_1(&currext->data,
- (unsigned int *)&s->tlsext_status_type)) {
- return 0;
- }
-#ifndef OPENSSL_NO_OCSP
- if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
- const unsigned char *ext_data;
- PACKET responder_id_list, exts;
- if (!PACKET_get_length_prefixed_2
- (&currext->data, &responder_id_list))
- return 0;
-
- /*
- * We remove any OCSP_RESPIDs from a previous handshake
- * to prevent unbounded memory growth - CVE-2016-6304
- */
- sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids,
- OCSP_RESPID_free);
- if (PACKET_remaining(&responder_id_list) > 0) {
- s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
- if (s->tlsext_ocsp_ids == NULL) {
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- } else {
- s->tlsext_ocsp_ids = NULL;
- }
-
- while (PACKET_remaining(&responder_id_list) > 0) {
- OCSP_RESPID *id;
- PACKET responder_id;
- const unsigned char *id_data;
-
- if (!PACKET_get_length_prefixed_2(&responder_id_list,
- &responder_id)
- || PACKET_remaining(&responder_id) == 0) {
- return 0;
- }
-
- id_data = PACKET_data(&responder_id);
- /* TODO(size_t): Convert d2i_* to size_t */
- id = d2i_OCSP_RESPID(NULL, &id_data,
- (int)PACKET_remaining(&responder_id));
- if (id == NULL)
- return 0;
-
- if (id_data != PACKET_end(&responder_id)) {
- OCSP_RESPID_free(id);
- return 0;
- }
-
- if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) {
- OCSP_RESPID_free(id);
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- }
-
- /* Read in request_extensions */
- if (!PACKET_as_length_prefixed_2(
- &currext->data, &exts))
- return 0;
-
- if (PACKET_remaining(&exts) > 0) {
- ext_data = PACKET_data(&exts);
- sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
- X509_EXTENSION_free);
- s->tlsext_ocsp_exts =
- d2i_X509_EXTENSIONS(NULL, &ext_data,
- (int)PACKET_remaining(&exts));
- if (s->tlsext_ocsp_exts == NULL
- || ext_data != PACKET_end(&exts)) {
- return 0;
- }
- }
- } else
-#endif
- {
- /*
- * We don't know what to do with any other type so ignore it.
- */
- s->tlsext_status_type = -1;
- }
- }
-#ifndef OPENSSL_NO_HEARTBEATS
- else if (SSL_IS_DTLS(s) && currext->type == TLSEXT_TYPE_heartbeat) {
- unsigned int hbtype;
-
- if (!PACKET_get_1(&currext->data, &hbtype)
- || PACKET_remaining(&currext->data)) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- switch (hbtype) {
- case 0x01: /* Client allows us to send HB requests */
- s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
- break;
- case 0x02: /* Client doesn't accept HB requests */
- s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
- s->tlsext_heartbeat |= SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
- break;
- default:
- *al = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
- }
-#endif
-#ifndef OPENSSL_NO_NEXTPROTONEG
- else if (currext->type == TLSEXT_TYPE_next_proto_neg
- && s->s3->tmp.finish_md_len == 0) {
- /*-
- * We shouldn't accept this extension on a
- * renegotiation.
- *
- * s->new_session will be set on renegotiation, but we
- * probably shouldn't rely that it couldn't be set on
- * the initial renegotiation too in certain cases (when
- * there's some other reason to disallow resuming an
- * earlier session -- the current code won't be doing
- * anything like that, but this might change).
- *
- * A valid sign that there's been a previous handshake
- * in this connection is if s->s3->tmp.finish_md_len >
- * 0. (We are talking about a check that will happen
- * in the Hello protocol round, well before a new
- * Finished message could have been computed.)
- */
- s->s3->next_proto_neg_seen = 1;
- }
-#endif
-
- else if (currext->type
- == TLSEXT_TYPE_application_layer_protocol_negotiation
- && s->s3->tmp.finish_md_len == 0) {
- if (!tls1_alpn_handle_client_hello(s,
- &currext->data, al))
- return 0;
- }
-
- /* session ticket processed earlier */
-#ifndef OPENSSL_NO_SRTP
- else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
- && currext->type == TLSEXT_TYPE_use_srtp) {
- if (ssl_parse_clienthello_use_srtp_ext(s,
- &currext->data, al))
- return 0;
- }
-#endif
- else if (currext->type == TLSEXT_TYPE_encrypt_then_mac
- && !(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC))
- s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
- /*
- * Note: extended master secret extension handled in
- * tls_check_client_ems_support()
- */
-
- /*
- * If this ClientHello extension was unhandled and this is a
- * nonresumed connection, check whether the extension is a custom
- * TLS Extension (has a custom_srv_ext_record), and if so call the
- * callback and record the extension number so that an appropriate
- * ServerHello may be later returned.
- */
- else if (!s->hit) {
- if (custom_ext_parse(s, 1, currext->type,
- PACKET_data(&currext->data),
- PACKET_remaining(&currext->data), al) <= 0)
- return 0;
- }
- }
-
- /* Need RI if renegotiating */
-
- if (!renegotiate_seen && s->renegotiate &&
- !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT,
- SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
- return 0;
- }
-
- /*
- * This function currently has no state to clean up, so it returns directly.
- * If parsing fails at any point, the function returns early.
- * The SSL object may be left with partial data from extensions, but it must
- * then no longer be used, and clearing it up will free the leftovers.
- */
- return 1;
-}
-
-int ssl_parse_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello)
-{
- int al = -1;
- custom_ext_init(&s->cert->srv_ext);
- if (ssl_scan_clienthello_tlsext(s, hello, &al) <= 0) {
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
- return 0;
- }
- if (ssl_check_clienthello_tlsext_early(s) <= 0) {
- SSLerr(SSL_F_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.
- */
-static char ssl_next_proto_validate(PACKET *pkt)
-{
- PACKET tmp_protocol;
-
- while (PACKET_remaining(pkt)) {
- if (!PACKET_get_length_prefixed_1(pkt, &tmp_protocol)
- || PACKET_remaining(&tmp_protocol) == 0)
- return 0;
- }
-
- return 1;
-}
-#endif
-
-static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
-{
- unsigned int length, type, size;
- int tlsext_servername = 0;
- int renegotiate_seen = 0;
-
-#ifndef OPENSSL_NO_NEXTPROTONEG
- s->s3->next_proto_neg_seen = 0;
-#endif
- s->tlsext_ticket_expected = 0;
-
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = NULL;
-#ifndef OPENSSL_NO_HEARTBEATS
- s->tlsext_heartbeat &= ~(SSL_DTLSEXT_HB_ENABLED |
- SSL_DTLSEXT_HB_DONT_SEND_REQUESTS);
-#endif
-
- s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
-
- s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
-
- if (!PACKET_get_net_2(pkt, &length))
- goto ri_check;
-
- if (PACKET_remaining(pkt) != length) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- if (!tls1_check_duplicate_extensions(pkt)) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- while (PACKET_get_net_2(pkt, &type) && PACKET_get_net_2(pkt, &size)) {
- const unsigned char *data;
- PACKET spkt;
-
- if (!PACKET_get_sub_packet(pkt, &spkt, size)
- || !PACKET_peek_bytes(&spkt, &data, size))
- goto ri_check;
-
- if (s->tlsext_debug_cb)
- s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg);
-
- if (type == TLSEXT_TYPE_renegotiate) {
- if (!ssl_parse_serverhello_renegotiate_ext(s, &spkt, al))
- return 0;
- renegotiate_seen = 1;
- } else if (s->version == SSL3_VERSION) {
- } else if (type == TLSEXT_TYPE_server_name) {
- if (s->tlsext_hostname == NULL || size > 0) {
- *al = TLS1_AD_UNRECOGNIZED_NAME;
- return 0;
- }
- tlsext_servername = 1;
- }
-#ifndef OPENSSL_NO_EC
- else if (type == TLSEXT_TYPE_ec_point_formats) {
- unsigned int ecpointformatlist_length;
- if (!PACKET_get_1(&spkt, &ecpointformatlist_length)
- || ecpointformatlist_length != size - 1) {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
- if (!s->hit) {
- s->session->tlsext_ecpointformatlist_length = 0;
- OPENSSL_free(s->session->tlsext_ecpointformatlist);
- if ((s->session->tlsext_ecpointformatlist =
- OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- s->session->tlsext_ecpointformatlist_length =
- ecpointformatlist_length;
- if (!PACKET_copy_bytes(&spkt,
- s->session->tlsext_ecpointformatlist,
- ecpointformatlist_length)) {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
-
- }
- }
-#endif /* OPENSSL_NO_EC */
-
- else if (type == TLSEXT_TYPE_session_ticket) {
- if (s->tls_session_ticket_ext_cb &&
- !s->tls_session_ticket_ext_cb(s, data, size,
- s->tls_session_ticket_ext_cb_arg))
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- if (!tls_use_ticket(s) || (size > 0)) {
- *al = TLS1_AD_UNSUPPORTED_EXTENSION;
- return 0;
- }
- s->tlsext_ticket_expected = 1;
- } else if (type == TLSEXT_TYPE_status_request) {
- /*
- * MUST be empty and only sent if we've requested a status
- * request message.
- */
- if ((s->tlsext_status_type == -1) || (size > 0)) {
- *al = TLS1_AD_UNSUPPORTED_EXTENSION;
- return 0;
- }
- /* Set flag to expect CertificateStatus message */
- s->tlsext_status_expected = 1;
- }
-#ifndef OPENSSL_NO_CT
- /*
- * Only take it if we asked for it - i.e if there is no CT validation
- * callback set, then a custom extension MAY be processing it, so we
- * need to let control continue to flow to that.
- */
- else if (type == TLSEXT_TYPE_signed_certificate_timestamp &&
- s->ct_validation_callback != NULL) {
- /* Simply copy it off for later processing */
- if (s->tlsext_scts != NULL) {
- OPENSSL_free(s->tlsext_scts);
- s->tlsext_scts = NULL;
- }
- s->tlsext_scts_len = size;
- if (size > 0) {
- s->tlsext_scts = OPENSSL_malloc(size);
- if (s->tlsext_scts == NULL) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- memcpy(s->tlsext_scts, data, size);
- }
- }
-#endif
-#ifndef OPENSSL_NO_NEXTPROTONEG
- else if (type == TLSEXT_TYPE_next_proto_neg &&
- s->s3->tmp.finish_md_len == 0) {
- unsigned char *selected;
- unsigned char selected_len;
- /* We must have requested it. */
- if (s->ctx->next_proto_select_cb == NULL) {
- *al = TLS1_AD_UNSUPPORTED_EXTENSION;
- return 0;
- }
- /* The data must be valid */
- if (!ssl_next_proto_validate(&spkt)) {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
- if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data,
- size,
- s->
- ctx->next_proto_select_cb_arg) !=
- SSL_TLSEXT_ERR_OK) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- /*
- * Could be non-NULL if server has sent multiple NPN extensions in
- * a single Serverhello
- */
- OPENSSL_free(s->next_proto_negotiated);
- s->next_proto_negotiated = OPENSSL_malloc(selected_len);
- if (s->next_proto_negotiated == NULL) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- memcpy(s->next_proto_negotiated, selected, selected_len);
- s->next_proto_negotiated_len = selected_len;
- s->s3->next_proto_neg_seen = 1;
- }
-#endif
-
- else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) {
- unsigned len;
- /* We must have requested it. */
- if (!s->s3->alpn_sent) {
- *al = TLS1_AD_UNSUPPORTED_EXTENSION;
- return 0;
- }
- /*-
- * The extension data consists of:
- * uint16 list_length
- * uint8 proto_length;
- * uint8 proto[proto_length];
- */
- if (!PACKET_get_net_2(&spkt, &len)
- || PACKET_remaining(&spkt) != len || !PACKET_get_1(&spkt, &len)
- || PACKET_remaining(&spkt) != len) {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = OPENSSL_malloc(len);
- if (s->s3->alpn_selected == NULL) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- if (!PACKET_copy_bytes(&spkt, s->s3->alpn_selected, len)) {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
- s->s3->alpn_selected_len = len;
- }
-#ifndef OPENSSL_NO_HEARTBEATS
- else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_heartbeat) {
- unsigned int hbtype;
- if (!PACKET_get_1(&spkt, &hbtype)) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- switch (hbtype) {
- case 0x01: /* Server allows us to send HB requests */
- s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
- break;
- case 0x02: /* Server doesn't accept HB requests */
- s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
- s->tlsext_heartbeat |= SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
- break;
- default:
- *al = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
- }
-#endif
-#ifndef OPENSSL_NO_SRTP
- else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) {
- if (ssl_parse_serverhello_use_srtp_ext(s, &spkt, al))
- return 0;
- }
-#endif
- else if (type == TLSEXT_TYPE_encrypt_then_mac) {
- /* Ignore if inappropriate ciphersuite */
- if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC) &&
- s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
- && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
- s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
- } else if (type == TLSEXT_TYPE_extended_master_secret) {
- s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
- if (!s->hit)
- s->session->flags |= SSL_SESS_FLAG_EXTMS;
- }
- /*
- * If this extension type was not otherwise handled, but matches a
- * custom_cli_ext_record, then send it to the c callback
- */
- else if (custom_ext_parse(s, 0, type, data, size, al) <= 0)
- return 0;
- }
-
- if (PACKET_remaining(pkt) != 0) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- if (!s->hit && tlsext_servername == 1) {
- if (s->tlsext_hostname) {
- if (s->session->tlsext_hostname == NULL) {
- s->session->tlsext_hostname =
- OPENSSL_strdup(s->tlsext_hostname);
- if (!s->session->tlsext_hostname) {
- *al = SSL_AD_UNRECOGNIZED_NAME;
- return 0;
- }
- } else {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- }
- }
-
- ri_check:
-
- /*
- * Determine if we need to see RI. Strictly speaking if we want to avoid
- * an attack we should *always* see RI even on initial server hello
- * because the client doesn't see any renegotiation during an attack.
- * However this would mean we could not connect to any server which
- * doesn't support RI so for the immediate future tolerate RI absence
- */
- if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
- && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
- SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
- return 0;
- }
-
- if (s->hit) {
- /*
- * Check extended master secret extension is consistent with
- * original session.
- */
- if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) !=
- !(s->session->flags & SSL_SESS_FLAG_EXTMS)) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, SSL_R_INCONSISTENT_EXTMS);
- return 0;
- }
- }
-
- return 1;