Module tech.kwik.agent15


module tech.kwik.agent15
Agent15 is a Java implementation of the handshake protocol of TLS 1.3 (RFC 8446, section 4), running on Java 11. It was developed for, and is used by, QUIC implementations: QUIC uses TLS 1.3 for encryption, but only the handshake layer, not the record layer (see RFC 9001, section 3).

What is implemented

Agent15 implements all of the handshake protocol needed to set up and maintain a QUIC connection, including HelloRetryRequest, session resumption and 0-RTT. Because it targets QUIC, it implements only the handshake layer, not the TLS record layer. A few handshake messages are intentionally not implemented, as they are not used with QUIC: EndOfEarlyData and KeyUpdate. Unsupported extensions do not cause parsing to fail; the parser represents them with an UnknownExtension object.

Agent15 also implements RFC 10024: Post-Quantum Traditional (PQ/T) Hybrid Key Agreement Mechanisms for TLS 1.3.

Supported cryptography

Cipher suites: TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256.
Signature algorithms: rsa_pkcs1_sha256 (certificates only), rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, ecdsa_secp256r1_sha256.
Named groups (key exchange): secp256r1, secp384r1, secp521r1, x25519 and x448, and the post-quantum hybrid key exchanges X25519MLKEM768, SecP256r1MLKEM768 and SecP384r1MLKEM1024. The latter are provided by a separate module, agent15-pqc (tech.kwik.agent15.pqc), that requires a Java 25 runtime; they are available exactly when that module is present.
A client can offer a key share for more than one group with the TlsClientEngine.startHandshake method that takes a list of key share groups, which avoids the extra round trip of a HelloRetryRequest when the server does not support the client's first choice.

Getting started

The public API lives in the tech.kwik.agent15.engine package.
  • Client: instantiate a TlsClientEngine with a ClientMessageSender and a TlsStatusEventHandler, then call startHandshake(). The ClientMessageSender is the callback used to actually send handshake messages; the TlsStatusEventHandler lets the application react to TLS events needed for the QUIC handshake (for example, when early or handshake secrets become available). Any TLS message received should be passed to the engine's received method.
  • Server: instantiate a TlsServerEngine with a ServerMessageSender, a TlsStatusEventHandler, and the server certificate and its private key. As with the client, any TLS message received should be passed to the engine, which takes care of sending the necessary messages back to the client. Which named groups the server offers for key exchange can be configured with TlsServerEngine.setSupportedGroups; by default it offers all groups its key exchange factories can provide, which is what makes the hybrid post-quantum groups available as soon as the agent15-pqc module is on the class path.
QUIC's transport-parameters extension is supported by injecting a custom extension parser through the engine API. Session resumption uses a PSK obtained from a NewSessionTicket message; the server keeps session tickets in an in-memory cache, so a restart invalidates all outstanding tickets. Client authentication with a client certificate is supported by the client engine.

Security

Certificates are validated against the default Java truststore; a custom trust manager can be configured to use other certificate authorities.

Handshake cryptography can also be extended through ServiceLoader: KeyExchangeFactory and SignatureAlgorithmFactory providers on the class/module path are loaded automatically (for example the agent15-pqc module). Treat those providers like any other trusted classpath code; a malicious provider could alter key agreement or certificate verification for the groups or schemes it registers.

  • Packages

    Exports
    Package
    Description
    Core types shared across the library, such as protocol constants, protocol exceptions and session tickets.
    TLS alert types, thrown as exceptions to signal protocol errors during the handshake.
    The public API of the library: the client and server TLS engines and their factories, plus the callback interfaces an application implements to send messages and react to handshake events.
    Platform abstraction for mapping cryptographic algorithm names, needed because Android uses different names than standard Java.
    The TLS extension types and the parser that dispatches to them.
    The TLS 1.3 handshake message types (RFC 8446 §4), such as ClientHello, ServerHello, Certificate and Finished.