tls13: srv: Fail connection if ticket lifetime exceed 7 days

Signed-off-by: Jerry Yu <jerry.h.yu@arm.com>
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
index a1e70d4..2ee1400 100644
--- a/include/mbedtls/ssl_ticket.h
+++ b/include/mbedtls/ssl_ticket.h
@@ -111,6 +111,13 @@
  * \note            It is recommended to pick a reasonable lifetime so as not
  *                  to negate the benefits of forward secrecy.
  *
+ * \note            The TLS 1.3 specification states that ticket lifetime must
+ *                  be smaller than seven days. If ticket lifetime has been
+ *                  set to a value greater than seven days in this module then
+ *                  if the TLS 1.3 is configured to send tickets after the
+ *                  handshake it will fail the connection when trying to send
+ *                  the first ticket.
+ *
  * \return          0 if successful,
  *                  or a specific MBEDTLS_ERR_XXX error code
  */
@@ -147,6 +154,13 @@
  * \note            It is recommended to pick a reasonable lifetime so as not
  *                  to negate the benefits of forward secrecy.
  *
+ * \note            The TLS 1.3 specification states that ticket lifetime must
+ *                  be smaller than seven days. If ticket lifetime has been
+ *                  set to a value greater than seven days in this module then
+ *                  if the TLS 1.3 is configured to send tickets after the
+ *                  handshake it will fail the connection when trying to send
+ *                  the first ticket.
+ *
  * \return          0 if successful,
  *                  or a specific MBEDTLS_ERR_XXX error code
  */
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 5c24657..13ae61d 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -3271,20 +3271,21 @@
         MBEDTLS_SSL_DEBUG_RET(1, "write_ticket", ret);
         return ret;
     }
-    /* RFC 8446 4.6.1
+
+    /* RFC 8446 section 4.6.1
+     *
      *  ticket_lifetime:  Indicates the lifetime in seconds as a 32-bit
-     *      unsigned integer in network byte order from the time of ticket
-     *      issuance.  Servers MUST NOT use any value greater than
-     *      604800 seconds (7 days).  The value of zero indicates that the
-     *      ticket should be discarded immediately.  Clients MUST NOT cache
-     *      tickets for longer than 7 days, regardless of the ticket_lifetime,
-     *      and MAY delete tickets earlier based on local policy.  A server
-     *      MAY treat a ticket as valid for a shorter period of time than what
-     *      is stated in the ticket_lifetime.
+     *     unsigned integer in network byte order from the time of ticket
+     *     issuance.  Servers MUST NOT use any value greater than
+     *     604800 seconds (7 days) ...
      */
     if (ticket_lifetime > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) {
-        ticket_lifetime = MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME;
+        MBEDTLS_SSL_DEBUG_MSG(
+            1, ("Ticket lifetime (%u) is greater than 7 days.",
+                (unsigned int) ticket_lifetime));
+        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
+
     MBEDTLS_PUT_UINT32_BE(ticket_lifetime, p, 0);
     MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime: %u",
                               (unsigned int) ticket_lifetime));
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index fd2fc0a..3d76501 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -13532,6 +13532,42 @@
             -s "key exchange mode: psk_ephemeral" \
             -s "found pre_shared_key extension"
 
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+                             MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+                             MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+                             MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test    "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime max value (7d)" \
+            "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604800 tickets=1" \
+            "$P_CLI reco_mode=1 reconnect=1" \
+            0 \
+            -c "Protocol is TLSv1.3" \
+            -c "HTTP/1.0 200 OK" \
+            -c "got new session ticket" \
+            -c "Reconnecting with saved session... ok" \
+            -s "Protocol is TLSv1.3" \
+            -S "Ticket lifetime (604800) is greater than 7 days."
+
+requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \
+                             MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+                             MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \
+                             MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test    "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime too long (7d + 1s)" \
+            "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604801 tickets=1" \
+            "$P_CLI reco_mode=1 reconnect=1" \
+            1 \
+            -c "Protocol is TLSv1.3" \
+            -C "HTTP/1.0 200 OK" \
+            -C "got new session ticket" \
+            -C "Reconnecting with saved session... ok" \
+            -S "Protocol is TLSv1.3" \
+            -s "Ticket lifetime (604801) is greater than 7 days."
+
 requires_openssl_tls1_3_with_compatible_ephemeral
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_DEBUG_C