summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederik Wedel-Heinen <frederik.wedel-heinen@dencrypt.dk>2023-10-03 13:19:42 +0200
committerMatt Caswell <matt@openssl.org>2024-03-28 09:55:19 +0000
commite925a2bd08a010050f015000f2ef1b609c5631a9 (patch)
tree3341867af0e6d469d5ee67eee457e3910cf02a41
parent1b71ffa0c5fefd0d0c8c6e160e063fe2d68bb10c (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.c66
-rw-r--r--ssl/statem/extensions_clnt.c80
-rw-r--r--ssl/statem/extensions_srvr.c46
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