Subject: [TLS] ticket lifetimes

From: Subodh Iyengar <[email-masked]>
Date: Tue, 29 Jan 2019 05:42:43 +0000

In TLS 1.3 we added a maximum age to the ticket lifetime to be 7 days. This had several original motivations including reducing the time that a ticket is reused (for privacy or PFS). Another major motivation for this was to limit the exposure of servers that use keyless ssl like mechanisms, i.e. if they kept a STEK locally, but the keyless SSL server remotely, then the theft of a STEK would presumably limit the MITM capabilities to the ticket lifetime.

However thinking about it some more because of the renewal capability of tickets in TLS 1.3, an entity owning the STEK could just re-issue new tickets forever on a resumed connection. This would look to the client as a new ticket and it would refresh its lifetime on the ticket. Thereby a MITM could intercept connections to users that have been to the server with the STEK. I'm wondering whether it might be useful to define a mechanism to limit the lifetime of all ticket resumption across all resumptions from the original connection instead of just the limited per ticket lifetime.

Subodh

---

From: Christopher Wood <[email-masked]>
Date: Mon, 28 Jan 2019 21:57:21 -0800

> However thinking about it some more because of the renewal capability of tickets in TLS 1.3, an entity owning the STEK could just re-issue new tickets forever on a resumed connection. This would lo…

Since clients already store tickets, could they not also store the
time of original ticket issuance and cap the resumption window to N
(7) days from that point? That is, it seems clients could implement
this behavior without any protocol support.

Best,
Chris

---

From: Subodh Iyengar <[email-masked]>
Date: Tue, 29 Jan 2019 06:04:49 +0000

Correct, however the server currently provides a value for this, and clients do not enforce a lower bound on this. 7 days is an upper bound.
Servers would provide a much lower value than 7 days practically.

If I'm understanding your suggestion correctly, you're suggesting that clients change the meaning of ticket_lifetime_hint?
That is not just limit it to the scope of the ticket but the entire TLS session? That would be fine to by me, however might break some folks.

Subodh
________________________________
From: Christopher Wood <[email-masked]>
Sent: Monday, January 28, 2019 9:57 PM
To: Subodh Iyengar
Cc: [email-masked]
Subject: Re: [TLS] ticket lifetimes

Best,
Chris

---

From: Christopher Wood <[email-masked]>
Date: Mon, 28 Jan 2019 22:13:36 -0800

> That is not just limit it to the scope of the ticket but the entire TLS session? That would be fine to by me, however might break some folks.

If by "entire TLS session" you mean the resumed (and renewed)
sessions, then yep!

Best,
Chris

---

From: Subodh Iyengar <[email-masked]>
Date: Tue, 29 Jan 2019 18:59:33 +0000

sessions, then yep!

Ya I think that'd need a new draft either way. Can definitely write that up
if people don't think it's the worst idea in the world.

Subodh
________________________________
From: Christopher Wood <[email-masked]>
Sent: Monday, January 28, 2019 10:13:36 PM
To: Subodh Iyengar
Cc: [email-masked]
Subject: Re: [TLS] ticket lifetimes

Best,
Chris

---

From: Nick Sullivan <[email-masked]>
Date: Tue, 29 Jan 2019 12:18:14 -0800

Wouldn't this issue also be mitigated by requiring the server to
re-authenticate during resumption with the certificate once in a while?

Nick

On Tue, Jan 29, 2019 at 11:00 AM Subodh Iyengar <[email-masked]> wrote:

