diff options
author | Frederik Wedel-Heinen <frederik.wedel-heinen@dencrypt.dk> | 2023-10-03 13:19:42 +0200 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2024-03-28 09:55:19 +0000 |
commit | e925a2bd08a010050f015000f2ef1b609c5631a9 (patch) | |
tree | 3341867af0e6d469d5ee67eee457e3910cf02a41 | |
parent | 1b71ffa0c5fefd0d0c8c6e160e063fe2d68bb10c (diff) |
Support TLS1.3 extensions with DTLS1.3
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22261)
-rw-r--r-- | ssl/statem/extensions.c | 66 | ||||
-rw-r--r-- | ssl/statem/extensions_clnt.c | 80 | ||||
-rw-r--r-- | ssl/statem/extensions_srvr.c | 46 |
3 files changed, 115 insertions, 77 deletions
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 0a64ca2246..ae249142ba 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -188,7 +188,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { * to indicate to the client the complete list of groups supported * by the server, with the server instead just indicating the * selected group for this connection in the ServerKeyExchange - * message. TLS 1.3 adds a scheme for the server to indicate + * message. (D)TLS 1.3 adds a scheme for the server to indicate * to the client its list of supported groups in the * EncryptedExtensions message, but none of the relevant * specifications permit sending supported_groups in the ServerHello. @@ -198,7 +198,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { * ServerHello anyway. Up to and including the 1.1.0 release, * we did not check for the presence of nonpermitted extensions, * so to avoid a regression, we must permit this extension in the - * TLS 1.2 ServerHello as well. + * (D)TLS 1.2 ServerHello as well. * * Note that there is no tls_parse_stoc_supported_groups function, * so we do not perform any additional parsing, validation, or @@ -339,7 +339,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { { TLSEXT_TYPE_supported_versions, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS_IMPLEMENTATION_ONLY, + | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, NULL, /* Processed inline as part of version selection */ NULL, tls_parse_stoc_supported_versions, @@ -348,8 +348,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { }, { TLSEXT_TYPE_psk_kex_modes, - SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS_IMPLEMENTATION_ONLY - | SSL_EXT_TLS1_3_ONLY, + SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ONLY, init_psk_kex_modes, tls_parse_ctos_psk_kex_modes, NULL, NULL, tls_construct_ctos_psk_kex_modes, NULL }, @@ -360,7 +359,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { */ TLSEXT_TYPE_key_share, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS_IMPLEMENTATION_ONLY + | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS1_3_ONLY, NULL, tls_parse_ctos_key_share, tls_parse_stoc_key_share, tls_construct_stoc_key_share, tls_construct_ctos_key_share, @@ -370,7 +369,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { /* Must be after key_share */ TLSEXT_TYPE_cookie, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + | SSL_EXT_TLS1_3_ONLY, NULL, tls_parse_ctos_cookie, tls_parse_stoc_cookie, tls_construct_stoc_cookie, tls_construct_ctos_cookie, NULL }, @@ -388,7 +387,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { { TLSEXT_TYPE_compress_certificate, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + | SSL_EXT_TLS1_3_ONLY, tls_init_compress_certificate, tls_parse_compress_certificate, tls_parse_compress_certificate, tls_construct_compress_certificate, tls_construct_compress_certificate, @@ -420,10 +419,10 @@ static const EXTENSION_DEFINITION ext_defs[] = { NULL, NULL, NULL, tls_construct_ctos_padding, NULL }, { - /* Required by the TLSv1.3 spec to always be the last extension */ + /* Required by the (D)TLSv1.3 spec to always be the last extension */ TLSEXT_TYPE_psk, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + | SSL_EXT_TLS1_3_ONLY, NULL, tls_parse_ctos_psk, tls_parse_stoc_psk, tls_construct_stoc_psk, tls_construct_ctos_psk, final_psk } @@ -554,33 +553,33 @@ static int verify_extension(SSL_CONNECTION *s, unsigned int context, int extension_is_relevant(SSL_CONNECTION *s, unsigned int extctx, unsigned int thisctx) { - int is_tls13; + int is_version13; /* * For HRR we haven't selected the version yet but we know it will be - * TLSv1.3 + * (D)TLSv1.3 */ if ((thisctx & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0) - is_tls13 = 1; + is_version13 = 1; else - is_tls13 = SSL_CONNECTION_IS_TLS13(s); + is_version13 = SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s); if ((SSL_CONNECTION_IS_DTLS(s) && (extctx & SSL_EXT_TLS_IMPLEMENTATION_ONLY) != 0) || (s->version == SSL3_VERSION && (extctx & SSL_EXT_SSL3_ALLOWED) == 0) /* - * Note that SSL_IS_TLS13() means "TLS 1.3 has been negotiated", + * Note that is_version13 means "(D)TLS 1.3 has been negotiated", * which is never true when generating the ClientHello. * However, version negotiation *has* occurred by the time the * ClientHello extensions are being parsed. - * Be careful to allow TLS 1.3-only extensions when generating + * Be careful to allow (D)TLS 1.3-only extensions when generating * the ClientHello. */ - || (is_tls13 && (extctx & SSL_EXT_TLS1_2_AND_BELOW_ONLY) != 0) - || (!is_tls13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0 + || (is_version13 && (extctx & SSL_EXT_TLS1_2_AND_BELOW_ONLY) != 0) + || (!is_version13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0 && (thisctx & SSL_EXT_CLIENT_HELLO) == 0) - || (s->server && !is_tls13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0) + || (s->server && !is_version13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0) || (s->hit && (extctx & SSL_EXT_IGNORE_ON_RESUMPTION) != 0)) return 0; return 1; @@ -831,7 +830,8 @@ int should_add_extension(SSL_CONNECTION *s, unsigned int extctx, if (!extension_is_relevant(s, extctx, thisctx) || ((extctx & SSL_EXT_TLS1_3_ONLY) != 0 && (thisctx & SSL_EXT_CLIENT_HELLO) != 0 - && (SSL_CONNECTION_IS_DTLS(s) || max_version < TLS1_3_VERSION))) + && (SSL_CONNECTION_IS_DTLS(s) ? DTLS_VERSION_LT(max_version, DTLS1_3_VERSION) + : max_version < TLS1_3_VERSION))) return 0; return 1; @@ -858,7 +858,7 @@ int tls_construct_extensions(SSL_CONNECTION *s, WPACKET *pkt, /* * If extensions are of zero length then we don't even add the * extensions length bytes to a ClientHello/ServerHello - * (for non-TLSv1.3). + * (for non-(D)TLSv1.3). */ || ((context & (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO)) != 0 @@ -1069,8 +1069,8 @@ static int final_server_name(SSL_CONNECTION *s, unsigned int context, int sent) return 0; case SSL_TLSEXT_ERR_ALERT_WARNING: - /* TLSv1.3 doesn't have warning alerts so we suppress this */ - if (!SSL_CONNECTION_IS_TLS13(s)) + /* (D)TLSv1.3 doesn't have warning alerts so we suppress this */ + if (!(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) ssl3_send_alert(s, SSL3_AL_WARNING, altmp); s->servername_done = 0; return 1; @@ -1177,15 +1177,15 @@ static int final_alpn(SSL_CONNECTION *s, unsigned int context, int sent) if (!s->server && !sent && s->session->ext.alpn_selected != NULL) s->ext.early_data_ok = 0; - if (!s->server || !SSL_CONNECTION_IS_TLS13(s)) + if (!s->server || !(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) return 1; /* * Call alpn_select callback if needed. Has to be done after SNI and - * cipher negotiation (HTTP/2 restricts permitted ciphers). In TLSv1.3 + * cipher negotiation (HTTP/2 restricts permitted ciphers). In (D)TLSv1.3 * we also have to do this before we decide whether to accept early_data. - * In TLSv1.3 we've already negotiated our cipher so we do this call now. - * For < TLSv1.3 we defer it until after cipher negotiation. + * In (D)TLSv1.3 we've already negotiated our cipher so we do this call now. + * For < (D)TLSv1.3 we defer it until after cipher negotiation. * * On failure SSLfatal() already called. */ @@ -1337,7 +1337,7 @@ static int init_srtp(SSL_CONNECTION *s, unsigned int context) static int final_sig_algs(SSL_CONNECTION *s, unsigned int context, int sent) { - if (!sent && SSL_CONNECTION_IS_TLS13(s) && !s->hit) { + if (!sent && (SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) && !s->hit) { SSLfatal(s, TLS13_AD_MISSING_EXTENSION, SSL_R_MISSING_SIGALGS_EXTENSION); return 0; @@ -1349,7 +1349,7 @@ static int final_sig_algs(SSL_CONNECTION *s, unsigned int context, int sent) static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) { #if !defined(OPENSSL_NO_TLS1_3) - if (!SSL_CONNECTION_IS_TLS13(s)) + if (!(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) return 1; /* Nothing to do for key_share in an HRR */ @@ -1446,14 +1446,18 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) * Find the first group we allow that is also in client's list */ for (i = 0; i < num_groups; i++) { + int version; + group_id = pgroups[i]; + version = SSL_CONNECTION_IS_DTLS(s) ? + DTLS1_3_VERSION : TLS1_3_VERSION; if (check_in_list(s, group_id, clntgroups, clnt_num_groups, 1) && tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED) - && tls_valid_group(s, group_id, TLS1_3_VERSION, - TLS1_3_VERSION, 0, NULL)) + && tls_valid_group(s, group_id, version, + version, 0, NULL)) break; } diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 381a6c9d7b..75d786a54a 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -191,6 +191,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, const uint16_t *pgroups = NULL; size_t num_groups = 0, i, tls13added = 0, added = 0; int min_version, max_version, reason; + const int isdtls = SSL_CONNECTION_IS_DTLS(s); reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); if (reason != 0) { @@ -199,12 +200,13 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, } /* - * We only support EC groups in TLSv1.2 or below, and in DTLS. Therefore + * We only support EC groups in (D)TLSv1.2 or below, and in DTLS. Therefore * if we don't have EC support then we don't send this extension. */ - if (!use_ecc(s, min_version, max_version) - && (SSL_CONNECTION_IS_DTLS(s) || max_version < TLS1_3_VERSION)) - return EXT_RETURN_NOT_SENT; + if (!use_ecc(s, min_version, max_version)) + if ((!isdtls && max_version < TLS1_3_VERSION) + || (isdtls && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION))) + return EXT_RETURN_NOT_SENT; /* * Add TLS extension supported_groups to the ClientHello message @@ -230,7 +232,8 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - if (okfortls13 && max_version == TLS1_3_VERSION) + if ((okfortls13 && max_version == TLS1_3_VERSION) + || (okfortls13 && max_version == DTLS1_3_VERSION)) tls13added++; added++; } @@ -244,7 +247,8 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - if (tls13added == 0 && max_version == TLS1_3_VERSION) { + if (tls13added == 0 && (max_version == TLS1_3_VERSION + || max_version == DTLS1_3_VERSION)) { SSLfatal_data(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_GROUPS, "No groups enabled for max supported SSL/TLS version"); return EXT_RETURN_FAIL; @@ -264,7 +268,8 @@ EXT_RETURN tls_construct_ctos_session_ticket(SSL_CONNECTION *s, WPACKET *pkt, if (!s->new_session && s->session != NULL && s->session->ext.tick != NULL - && s->session->ssl_version != TLS1_3_VERSION) { + && s->session->ssl_version != TLS1_3_VERSION + && s->session->ssl_version != DTLS1_3_VERSION) { ticklen = s->session->ext.ticklen; } else if (s->session && s->ext.session_ticket != NULL && s->ext.session_ticket->data != NULL) { @@ -534,6 +539,7 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt size_t chainidx) { int currv, min_version, max_version, reason; + int isdtls = SSL_CONNECTION_IS_DTLS(s); reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); if (reason != 0) { @@ -542,10 +548,10 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt } /* - * Don't include this if we can't negotiate TLSv1.3. We can do a straight - * comparison here because we will never be called in DTLS. + * Don't include this if we can't negotiate (D)TLSv1.3. */ - if (max_version < TLS1_3_VERSION) + if ((!isdtls && max_version < TLS1_3_VERSION) + || (isdtls && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION))) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions) @@ -555,10 +561,19 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt return EXT_RETURN_FAIL; } - for (currv = max_version; currv >= min_version; currv--) { - if (!WPACKET_put_bytes_u16(pkt, currv)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; + if (isdtls) { + for (currv = max_version; DTLS_VERSION_GE(currv, min_version); currv++) { + if (!WPACKET_put_bytes_u16(pkt, currv)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + } + } else { + for (currv = max_version; currv >= min_version; currv--) { + if (!WPACKET_put_bytes_u16(pkt, currv)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { @@ -684,10 +699,14 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt, curve_id = s->s3.group_id; } else { for (i = 0; i < num_groups; i++) { + int version; + if (!tls_group_allowed(s, pgroups[i], SSL_SECOP_CURVE_SUPPORTED)) continue; - if (!tls_valid_group(s, pgroups[i], TLS1_3_VERSION, TLS1_3_VERSION, + version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + + if (!tls_valid_group(s, pgroups[i], version, version, 0, NULL)) continue; @@ -765,7 +784,8 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, if (s->psk_use_session_cb != NULL && (!s->psk_use_session_cb(ssl, handmd, &id, &idlen, &psksess) || (psksess != NULL - && psksess->ssl_version != TLS1_3_VERSION))) { + && psksess->ssl_version != TLS1_3_VERSION + && psksess->ssl_version != DTLS1_3_VERSION))) { SSL_SESSION_free(psksess); SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); return EXT_RETURN_FAIL; @@ -787,6 +807,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, } else if (psklen > 0) { const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; const SSL_CIPHER *cipher; + int version; idlen = strlen(identity); if (idlen > PSK_MAX_IDENTITY_LEN) { @@ -797,7 +818,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, /* * We found a PSK using an old style callback. We don't know - * the digest so we default to SHA256 as per the TLSv1.3 spec + * the digest so we default to SHA256 as per the (D)TLSv1.3 spec */ cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); if (cipher == NULL) { @@ -806,10 +827,12 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, } psksess = SSL_SESSION_new(); + version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + if (psksess == NULL || !SSL_SESSION_set1_master_key(psksess, psk, psklen) || !SSL_SESSION_set_cipher(psksess, cipher) - || !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)) { + || !SSL_SESSION_set_protocol_version(psksess, version)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); OPENSSL_cleanse(psk, psklen); return EXT_RETURN_FAIL; @@ -941,7 +964,7 @@ EXT_RETURN tls_construct_ctos_padding(SSL_CONNECTION *s, WPACKET *pkt, * If we're going to send a PSK then that will be written out after this * extension, so we need to calculate how long it is going to be. */ - if (s->session->ssl_version == TLS1_3_VERSION + if ((s->session->ssl_version == TLS1_3_VERSION || s->session->ssl_version == DTLS1_3_VERSION) && s->session->ext.ticklen != 0 && s->session->cipher != NULL) { const EVP_MD *md = ssl_md(SSL_CONNECTION_GET_CTX(s), @@ -1011,7 +1034,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt, * If this is an incompatible or new session then we have nothing to resume * so don't add this extension. */ - if (s->session->ssl_version != TLS1_3_VERSION + if ((s->session->ssl_version != TLS1_3_VERSION && s->session->ssl_version != DTLS1_3_VERSION) || (s->session->ext.ticklen == 0 && s->psksession == NULL)) return EXT_RETURN_NOT_SENT; @@ -1419,18 +1442,18 @@ int tls_parse_stoc_status_request(SSL_CONNECTION *s, PACKET *pkt, /* * MUST only be sent if we've requested a status - * request message. In TLS <= 1.2 it must also be empty. + * request message. In (D)TLS <= 1.2 it must also be empty. */ if (s->ext.status_type != TLSEXT_STATUSTYPE_ocsp) { SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } - if (!SSL_CONNECTION_IS_TLS13(s) && PACKET_remaining(pkt) > 0) { + if (!(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) && PACKET_remaining(pkt) > 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) { /* We only know how to handle this if it's for the first Certificate in * the chain. We ignore any other responses. */ @@ -1742,9 +1765,9 @@ int tls_parse_stoc_supported_versions(SSL_CONNECTION *s, PACKET *pkt, /* * The only protocol version we support which is valid in this extension in - * a ServerHello is TLSv1.3 therefore we shouldn't be getting anything else. + * a ServerHello is (D)TLSv1.3 therefore we shouldn't be getting anything else. */ - if (version != TLS1_3_VERSION) { + if (version != TLS1_3_VERSION && version != DTLS1_3_VERSION) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); return 0; @@ -1788,6 +1811,7 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, if ((context & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0) { const uint16_t *pgroups = NULL; size_t i, num_groups; + int version; if (PACKET_remaining(pkt) != 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); @@ -1809,10 +1833,12 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, if (group_id == pgroups[i]) break; } + + version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + if (i >= num_groups || !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED) - || !tls_valid_group(s, group_id, TLS1_3_VERSION, TLS1_3_VERSION, - 0, NULL)) { + || !tls_valid_group(s, group_id, version, version, 0, NULL)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 21db977c88..8f26009eff 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -133,10 +133,10 @@ int tls_parse_ctos_server_name(SSL_CONNECTION *s, PACKET *pkt, } /* - * In TLSv1.2 and below the SNI is associated with the session. In TLSv1.3 + * In (D)TLSv1.2 and below the SNI is associated with the session. In (D)TLSv1.3 * we always use the SNI value from the handshake. */ - if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { + if (!s->hit || (SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) { if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) { SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME, SSL_R_BAD_EXTENSION); return 0; @@ -161,9 +161,9 @@ int tls_parse_ctos_server_name(SSL_CONNECTION *s, PACKET *pkt, 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. + * In (D)TLSv1.2 and below we should check if the SNI is consistent + * between the initial handshake and the resumption. In (D)TLSv1.3 SNI + * is not associated with the session. */ s->servername_done = (s->session->ext.hostname != NULL) && PACKET_equal(&hostname, s->session->ext.hostname, @@ -647,6 +647,9 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, } while (PACKET_remaining(&key_share_list) > 0) { + const int version13 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; + if (!PACKET_get_net_2(&key_share_list, &group_id) || !PACKET_get_length_prefixed_2(&key_share_list, &encoded_pt) || PACKET_remaining(&encoded_pt) == 0) { @@ -683,9 +686,9 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, || !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED) /* * We tolerate but ignore a group id that we don't think is - * suitable for TLSv1.3 + * suitable for (D)TLSv1.3 */ - || !tls_valid_group(s, group_id, TLS1_3_VERSION, TLS1_3_VERSION, + || !tls_valid_group(s, group_id, version13, version13, 0, NULL)) { /* Share not suitable */ continue; @@ -803,7 +806,7 @@ int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } - if (version != TLS1_3_VERSION) { + if (version != TLS1_3_VERSION && version != DTLS1_3_VERSION) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); return 0; @@ -939,7 +942,7 @@ int tls_parse_ctos_supported_groups(SSL_CONNECTION *s, PACKET *pkt, return 0; } - if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { + if (!s->hit || (SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) { OPENSSL_free(s->ext.peer_supportedgroups); s->ext.peer_supportedgroups = NULL; s->ext.peer_supportedgroups_len = 0; @@ -1081,10 +1084,11 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, } else if (pskdatalen > 0) { const SSL_CIPHER *cipher; const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; + int version; /* * We found a PSK using an old style callback. We don't know - * the digest so we default to SHA256 as per the TLSv1.3 spec + * the digest so we default to SHA256 as per the (D)TLSv1.3 spec */ cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); if (cipher == NULL) { @@ -1094,12 +1098,14 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, } sess = SSL_SESSION_new(); + version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + if (sess == NULL || !SSL_SESSION_set1_master_key(sess, pskdata, pskdatalen) || !SSL_SESSION_set_cipher(sess, cipher) || !SSL_SESSION_set_protocol_version(sess, - TLS1_3_VERSION)) { + version)) { OPENSSL_cleanse(pskdata, pskdatalen); SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; @@ -1306,10 +1312,10 @@ EXT_RETURN tls_construct_stoc_server_name(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_NOT_SENT; /* - * Prior to TLSv1.3 we ignore any SNI in the current handshake if resuming. + * Prior to (D)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_CONNECTION_IS_TLS13(s)) + if (s->hit && !(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name) @@ -1460,7 +1466,7 @@ EXT_RETURN tls_construct_stoc_status_request(SSL_CONNECTION *s, WPACKET *pkt, if (!s->ext.status_expected) return EXT_RETURN_NOT_SENT; - if (SSL_CONNECTION_IS_TLS13(s) && chainidx != 0) + if ((SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) && chainidx != 0) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request) @@ -1470,11 +1476,12 @@ EXT_RETURN tls_construct_stoc_status_request(SSL_CONNECTION *s, WPACKET *pkt, } /* - * In TLSv1.3 we include the certificate status itself. In <= TLSv1.2 we + * In (D)TLSv1.3 we include the certificate status itself. In <= (D)TLSv1.2 we * send back an empty extension, with the certificate status appearing as a * separate message */ - if (SSL_CONNECTION_IS_TLS13(s) && !tls_construct_cert_status_body(s, pkt)) { + if ((SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) + && !tls_construct_cert_status_body(s, pkt)) { /* SSLfatal() already called */ return EXT_RETURN_FAIL; } @@ -1610,7 +1617,7 @@ EXT_RETURN tls_construct_stoc_supported_versions(SSL_CONNECTION *s, WPACKET *pkt unsigned int context, X509 *x, size_t chainidx) { - if (!ossl_assert(SSL_CONNECTION_IS_TLS13(s))) { + if (!ossl_assert((SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)))) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1775,6 +1782,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, int ret = EXT_RETURN_FAIL; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); SSL *ssl = SSL_CONNECTION_GET_SSL(s); + const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return EXT_RETURN_NOT_SENT; @@ -1790,7 +1798,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, || !WPACKET_get_total_written(pkt, &startlen) || !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, version) || !WPACKET_put_bytes_u16(pkt, s->s3.group_id) || !ssl->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt, &ciphlen) @@ -1986,7 +1994,7 @@ EXT_RETURN tls_construct_stoc_client_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, /* * Note: only supposed to send this if we are going to do a cert request, - * but TLSv1.3 could do a PHA request if the client supports it + * but (D)TLSv1.3 could do a PHA request if the client supports it */ if ((!send_certificate_request(sc) && sc->post_handshake_auth != SSL_PHA_EXT_RECEIVED) || sc->ext.client_cert_type_ctos != OSSL_CERT_TYPE_CTOS_GOOD |