Skip to content

Commit bfa82b4

Browse files
uttamguptaUttam Gupta
authored andcommitted
Issue-973 (part1) - Removing direct dependency on BouncyCastle library and using JCE.
- This is first change towards removing direct dependency on BouncyCastle. - Removed the imports org.bouncycastle.crypto.prng.RandomGenerator and org.bouncycastle.crypto.prng.VMPCRandomGenerator from the file BouncyCastleRandom.java, eliminating the direct dependency on BouncyCastle. Now using JCE with a provider, allowing SecureRandom to utilize the BC provider. - Added a new class, BouncyCastleFipsRandom, similar to BouncyCastleRandom.java, which leverages the BCFIPS provider to create SecureRandom instances. - Upgraded gradle plugin, groovy and Mockito versions to ensure compatibility with Java 21. from org.spockframework:spock-core:2.3-groovy-3.0 to org.spockframework:spock-core:2.4-M5-groovy-4.0 from org.mockito:mockito-core:4.11.0 to org.mockito:mockito-core:5.15.2 from gradle-8.2-bin.zip to gradle-8.11-bin.zip Testing: I have run gradle clean build with java 11 and Java 21 and works. Test Gradle Test Executor 2; Executed: 470/469/0 ✓ Test Gradle Test Run :test; Executed: 470/469/0
1 parent 31ed354 commit bfa82b4

File tree

5 files changed

+110
-18
lines changed

5 files changed