> ------------------------------
> *From:* Christopher Wood <[email-masked]>
> *Sent:* Monday, January 28, 2019 10:13:36 PM
> *To:* Subodh Iyengar
> *Cc:* [email-masked]
> *Subject:* Re: [TLS] ticket lifetimes
>
> > Correct, however the server currently provides a value for this, and
> clients do not enforce a lower bound on this. 7 days is an upper bound.
> > If I'm understanding your suggestion correctly, you're suggesting that
> clients change the meaning of ticket_lifetime_hint?
> > That is not just limit it to the scope of the ticket but the entire TLS
> session? That would be fine to by me, however might break some folks.
>
> > > In TLS 1.3 we added a maximum age to the ticket lifetime to be 7 days.
> This had several original motivations including reducing the time that a
> ticket is reused (for privacy or PFS). Another major motivation for this
> was to limit the exposure of servers that use keyless ssl like mechanisms,
> i.e. if they kept a STEK locally, but the keyless SSL server remotely, then
> the theft of a STEK would presumably limit the MITM capabilities to the
> ticket lifetime.
> > >
> > > However thinking about it some more because of the renewal capability
> of tickets in TLS 1.3, an entity owning the STEK could just re-issue new
> tickets forever on a resumed connection. This would look to the client as a
> new ticket and it would refresh its lifetime on the ticket. Thereby a MITM
> could intercept connections to users that have been to the server with the
> STEK. I'm wondering whether it might be useful to define a mechanism to
> limit the lifetime of all ticket resumption across all resumptions from the
> original connection instead of just the limited per ticket lifetime.
> >
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: David Benjamin <[email-masked]>
Date: Tue, 29 Jan 2019 15:02:04 -0600

This two-lifetime thing is actually already what we implement in BoringSSL.
:-) We track both a lifetime for the ticket (one day) and also for the
original authentication the ticket roots up to (one week). The lifetime of
the ticket is bounded by both these values, and the latter is not
extendable on renew.

> re-authenticate during resumption with the certificate once in a while?

Existing servers won't do this, so I see this less as a mitigation and more
as an optimization to plug the one-week-cliff that the fix produces. But,
yeah, that would be handy. (Probably something like: "re"-auth'd identity
apply to tickets, PSK applies to connection. Client sends an extension to
advertise we're nearing the unrenewable bound.)

David

>> > > In TLS 1.3 we added a maximum age to the ticket lifetime to be 7
>> days. This had several original motivations including reducing the time
>> that a ticket is reused (for privacy or PFS). Another major motivation for
>> this was to limit the exposure of servers that use keyless ssl like
>> mechanisms, i.e. if they kept a STEK locally, but the keyless SSL server
>> remotely, then the theft of a STEK would presumably limit the MITM
>> capabilities to the ticket lifetime.
>> > >

---

From: Subodh Iyengar <[email-masked]>
Date: Tue, 29 Jan 2019 22:14:02 +0000

> Wouldn't this issue also be mitigated by requiring the server to re-authenticate during resumption with the certificate once in a while?

I think it's probably just easier to drop the resumption completely.

> This two-lifetime thing is actually already what we implement in BoringSSL. 😊

Fantastic. Would it help to have an extension to set a lower bound on this value, or just make it more painful?

Subodh
________________________________
From: David Benjamin <[email-masked]>
Sent: Tuesday, January 29, 2019 1:02 PM
To: Nick Sullivan
Cc: Subodh Iyengar; [email-masked]
Subject: Re: [TLS] ticket lifetimes

This two-lifetime thing is actually already what we implement in BoringSSL. :-) We track both a lifetime for the ticket (one day) and also for the original authentication the ticket roots up to (one week). The lifetime of the ticket is bounded by both these values, and the latter is not extendable on renew.

On Tue, Jan 29, 2019 at 2:18 PM Nick Sullivan <nick=[email-masked]<mailto:[email-masked]>> wrote:
Wouldn't this issue also be mitigated by requiring the server to re-authenticate during resumption with the certificate once in a while?

Existing servers won't do this, so I see this less as a mitigation and more as an optimization to plug the one-week-cliff that the fix produces. But, yeah, that would be handy. (Probably something like: "re"-auth'd identity apply to tickets, PSK applies to connection. Client sends an extension to advertise we're nearing the unrenewable bound.)

David

Nick

sessions, then yep!

