← All recipes
Moderne licensed

Enforce a TLS 1.3 floor in Java sources

Recipe IDio.moderne.cryptography.pqc.EnforceTls13JavaArtifactio.moderne.recipe:rewrite-cryptography

Rewrites JSSE and BouncyCastle protocol configuration to a TLS 1.3 floor, so that JEP 527 hybrid key exchange — which exists for TLS 1.3 only — can negotiate. Covers SSLContext.getInstance algorithm literals, the setEnabledProtocols/setProtocols sinks including BCSSLParameters, same-file protocol array constants whose only readers are those sinks, the jdk.tls.client.protocols, jdk.tls.server.protocols and https.protocols system properties, and getSupportedVersions overrides on BouncyCastle TlsPeer subclasses. Surfaces that cannot be rewritten safely — an array constant shared with non-TLS code, or a Security.setProperty("jdk.tls.disabledAlgorithms", ...) call that replaces rather than extends the JDK default list — are marked and recorded as Report only rows instead of being changed. Protocol values that are not statically resolvable are left alone without a row: finding those is the discovery recipes' job, and reporting them here would duplicate their findings. Test sources are skipped by default, because a protocol test usually enables a legacy version on purpose in order to assert that it is refused. One shape deserves review before the diff is merged: a protocol list that was deliberately *widened* to work around a handshake failure against a legacy peer looks exactly like an unmaintained legacy floor, and narrowing it will re-break that peer. Every rewrite is recorded in the enforcement data table with its before and after protocols, and retainTls12In scopes the exception once such a site is identified.

Single recipeProprietary

Usage

This recipe has no required configuration options. You’ll need the Moderne CLI configured before running the command below.

mod run . --recipe io.moderne.cryptography.pqc.EnforceTls13Java

If the recipe isn’t available locally, install it with:

mod config recipes jar install io.moderne.recipe:rewrite-cryptography:RELEASE

Options

NameTypeDescription
minimumProtocolStringThe protocol floor to enforce globally: TLSv1.3 (the default) strips TLSv1.2 from every enabled-protocols list, TLSv1.2 retains it everywhere. Use retainTls12In instead when only some modules need the exception. SSLContext.getInstance algorithm names are rewritten to TLSv1.3 under either setting, because the algorithm name is a *ceiling*: a TLSv1.2 context can never negotiate TLS 1.3, so a TLSv1.2 floor would otherwise be capped below the version it is meant to allow.
e.g. TLSv1.2
retainTls12InListGlobs naming the sources that keep TLSv1.2 in their rewritten protocol lists, matched against both the source path and the enclosing fully qualified class name. SSLv2Hello, SSLv3, TLSv1 and TLSv1.1 are still stripped inside a matched source, and TLSv1.3 is still ensured present — the exception is for partners stuck on TLS 1.2, not for keeping a legacy floor.
e.g. **/legacy/**
rewriteContextAlgorithmBooleanRewrite legacy SSLContext.getInstance algorithm literals — SSL, SSLv3, TLSv1, TLSv1.1, TLSv1.2, matched case-insensitively as JCA does — to TLSv1.3. On its own this is hygiene rather than enforcement, since the algorithm name only raises the ceiling; it is enforcement because this recipe rewrites the enabled-protocols lists in the same pass. Default true.
skipTestSourcesBooleanLeave test sources alone. A protocol test very often enables a legacy version on purpose so it can assert that the version is refused, so rewriting it hardens nothing and deletes the coverage that proves the hardening works. Set to false to rewrite tests as well, which is only useful once the production code is already enforced. Default true.
strictAlgorithmNameBooleanAlso rewrite the version-flexible algorithm names TLS and Default to TLSv1.3. Off by default: those names already permit TLS 1.3, so changing them narrows what the JVM may negotiate without making anything post-quantum ready.

Data tables

Structured output this recipe can produce.

  • TLS protocol enforcementProtocol configuration surfaces rewritten to a TLS 1.3 floor, and surfaces flagged as needing manual review because rewriting them would change behaviour in a way a source scan cannot justify. Rows describe declared configuration only: a JVM's `java.security` file, container `-D` flags and environment variables are invisible here, so an enforced source does not prove an enforced runtime.io.moderne.cryptography.pqc.table.ProtocolEnforcementTable
  • Source files that had resultsSource files that were modified by the recipe run.org.openrewrite.table.SourcesFileResults
  • Source files that had search resultsSearch results that were found during the recipe run.org.openrewrite.table.SearchResults
  • Source files that errored on a recipeThe details of all errors produced by a recipe run.org.openrewrite.table.SourcesFileErrors
  • Recipe performanceStatistics used in analyzing the performance of recipes.org.openrewrite.table.RecipeRunStats