[gnutls-devel] session ticket key rotation

Nikos Mavrogiannopoulos nmav at gnutls.org
Mon Nov 14 10:38:38 CET 2016


On Sun, Nov 13, 2016 at 9:25 PM, Daniel Kahn Gillmor
<dkg at fifthhorseman.net> wrote:
> Hi GnuTLS folks--
> I'm trying to add session tickets to a GnuTLS-enabled daemon.
> I'm using gnutls_session_ticket_enable_server(), but it looks like there
> is no way to smoothly rotate session ticket keys.  That is, as soon as i
> call gnutls_session_ticket_enable_server(), all previously-issued
> session tickets become invalidated.

Hi Daniel,
 Right, it was intended for the applications to handle such rotation,
and a smooth rotation is not possible as I see with the current API.

> What i'd prefer is for my server to have a pool of N session tickets
> keys, and for me to expire (and replace) one of them (in sequence) every
> K seconds.
> The tickets issued by this setup would have some reserved space that
> indicated which of the slots is in use (e.g. the top 3 bits, if N = 8).
> When encrypting, we'd always select the most recently-regeneratted slot,
> and we'd set those bits to correspond to the slot in use.
>
> When decrypting, we'd select the key to decrypt with based on the
> corresponding bits.

Seems reasonable.

> Is there a way to do this in GnuTLS as it currently stands?  If not,
> would you be interested in such a feature?

Certainly. My goal for the new releases is to make it as simple as
possible for applications to use gnutls. I no longer try to push to
applications all the hard parts :)

> I'm imagining that an opaque server-side API for this would look
> something like:
>     struct gnutls_ticket_key_pool_int;
>     typedef struct gnutls_ticket_key_pool_int *gnutls_ticket_key_pool_t;
>
>     int gnutls_ticket_key_pool_init(gnutls_ticket_key_pool_t *pool, int numkeys);
>     int gnutls_ticket_key_pool_free(gnutls_ticket_key_pool_t pool);
>     int gnutls_ticket_key_pool_rotate(gnutls_ticket_key_pool_t pool);

The tricky part would be making the rotate function semantics easy to
use, even in multi-threaded environments, and allow efficient access
to keys at the same time. You wouldn't want a multi-threaded server to
hold a lock in order to access a ticket key.

That's not an easy goal to achieve; something similar using atomic
variables of C11 (with fallback) was done in gnutls_rnd() (see
random.c and  _gnutls_rnd_init).

> Users would associate the ticket key pool with a session using
> gnutls_credentials_get and gnutls_credentials_set, making the workflow
> and memory ownership model aligned with existing use.

The change in semantics by that would be that the credentials
structure would no longer hold only read-only data. However, if the
rotation is transparent for all types of applications, I have no
objection on that.

> The opacity of the object might cause trouble if you wanted to share the
> pool session ticket keys across a pool of front-end servers, or if you
> wanted session tickets to survive a server reboot.  You could handle
> that situation by adding a pair of serialization/deserialization
> functions for the ticket key pool.

Serialization and de/serialization would simplify things a lot for
applications. It would require some versioning though to allow
upgrading to a new ticket key handling at the future.

> Any thoughts?  Is there already a good way to do something like this in
> the existing API and i'm just missing it?

I do not think so.

regards,
Nikos



More information about the Gnutls-devel mailing list