Subodh
________________________________
From: Christopher Wood <[email-masked]<mailto:[email-masked]>>
Sent: Monday, January 28, 2019 10:13:36 PM
To: Subodh Iyengar
Cc: [email-masked]<mailto:[email-masked]>
Subject: Re: [TLS] ticket lifetimes

Best,
Chris

> From: Christopher Wood <[email-masked]<mailto:[email-masked]>>
> Cc: [email-masked]<mailto:[email-masked]>
> On Mon, Jan 28, 2019 at 9:43 PM Subodh Iyengar <[email-masked]<mailto:[email-masked]>> wrote:
> >
_______________________________________________
TLS mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/tls<https://urldefense.proofpoint.com/v2/url?u=https-3A__www.ietf.org_mailman_listinfo_tls&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=h3Ju9EBS7mHtwg-wAyN7fQ&m=AeHpkYXwQtF4DjfqdHNluOLIcTHODTihn7i4WBzucjA&s=B4zL6Emv0jyhAsuJyBnxMzO8l1w7SDu5OpB4m8jarMk&e=>
_______________________________________________
TLS mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/tls
<https://urldefense.proofpoint.com/v2/url?u=https-3A__www.ietf.org_mailman_listinfo_tls&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=h3Ju9EBS7mHtwg-wAyN7fQ&m=AeHpkYXwQtF4DjfqdHNluOLIcTHODTihn7i4WBzucjA&s=B4zL6Emv0jyhAsuJyBnxMzO8l1w7SDu5OpB4m8jarMk&e=>

---

From: David Benjamin <[email-masked]>
Date: Tue, 29 Jan 2019 16:52:32 -0600

> value, or just make it more painful?

(Did you mean upper bound?)

I'd actually interpreted the RFC 8446 text to imply a 7 day upper bound on
the renewability, but apparently that's not how others read it! I don't
care strongly either way about an extension to set a renewal bound, I
think. A client is always free to tighten ticket lifetime policies
unilaterally. We don't need an extension to advertise its policies unless
we want to allow server to change their behavior in response. In the other
direction, if we think the server may also have an opinion on renewability
(you mention keyless things), a NewSessionTicket extension would be easy to
support. The client would then use the more restrictive of the server's
preferences and its local policy.

Though, I guess, having not specified it this way from the start, the
server can't be sure the client honors the extension. I don't know what
consequences that has for server-preference scenario.

(For completeness, BoringSSL doesn't allow TLS 1.2 ticket renewals to
extend lifetime at all, only TLS 1.3, and TLS 1.2 lifetimes are capped much
more tightly. Since TLS 1.2 resumption doesn't involve an ECDH operation,
any concerns about a stale online signature are overshadowed by how much
data the client is willing to make vulnerable to a single session secret.
We'd probably do something similar if we implemented TLS 1.3's
plain psk_ke, but we only do psk_dhe_ke.)

David

