X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fextensions_srvr.c;h=549a207430386e411eaf4f516507a01de16bf037;hp=7c9a3f7a6a66079fe6c70e8ab0d1f236cac80da4;hb=fc69f32cd6852e60627969138be80cc665a573dd;hpb=f929439f61e7e4cf40e06de56880758b5344f198 diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 7c9a3f7a6a..549a207430 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1,15 +1,15 @@ /* * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include -#include "../ssl_locl.h" -#include "statem_locl.h" +#include "../ssl_local.h" +#include "statem_local.h" #include "internal/cryptlib.h" #define COOKIE_STATE_FORMAT_VERSION 0 @@ -53,20 +53,20 @@ int tls_parse_ctos_renegotiate(SSL *s, PACKET *pkt, unsigned int context, } /* Check that the extension matches */ - if (ilen != s->s3->previous_client_finished_len) { + if (ilen != s->s3.previous_client_finished_len) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PARSE_CTOS_RENEGOTIATE, SSL_R_RENEGOTIATION_MISMATCH); return 0; } - if (memcmp(data, s->s3->previous_client_finished, - s->s3->previous_client_finished_len)) { + if (memcmp(data, s->s3.previous_client_finished, + s->s3.previous_client_finished_len)) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PARSE_CTOS_RENEGOTIATE, SSL_R_RENEGOTIATION_MISMATCH); return 0; } - s->s3->send_connection_binding = 1; + s->s3.send_connection_binding = 1; return 1; } @@ -127,7 +127,11 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, return 0; } - if (!s->hit) { + /* + * In TLSv1.2 and below the SNI is associated with the session. In TLSv1.3 + * we always use the SNI value from the handshake. + */ + if (!s->hit || SSL_IS_TLS13(s)) { if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) { SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME, SSL_F_TLS_PARSE_CTOS_SERVER_NAME, @@ -142,9 +146,13 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, return 0; } - OPENSSL_free(s->session->ext.hostname); - s->session->ext.hostname = NULL; - if (!PACKET_strndup(&hostname, &s->session->ext.hostname)) { + /* + * Store the requested SNI in the SSL as temporary storage. + * If we accept it, it will get stored in the SSL_SESSION as well. + */ + OPENSSL_free(s->ext.hostname); + s->ext.hostname = NULL; + if (!PACKET_strndup(&hostname, &s->ext.hostname)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_SERVER_NAME, ERR_R_INTERNAL_ERROR); return 0; @@ -152,16 +160,18 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, s->servername_done = 1; } else { + /* + * In TLSv1.2 and below we should check if the SNI is consistent between + * the initial handshake and the resumption. In TLSv1.3 SNI is not + * associated with the session. + */ /* * TODO(openssl-team): if the SNI doesn't match, we MUST * fall back to a full handshake. */ - s->servername_done = s->session->ext.hostname + s->servername_done = (s->session->ext.hostname != NULL) && PACKET_equal(&hostname, s->session->ext.hostname, strlen(s->session->ext.hostname)); - - if (!s->servername_done && s->session->ext.hostname != NULL) - s->ext.early_data_ok = 0; } return 1; @@ -249,8 +259,8 @@ int tls_parse_ctos_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, if (!s->hit) { if (!PACKET_memdup(&ec_point_format_list, - &s->session->ext.ecpointformats, - &s->session->ext.ecpointformats_len)) { + &s->ext.peer_ecpointformats, + &s->ext.peer_ecpointformats_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR); return 0; @@ -324,6 +334,10 @@ int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, { PACKET responder_id_list, exts; + /* We ignore this in a resumption handshake */ + if (s->hit) + return 1; + /* Not defined if we get one of these in a client Certificate */ if (x != NULL) return 1; @@ -437,7 +451,7 @@ int tls_parse_ctos_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * renegotiation. */ if (SSL_IS_FIRST_HANDSHAKE(s)) - s->s3->npn_seen = 1; + s->s3.npn_seen = 1; return 1; } @@ -473,11 +487,11 @@ int tls_parse_ctos_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } } while (PACKET_remaining(&protocol_list) != 0); - OPENSSL_free(s->s3->alpn_proposed); - s->s3->alpn_proposed = NULL; - s->s3->alpn_proposed_len = 0; + OPENSSL_free(s->s3.alpn_proposed); + s->s3.alpn_proposed = NULL; + s->s3.alpn_proposed_len = 0; if (!PACKET_memdup(&save_protocol_list, - &s->s3->alpn_proposed, &s->s3->alpn_proposed_len)) { + &s->s3.alpn_proposed, &s->s3.alpn_proposed_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_ALPN, ERR_R_INTERNAL_ERROR); return 0; @@ -612,7 +626,7 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; /* Sanity check */ - if (s->s3->peer_tmp != NULL) { + if (s->s3.peer_tmp != NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR); return 0; @@ -639,7 +653,7 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } - if (s->s3->group_id != 0 && PACKET_remaining(&key_share_list) == 0) { + if (s->s3.group_id != 0 && PACKET_remaining(&key_share_list) == 0) { /* * If we set a group_id already, then we must have sent an HRR * requesting a new key_share. If we haven't got one then that is an @@ -670,8 +684,8 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * If we sent an HRR then the key_share sent back MUST be for the group * we requested, and must be the only key_share sent. */ - if (s->s3->group_id != 0 - && (group_id != s->s3->group_id + if (s->s3.group_id != 0 + && (group_id != s->s3.group_id || PACKET_remaining(&key_share_list) != 0)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_BAD_KEY_SHARE); @@ -691,15 +705,15 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, continue; } - if ((s->s3->peer_tmp = ssl_generate_param_group(group_id)) == NULL) { + if ((s->s3.peer_tmp = ssl_generate_param_group(s, group_id)) == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); return 0; } - s->s3->group_id = group_id; + s->s3.group_id = group_id; - if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp, + if (!EVP_PKEY_set1_tls_encodedpoint(s->s3.peer_tmp, PACKET_data(&encoded_pt), PACKET_remaining(&encoded_pt))) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, @@ -717,6 +731,7 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { +#ifndef OPENSSL_NO_TLS1_3 unsigned int format, version, key_share, group_id; EVP_MD_CTX *hctx; EVP_PKEY *pkey; @@ -730,7 +745,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* Ignore any cookie if we're not set up to verify it */ if (s->ctx->verify_stateless_cookie_cb == NULL - || (s->s3->flags & TLS1_FLAGS_STATELESS) == 0) + || (s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return 1; if (!PACKET_as_length_prefixed_2(pkt, &cookie)) { @@ -765,7 +780,8 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } hmaclen = SHA256_DIGEST_LENGTH; - if (EVP_DigestSignInit(hctx, NULL, EVP_sha256(), NULL, pkey) <= 0 + if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->propq, pkey, + s->ctx->libctx) <= 0 || EVP_DigestSign(hctx, hmac, &hmaclen, data, rawlen - SHA256_DIGEST_LENGTH) <= 0 || hmaclen != SHA256_DIGEST_LENGTH) { @@ -823,8 +839,8 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, SSL_R_LENGTH_MISMATCH); return 0; } - if (group_id != s->s3->group_id - || s->s3->tmp.new_cipher + if (group_id != s->s3.group_id + || s->s3.tmp.new_cipher != ssl_get_cipher_by_char(s, ciphdata, 0)) { /* * We chose a different cipher or group id this time around to what is @@ -876,7 +892,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, || !WPACKET_memcpy(&hrrpkt, hrrrandom, SSL3_RANDOM_SIZE) || !WPACKET_sub_memcpy_u8(&hrrpkt, s->tmp_session_id, s->tmp_session_id_len) - || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, &hrrpkt, + || !s->method->put_cipher_by_char(s->s3.tmp.new_cipher, &hrrpkt, &ciphlen) || !WPACKET_put_bytes_u8(&hrrpkt, 0) || !WPACKET_start_sub_packet_u16(&hrrpkt)) { @@ -887,8 +903,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_supported_versions) || !WPACKET_start_sub_packet_u16(&hrrpkt) - /* TODO(TLS1.3): Fix this before release */ - || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_3_VERSION_DRAFT) + || !WPACKET_put_bytes_u16(&hrrpkt, s->version) || !WPACKET_close(&hrrpkt)) { WPACKET_cleanup(&hrrpkt); SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, @@ -898,7 +913,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (key_share) { if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_key_share) || !WPACKET_start_sub_packet_u16(&hrrpkt) - || !WPACKET_put_bytes_u16(&hrrpkt, s->s3->group_id) + || !WPACKET_put_bytes_u16(&hrrpkt, s->s3.group_id) || !WPACKET_close(&hrrpkt)) { WPACKET_cleanup(&hrrpkt); SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, @@ -932,11 +947,12 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, s->hello_retry_request = 1; s->ext.cookieok = 1; +#endif return 1; } -#ifndef OPENSSL_NO_EC +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -952,12 +968,12 @@ int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context, } if (!s->hit || SSL_IS_TLS13(s)) { - OPENSSL_free(s->session->ext.supportedgroups); - s->session->ext.supportedgroups = NULL; - s->session->ext.supportedgroups_len = 0; + OPENSSL_free(s->ext.peer_supportedgroups); + s->ext.peer_supportedgroups = NULL; + s->ext.peer_supportedgroups_len = 0; if (!tls1_save_u16(&supported_groups_list, - &s->session->ext.supportedgroups, - &s->session->ext.supportedgroups_len)) { + &s->ext.peer_supportedgroups, + &s->ext.peer_supportedgroups_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); @@ -979,7 +995,10 @@ int tls_parse_ctos_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } - s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS; + if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET) + return 1; + + s->s3.flags |= TLS1_FLAGS_RECEIVED_EXTMS; return 1; } @@ -1003,6 +1022,34 @@ int tls_parse_ctos_early_data(SSL *s, PACKET *pkt, unsigned int context, return 1; } +static SSL_TICKET_STATUS tls_get_stateful_ticket(SSL *s, PACKET *tick, + SSL_SESSION **sess) +{ + SSL_SESSION *tmpsess = NULL; + + s->ext.ticket_expected = 1; + + switch (PACKET_remaining(tick)) { + case 0: + return SSL_TICKET_EMPTY; + + case SSL_MAX_SSL_SESSION_ID_LENGTH: + break; + + default: + return SSL_TICKET_NO_DECRYPT; + } + + tmpsess = lookup_sess_in_cache(s, PACKET_data(tick), + SSL_MAX_SSL_SESSION_ID_LENGTH); + + if (tmpsess == NULL) + return SSL_TICKET_NO_DECRYPT; + + *sess = tmpsess; + return SSL_TICKET_SUCCESS; +} + int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1026,6 +1073,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } + s->ext.ticket_expected = 0; for (id = 0; PACKET_remaining(&identities) != 0; id++) { PACKET identity; unsigned long ticket_agel; @@ -1047,6 +1095,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } +#ifndef OPENSSL_NO_PSK if(sess == NULL && s->psk_server_callback != NULL && idlen <= PSK_MAX_IDENTITY_LEN) { @@ -1097,6 +1146,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, OPENSSL_cleanse(pskdata, pskdatalen); } } +#endif /* OPENSSL_NO_PSK */ if (sess != NULL) { /* We found a PSK */ @@ -1119,21 +1169,49 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, ext = 1; if (id == 0) s->ext.early_data_ok = 1; + s->ext.ticket_expected = 1; } else { uint32_t ticket_age = 0, now, agesec, agems; - int ret = tls_decrypt_ticket(s, PACKET_data(&identity), + int ret; + + /* + * If we are using anti-replay protection then we behave as if + * SSL_OP_NO_TICKET is set - we are caching tickets anyway so there + * is no point in using full stateless tickets. + */ + if ((s->options & SSL_OP_NO_TICKET) != 0 + || (s->max_early_data > 0 + && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0)) + ret = tls_get_stateful_ticket(s, &identity, &sess); + else + ret = tls_decrypt_ticket(s, PACKET_data(&identity), PACKET_remaining(&identity), NULL, 0, &sess); + if (ret == SSL_TICKET_EMPTY) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, + SSL_R_BAD_EXTENSION); + return 0; + } + if (ret == SSL_TICKET_FATAL_ERR_MALLOC || ret == SSL_TICKET_FATAL_ERR_OTHER) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, ERR_R_INTERNAL_ERROR); return 0; } - if (ret == SSL_TICKET_NO_DECRYPT) + if (ret == SSL_TICKET_NONE || ret == SSL_TICKET_NO_DECRYPT) continue; + /* Check for replay */ + if (s->max_early_data > 0 + && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0 + && !SSL_CTX_remove_session(s->session_ctx, sess)) { + SSL_SESSION_free(sess); + sess = NULL; + continue; + } + ticket_age = (uint32_t)ticket_agel; now = (uint32_t)time(NULL); agesec = now - (uint32_t)sess->time; @@ -1161,12 +1239,14 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } } - md = ssl_md(sess->cipher->algorithm2); - if (md != ssl_md(s->s3->tmp.new_cipher->algorithm2)) { + md = ssl_md(s->ctx, sess->cipher->algorithm2); + if (!EVP_MD_is_a(md, + EVP_MD_name(ssl_md(s->ctx, s->s3.tmp.new_cipher->algorithm2)))) { /* The ciphersuite is not compatible with this session. */ SSL_SESSION_free(sess); sess = NULL; s->ext.early_data_ok = 0; + s->ext.ticket_expected = 0; continue; } break; @@ -1204,7 +1284,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, goto err; } - sess->ext.tick_identity = id; + s->ext.tick_identity = id; SSL_SESSION_free(s->session); s->session = sess; @@ -1235,17 +1315,17 @@ EXT_RETURN tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - if (!s->s3->send_connection_binding) + if (!s->s3.send_connection_binding) return EXT_RETURN_NOT_SENT; /* Still add this even if SSL_OP_NO_RENEGOTIATION is set */ if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_start_sub_packet_u8(pkt) - || !WPACKET_memcpy(pkt, s->s3->previous_client_finished, - s->s3->previous_client_finished_len) - || !WPACKET_memcpy(pkt, s->s3->previous_server_finished, - s->s3->previous_server_finished_len) + || !WPACKET_memcpy(pkt, s->s3.previous_client_finished, + s->s3.previous_client_finished_len) + || !WPACKET_memcpy(pkt, s->s3.previous_server_finished, + s->s3.previous_server_finished_len) || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE, @@ -1260,8 +1340,14 @@ EXT_RETURN tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - if (s->hit || s->servername_done != 1 - || s->session->ext.hostname == NULL) + if (s->servername_done != 1) + return EXT_RETURN_NOT_SENT; + + /* + * Prior to TLSv1.3 we ignore any SNI in the current handshake if resuming. + * We just use the servername from the initial handshake. + */ + if (s->hit && !SSL_IS_TLS13(s)) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name) @@ -1303,10 +1389,10 @@ EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; + 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)) - && (s->session->ext.ecpointformats != NULL); + && (s->ext.peer_ecpointformats != NULL); const unsigned char *plist; size_t plistlen; @@ -1327,7 +1413,7 @@ EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, } #endif -#ifndef OPENSSL_NO_EC +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) @@ -1335,8 +1421,8 @@ EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, const uint16_t *groups; size_t numgroups, i, first = 1; - /* s->s3->group_id is non zero if we accepted a key_share */ - if (s->s3->group_id == 0) + /* s->s3.group_id is non zero if we accepted a key_share */ + if (s->s3.group_id == 0) return EXT_RETURN_NOT_SENT; /* Get our list of supported groups */ @@ -1351,13 +1437,14 @@ EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, for (i = 0; i < numgroups; i++) { uint16_t group = groups[i]; - if (tls_curve_allowed(s, group, SSL_SECOP_CURVE_SUPPORTED)) { + if (tls_valid_group(s, group, SSL_version(s)) + && tls_group_allowed(s, group, SSL_SECOP_CURVE_SUPPORTED)) { if (first) { /* * Check if the client is already using our preferred group. If * so we don't need to add this extension */ - if (s->s3->group_id == group) + if (s->s3.group_id == group) return EXT_RETURN_NOT_SENT; /* Add extension header */ @@ -1417,6 +1504,10 @@ EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { + /* We don't currently support this extension inside a CertificateRequest */ + if (context == SSL_EXT_TLS1_3_CERTIFICATE_REQUEST) + return EXT_RETURN_NOT_SENT; + if (!s->ext.status_expected) return EXT_RETURN_NOT_SENT; @@ -1457,9 +1548,9 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, const unsigned char *npa; unsigned int npalen; int ret; - int npn_seen = s->s3->npn_seen; + int npn_seen = s->s3.npn_seen; - s->s3->npn_seen = 0; + s->s3.npn_seen = 0; if (!npn_seen || s->ctx->ext.npn_advertised_cb == NULL) return EXT_RETURN_NOT_SENT; @@ -1473,7 +1564,7 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - s->s3->npn_seen = 1; + s->s3.npn_seen = 1; } return EXT_RETURN_SENT; @@ -1483,15 +1574,15 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, EXT_RETURN tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - if (s->s3->alpn_selected == NULL) + if (s->s3.alpn_selected == NULL) return EXT_RETURN_NOT_SENT; 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_sub_memcpy_u8(pkt, s->s3.alpn_selected, + s->s3.alpn_selected_len) || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, @@ -1535,10 +1626,10 @@ EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, * 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) { + 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->ext.use_etm = 0; return EXT_RETURN_NOT_SENT; } @@ -1556,7 +1647,7 @@ EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, EXT_RETURN tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - if ((s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) + if ((s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret) @@ -1582,8 +1673,7 @@ EXT_RETURN tls_construct_stoc_supported_versions(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions) || !WPACKET_start_sub_packet_u16(pkt) - /* TODO(TLS1.3): Update to remove the TLSv1.3 draft indicator */ - || !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT) + || !WPACKET_put_bytes_u16(pkt, s->version) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS, @@ -1601,7 +1691,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, #ifndef OPENSSL_NO_TLS1_3 unsigned char *encodedPoint; size_t encoded_pt_len = 0; - EVP_PKEY *ckey = s->s3->peer_tmp, *skey = NULL; + EVP_PKEY *ckey = s->s3.peer_tmp, *skey = NULL; if (s->hello_retry_request == SSL_HRR_PENDING) { if (ckey != NULL) { @@ -1610,7 +1700,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, } if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share) || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_put_bytes_u16(pkt, s->s3->group_id) + || !WPACKET_put_bytes_u16(pkt, s->s3.group_id) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, @@ -1633,13 +1723,13 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share) || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_put_bytes_u16(pkt, s->s3->group_id)) { + || !WPACKET_put_bytes_u16(pkt, s->s3.group_id)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - skey = ssl_generate_pkey(ckey); + skey = ssl_generate_pkey(s, ckey); if (skey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_MALLOC_FAILURE); @@ -1666,19 +1756,21 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, OPENSSL_free(encodedPoint); /* This causes the crypto state to be updated based on the derived keys */ - s->s3->tmp.pkey = skey; + s->s3.tmp.pkey = skey; if (ssl_derive(s, skey, ckey, 1) == 0) { /* SSLfatal() already called */ return EXT_RETURN_FAIL; } -#endif - return EXT_RETURN_SENT; +#else + return EXT_RETURN_FAIL; +#endif } EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { +#ifndef OPENSSL_NO_TLS1_3 unsigned char *hashval1, *hashval2, *appcookie1, *appcookie2, *cookie; unsigned char *hmac, *hmac2; size_t startlen, ciphlen, totcookielen, hashlen, hmaclen, appcookielen; @@ -1686,7 +1778,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, EVP_PKEY *pkey; int ret = EXT_RETURN_FAIL; - if ((s->s3->flags & TLS1_FLAGS_STATELESS) == 0) + if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return EXT_RETURN_NOT_SENT; if (s->ctx->gen_stateless_cookie_cb == NULL) { @@ -1702,11 +1794,11 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_reserve_bytes(pkt, MAX_COOKIE_SIZE, &cookie) || !WPACKET_put_bytes_u16(pkt, COOKIE_STATE_FORMAT_VERSION) || !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION) - || !WPACKET_put_bytes_u16(pkt, s->s3->group_id) - || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, + || !WPACKET_put_bytes_u16(pkt, s->s3.group_id) + || !s->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt, &ciphlen) /* Is there a key_share extension present in this HRR? */ - || !WPACKET_put_bytes_u8(pkt, s->s3->peer_tmp == NULL) + || !WPACKET_put_bytes_u8(pkt, s->s3.peer_tmp == NULL) || !WPACKET_put_bytes_u32(pkt, (unsigned int)time(NULL)) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_reserve_bytes(pkt, EVP_MAX_MD_SIZE, &hashval1)) { @@ -1773,7 +1865,8 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, goto err; } - if (EVP_DigestSignInit(hctx, NULL, EVP_sha256(), NULL, pkey) <= 0 + if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->propq, pkey, + s->ctx->libctx) <= 0 || EVP_DigestSign(hctx, hmac, &hmaclen, cookie, totcookielen) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, @@ -1803,6 +1896,9 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, EVP_MD_CTX_free(hctx); EVP_PKEY_free(pkey); return ret; +#else + return EXT_RETURN_FAIL; +#endif } EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, @@ -1818,8 +1914,8 @@ EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17 }; - if (((s->s3->tmp.new_cipher->id & 0xFFFF) != 0x80 - && (s->s3->tmp.new_cipher->id & 0xFFFF) != 0x81) + if (((s->s3.tmp.new_cipher->id & 0xFFFF) != 0x80 + && (s->s3.tmp.new_cipher->id & 0xFFFF) != 0x81) || (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG) == 0) return EXT_RETURN_NOT_SENT; @@ -1874,7 +1970,7 @@ EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk) || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_put_bytes_u16(pkt, s->session->ext.tick_identity) + || !WPACKET_put_bytes_u16(pkt, s->ext.tick_identity) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_PSK, ERR_R_INTERNAL_ERROR);