+110
-18
lines changed

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ testing {
8686
useJUnitJupiter()
8787
dependencies {
8888
implementation "org.slf4j:slf4j-api:2.0.13"
89-
implementation 'org.spockframework:spock-core:2.3-groovy-3.0'
90-
implementation "org.mockito:mockito-core:4.11.0"
89+
implementation "org.spockframework:spock-core:2.4-M5-groovy-4.0"
90+
implementation "org.mockito:mockito-core:5.15.2"
9191
implementation "org.assertj:assertj-core:3.24.2"
9292
implementation "ru.vyarus:spock-junit5:1.2.0"
9393
implementation "org.apache.sshd:sshd-core:$sshdVersion"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

src/main/java/net/schmizz/sshj/DefaultConfig.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@
5959
* net.schmizz.sshj.transport.mac.HMACMD596}</li>
6060
* <li>{@link net.schmizz.sshj.ConfigImpl#setCompressionFactories Compression}: {@link net.schmizz.sshj.transport.compression.NoneCompression}</li>
6161
* <li>{@link net.schmizz.sshj.ConfigImpl#setKeyAlgorithms KeyAlgorithm}: {@link net.schmizz.sshj.signature.SignatureRSA}, {@link net.schmizz.sshj.signature.SignatureDSA}</li>
62-
* <li>{@link net.schmizz.sshj.ConfigImpl#setRandomFactory PRNG}: {@link net.schmizz.sshj.transport.random.BouncyCastleRandom}* or {@link net.schmizz.sshj.transport.random.JCERandom}</li>
62+
* <li>{@link net.schmizz.sshj.ConfigImpl#setRandomFactory BC}: {@link net.schmizz.sshj.transport.random.BouncyCastleRandom}* or {@link net.schmizz.sshj.transport.random.JCERandom}</li>
63+
* <li>{@link net.schmizz.sshj.ConfigImpl#setRandomFactory BCFIPS}: {@link net.schmizz.sshj.transport.random.BouncyCastleFipsRandom}* or {@link net.schmizz.sshj.transport.random.JCERandom}</li>
6364
* <li>{@link net.schmizz.sshj.ConfigImpl#setFileKeyProviderFactories Key file support}: {@link net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile}*, {@link
6465
* net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile}*</li>
6566
* <li>{@link net.schmizz.sshj.ConfigImpl#setVersion Client version}: {@code "NET_3_0"}</li>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright (C)2009 - SSHJ Contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package net.schmizz.sshj.transport.random;
17+
18+
import org.slf4j.Logger;
19+
import org.slf4j.LoggerFactory;
20+
21+
import java.security.NoSuchProviderException;
22+
import java.security.SecureRandom;
23+
24+
/**
25+
* BouncyCastle <code>Random</code>. This pseudo random number generator uses BouncyCastle fips.
26+
* The JRE random will be used when creating a new generator to add some random data to the seed.
27+
*/
28+
public class BouncyCastleFipsRandom
29+
implements Random {
30+
31+
private static final Logger logger = LoggerFactory.getLogger(BouncyCastleFipsRandom.class);
32+
33+
/** Named factory for the BouncyCastle <code>Random</code> */
34+
public static class Factory
35+
implements net.schmizz.sshj.common.Factory<Random> {
36+
37+
@Override
38+
public Random create() {
39+
return new BouncyCastleFipsRandom();
40+
}
41+
42+
}
43+
private byte[] tmp = new byte[16];
44+
private final SecureRandom random;
45+
46+
public BouncyCastleFipsRandom() {
47+
logger.info("Generating random seed from SecureRandom of BCFIPS.");
48+
long t = System.currentTimeMillis();
49+
try {
50+
// Use SecureRandom with the BCFIPS provider
51+
random = SecureRandom.getInstance("DEFAULT", "BCFIPS");
52+
} catch (NoSuchProviderException e) {
53+
throw new RuntimeException("BCFIPS provider is not available", e);
54+
} catch (Exception e) {
55+
throw new RuntimeException("Failed to initialize SecureRandom with BCFIPS provider", e);
56+
}
57+
logger.debug("Creating random seed took {} ms", System.currentTimeMillis() - t);
58+
}
59+
60+
@Override
61+
public synchronized void fill(byte[] bytes, int start, int len) {
62+
if (start == 0 && len == bytes.length) {
63+
random.nextBytes(bytes);
64+
} else {
65+
synchronized (this) {
66+
if (len > tmp.length) tmp = new byte[len];
67+
random.nextBytes(tmp);
68+
System.arraycopy(tmp, 0, bytes, start, len);
69+
}
70+
}
71+
}
72+
73+
@Override
74+
public void fill(byte[] bytes) {
75+
random.nextBytes(bytes);
76+
}
77+
78+
}

src/main/java/net/schmizz/sshj/transport/random/BouncyCastleRandom.java

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@
1515
*/
1616
package net.schmizz.sshj.transport.random;
1717

18-
import org.bouncycastle.crypto.prng.RandomGenerator;
19-
import org.bouncycastle.crypto.prng.VMPCRandomGenerator;
2018
import org.slf4j.Logger;
2119
import org.slf4j.LoggerFactory;
2220

21+
import java.security.NoSuchProviderException;
2322
import java.security.SecureRandom;
2423

2524
/**
26-
* BouncyCastle <code>Random</code>. This pseudo random number generator uses the a very fast PRNG from BouncyCastle.
25+
* BouncyCastle <code>Random</code>. This pseudo random number generator uses BouncyCastle non fips.
2726
* The JRE random will be used when creating a new generator to add some random data to the seed.
2827
*/
2928
public class BouncyCastleRandom
@@ -41,21 +40,35 @@ public Random create() {
4140
}
4241

4342
}
43+
private byte[] tmp = new byte[16];
44+
private final SecureRandom random;
4445

45-
private final RandomGenerator random = new VMPCRandomGenerator();
46-
47-
public BouncyCastleRandom() {
48-
logger.info("Generating random seed from SecureRandom.");
49-
long t = System.currentTimeMillis();
50-
byte[] seed = new SecureRandom().generateSeed(8);
51-
logger.debug("Creating random seed took {} ms", System.currentTimeMillis() - t);
52-
random.addSeedMaterial(seed);
46+
public BouncyCastleRandom() {
47+
logger.info("Generating random seed from SecureRandom of BC.");
48+
long t = System.currentTimeMillis();
49+
try {
50+
// Use SecureRandom with the BC provider
51+
random = SecureRandom.getInstance("DEFAULT", "BC");
52+
} catch (NoSuchProviderException e) {
53+
throw new RuntimeException("BC provider is not in the classpath", e);
54+
} catch (Exception e) {
55+
throw new RuntimeException("Failed to initialize SecureRandom with BC provider", e);
5356
}
57+
logger.debug("Creating random seed took {} ms", System.currentTimeMillis() - t);
58+
}
5459

55-
@Override
56-
public void fill(byte[] bytes, int start, int len) {
57-
random.nextBytes(bytes, start, len);
60+
@Override
61+
public synchronized void fill(byte[] bytes, int start, int len) {
62+
if (start == 0 && len == bytes.length) {
63+
random.nextBytes(bytes);
64+
} else {
65+
synchronized (this) {
66+
if (len > tmp.length) tmp = new byte[len];
67+
random.nextBytes(tmp);
68+
System.arraycopy(tmp, 0, bytes, start, len);
69+
}
5870
}
71+
}
5972

6073
@Override
6174
public void fill(byte[] bytes) {

0 commit comments

Comments
 (0)