> *From:* David Benjamin <[email-masked]>
> *Sent:* Tuesday, January 29, 2019 1:02 PM
> *To:* Nick Sullivan
> *Cc:* Subodh Iyengar; [email-masked]
>
> This two-lifetime thing is actually already what we implement in
> BoringSSL. :-) We track both a lifetime for the ticket (one day) and also
> for the original authentication the ticket roots up to (one week). The
> lifetime of the ticket is bounded by both these values, and the latter is
> not extendable on renew.
>
> Existing servers won't do this, so I see this less as a mitigation and
> more as an optimization to plug the one-week-cliff that the fix produces.
> But, yeah, that would be handy. (Probably something like: "re"-auth'd
> identity apply to tickets, PSK applies to connection. Client sends an
> extension to advertise we're nearing the unrenewable bound.)
>
> David
>
>
> Nick
>

---

From: Subodh Iyengar <[email-masked]>
Date: Wed, 30 Jan 2019 04:28:54 +0000

> Na I meant lower bound. That is such an extension would be useless if the time the server mentioned > time the client decided to cache it. However the server might advertise a time < time the client decided to cache it, in which it would be useful.

> I'd actually interpreted the RFC 8446 text to imply a 7 day upper bound on the renewability, but apparently that's not how others read it!
>
Though, I guess, having not specified it this way from the start, the server can't be sure the client honors the extension. I don't know what consequences that has for server-preference scenario.

Yup I think there is a disconnect between the intention of the server operator and the protocol. That is the server operator would like to have only 7 day uses of the PSK, however unbeknownst to then, their library is renewing the ticket and extending the lifetime of the PSK. This disconnect exists in both TLS 1.2 and 1.3, however for TLS 1.2 the renewal of tickets is less widely deployed than it should be because of some historic client intolerance of it.

I think the interpretation that the lifetime applies to the current ticket only is the more common interpretation. I did a short study of several TLS 1.3 implementation shandling of ticket lifetimes by staring at some code really intensely:

OpenSSL:
Leaves ticket management on the client to the caller via callbacks and doesn't enforce anything by itself.

NSS:
Looks like it treats the lifetime of each ticket independently and enforces the ticket lifetime.

https://dxr.mozilla.org/mozilla-central/source/security/nss/lib/ssl/tls13con.c#459
<https://dxr.mozilla.org/mozilla-central/source/security/nss/lib/ssl/sslnonce.c#726>https://dxr.mozilla.org/mozilla-central/source/security/nss/lib/ssl/sslnonce.c#1202
https://dxr.mozilla.org/mozilla-central/source/security/nss/lib/ssl/tls13con.c#4661

OpenJDK:
Ignores lifetime hint after checking that it is < 7 days and then uses a jdk specified timeout which is a default of 1 day

http://hg.openjdk.java.net/jdk/jdk11/file/68fa3d4026ea/src/java.base/share/classes/sun/security/ssl/NewSessionTicket.java#l336
http://hg.openjdk.java.net/jdk/jdk11/file/68fa3d4026ea/src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java#l65

boringssl:

Has the ability to use an internal session cache. Before it uses a ticket it checks the session timeout against current time. Everytime it receives a new session ticket it clamps the SSL_SESSION's timeout using ssl_session_rebase_time and then clears any timed out tickets with SSL_CTX_flush_sessions.

Fizz:

Treats each ticket lifetime independently.

mbed tls:
Leaves it to caller with mbedtls_ssl_conf_session_cache.  However the API doesn't allow mbedtls to verify whether or not the ticket_lifetime has exceeded and its up to the caller to verify this.

Seems like there is room for clarification on the ticket lifetime.

Subodh
________________________________
From: David Benjamin <[email-masked]>
Sent: Tuesday, January 29, 2019 2:52 PM
To: Subodh Iyengar
Cc: Nick Sullivan; [email-masked]
Subject: Re: [TLS] ticket lifetimes

I'd actually interpreted the RFC 8446 text to imply a 7 day upper bound on the renewability, but apparently that's not how others read it! I don't care strongly either way about an extension to set a renewal bound, I think. A client is always free to tighten ticket lifetime policies unilaterally. We don't need an extension to advertise its policies unless we want to allow server to change their behavior in response. In the other direction, if we think the server may also have an opinion on renewability (you mention keyless things), a NewSessionTicket extension would be easy to support. The client would then use the more restrictive of the server's preferences and its local policy.

Though, I guess, having not specified it this way from the start, the server can't be sure the client honors the extension. I don't know what consequences that has for server-preference scenario.

(For completeness, BoringSSL doesn't allow TLS 1.2 ticket renewals to extend lifetime at all, only TLS 1.3, and TLS 1.2 lifetimes are capped much more tightly. Since TLS 1.2 resumption doesn't involve an ECDH operation, any concerns about a stale online signature are overshadowed by how much data the client is willing to make vulnerable to a single session secret. We'd probably do something similar if we implemented TLS 1.3's plain psk_ke, but we only do psk_dhe_ke.)

David

Subodh
________________________________
From: David Benjamin <[email-masked]<mailto:[email-masked]>>
Sent: Tuesday, January 29, 2019 1:02 PM
To: Nick Sullivan
Cc: Subodh Iyengar; [email-masked]<mailto:[email-masked]>

David

Nick

sessions, then yep!

Subodh

Best,
Chris

---

From: David Benjamin <[email-masked]>
Date: Tue, 29 Jan 2019 23:42:07 -0600

On Tue, Jan 29, 2019 at 10:29 PM Subodh Iyengar <[email-masked]> wrote:

> > Na I meant lower bound. That is such an extension would be useless if
> the time the server mentioned > time the client decided to cache it.
> However the server might advertise a time < time the client decided to
> cache it, in which it would be useful.
>

Oh, I think we were maybe using the words differently. I was thinking
"upper bound" in the sense any server-sent value should be an upper bound
on the true lifetime because the client can always choose to drop it
earlier, but it should not drop it later than that point. Interpreting the
server-sent value as a lower-bound, in this sense of the word, would be
silly as that precludes the client from evicting the cache of its own
accord.

> > I'd actually interpreted the RFC 8446 text to imply a 7 day upper bound
> on the renewability, but apparently that's not how others read it!
> >
>
> Yup I think there is a disconnect between the intention of the server
> operator and the protocol. That is the server operator would like to have
> only 7 day uses of the PSK, however unbeknownst to then, their library is
> renewing the ticket and extending the lifetime of the PSK. This disconnect
> exists in both TLS 1.2 and 1.3, however for TLS 1.2 the renewal of tickets
> is less widely deployed than it should be because of some historic client
> intolerance of it.
>
> I think the interpretation that the lifetime applies to the current ticket
> only is the more common interpretation. I did a short study of several TLS
> 1.3 implementation shandling of ticket lifetimes by staring at some code
> really intensely:
>

Er, right, sorry I should have been clearer. Yeah, we interpret
ticket_lifetime field in NewSessionTicket to be the renewable lifetime,
since the spec talks about a particular ticket. We then implement an
unrenewable lifetime which is set at 7 days after the initial handshake.

I'd read the hard-coded 7 day timeout as a bound on the latter but, now
that I look at it again, I'm not sure why I thought that. (Though I'm
pretty happy with the interpretation anyway.) We'd definitely discussed the
authentication freshness cliff during standardization, but maybe that text
never made it in there? :-/

