ol.clave.ext.jetty
Jetty integration for clave automation.
Provides SNI-based certificate selection during TLS handshakes. Certificates are looked up on-demand for each connection based on the requested hostname, so renewals take effect immediately.
This ns is useful for authors integrating with jetty directly. If you want to use a jetty ring adapter see:
sni-key-manager
(sni-key-manager lookup-fn)
Create an X509ExtendedKeyManager that looks up certificates by SNI hostname.
On each TLS handshake, extracts the SNI hostname from the ClientHello and
calls lookup-fn to retrieve the certificate bundle for that hostname.
| key | description |
|-------------|---------------------------------------------------------|
| lookup-fn | Function (fn [hostname] bundle) returning cert bundle |
The lookup-fn receives the SNI hostname and should return a certificate
bundle map with :certificate (vector of X509Certificate) and :private-key.
Returns nil if no certificate is available for that hostname.
sni-ssl-context
(sni-ssl-context lookup-fn)
Create an SSLContext configured with SNI-aware certificate selection.
Uses lookup-fn to fetch certificates during TLS handshake based on
the client’s requested hostname (SNI). Certificates are looked up fresh
on each handshake, so renewals take effect immediately.
| key | description |
|-------------|---------------------------------------------------------|
| lookup-fn | Function (fn [hostname] bundle) returning cert bundle |
Returns a javax.net.ssl.SSLContext ready for use with Jetty.
(def ssl-ctx (sni-ssl-context
(fn [hostname] (auto/lookup-cert system hostname))))
(jetty/run-jetty handler {:ssl-context ssl-ctx ...})
sni-alpn-key-manager
(sni-alpn-key-manager lookup-fn challenge-registry)
Create an X509ExtendedKeyManager that handles both SNI and ALPN challenges.
Extends the SNI-based certificate selection with TLS-ALPN-01 challenge support. During TLS handshake: 1. If ALPN protocol is 'acme-tls/1' and challenge-registry has data, serve challenge cert 2. Otherwise, use lookup-fn for normal SNI-based cert selection
This does NOT interfere with HTTP/2 (h2) negotiation because: - Regular clients offer ["h2", "http/1.1"] → normal cert via SNI lookup - ACME servers offer ["acme-tls/1"] exclusively → challenge cert
| key | description |
|----------------------|---------------------------------------------------|
| lookup-fn | Function (fn [hostname] bundle) for SNI lookup |
| challenge-registry | Atom with domain→challenge-cert-data map |
The challenge-registry contains maps as returned by tlsalpn01-challenge-cert:
- :x509 - The X509Certificate to serve
- :keypair - The KeyPair with private key
sni-alpn-ssl-context
(sni-alpn-ssl-context lookup-fn tls-alpn-solver)
Create an SSLContext with SNI cert selection and ALPN challenge support.
For normal HTTPS traffic: looks up certs by SNI hostname via lookup-fn. For ACME TLS-ALPN-01 challenges: serves challenge cert when ALPN is 'acme-tls/1'.
| key | description |
|-------------------|--------------------------------------------------|
| lookup-fn | Function (fn [hostname] bundle) for SNI lookup |
| tls-alpn-solver | TLS-ALPN solver with :registry key ) |
Returns a javax.net.ssl.SSLContext ready for use with Jetty.
(def tls-alpn-solver (tls-alpn/switchable-solver {:port 443 }))
(def ssl-ctx (sni-alpn-ssl-context
(fn [hostname] (auto/lookup-cert system hostname))
tls-alpn-solver))
(jetty/run-jetty handler {:ssl-context ssl-ctx ...})