[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