Hi all,
I would like to bring up the following:
(How) Shall the APIs for PSKs and TLS session resumption be modified in Mbed TLS 3.0?
The motivation for this question is the consolidation of PSKs, ticket-based resumption and session-id-based resumption in TLS 1.3. Now, while there will be no TLS 1.3 support in Mbed TLS 3.0 as it stands, I think it would be beneficial to make the API amenable to TLS 1.3 as much as possible already now.
Finding the right API here is non-trivial, and I'll describe first how the current API works and how TLS 1.2 and 1.3 differ, before making suggestions on how the Mbed TLS 3 API might look like. The mail is therefore quite long, but I hope you'll bear with me.
# Session Resumption in Mbed TLS 2.X
Recall how resumption works in Mbed TLS 2.X on the client:
1. Establish a connection as usual 2. Store established session for later re-use `mbedtls_ssl_session_save()` saves connection parameters relevant for session resumption in an instance of `mbedtls_ssl_session`.
Optional: 2.1: Serialize session for offline storage 2.2: Deserialize session
3. Loading a stored session `mbedtls_ssl_session_load()` is called on the stored session after initialization and before running the handshake via `mbedtls_ssl_handshake()`.
4. Connect using stored session Run `mbedtls_ssl_handshake()` as usual.
To my knowledge, the following is transparent to the user: * The means by which resumption is achieved, which can be either id- or ticket-based. * Whether the session was resumed or not - there is a silent fallback to a full handshake when session resumption is rejected by the server.
On the server, ticket- and id-based resumption are configured independently as follows: - ID-based resumption is controlled via `mbedtls_ssl_conf_session_cache()` - Ticket-based resumption is controlled via `mbedtls_ssl_conf_session_tickets_cb()`.
# PSKs in Mbed TLS 2.X
Coming to PSKs: First, recall that, under the hood, resumed connections establish a master secret purely on the basis of a previous master secret, without resorting to asymmetric crypto. The same is true for PSK-based connections, and this observation is embodied in TLS 1.3 which, as mentioned, consolidates resumption and PSKs.
In TLS 1.2, though, PSKs and session resumption are different, and consequently Mbed TLS handles them through a separate API `mbedtls_ssl_conf_psk()`, which takes the PSK identifier and the PSK itself.
Side-question: Should this apply to the SSL configuration or the SSL context? It seems to me that somebody might want to run multiple PSK-based connections with different PSKs, but same configuration otherwise. At the moment, this would require a configuration per connection.
Maybe this decision of what belongs at the level of the config could be thoroughly discussed independently?
# PSKs in TLS 1.3
In TLS 1.3, all kinds of resumptions are hanlded ander the umbrella of PSKs: The client offers PSK identities in its ClientHello, the server picks one or leaves it, and the master secret for the connection is derived from the PSK associated with the PSK identity.
Underlying this is some form of translation
`PSK-Identity -> PSK`
on the server which allows to derive the PSK from the PSK identity.
How this mapping is realized is entirely implementation-specific, but it can take at least the following forms, giving back all forms of session resumption:
- 'PSK Identity -> PSK' via database lookup: This subsumes classical PSKs and ID-based resumption, since the data necessary to resume a session is stored on the server.
- 'PSK Identity -> PSK' via AEAD: The PSK can be encoded in the PSK identity itself by using some authenticated encryption of the PSK as the PSK identity, the key for which resides on the server. This subsumes Ticket-based resumption.
There are the following noteworthy differences, though:
1. In TLS 1.2, the server provides a 'PSK identity hint' and the client picks a particular PSK identity. In TLS 1.3, the client offers a _list_ of PSKs, and the server picks one or none.
2. In TLS 1.2, the server can issue only a single session ticket. In TLS 1.3, the server can issue as many session tickets as he wishes, and the client can use any of those for later session resumption.
This has the following consequences for the API: 1. The PSK-configuration API must allow the configuration of multiple PSKs on the client. 2. There must be a means to export more than one session ticket for later resumption.
# API considerations for Mbed TLS 3.X
## Part 1: Load/Save API
In essence, keep the flow of `mbedtls_ssl_session_load/save()`, but make the following adjustments. Whether the target structure remains `mbedtls_ssl_session` and how it looks like internally isn't relevant at this point and is up to discussion.
1. It must be possible 'save' a session multiple times, which in TLS 1.3 amounts to exporting the tickets issued by the server one-by-one.
This can be realized in a variety of ways, for example: - Allow calling `mbedtls_ssl_session_save()` multiple times, and modify its semantics from the idempotent nature of Mbed TLS 2.X to iterating through the available tickets, and returning an error when no more tickets are available.
This has the benefit that it likely requires no code change for users migrating from Mbed TLS 2.X, since a change is needed only when an application stores a single session multiple times, which could be done by calling `mbedtls_ssl_session_save()` multiple times before, while now one would need to call it once and manually replicate the obtained session structure.
On the negative side, this wastes memory for applications not interested in session resumption, or those that only need a single ticket. We don't want the server to be able to flood the client with arbitrarily many tickets.
- Allow registering a callback that's triggered whenever a new ticket arrives.
The drawback of this is that it is larger deviation from the Mbed TLS 2.X API. On the positive side, applications that don't need tickets, or only need a limited number of such, can simply drop further tickets and thereby prevent allocating RAM for them.
2. It must be possible to 'load' multiple sessions, meaning that the client should offer any of them to the server for resumption.
## Part 2: Consolidation with PSK
Make it possible to setup an `mbedtls_ssl_session` (or whatever it will be called) structure manually from an externally PSK provisioned PSK, and allow loading this session for resumption as above, via one of potentially many calls to `mbedtls_ssl_session_load()`.
There are multiple variants to this, for example:
1. Make `mbedtls_ssl_session` transparent so users can build it manually by filling the respective fields.
2. Provide a helper API to build a session from a PSK.
The old API `mbedtls_ssl_conf_psk()` can then be _derived_ from this for convenience, building a session from the provided PSK and loading it, in a single API.
Before going into further details and making the mail even longer: What do you think of this approach? Do you see alternatives?
Best, Hanno IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.