]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Support TLS1.3 extensions with DTLS1.3
authorFrederik Wedel-Heinen <frederik.wedel-heinen@dencrypt.dk>
Tue, 3 Oct 2023 11:19:42 +0000 (13:19 +0200)
committerTomas Mraz <tomas@openssl.org>
Thu, 9 Jan 2025 15:58:38 +0000 (16:58 +0100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22261)

ssl/statem/extensions.c
ssl/statem/extensions_clnt.c
ssl/statem/extensions_srvr.c

index 762c7ac0d4ef40b8a69373e1fbe73dd612d05467..375308c5f770026d2fce045f067cf66f4d104eee 100644 (file)
@@ -190,7 +190,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.
@@ -200,7 +200,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
@@ -341,7 +341,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,
@@ -350,8 +350,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
     },
@@ -362,7 +361,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,
@@ -372,7 +371,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
     },
@@ -390,7 +389,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,
@@ -422,10 +421,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
     }
@@ -556,33 +555,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;
@@ -833,7 +832,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;
@@ -860,7 +860,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
@@ -1072,8 +1072,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;
@@ -1180,15 +1180,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.
      */
@@ -1340,7 +1340,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;
@@ -1364,7 +1364,7 @@ static int final_supported_versions(SSL_CONNECTION *s, unsigned int context,
 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 */
@@ -1464,14 +1464,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;
                 }
 
index fb9f8796bac13e42eb342c053c8dee77d6fbee38..2d3486ad34fef8fe3f49a3854f58f05e8fc84dc3 100644 (file)
@@ -218,6 +218,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) {
@@ -226,12 +227,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
@@ -257,7 +259,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++;
         }
@@ -271,7 +274,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;
@@ -291,7 +295,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) {
@@ -561,6 +566,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) {
@@ -569,10 +575,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)
@@ -582,10 +588,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)) {
@@ -711,10 +726,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;
 
@@ -792,7 +811,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(ussl, 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;
@@ -814,6 +834,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) {
@@ -824,7 +845,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_CONNECTION_GET_SSL(s),
                                      tls13_aes128gcmsha256_id);
@@ -834,10 +855,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;
@@ -969,7 +992,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),
@@ -1044,7 +1067,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;
 
@@ -1458,18 +1481,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.
          */
@@ -1805,9 +1828,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;
@@ -1851,6 +1874,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);
@@ -1872,10 +1896,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;
         }
index 73b93048cbfd6b5266187cec14960bcbdbb0f525..fa3b8fdfdf29c1eb4cfe67e46a5cd274f50c4ba8 100644 (file)
@@ -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,
@@ -652,6 +652,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) {
@@ -688,9 +691,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;
@@ -808,7 +811,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;
@@ -944,7 +947,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;
@@ -1087,10 +1090,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_CONNECTION_GET_SSL(s),
                                          tls13_aes128gcmsha256_id);
@@ -1101,12 +1105,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;
@@ -1315,10 +1321,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)
@@ -1469,7 +1475,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)
@@ -1479,11 +1485,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;
     }
@@ -1620,7 +1627,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;
     }
@@ -1786,6 +1793,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt,
     SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
     SSL *ssl = SSL_CONNECTION_GET_SSL(s);
     SSL *ussl = SSL_CONNECTION_GET_USER_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;
@@ -1801,7 +1809,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)
@@ -1997,7 +2005,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