Class Ticketer

java.lang.Object
io.github.mahmoudimus.quic.tls.Ticketer

public final class Ticketer extends Object
A stateless session ticket encrypter for a server (RFC 8446 section 4.6.1, RFC 5077 section 4): the session state is sealed into the ticket with AES-256-GCM under a server key, so the server keeps nothing per session. The key rotates once per lifetime; tickets sealed under the previous key are still opened during the following lifetime, so every ticket stays usable for at least one lifetime and at most two.
   key_name (16) | nonce (12) | AES-256-GCM(state) with the key name as additional data | tag (16)
 

The nonce is random for every ticket (a counter would let observers link tickets). A ticket longer than any this ticketer sealed is rejected before decryption.

Servers that must accept each other's tickets need to share a ticketer, which this class does not provide across processes: each instance has its own random keys.

Threads. Thread-safe without locks: the key state is an immutable value swapped atomically, and every operation uses its own Cipher.

  • Field Details

    • DEFAULT_LIFETIME

      public static final Duration DEFAULT_LIFETIME
      The default lifetime of a ticket key, and so of tickets: 6 hours, as rustls uses.
    • MAX_LIFETIME

      public static final Duration MAX_LIFETIME
      The longest ticket lifetime TLS 1.3 allows: 7 days (RFC 8446 section 4.6.1).
  • Method Details

    • create

      public static Ticketer create()
      A ticketer with random keys rotated every DEFAULT_LIFETIME.
      Returns:
      the ticketer
    • create

      public static Ticketer create(Duration lifetime, InstantSource clock)
      A ticketer with random keys.
      Parameters:
      lifetime - how long a key seals tickets, which is also the lifetime announced in each ticket; at most 7 days
      clock - the wall clock that times rotation
      Returns:
      the ticketer
      Throws:
      IllegalArgumentException - if the lifetime is not positive or exceeds 7 days
    • lifetime

      public Duration lifetime()
      The lifetime of a key, announced as the ticket lifetime.
      Returns:
      the lifetime
    • encrypt

      public byte[] encrypt(byte[] plaintext)
      Seals session state into a ticket under the current key.
      Parameters:
      plaintext - the encoded session state
      Returns:
      the ticket
    • decrypt

      public byte[] decrypt(byte[] ticket)
      Opens a ticket sealed by this ticketer under its current key, or its previous key while that is within its grace lifetime.
      Parameters:
      ticket - the ticket from a client
      Returns:
      the session state, or null if the ticket is not one of ours, has been tampered with, or its key is gone