-
- 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,
- 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 |pkt|.
- * 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 PACKET *pkt)
-{
- 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 = *pkt;
-
- 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 */
-
-/*
- * Parse ClientHello extensions and stash extension info in various parts of
- * the SSL object. Verify that there are no duplicate extensions.
- *
- * Behaviour upon resumption is extension-specific. If the extension has no
- * effect during resumption, it is parsed (to verify its format) but otherwise
- * ignored.
- *
- * Consumes the entire packet in |pkt|. Returns 1 on success and 0 on failure.
- * Upon failure, sets |al| to the appropriate alert.
- */
-static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
-{
- unsigned int type;
- int renegotiate_seen = 0;
- PACKET extensions;
-
- *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, pkt);
-#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;
-
- if (PACKET_remaining(pkt) == 0)
- goto ri_check;
-
- if (!PACKET_as_length_prefixed_2(pkt, &extensions))
- return 0;
-
- if (!tls1_check_duplicate_extensions(&extensions))
- return 0;
-
- /*
- * We parse all extensions to ensure the ClientHello is well-formed but,
- * unless an extension specifies otherwise, we ignore extensions upon
- * resumption.
- */
- while (PACKET_get_net_2(&extensions, &type)) {
- PACKET extension;
- if (!PACKET_get_length_prefixed_2(&extensions, &extension))
- return 0;
-
- if (s->tlsext_debug_cb)
- s->tlsext_debug_cb(s, 0, type, PACKET_data(&extension),
- PACKET_remaining(&extension),
- s->tlsext_debug_arg);
-
- if (type == TLSEXT_TYPE_renegotiate) {
- if (!ssl_parse_clienthello_renegotiate_ext(s, &extension, 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 (type == TLSEXT_TYPE_server_name) {
- unsigned int servname_type;
- PACKET sni, hostname;
-
- if (!PACKET_as_length_prefixed_2(&extension, &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 (type == TLSEXT_TYPE_srp) {
- PACKET srp_I;
-
- if (!PACKET_as_length_prefixed_1(&extension, &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 (type == TLSEXT_TYPE_ec_point_formats) {
- PACKET ec_point_format_list;
-
- if (!PACKET_as_length_prefixed_1(&extension, &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 (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(&extension, &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 (type == TLSEXT_TYPE_session_ticket) {
- if (s->tls_session_ticket_ext_cb &&
- !s->tls_session_ticket_ext_cb(s, PACKET_data(&extension),
- PACKET_remaining(&extension),
- s->tls_session_ticket_ext_cb_arg))
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_signature_algorithms) {
- PACKET supported_sig_algs;
-
- if (!PACKET_as_length_prefixed_2(&extension, &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 (type == TLSEXT_TYPE_status_request) {
- if (!PACKET_get_1(&extension,
- (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
- (&extension, &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);
- id = d2i_OCSP_RESPID(NULL, &id_data,
- 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(&extension, &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,
- 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) && type == TLSEXT_TYPE_heartbeat) {
- unsigned int hbtype;
-
- if (!PACKET_get_1(&extension, &hbtype)
- || PACKET_remaining(&extension)) {
- *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 (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 (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
- s->s3->tmp.finish_md_len == 0) {
- if (!tls1_alpn_handle_client_hello(s, &extension, al))
- return 0;
- }
-
- /* session ticket processed earlier */
-#ifndef OPENSSL_NO_SRTP
- else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
- && type == TLSEXT_TYPE_use_srtp) {
- if (ssl_parse_clienthello_use_srtp_ext(s, &extension, al))
- return 0;
- }
-#endif
- else if (type == TLSEXT_TYPE_encrypt_then_mac)
- s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
- /*
- * Note: extended master secret extension handled in
- * tls_check_serverhello_tlsext_early()
- */
-
- /*
- * 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, type, PACKET_data(&extension),
- PACKET_remaining(&extension), al) <= 0)
- return 0;
- }
- }
-
- if (PACKET_remaining(pkt) != 0) {
- /*
- * tls1_check_duplicate_extensions should ensure this never happens.
- */
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
-
- ri_check:
-
- /* 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, PACKET *pkt)
-{
- int al = -1;
- custom_ext_init(&s->cert->srv_ext);
- if (ssl_scan_clienthello_tlsext(s, pkt, &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->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;
-}
-
-int ssl_prepare_clienthello_tlsext(SSL *s)
-{
- s->s3->alpn_sent = 0;
- return 1;
-}
-
-int ssl_prepare_serverhello_tlsext(SSL *s)
-{
- return 1;
-}
-
-static int ssl_check_clienthello_tlsext_early(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);
- 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);
-
- switch (ret) {
- case SSL_TLSEXT_ERR_ALERT_FATAL:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
- return -1;
-
- case SSL_TLSEXT_ERR_ALERT_WARNING:
- ssl3_send_alert(s, SSL3_AL_WARNING, al);
- return 1;
-
- case SSL_TLSEXT_ERR_NOACK:
- s->servername_done = 0;
- default:
- return 1;
- }
-}
-
-/* Initialise digests to default values */
-void ssl_set_default_md(SSL *s)
-{
- const EVP_MD **pmd = s->s3->tmp.md;
-#ifndef OPENSSL_NO_DSA
- pmd[SSL_PKEY_DSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX);
-#endif
-#ifndef OPENSSL_NO_RSA
- if (SSL_USE_SIGALGS(s))
- pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX);
- else
- pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_MD5_SHA1_IDX);
- pmd[SSL_PKEY_RSA_ENC] = pmd[SSL_PKEY_RSA_SIGN];
-#endif
-#ifndef OPENSSL_NO_EC
- pmd[SSL_PKEY_ECC] = ssl_md(SSL_MD_SHA1_IDX);
-#endif
-#ifndef OPENSSL_NO_GOST
- pmd[SSL_PKEY_GOST01] = ssl_md(SSL_MD_GOST94_IDX);
- pmd[SSL_PKEY_GOST12_256] = ssl_md(SSL_MD_GOST12_256_IDX);
- pmd[SSL_PKEY_GOST12_512] = ssl_md(SSL_MD_GOST12_512_IDX);
-#endif
-}
-
-int tls1_set_server_sigalgs(SSL *s)
-{
- int al;
- size_t i;
-
- /* Clear any shared signature algorithms */
- OPENSSL_free(s->cert->shared_sigalgs);
- s->cert->shared_sigalgs = NULL;
- s->cert->shared_sigalgslen = 0;
- /* Clear certificate digests and validity flags */
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- s->s3->tmp.md[i] = NULL;
- s->s3->tmp.valid_flags[i] = 0;
- }
-
- /* If sigalgs received process it. */
- if (s->s3->tmp.peer_sigalgs) {
- if (!tls1_process_sigalgs(s)) {
- SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
- al = SSL_AD_INTERNAL_ERROR;
- goto err;
- }
- /* Fatal error is no shared signature algorithms */
- if (!s->cert->shared_sigalgs) {
- SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
- SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS);
- al = SSL_AD_ILLEGAL_PARAMETER;
- goto err;
- }
- } else {
- ssl_set_default_md(s);
- }
- return 1;
- err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
- return 0;
-}
-
-/*
- * Upon success, returns 1.
- * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
- */
-int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
-{
- s->tlsext_status_expected = 0;
-
- /*
- * If status request then ask callback what to do. Note: this must be
- * called after servername callbacks in case the certificate has changed,
- * and must be called after the cipher has been chosen because this may
- * influence which certificate is sent
- */
- if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
- int ret;
- CERT_PKEY *certpkey;
- certpkey = ssl_get_server_send_pkey(s);
- /* If no certificate can't return certificate status */
- if (certpkey != NULL) {
- /*
- * Set current certificate to one we will use so SSL_get_certificate
- * et al can pick it up.
- */
- s->cert->key = certpkey;
- ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
- switch (ret) {
- /* We don't want to send a status request response */
- case SSL_TLSEXT_ERR_NOACK:
- s->tlsext_status_expected = 0;
- break;
- /* status request response should be sent */
- case SSL_TLSEXT_ERR_OK:
- if (s->tlsext_ocsp_resp)
- s->tlsext_status_expected = 1;
- break;
- /* something bad happened */
- case SSL_TLSEXT_ERR_ALERT_FATAL:
- default:
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- }
- }
-
- if (!tls1_alpn_handle_client_hello_late(s, al)) {
- return 0;
- }
-
- return 1;
-}
-
-int ssl_check_serverhello_tlsext(SSL *s)
-{
- int ret = SSL_TLSEXT_ERR_NOACK;
- int al = SSL_AD_UNRECOGNIZED_NAME;
-
-#ifndef OPENSSL_NO_EC
- /*
- * If we are client and using an elliptic curve cryptography cipher
- * suite, then if server returns an EC point formats lists extension it
- * must contain uncompressed.
- */
- unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- if ((s->tlsext_ecpointformatlist != NULL)
- && (s->tlsext_ecpointformatlist_length > 0)
- && (s->session->tlsext_ecpointformatlist != NULL)
- && (s->session->tlsext_ecpointformatlist_length > 0)
- && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA))) {
- /* we are using an ECC cipher */
- size_t i;
- unsigned char *list;
- int found_uncompressed = 0;
- list = s->session->tlsext_ecpointformatlist;
- for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) {
- if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) {
- found_uncompressed = 1;
- break;
- }
- }
- if (!found_uncompressed) {
- SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,
- SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
- return -1;
- }
- }
- ret = SSL_TLSEXT_ERR_OK;
-#endif /* OPENSSL_NO_EC */
-
- if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
- ret =
- s->ctx->tlsext_servername_callback(s, &al,
- s->ctx->tlsext_servername_arg);
- else if (s->initial_ctx != NULL
- && s->initial_ctx->tlsext_servername_callback != 0)
- ret =
- s->initial_ctx->tlsext_servername_callback(s, &al,
- s->
- initial_ctx->tlsext_servername_arg);
-
- /*
- * Ensure we get sensible values passed to tlsext_status_cb in the event
- * that we don't receive a status message
- */
- OPENSSL_free(s->tlsext_ocsp_resp);
- s->tlsext_ocsp_resp = NULL;
- s->tlsext_ocsp_resplen = -1;
-
- switch (ret) {
- case SSL_TLSEXT_ERR_ALERT_FATAL:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
- return -1;
-
- case SSL_TLSEXT_ERR_ALERT_WARNING:
- ssl3_send_alert(s, SSL3_AL_WARNING, al);
- return 1;
-
- case SSL_TLSEXT_ERR_NOACK:
- s->servername_done = 0;
- default:
- return 1;
- }
-}
-
-int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt)
-{
- int al = -1;
- if (s->version < SSL3_VERSION)
- return 1;
- if (ssl_scan_serverhello_tlsext(s, pkt, &al) <= 0) {
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
- return 0;
- }
-
- if (ssl_check_serverhello_tlsext(s) <= 0) {
- SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT);
- return 0;
- }
- return 1;
-}
-
-/*-
- * Since the server cache lookup is done early on in the processing of the
- * ClientHello and other operations depend on the result some extensions
- * need to be handled at the same time.
- *
- * Two extensions are currently handled, session ticket and extended master
- * secret.
- *
- * session_id: ClientHello session ID.
- * ext: ClientHello extensions (including length prefix)
- * ret: (output) on return, if a ticket was decrypted, then this is set to
- * point to the resulting session.
- *
- * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
- * ciphersuite, in which case we have no use for session tickets and one will
- * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
- *
- * Returns:
- * -1: fatal error, either from parsing or decrypting the ticket.
- * 0: no ticket was found (or was ignored, based on settings).
- * 1: a zero length extension was found, indicating that the client supports
- * session tickets but doesn't currently have one to offer.
- * 2: either s->tls_session_secret_cb was set, or a ticket was offered but
- * couldn't be decrypted because of a non-fatal error.
- * 3: a ticket was successfully decrypted and *ret was set.
- *
- * Side effects:
- * Sets s->tlsext_ticket_expected to 1 if the server will have to issue
- * a new session ticket to the client because the client indicated support
- * (and s->tls_session_secret_cb is NULL) but the client either doesn't have
- * a session ticket or we couldn't use the one it gave us, or if
- * s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
- * Otherwise, s->tlsext_ticket_expected is set to 0.
- *
- * For extended master secret flag is set if the extension is present.
- *
- */
-int tls_check_serverhello_tlsext_early(SSL *s, const PACKET *ext,
- const PACKET *session_id,
- SSL_SESSION **ret)
-{
- unsigned int i;
- PACKET local_ext = *ext;
- int retv = -1;
-
- int have_ticket = 0;
- int use_ticket = tls_use_ticket(s);
-
- *ret = NULL;
- s->tlsext_ticket_expected = 0;
- s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
-
- /*
- * If tickets disabled behave as if no ticket present to permit stateful
- * resumption.
- */
- if ((s->version <= SSL3_VERSION))
- return 0;
-
- if (!PACKET_get_net_2(&local_ext, &i)) {
- retv = 0;
- goto end;
- }
- while (PACKET_remaining(&local_ext) >= 4) {
- unsigned int type, size;
-
- if (!PACKET_get_net_2(&local_ext, &type)
- || !PACKET_get_net_2(&local_ext, &size)) {
- /* Shouldn't ever happen */
- retv = -1;
- goto end;
- }
- if (PACKET_remaining(&local_ext) < size) {
- retv = 0;
- goto end;
- }
- if (type == TLSEXT_TYPE_session_ticket && use_ticket) {
- int r;
- const unsigned char *etick;
-
- /* Duplicate extension */
- if (have_ticket != 0) {
- retv = -1;
- goto end;
- }
- have_ticket = 1;
-
- if (size == 0) {
- /*
- * The client will accept a ticket but doesn't currently have
- * one.
- */
- s->tlsext_ticket_expected = 1;
- retv = 1;
- continue;
- }
- if (s->tls_session_secret_cb) {
- /*
- * Indicate that the ticket couldn't be decrypted rather than
- * generating the session from ticket now, trigger
- * abbreviated handshake based on external mechanism to
- * calculate the master secret later.
- */
- retv = 2;
- continue;
- }
- if (!PACKET_get_bytes(&local_ext, &etick, size)) {
- /* Shouldn't ever happen */
- retv = -1;
- goto end;
- }
- r = tls_decrypt_ticket(s, etick, size, PACKET_data(session_id),
- PACKET_remaining(session_id), ret);
- switch (r) {
- case 2: /* ticket couldn't be decrypted */
- s->tlsext_ticket_expected = 1;
- retv = 2;
- break;
- case 3: /* ticket was decrypted */
- retv = r;
- break;
- case 4: /* ticket decrypted but need to renew */
- s->tlsext_ticket_expected = 1;
- retv = 3;
- break;
- default: /* fatal error */
- retv = -1;
- break;
- }
- continue;
- } else {
- if (type == TLSEXT_TYPE_extended_master_secret)
- s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
- if (!PACKET_forward(&local_ext, size)) {
- retv = -1;
- goto end;
- }
- }
- }
- if (have_ticket == 0)
- retv = 0;
- end:
- return retv;