Subject: [TLS] Session ticket (re-)use in multi-process applications?

From: Viktor Dukhovni <[email-masked]>
Date: Fri, 28 Apr 2017 14:20:38 -0400

Unlike many/most browsers, Postfix makes each TLS connection from a separate smtp(8) client process.

TLS session reuse is supported via a shared service process tlsmgr(8) which maintains a cache of
saved sessions for peer destinations that have provided session resumption data (session tickets,
or just a session id).

Once a session is saved into the session database, it is used by multiple clients until it
expires (with TLS <= 1.2, resumption typically does not create a new session, and the same
session remains in the cache).

How should this change with TLS 1.3?  The draft says:

   Clients SHOULD attempt to use each
   ticket no more than once, with more recent tickets being used first.

What does this mean in practice?  What happens if Postfix continues to use the
same ticket multiple times anyway?  Will servers somehow invalidate the ticket
after first use?  Are the consequences of reuse more severe than with TLS 1.2?

To avoid re-use, it would seem that tlsmgr(8) would have to delete the ticket
from the cache after vending it to an smtp(8) client.  For the cache to work
at all well, with sessions consistently resumed after an initial ramp-up, it
would seem that the cache would now need to store a list of tickets, rather
than just a single ticket for each destination.  If so, that's considerable
new complexity. :-(

I'd need to prepend tickets to the cache slot, rather than replace the cache
slot, and trim tickets from the end if the list of available tickets grows
too long.  Then when a client asks for a ticket, pop the first entry of the
list.

This design would have to coexist with the existing support for TLS <= 1.2
session resumption.  So some cache slots would be single-instance multi-use,
and others multi-instance single-use.

When resuming with a TLS 1.3 peer, what happens if the peer is behind a load
balancer, and some of the nodes are still TLS 1.2?  Does the handshake fail,
or we somehow end-up doing a full TLS 1.2 handshake?

(Postfix will in many cases "see through" load-balancers, because STARTTLS
is preceded by the peer's SMTP banner and EHLO response which include a
notional remote server name, and when that's server-specific, I use a
separate cache entry for each server).

I'll also need to figure out how all of this plays out in the new OpenSSL
1.1.1 code and its "new session" callbacks.

Unlike most other TLS 1.3 changes, this one is not going to be particularly
transparent to the application, unless ignoring the "SHOULD" and just
reusing session tickets works against peer servers and within the updated
OpenSSL "new session" callback implementation.

Obviously, the OpenSSL-specific issues I'll be hashing out elsewhere, just
mentioning that there are API implications to changes in how resumption is
to be handled...

-- 
	Viktor.

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 28 Apr 2017 11:29:24 -0700

> after first use?  Are the consequences of reuse more severe than with TLS

Shouldn't be. Mostly, it allows attackers to correlate multiple sessions
from the same
client, which sounds like it's not an issue in your case.

To avoid re-use, it would seem that tlsmgr(8) would have to delete the
> ticket

Well, the idea is that the server gives you a new ticket on each handshake,
so that
you don't have to reuse.

> or we somehow end-up doing a full TLS 1.2 handshake?

You should get a TLS 1.2 handshake, modulo bugs.

-Ekr

---

From: Viktor Dukhovni <[email-masked]>
Date: Fri, 28 Apr 2017 15:10:21 -0400

> On Apr 28, 2017, at 2:29 PM, Eric Rescorla <[email-masked]> wrote:
> 
> Shouldn't be. Mostly, it allows attackers to correlate multiple sessions from the same

Well, the server 220 banner, client EHLO command and server 250 EHLO response that
precede STARTTLS pretty much take care of correlating sessions from the same client.

Also SMTP is not usually tunneled through proxies, and there is no issue similar to
identifying which HTTP pages a client is loading by correlating multiple requests.
Each message delivery is independent.

Just the client and server IP addresses leak essentially all the data of interest.
The only thing not leaked by these is leaked via SNI and DNS MX lookups.

So I take it that reuse would (in this case) be reasonably harmless.
So I can use the "latest" tickets as often as it remains the "latest"
ticket.  And servers will likely cooperate?

The only change might then be that I might see a much higher rate of session
updates as each handshake obtains another new ticket?  Unless of course whether
to issue a new ticket, or let the current ticket stand is left to the application.

This raises an interoperability question:

	* Should SMTP servers always issue a new ticket when a client resumes a
          session with an existing ticket?

On the one hand, a lot of churn can be saved if the server can replace only
tickets that are close to expiring.

On the other hand, if most clients follow the draft recommendation and discard
tickets on first use, then not issuing a replacement ticket each time will mean
that each session will be resumed just once, and 50% of connections will incur
the cost of a full handshake.

Is the question of whether/when to issue new tickets expected to be part of
an "application profile"?  Do we need a TLS 1.3 application profile for SMTP?
Or just issue a fresh ticket on every resumption?

-- 
	Viktor.