Commits
Tarun Sukhani authored 7a3a4bfc235
refactor: drop JKS support; PEM-only HTTPS via mkcert or openssl (PF-68, release 1.12.20)
Now that PF-66 unified PEM and JKS through one Netty SslContext under a
single ALPN configuration, JKS is structurally redundant. Every TLS
configuration JKS expressed has an equivalent in PEM, the local-dev
workflow is one mkcert command on PEM versus three (openssl pkcs12 +
keytool import) on JKS, and Chrome's QUIC stack only honors trusted
certs — a mkcert-signed PEM is trusted by the system store after
mkcert -install, so HTTP/3 actually negotiates in the browser. The
play1 fork is alpha with no JKS-based deployments.
Java side:
- SslHttpServerPipelineFactory.buildSslContext: drop JKS else-branch.
Throw IllegalStateException with a "PEM-only" message naming the
expected cert/key paths when conf/host.cert or conf/host.key is
missing. Drop unused KeyStore / KeyManagerFactory / FileInputStream
imports.
- Http3SslContextFactory.build: same drop. Drop unused imports.
Python CLI side:
- https.py rewritten as PEM-aware: detects mkcert on PATH and runs
`mkcert -cert-file conf/host.cert -key-file conf/host.key
localhost 127.0.0.1 ::1` if present; otherwise falls back to
`openssl req -x509 -newkey rsa:2048 -nodes` for a self-signed cert
with subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1, valid 3650
days. The fallback prints a hint about installing mkcert for
browser-trusted local-dev TLS. enable-https sets certificate.file
+ certificate.key.file in application.conf (only when not already
active — same comment/uncomment-only contract as the previous
iteration). disable-https comments https.port; cert+key files and
certificate.* lines are preserved.
- autotest.py: keystore.file check replaced with certificate.file
check. The legacy -Djavax.net.ssl.trustStore arg passed to
FirePhoque is dropped — that JVM property expects a JKS keystore,
which we no longer have. Operators autotesting under HTTPS should
install mkcert; its `mkcert -install` adds the local CA to the
system trust store and the JDK picks it up automatically.
Skeleton + integration testapp:
- resources/application-skel/conf/application.conf: replace the
commented keystore.* / trustmanager.algorithm / certificate.password
block with a commented certificate.file + certificate.key.file pair,
noting the unencrypted-PEM constraint.
- framework/test-src/integration/testapp/conf: regenerate as PEM
(host.cert + host.key via openssl req -x509 -newkey rsa:2048 -nodes
with SAN=DNS:localhost,IP:127.0.0.1,IP:::1). Delete test-keystore.jks.
Update %test.* keys from keystore.file/.password to certificate.file/
.key.file. Http3FunctionalTest Javadoc updated to refer to PEM.
Tests:
- SslHttpServerPipelineFactoryAlpnTest:
• Drop buildSslContextFromJksAdvertisesH2ThenHttp1 (JKS no longer
builds).
• Add buildSslContextFromPemAdvertisesH2ThenHttp1: generates a PEM
cert+key via openssl subprocess (mirrors production CLI fallback),
asserts the SslContext's ALPN negotiator advertises h2 then http/1.1.
• Add buildSslContextThrowsWhenCertFilesMissing: asserts a clean
IllegalStateException with the expected paths in the message,
preventing a regression where we silently fall through to a less
helpful error.
• Existing flag/protocol-list tests retained.
- Integration tests (Http2FunctionalTest 3/3, Http3FunctionalTest 1/1):
pass against the PEM testapp config.
Documentation:
- cmd-enable-https.txt rewritten for the PEM workflow: documents the
mkcert preference + openssl fallback, explicit unencrypted-PEM
constraint, and the four-step idempotent flow (generate-or-reuse
cert+key, set certificate.*, set https.port, set http.port).
- cmd-disable-https.txt: refers to host.cert/host.key (not
certificate.jks); drops keystore.* mentions.
- documentation/manual/configuration.textile: replace the `keystore`
section with `certificate` (PEM) section. Drop the standalone
`trustmanager.algorithm` section (no longer read at the framework
level). Update ssl.KeyManagerFactory.algorithm description to drop
the keystore.file cross-reference.
- documentation/manual/production.textile: replace the JKS-vs-PEM
examples with a single PEM-only section pointing at play
enable-https for local dev and showing the openssl one-liner for
manual generation.
- documentation/manual_ja/* (Japanese translations): out of scope —
flagged as a separate follow-up if the project wants them updated.
End-to-end verified on a fresh app:
$ play new pf68test && cd pf68test && play enable-https
~ Generated mkcert-signed PEM cert+key at conf/host.cert and conf/host.key.
~ (Trusted by the system store after `mkcert -install` — Chrome will accept HTTP/3.)
~ HTTP enabled on port 9000.
~ HTTPS enabled on port 9443 (HTTP/2 + HTTP/3 via ALPN).
$ play start
Listening for HTTP on port 9000 (...)
Listening for HTTPS on port 9443 (...)
Listening for HTTP/3 on UDP port 9443 ...
$ curl -s http://localhost:9000/ → 1.1 200
$ curl -ks --http2 https://localhost:9443/ → 2 200
$ curl -kvs https://localhost:9443/ | grep alt-svc
< alt-svc: h3=":9443"; ma=86400
$ play enable-https (reuse path)
~ HTTPS is already enabled in conf/application.conf.
~ Cert+key present at conf/host.cert and conf/host.key.
cert mtime unchanged
$ play disable-https
~ HTTPS disabled.
~ The cert+key at conf/host.cert and conf/host.key are preserved
PEM files preserved on disk; certificate.* lines preserved in
application.conf; only https.port is commented out.
application.conf after enable-https has ONLY: http.port,
certificate.file, certificate.key.file, https.port. Zero keystore.*
or trustmanager.* lines anywhere.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>