> boringssl:
>
> Has the ability to use an internal session cache. Before it uses a ticket
> it checks the session timeout against current time. Everytime it receives a
> new session ticket it clamps the SSL_SESSION's timeout
> using ssl_session_rebase_time and then clears any timed out tickets
> with SSL_CTX_flush_sessions.
>

Not quite. The internal session cache is only active on the server. It's
not using the right key to be used on a client anyway. The client uses
callbacks to maintain an external cache. (One could imagine passing the key
in or whatever, but our API evolved from the callback-based story from
OpenSSL, and that's worked well enough to not change it.) But the external
cache stores SSL_SESSION objects which have timeouts. Those timeouts are
managed by BoringSSL and implement the various lifetime policies.

ssl_session_rebase_time itself does not change any lifetimes. It just
rebases the starting time for convenience (per spec, ticket age and ticket
lifetime are measured from issuance of the particular ticket, not the
original auth point). There's also two timeouts on each ticket, as noted,
and one of them never renews.

Agreed.

> *Sent:* Tuesday, January 29, 2019 2:52 PM
> *To:* Subodh Iyengar
> *Cc:* Nick Sullivan; [email-masked]
>
> BoringSSL. 😊

---

From: Nikos Mavrogiannopoulos <[email-masked]>
Date: Wed, 30 Jan 2019 08:37:02 +0100

On Tue, Jan 29, 2019 at 11:53 PM David Benjamin <[email-masked]>
wrote:

>> Fantastic. Would it help to have an extension to set a lower bound on
>> this value, or just make it more painful?
>>
>
> the renewability, but apparently that's not how others read it!
>

That was also our understanding in the implementation for gnutls.

regards,
Nikos