Commit 5a85e4152d for openssl.org

commit 5a85e4152d817749400b0e30ebbbcce738fbfbb5
Author: Abel Tom <abeltom.kernel@gmail.com>
Date:   Wed Jun 17 09:56:46 2026 +0200

    Enforce RFC 8446 ticket lifetime limit for TLS 1.3 client

    Add client-side validation to check if session ticket lifetime
    hints exceeds 7 days in TLS1.3 connections and caps it to the
    maximum value of 7 days(604800 seconds).

    Modified `CHANGES.md` with the description of updated change.

    Resolves: #30808

    Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    MergeDate: Thu Jun 18 12:25:33 2026
    (Merged from https://github.com/openssl/openssl/pull/31174)

diff --git a/CHANGES.md b/CHANGES.md
index 37aec14608..450d5defdc 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -201,6 +201,18 @@ OpenSSL Releases

    *Dimitri John Ledkov*

+ * Add client-side validation for TLS 1.3 session ticket lifetimes.
+
+   In accordance with [RFC 8446 Section 4.6.1](https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.1),
+   TLS 1.3 clients must not cache session tickets
+   for longer than 7 days (604800 seconds).
+   When processing a new session ticket message with a
+   `ticket_lifetime_hint` value greater than 7 days,
+   the client now caps the lifetime to the
+   maximum permitted value of 7 days (604800 seconds).
+
+   *Abel Thomas*
+
 ### Changes between 3.6 and 4.0.0 [14 Apr 2026]

  * Added `-expected-rpks` option to the `openssl s_client`
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 00ca50a3e6..6c77296c31 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -3172,6 +3172,14 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s,
     if (SSL_CONNECTION_IS_TLS13(s)) {
         PACKET extpkt;

+        /*
+         * Fulfilling RFC8446:4.6.1 requirement: Clients MUST NOT cache
+         * tickets for longer than 7 days.
+         */
+        if (ticket_lifetime_hint > 604800) {
+            ticket_lifetime_hint = 604800;
+        }
+
         if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
             || PACKET_remaining(pkt) != 0) {
             SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH);