Skip to content

Commit a63c2cb

Browse files
committed
GH-803: use JDK built-in ML-KEM on Java24+
Add KEMs to SecurityUtils and SecurityEntityFactories. Configure the "SunJCEWrapper" SecurityProviderRegistrar to include support for ML-KEM if it is available in Java's SunJCE security provider. Rename interface KeyEncapsulationMethod to KEM: this serves now as a wrapper around different KEM implementations from Bouncy Castle or from the JDK. Because the class name is user-visible in the security provider registrar configuration, using KEM minimizes confusions. Move the Bouncy Castle implementations from sshd-core to sshd-common where the rest of BC-specific stuff lives. Add a JceKEM factory to create KEM instances if supported by the platform. This default factory always throws NoSuchAlgorithmException. In the multi-release section for Java 24, add a real JceKEM factory that returns instances of our own KEM wrapper class that internally use javax.crypto.KEM. Change the Github workflows to use Java 25 for compiling, and run the tests on Java 8, 17, and 25. (Previously we tested on 8, 11, and 17.) The new JDK ML-KEM support is tested in the "multirelease" execution of the maven-failsafe-plugin in bundle sshd-test in test OpenSshMlKemTest.
1 parent e173cb7 commit a63c2cb

28 files changed

Lines changed: 614 additions & 136 deletions

File tree

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
strategy:
3636
matrix:
3737
os: [ ubuntu-latest ]
38-
java: [ '17' ]
38+
java: [ '25' ]
3939
steps:
4040
- uses: actions/checkout@v4
4141

@@ -66,7 +66,7 @@ jobs:
6666
strategy:
6767
matrix:
6868
os: [ ubuntu-latest, windows-latest ]
69-
java: [ '8', '11', '17' ]
69+
java: [ '8', '17', '25' ]
7070
steps:
7171
- uses: actions/checkout@v4
7272

@@ -76,7 +76,7 @@ jobs:
7676
distribution: temurin
7777
java-version: |
7878
${{ matrix.java }}
79-
17
79+
25
8080
8181
- uses: actions/cache@v4
8282
with:

.github/workflows/master-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
uses: actions/setup-java@v4
5353
with:
5454
distribution: temurin
55-
java-version: '17'
55+
java-version: '25'
5656
# Create a ~/.m2/settings.xml referencing these environment variable names
5757
server-id: 'apache.snapshots.https'
5858
server-username: NEXUS_USERNAME

.github/workflows/next-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
uses: actions/setup-java@v4
5353
with:
5454
distribution: temurin
55-
java-version: '17'
55+
java-version: '25'
5656
# Create a ~/.m2/settings.xml referencing these environment variable names
5757
server-id: 'apache.snapshots.https'
5858
server-username: NEXUS_USERNAME

CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,7 @@ Complete refactoring of the SSH transport protocol. New feature: support for cli
6666
the version used in SSH. Since the Poly1305 MAC in Java is not accessible separately, Apache MINA SSHD still
6767
has to use its own implementation for that part.)
6868

69+
* [GH-803](https://github.com/apache/mina-sshd/issues/803) Support the JDK built-in ML-KEMs on Java24+
70+
71+
Use the ML-KEM implementations from SunJCE if run on Java >= 24. For Java < 24, The Bouncy Castle implementations
72+
are used. The SunJCE ML-KEMs are advertised in the `SunJCESecurityProviderRegistrar`.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272

7373
<properties>
7474
<japicmp-sshd-last-release>2.16.0</japicmp-sshd-last-release>
75-
<minimalJavaBuildVersion>17</minimalJavaBuildVersion>
75+
<minimalJavaBuildVersion>24</minimalJavaBuildVersion>
7676
<surefireJdk>[${minimalJavaBuildVersion},)</surefireJdk>
7777
<minimalMavenBuildVersion>3.9.8</minimalMavenBuildVersion>
7878

sshd-common/pom.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,19 @@
200200
<release>15</release>
201201
</configuration>
202202
</execution>
203+
<execution>
204+
<id>compile-24</id>
205+
<goals>
206+
<goal>compile</goal>
207+
</goals>
208+
<configuration>
209+
<compileSourceRoots>
210+
<compileSourceRoot>${project.basedir}/src/main/java24</compileSourceRoot>
211+
</compileSourceRoots>
212+
<multiReleaseOutput>true</multiReleaseOutput>
213+
<release>24</release>
214+
</configuration>
215+
</execution>
203216
</executions>
204217
</plugin>
205218
</plugins>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.sshd.common.util.security;
20+
21+
import java.security.NoSuchAlgorithmException;
22+
import java.security.Provider;
23+
24+
enum JceKEM implements KEMFactory {
25+
26+
INSTANCE;
27+
28+
@Override
29+
public KEM get(String algorithm, Provider provider) throws NoSuchAlgorithmException {
30+
throw new NoSuchAlgorithmException();
31+
}
32+
33+
@Override
34+
public boolean isSupported(String algorithm) {
35+
return false;
36+
}
37+
}

sshd-core/src/main/java/org/apache/sshd/common/kex/KeyEncapsulationMethod.java renamed to sshd-common/src/main/java/org/apache/sshd/common/util/security/KEM.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package org.apache.sshd.common.kex;
19+
package org.apache.sshd.common.util.security;
20+
21+
import org.apache.sshd.common.OptionalFeature;
2022

2123
/**
2224
* General interface for key encapsulation methods (KEM).
2325
*/
24-
public interface KeyEncapsulationMethod {
26+
public interface KEM extends OptionalFeature {
27+
28+
String ML_KEM_768 = "ML-KEM-768";
29+
30+
String ML_KEM_1024 = "ML-KEM-1024";
31+
32+
String SNTRUP_761 = "SNTRUP-761";
2533

2634
/**
2735
* Client-side KEM operations.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.sshd.common.util.security;
20+
21+
import java.security.NoSuchAlgorithmException;
22+
import java.security.Provider;
23+
24+
public interface KEMFactory {
25+
26+
default KEM get(String algorithm) throws NoSuchAlgorithmException {
27+
return get(algorithm, null);
28+
}
29+
30+
KEM get(String algorithm, Provider provider) throws NoSuchAlgorithmException;
31+
32+
default boolean isSupported(String algorithm) {
33+
try {
34+
KEM kem = get(algorithm);
35+
return kem.isSupported();
36+
} catch (Throwable t) {
37+
return false;
38+
}
39+
}
40+
41+
}

sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityEntityFactory.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ default SecureRandom createSecureRandom(String algorithm) throws GeneralSecurity
7676
throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not supported (default)");
7777
}
7878

79+
default KEM createKEM(String algorithm) throws GeneralSecurityException {
80+
throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not supported (default)");
81+
}
82+
7983
class Named implements SecurityEntityFactory {
8084

8185
private final String name;
@@ -232,5 +236,10 @@ public Signature createSignature(String algorithm) throws GeneralSecurityExcepti
232236
public SecureRandom createSecureRandom(String algorithm) throws GeneralSecurityException {
233237
return SecureRandom.getInstance(algorithm);
234238
}
239+
240+
@Override
241+
public KEM createKEM(String algorithm) throws GeneralSecurityException {
242+
return JceKEM.INSTANCE.get(algorithm);
243+
}
235244
}
236245
}

0 commit comments

Comments
 (0)