undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
366
test/jdk/java/security/SecureRandom/ApiTest.java
Normal file
366
test/jdk/java/security/SecureRandom/ApiTest.java
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8141039
|
||||
* @library /lib/testlibrary
|
||||
* @summary This test do API coverage for SecureRandom. It covers most of
|
||||
* supported operations along with possible positive and negative
|
||||
* parameters for DRBG mechanism.
|
||||
* @run main/othervm ApiTest Hash_DRBG
|
||||
* @run main/othervm ApiTest HMAC_DRBG
|
||||
* @run main/othervm ApiTest CTR_DRBG
|
||||
* @run main/othervm ApiTest SHA1PRNG
|
||||
* @run main/othervm ApiTest NATIVE
|
||||
*/
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.security.SecureRandomParameters;
|
||||
import java.security.DrbgParameters;
|
||||
import java.security.DrbgParameters.Instantiation;
|
||||
import java.security.DrbgParameters.Capability;
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
public class ApiTest {
|
||||
|
||||
private static final boolean SHOULD_PASS = true;
|
||||
private static final long SEED = 1l;
|
||||
private static final String INVALID_ALGO = "INVALID";
|
||||
private static final String DRBG_CONFIG = "securerandom.drbg.config";
|
||||
private static final String DRBG_CONFIG_VALUE
|
||||
= Security.getProperty(DRBG_CONFIG);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.setProperty("java.security.egd", "file:/dev/urandom");
|
||||
|
||||
if (args == null || args.length < 1) {
|
||||
throw new RuntimeException("No mechanism available to run test.");
|
||||
}
|
||||
String mech
|
||||
= "NATIVE".equals(args[0]) ? supportedNativeAlgo() : args[0];
|
||||
String[] algs = null;
|
||||
boolean success = true;
|
||||
|
||||
try {
|
||||
if (!isDRBG(mech)) {
|
||||
SecureRandom random = SecureRandom.getInstance(mech);
|
||||
verifyAPI(random, mech);
|
||||
return;
|
||||
} else if (mech.equals("CTR_DRBG")) {
|
||||
algs = new String[]{"AES-128", "AES-192", "AES-256",
|
||||
INVALID_ALGO};
|
||||
} else if (mech.equals("Hash_DRBG") || mech.equals("HMAC_DRBG")) {
|
||||
algs = new String[]{"SHA-224", "SHA-256", "SHA-512/224",
|
||||
"SHA-512/256", "SHA-384", "SHA-512", INVALID_ALGO};
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
String.format("Not a valid mechanism '%s'", mech));
|
||||
}
|
||||
runForEachMech(mech, algs);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.out);
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
throw new RuntimeException("At least one test failed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the test for a DRBG mechanism with a possible set of parameter
|
||||
* combination.
|
||||
* @param mech DRBG mechanism name
|
||||
* @param algs Algorithm supported by each mechanism
|
||||
* @throws Exception
|
||||
*/
|
||||
private static void runForEachMech(String mech, String[] algs)
|
||||
throws Exception {
|
||||
for (String alg : algs) {
|
||||
runForEachAlg(mech, alg);
|
||||
}
|
||||
}
|
||||
|
||||
private static void runForEachAlg(String mech, String alg)
|
||||
throws Exception {
|
||||
for (int strength : new int[]{-1, 0, 1, 223, 224,
|
||||
192, 255, 256}) {
|
||||
for (Capability cp : Capability.values()) {
|
||||
for (byte[] pr : new byte[][]{null, new byte[]{},
|
||||
"personal".getBytes()}) {
|
||||
SecureRandomParameters param
|
||||
= DrbgParameters.instantiation(strength, cp, pr);
|
||||
runForEachParam(mech, alg, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runForEachParam(String mech, String alg,
|
||||
SecureRandomParameters param) throws Exception {
|
||||
|
||||
for (boolean df : new Boolean[]{true, false}) {
|
||||
try {
|
||||
Security.setProperty(DRBG_CONFIG, mech + "," + alg + ","
|
||||
+ (df ? "use_df" : "no_df"));
|
||||
System.out.printf("%nParameter for SecureRandom "
|
||||
+ "mechanism: %s is (param:%s, algo:%s, df:%s)",
|
||||
mech, param, alg, df);
|
||||
SecureRandom sr = SecureRandom.getInstance("DRBG", param);
|
||||
verifyAPI(sr, mech);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// Verify exception status for current test.
|
||||
checkException(getDefaultAlg(mech, alg), param, e);
|
||||
} finally {
|
||||
Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the algorithm supported for input mechanism.
|
||||
* @param mech Mechanism name
|
||||
* @param alg Algorithm name
|
||||
* @return Algorithm name
|
||||
*/
|
||||
private static String getDefaultAlg(String mech, String alg)
|
||||
throws NoSuchAlgorithmException {
|
||||
if (alg == null) {
|
||||
switch (mech) {
|
||||
case "Hash_DRBG":
|
||||
case "HMAC_DRBG":
|
||||
return "SHA-256";
|
||||
case "CTR_DRBG":
|
||||
return (Cipher.getMaxAllowedKeyLength("AES") < 256)
|
||||
? "AES-128" : "AES-256";
|
||||
default:
|
||||
throw new RuntimeException("Mechanism not supported");
|
||||
}
|
||||
}
|
||||
return alg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the exception type either it is expected to occur or not.
|
||||
* @param alg Algorithm name
|
||||
* @param param DRBG parameter
|
||||
* @param e Exception to verify
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
private static void checkException(String alg, SecureRandomParameters param,
|
||||
NoSuchAlgorithmException e) throws NoSuchAlgorithmException {
|
||||
|
||||
int strength = ((Instantiation) param).getStrength();
|
||||
boolean error = true;
|
||||
switch (alg) {
|
||||
case INVALID_ALGO:
|
||||
error = false;
|
||||
break;
|
||||
case "SHA-224":
|
||||
case "SHA-512/224":
|
||||
if (strength > 192) {
|
||||
error = false;
|
||||
}
|
||||
break;
|
||||
case "SHA-256":
|
||||
case "SHA-512/256":
|
||||
case "SHA-384":
|
||||
case "SHA-512":
|
||||
if (strength > 256) {
|
||||
error = false;
|
||||
}
|
||||
break;
|
||||
case "AES-128":
|
||||
case "AES-192":
|
||||
case "AES-256":
|
||||
int algoStrength = Integer.parseInt(alg.substring("AES-".length()));
|
||||
int maxAESStrength = Cipher.getMaxAllowedKeyLength("AES");
|
||||
if (strength > algoStrength
|
||||
|| algoStrength > maxAESStrength) {
|
||||
error = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (error) {
|
||||
throw new RuntimeException("Unknown :", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find if the mechanism is a DRBG mechanism.
|
||||
* @param mech Mechanism name
|
||||
* @return True for DRBG mechanism else False
|
||||
*/
|
||||
private static boolean isDRBG(String mech) {
|
||||
return mech.contains("_DRBG");
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the name of supported native mechanism name for current platform.
|
||||
*/
|
||||
private static String supportedNativeAlgo() {
|
||||
String nativeSr = "Windows-PRNG";
|
||||
try {
|
||||
SecureRandom.getInstance(nativeSr);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
nativeSr = "NativePRNG";
|
||||
}
|
||||
return nativeSr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a possible set of SecureRandom API for a SecureRandom instance.
|
||||
* @param random SecureRandom instance
|
||||
* @param mech Mechanism used to create SecureRandom instance
|
||||
*/
|
||||
private static void verifyAPI(SecureRandom random, String mech)
|
||||
throws Exception {
|
||||
|
||||
System.out.printf("%nTest SecureRandom mechanism: %s for provider: %s",
|
||||
mech, random.getProvider().getName());
|
||||
byte[] output = new byte[2];
|
||||
|
||||
// Generate random number.
|
||||
random.nextBytes(output);
|
||||
|
||||
// Seed the SecureRandom with a generated seed value of lesser size.
|
||||
byte[] seed = random.generateSeed(1);
|
||||
random.setSeed(seed);
|
||||
random.nextBytes(output);
|
||||
|
||||
// Seed the SecureRandom with a fixed seed value.
|
||||
random.setSeed(SEED);
|
||||
random.nextBytes(output);
|
||||
|
||||
// Seed the SecureRandom with a larger seed value.
|
||||
seed = random.generateSeed(128);
|
||||
random.setSeed(seed);
|
||||
random.nextBytes(output);
|
||||
|
||||
// Additional operation only supported for DRBG based SecureRandom.
|
||||
// Execute the code block and expect to pass for DRBG. If it will fail
|
||||
// then it should fail with specified exception type. Else the case
|
||||
// will be considered as a test case failure.
|
||||
matchExc(() -> {
|
||||
random.reseed();
|
||||
random.nextBytes(output);
|
||||
},
|
||||
isDRBG(mech),
|
||||
UnsupportedOperationException.class,
|
||||
String.format("PASS - Unsupported reseed() method for "
|
||||
+ "SecureRandom Algorithm %s ", mech));
|
||||
|
||||
matchExc(() -> {
|
||||
random.reseed(DrbgParameters.reseed(false, new byte[]{}));
|
||||
random.nextBytes(output);
|
||||
},
|
||||
isDRBG(mech),
|
||||
UnsupportedOperationException.class,
|
||||
String.format("PASS - Unsupported reseed(param) method for "
|
||||
+ "SecureRandom Algorithm %s ", mech));
|
||||
|
||||
matchExc(() -> {
|
||||
random.reseed(DrbgParameters.reseed(true, new byte[]{}));
|
||||
random.nextBytes(output);
|
||||
},
|
||||
isDRBG(mech),
|
||||
!isSupportPR(mech, random) ? IllegalArgumentException.class
|
||||
: UnsupportedOperationException.class,
|
||||
String.format("PASS - Unsupported or illegal reseed(param) "
|
||||
+ "method for SecureRandom Algorithm %s ", mech));
|
||||
|
||||
matchExc(() -> random.nextBytes(output,
|
||||
DrbgParameters.nextBytes(-1, false, new byte[]{})),
|
||||
isDRBG(mech),
|
||||
UnsupportedOperationException.class,
|
||||
String.format("PASS - Unsupported nextBytes(out, nextByteParam)"
|
||||
+ " method for SecureRandom Algorithm %s ", mech));
|
||||
|
||||
matchExc(() -> random.nextBytes(output,
|
||||
DrbgParameters.nextBytes(-1, true, new byte[]{})),
|
||||
isDRBG(mech),
|
||||
!isSupportPR(mech, random) ? IllegalArgumentException.class
|
||||
: UnsupportedOperationException.class,
|
||||
String.format("PASS - Unsupported or illegal "
|
||||
+ "nextBytes(out, nextByteParam) method for "
|
||||
+ "SecureRandom Algorithm %s ", mech));
|
||||
|
||||
matchExc(() -> {
|
||||
random.reseed(null);
|
||||
random.nextBytes(output);
|
||||
},
|
||||
!SHOULD_PASS,
|
||||
IllegalArgumentException.class,
|
||||
"PASS - Test is expected to fail when parameter for reseed() "
|
||||
+ "is null");
|
||||
|
||||
matchExc(() -> random.nextBytes(output, null),
|
||||
!SHOULD_PASS,
|
||||
IllegalArgumentException.class,
|
||||
"PASS - Test is expected to fail when parameter for nextBytes()"
|
||||
+ " is null");
|
||||
|
||||
}
|
||||
|
||||
private static boolean isSupportPR(String mech, SecureRandom random) {
|
||||
return (isDRBG(mech) && ((Instantiation) random.getParameters())
|
||||
.getCapability()
|
||||
.supportsPredictionResistance());
|
||||
}
|
||||
|
||||
private interface RunnableCode {
|
||||
|
||||
void run() throws Exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a given code block and verify, if the exception type is expected.
|
||||
* @param r Code block to run
|
||||
* @param ex Expected exception type
|
||||
* @param shouldPass If the code execution expected to pass without failure
|
||||
* @param msg Message to log in case of expected failure
|
||||
*/
|
||||
private static void matchExc(RunnableCode r, boolean shouldPass, Class ex,
|
||||
String msg) {
|
||||
try {
|
||||
r.run();
|
||||
if (!shouldPass) {
|
||||
throw new RuntimeException("Excecution should fail here.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.printf("%nOccured exception: %s - Expected exception: "
|
||||
+ "%s : ", e.getClass(), ex.getCanonicalName());
|
||||
if (ex.isAssignableFrom(e.getClass())) {
|
||||
System.out.printf("%n%s : Expected Exception occured: %s : ",
|
||||
e.getClass(), msg);
|
||||
} else if (shouldPass) {
|
||||
throw new RuntimeException(e);
|
||||
} else {
|
||||
System.out.printf("Ignore the following exception: %s%n",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
157
test/jdk/java/security/SecureRandom/DefaultAlgo.java
Normal file
157
test/jdk/java/security/SecureRandom/DefaultAlgo.java
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static java.lang.System.out;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Provider.Service;
|
||||
import java.util.Arrays;
|
||||
import sun.security.provider.SunEntries;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8228613 8246613 8248505
|
||||
* @summary Ensure that the default SecureRandom algo used is based
|
||||
* on the registration ordering, and falls to next provider
|
||||
* if none are found
|
||||
* @modules java.base/sun.security.provider
|
||||
*/
|
||||
public class DefaultAlgo {
|
||||
|
||||
private static final String SR_IMPLCLASS =
|
||||
"sun.security.provider.SecureRandom";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String[] algos = { "A", "B", "C" };
|
||||
test3rdParty(algos);
|
||||
// reverse the order and re-check
|
||||
String[] algosReversed = { "C", "B", "A" };
|
||||
test3rdParty(algosReversed);
|
||||
}
|
||||
|
||||
private static void test3rdParty(String[] algos) {
|
||||
Provider[] provs = {
|
||||
new SampleLegacyProvider(algos),
|
||||
new SampleServiceProvider(algos),
|
||||
new CustomProvider(algos)
|
||||
};
|
||||
for (Provider p : provs) {
|
||||
checkDefault(p, algos);
|
||||
}
|
||||
}
|
||||
|
||||
// validate the specified SecureRandom obj to be from the specified
|
||||
// provider and matches the specified algorithm
|
||||
private static void validate(SecureRandom sr, String pName, String algo) {
|
||||
if (!sr.getProvider().getName().equals(pName)) {
|
||||
throw new RuntimeException("Failed provider check, exp: " +
|
||||
pName + ", got " + sr.getProvider().getName());
|
||||
}
|
||||
if (!sr.getAlgorithm().equals(algo)) {
|
||||
throw new RuntimeException("Failed algo check, exp: " +
|
||||
algo + ", got " + sr.getAlgorithm());
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkDefault(Provider p, String ... algos) {
|
||||
String pName = p.getName();
|
||||
out.println(pName + " with " + Arrays.toString(algos));
|
||||
int pos = Security.insertProviderAt(p, 1);
|
||||
|
||||
boolean isLegacy = pName.equals("SampleLegacy");
|
||||
try {
|
||||
if (isLegacy) {
|
||||
for (String s : algos) {
|
||||
validate(new SecureRandom(), pName, s);
|
||||
p.remove("SecureRandom." + s);
|
||||
out.println("removed " + s);
|
||||
}
|
||||
validate(new SecureRandom(), System.getProperty("test.provider.name", "SUN"),
|
||||
System.getProperty("test.default.secure.random.algorithm.name",
|
||||
SunEntries.DEF_SECURE_RANDOM_ALGO));
|
||||
} else {
|
||||
validate(new SecureRandom(), pName, algos[0]);
|
||||
}
|
||||
out.println("=> Test Passed");
|
||||
} finally {
|
||||
if (pos != -1) {
|
||||
Security.removeProvider(pName);
|
||||
}
|
||||
if (isLegacy) {
|
||||
// add back the removed algos
|
||||
for (String s : algos) {
|
||||
p.put("SecureRandom." + s, SR_IMPLCLASS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class SampleLegacyProvider extends Provider {
|
||||
SampleLegacyProvider(String[] listOfSupportedRNGs) {
|
||||
super("SampleLegacy", "1.0", "test provider using legacy put");
|
||||
for (String s : listOfSupportedRNGs) {
|
||||
put("SecureRandom." + s, SR_IMPLCLASS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class SampleServiceProvider extends Provider {
|
||||
SampleServiceProvider(String[] listOfSupportedRNGs) {
|
||||
super("SampleService", "1.0", "test provider using putService");
|
||||
for (String s : listOfSupportedRNGs) {
|
||||
putService(new Provider.Service(this, "SecureRandom", s,
|
||||
SR_IMPLCLASS, null, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// custom provider which overrides putService(...)/getService() and uses
|
||||
// its own Service impl
|
||||
private static class CustomProvider extends Provider {
|
||||
private static class CustomService extends Provider.Service {
|
||||
CustomService(Provider p, String type, String algo, String cName) {
|
||||
super(p, type, algo, cName, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
CustomProvider(String[] listOfSupportedRNGs) {
|
||||
super("Custom", "1.0", "test provider overrides putService with " +
|
||||
" custom service with legacy registration");
|
||||
for (String s : listOfSupportedRNGs) {
|
||||
putService(new CustomService(this, "SecureRandom", s ,
|
||||
SR_IMPLCLASS));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void putService(Provider.Service s) {
|
||||
// convert to legacy puts
|
||||
put(s.getType() + "." + s.getAlgorithm(), s.getClassName());
|
||||
put(s.getType() + ":" + s.getAlgorithm(), s);
|
||||
}
|
||||
@Override
|
||||
public Provider.Service getService(String type, String algo) {
|
||||
return (Provider.Service) get(type + ":" + algo);
|
||||
}
|
||||
}
|
||||
}
|
||||
94
test/jdk/java/security/SecureRandom/DefaultProvider.java
Normal file
94
test/jdk/java/security/SecureRandom/DefaultProvider.java
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static java.lang.System.out;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8048356
|
||||
* @summary Assert default provider used on all OS for SecureRandom
|
||||
*/
|
||||
public class DefaultProvider {
|
||||
|
||||
private static final String OS_NAME = System.getProperty("os.name");
|
||||
private static final String WINDOWS = "Windows";
|
||||
|
||||
public static void main(String[] args) throws NoSuchAlgorithmException {
|
||||
out.println("Operating System: " + OS_NAME);
|
||||
|
||||
/* Test default provider used with constructor */
|
||||
out.println("TEST: Default provider with constructor");
|
||||
SecureRandom secureRandom = new SecureRandom();
|
||||
String provider = secureRandom.getProvider().getName();
|
||||
if (!provider.equals(System.getProperty("test.provider.name", "SUN"))) {
|
||||
throw new RuntimeException("Unexpected provider name: "
|
||||
+ provider);
|
||||
}
|
||||
out.println("Passed, default provider with constructor: " + provider);
|
||||
|
||||
/* Test default provider with getInstance(String algorithm) */
|
||||
out.println("TEST: SHA1PRNG supported on all platforms by SUN provider");
|
||||
String algorithm = "SHA1PRNG";
|
||||
provider = System.getProperty("test.provider.name", "SUN");
|
||||
|
||||
SecureRandom instance = SecureRandom.getInstance(algorithm);
|
||||
assertInstance(instance, algorithm, provider);
|
||||
out.println("Passed.");
|
||||
|
||||
if (!OS_NAME.startsWith(WINDOWS)) {
|
||||
out.println("TEST: NativePRNG supported on all platforms"
|
||||
+ "(except Windows), by SUN provider");
|
||||
algorithm = "NativePRNG";
|
||||
provider = System.getProperty("test.provider.name", "SUN");
|
||||
} else {
|
||||
out.println(
|
||||
"TEST: Windows-PRNG supported on windows by SunMSCAPI provider");
|
||||
algorithm = "Windows-PRNG";
|
||||
provider = "SunMSCAPI";
|
||||
}
|
||||
instance = SecureRandom.getInstance(algorithm);
|
||||
assertInstance(instance, algorithm, provider);
|
||||
out.println("Passed.");
|
||||
}
|
||||
|
||||
private static void assertInstance(SecureRandom instance,
|
||||
String expectedAlgorithm,
|
||||
String expectedProvider) {
|
||||
if (instance != null) {
|
||||
if (!expectedAlgorithm.equalsIgnoreCase(instance.getAlgorithm())) {
|
||||
throw new RuntimeException("Expected algorithm:"
|
||||
+ expectedAlgorithm + " actual: " + instance.getAlgorithm());
|
||||
}
|
||||
|
||||
if (!expectedProvider.equalsIgnoreCase(instance.getProvider().getName())) {
|
||||
throw new RuntimeException("Expected provider: "
|
||||
+ expectedProvider + " actual: "
|
||||
+ instance.getProvider().getName());
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Secure instance is not created");
|
||||
}
|
||||
}
|
||||
}
|
||||
136
test/jdk/java/security/SecureRandom/DrbgParametersSpec.java
Normal file
136
test/jdk/java/security/SecureRandom/DrbgParametersSpec.java
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8051408 8158534
|
||||
* @summary Make sure DrbgParameters coded as specified
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.Asserts
|
||||
* @run main DrbgParametersSpec
|
||||
*/
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import java.security.DrbgParameters;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static java.security.DrbgParameters.Capability.*;
|
||||
|
||||
public class DrbgParametersSpec {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
|
||||
byte[] p, np1, np2;
|
||||
|
||||
// Capability
|
||||
Asserts.assertTrue(PR_AND_RESEED.supportsPredictionResistance());
|
||||
Asserts.assertTrue(PR_AND_RESEED.supportsReseeding());
|
||||
Asserts.assertFalse(RESEED_ONLY.supportsPredictionResistance());
|
||||
Asserts.assertTrue(RESEED_ONLY.supportsReseeding());
|
||||
Asserts.assertFalse(NONE.supportsPredictionResistance());
|
||||
Asserts.assertFalse(NONE.supportsReseeding());
|
||||
|
||||
// Instantiation
|
||||
p = "Instantiation".getBytes();
|
||||
DrbgParameters.Instantiation ins = DrbgParameters
|
||||
.instantiation(192, RESEED_ONLY, p);
|
||||
Asserts.assertTrue(ins.getStrength() == 192);
|
||||
Asserts.assertTrue(ins.getCapability() == RESEED_ONLY);
|
||||
np1 = ins.getPersonalizationString();
|
||||
np2 = ins.getPersonalizationString();
|
||||
// Getter outputs have same content but not the same object
|
||||
Asserts.assertTrue(Arrays.equals(np1, p));
|
||||
Asserts.assertTrue(Arrays.equals(np2, p));
|
||||
Asserts.assertNE(np1, np2);
|
||||
// Changes to original input has no affect on object
|
||||
p[0] = 'X';
|
||||
np2 = ins.getPersonalizationString();
|
||||
Asserts.assertTrue(Arrays.equals(np1, np2));
|
||||
|
||||
ins = DrbgParameters.instantiation(-1, NONE, null);
|
||||
Asserts.assertNull(ins.getPersonalizationString());
|
||||
|
||||
iae(() -> DrbgParameters.instantiation(-2, NONE, null));
|
||||
npe(() -> DrbgParameters.instantiation(-1, null, null));
|
||||
|
||||
// NextBytes
|
||||
p = "NextBytes".getBytes();
|
||||
DrbgParameters.NextBytes nb = DrbgParameters
|
||||
.nextBytes(192, true, p);
|
||||
Asserts.assertTrue(nb.getStrength() == 192);
|
||||
Asserts.assertTrue(nb.getPredictionResistance());
|
||||
np1 = nb.getAdditionalInput();
|
||||
np2 = nb.getAdditionalInput();
|
||||
// Getter outputs have same content but not the same object
|
||||
Asserts.assertTrue(Arrays.equals(np1, p));
|
||||
Asserts.assertTrue(Arrays.equals(np2, p));
|
||||
Asserts.assertNE(np1, np2);
|
||||
// Changes to original input has no affect on object
|
||||
p[0] = 'X';
|
||||
np2 = nb.getAdditionalInput();
|
||||
Asserts.assertTrue(Arrays.equals(np1, np2));
|
||||
|
||||
iae(() -> DrbgParameters.nextBytes(-2, false, null));
|
||||
|
||||
// Reseed
|
||||
p = "Reseed".getBytes();
|
||||
DrbgParameters.Reseed rs = DrbgParameters
|
||||
.reseed(true, p);
|
||||
Asserts.assertTrue(rs.getPredictionResistance());
|
||||
np1 = rs.getAdditionalInput();
|
||||
np2 = rs.getAdditionalInput();
|
||||
// Getter outputs have same content but not the same object
|
||||
Asserts.assertTrue(Arrays.equals(np1, p));
|
||||
Asserts.assertTrue(Arrays.equals(np2, p));
|
||||
Asserts.assertNE(np1, np2);
|
||||
// Changes to original input has no affect on object
|
||||
p[0] = 'X';
|
||||
np2 = rs.getAdditionalInput();
|
||||
Asserts.assertTrue(Arrays.equals(np1, np2));
|
||||
}
|
||||
|
||||
static void iae(RunnableWithException r) throws Exception {
|
||||
checkException(r, IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
static void npe(RunnableWithException r) throws Exception {
|
||||
checkException(r, NullPointerException.class);
|
||||
}
|
||||
|
||||
interface RunnableWithException {
|
||||
void run() throws Exception;
|
||||
}
|
||||
|
||||
static void checkException(RunnableWithException r, Class ex)
|
||||
throws Exception {
|
||||
try {
|
||||
r.run();
|
||||
} catch (Exception e) {
|
||||
if (ex.isAssignableFrom(e.getClass())) {
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
throw new Exception("No exception thrown");
|
||||
}
|
||||
}
|
||||
101
test/jdk/java/security/SecureRandom/EnoughSeedTest.java
Normal file
101
test/jdk/java/security/SecureRandom/EnoughSeedTest.java
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8141039
|
||||
* @library /lib/testlibrary
|
||||
* @summary Check SecureRandom generate expected seed counts what the caller
|
||||
* asked for.
|
||||
* @run main/othervm EnoughSeedTest
|
||||
*/
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import static java.lang.Math.*;
|
||||
|
||||
public class EnoughSeedTest {
|
||||
|
||||
private static final String DRBG_CONFIG = "securerandom.drbg.config";
|
||||
private static final String DRBG_CONFIG_VALUE
|
||||
= Security.getProperty(DRBG_CONFIG);
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("java.security.egd", "file:/dev/urandom");
|
||||
|
||||
boolean success = true;
|
||||
for (String mech : new String[]{
|
||||
"SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) {
|
||||
System.out.printf("%nTest for SecureRandom algorithm: '%s'", mech);
|
||||
try {
|
||||
SecureRandom sr = null;
|
||||
if (!mech.contains("_DRBG")) {
|
||||
sr = SecureRandom.getInstance(mech);
|
||||
} else {
|
||||
Security.setProperty(DRBG_CONFIG, mech);
|
||||
sr = SecureRandom.getInstance("DRBG");
|
||||
}
|
||||
|
||||
success &= forEachSeedBytes(sr);
|
||||
System.out.printf("%nCompleted test for SecureRandom "
|
||||
+ "mechanism: '%s'", mech);
|
||||
} catch (Exception e) {
|
||||
success &= false;
|
||||
e.printStackTrace(System.out);
|
||||
} finally {
|
||||
Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE);
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
throw new RuntimeException("At least one test failed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates fixed number of seed bytes through a SecureRandom instance
|
||||
* to verify it's seed generation status.
|
||||
* @param sr SecureRandom instance
|
||||
* @return The test success indicator
|
||||
*/
|
||||
private static boolean forEachSeedBytes(SecureRandom sr) {
|
||||
boolean success = true;
|
||||
sr.setSeed(1l);
|
||||
for (int seedByte : new int[]{Integer.MIN_VALUE, -1, 0, 1, 256, 1024,
|
||||
Short.MAX_VALUE, (int) pow(2, 20)}) {
|
||||
try {
|
||||
byte[] seed = sr.generateSeed(seedByte);
|
||||
if (seed.length != seedByte) {
|
||||
throw new RuntimeException("Not able to produce expected "
|
||||
+ "seed size.");
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (seedByte >= 0) {
|
||||
throw new RuntimeException("Unknown Exception occured.", e);
|
||||
}
|
||||
System.out.printf("%nPASS - Exception expected when required "
|
||||
+ "seed size requested is negative: %s", seedByte);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
104
test/jdk/java/security/SecureRandom/GetAlgorithm.java
Normal file
104
test/jdk/java/security/SecureRandom/GetAlgorithm.java
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4915392 8141039
|
||||
* @summary test that the getAlgorithm() method works correctly
|
||||
* @author Andreas Sterbenz
|
||||
* @run main GetAlgorithm
|
||||
*/
|
||||
import java.io.*;
|
||||
import java.security.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class GetAlgorithm {
|
||||
|
||||
private static final String BASE = System.getProperty("test.src", ".");
|
||||
private static final String DRBG_CONFIG = "securerandom.drbg.config";
|
||||
private static final String DRBG_CONFIG_VALUE
|
||||
= Security.getProperty(DRBG_CONFIG);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SecureRandom sr = new SecureRandom();
|
||||
if (sr.getAlgorithm().equals("unknown")) {
|
||||
throw new Exception("Unknown: " + sr.getAlgorithm());
|
||||
}
|
||||
|
||||
for (String mech : new String[]{supportedNativeAlgo(), "SHA1PRNG",
|
||||
"Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) {
|
||||
if (!mech.contains("_DRBG")) {
|
||||
check(mech, SecureRandom.getInstance(mech));
|
||||
} else {
|
||||
try {
|
||||
Security.setProperty(DRBG_CONFIG, mech);
|
||||
check("DRBG", SecureRandom.getInstance("DRBG"));
|
||||
} finally {
|
||||
Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
check("unknown", new MySecureRandom());
|
||||
|
||||
InputStream in = new FileInputStream(
|
||||
new File(BASE, "sha1prng-old.bin"));
|
||||
ObjectInputStream oin = new ObjectInputStream(in);
|
||||
sr = (SecureRandom) oin.readObject();
|
||||
oin.close();
|
||||
check("unknown", sr);
|
||||
|
||||
in = new FileInputStream(new File(BASE, "sha1prng-new.bin"));
|
||||
oin = new ObjectInputStream(in);
|
||||
sr = (SecureRandom) oin.readObject();
|
||||
oin.close();
|
||||
check("SHA1PRNG", sr);
|
||||
|
||||
System.out.println("All tests passed");
|
||||
}
|
||||
|
||||
private static void check(String s1, SecureRandom sr) throws Exception {
|
||||
String s2 = sr.getAlgorithm();
|
||||
if (s1.equals(s2) == false) {
|
||||
throw new Exception("Expected " + s1 + ", got " + s2);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MySecureRandom extends SecureRandom {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the name of supported native mechanism name for current platform.
|
||||
*/
|
||||
private static String supportedNativeAlgo() {
|
||||
String nativeSr = "Windows-PRNG";
|
||||
try {
|
||||
SecureRandom.getInstance(nativeSr);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
nativeSr = "NativePRNG";
|
||||
}
|
||||
return nativeSr;
|
||||
}
|
||||
|
||||
}
|
||||
317
test/jdk/java/security/SecureRandom/GetInstanceTest.java
Normal file
317
test/jdk/java/security/SecureRandom/GetInstanceTest.java
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8141039
|
||||
* @library /test/lib
|
||||
* @summary SecureRandom supports multiple getInstance method including
|
||||
* getInstanceStrong() method. This test verifies a set of possible
|
||||
* cases for getInstance with different SecureRandom mechanism
|
||||
* supported in Java.
|
||||
* @run main GetInstanceTest
|
||||
*/
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.SecureRandomParameters;
|
||||
import java.security.DrbgParameters;
|
||||
import static java.security.DrbgParameters.Capability.*;
|
||||
import java.security.Security;
|
||||
import java.util.Arrays;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
public class GetInstanceTest {
|
||||
|
||||
private static final boolean PASS = true;
|
||||
private static final String INVALID_ALGO = "INVALID";
|
||||
private static final String SUN_PROVIDER = "SUN";
|
||||
private static final String INVALID_PROVIDER = "INVALID";
|
||||
private static final String STRONG_ALG_SEC_PROP
|
||||
= "securerandom.strongAlgorithms";
|
||||
private static final String DRBG_CONFIG = "securerandom.drbg.config";
|
||||
private static final String DRBG_CONFIG_VALUE
|
||||
= Security.getProperty(DRBG_CONFIG);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
boolean success = true;
|
||||
// Only accepted failure is NoSuchAlgorithmException.
|
||||
// For any other failure the test case will fail here.
|
||||
SecureRandom sr = matchExc(() -> SecureRandom.getInstanceStrong(),
|
||||
PASS, NoSuchAlgorithmException.class,
|
||||
"PASS - Undefined security Property "
|
||||
+ "'securerandom.strongAlgorithms'");
|
||||
System.out.format("Current platform supports mechanism: '%s' through "
|
||||
+ "provider: '%s' for the method getInstanceStrong().",
|
||||
sr.getAlgorithm(), sr.getProvider().getName());
|
||||
|
||||
// DRBG name should appear with "securerandom.strongAlgorithms"
|
||||
// security property.
|
||||
String origDRBGConfig = Security.getProperty(STRONG_ALG_SEC_PROP);
|
||||
if (!origDRBGConfig.contains("DRBG")) {
|
||||
throw new RuntimeException("DRBG is not associated with default "
|
||||
+ "strong algorithm through security Property: "
|
||||
+ "'securerandom.strongAlgorithms'.");
|
||||
}
|
||||
try {
|
||||
Security.setProperty(STRONG_ALG_SEC_PROP, "DRBG:" +
|
||||
System.getProperty("test.provider.name", SUN_PROVIDER));
|
||||
sr = matchExc(() -> SecureRandom.getInstanceStrong(),
|
||||
PASS, NoSuchAlgorithmException.class,
|
||||
"PASS - Undefined security Property "
|
||||
+ "'securerandom.strongAlgorithms'");
|
||||
checkAttributes(sr, "DRBG");
|
||||
} finally {
|
||||
Security.setProperty(STRONG_ALG_SEC_PROP, origDRBGConfig);
|
||||
}
|
||||
|
||||
for (String mech : new String[]{
|
||||
"SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG", INVALID_ALGO,}) {
|
||||
System.out.printf("%nTest SecureRandom mechanism: '%s'", mech);
|
||||
try {
|
||||
if (isDRBG(mech)) {
|
||||
Security.setProperty(DRBG_CONFIG, mech);
|
||||
}
|
||||
verifyInstance(mech);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.out);
|
||||
success = false;
|
||||
} finally {
|
||||
Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE);
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
throw new RuntimeException("At least one test failed.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void verifyInstance(String mech) throws Exception {
|
||||
|
||||
String srAlgo = isDRBG(mech) ? "DRBG" : mech;
|
||||
|
||||
// Test for getInstance(algorithm) method.
|
||||
// It should pass for all case other than invalid algorithm name.
|
||||
// If it fails then the expected exception type should be
|
||||
// NoSuchAlgorithmException. Any other Exception type occured will be
|
||||
// treated as failure.
|
||||
checkAttributes(
|
||||
matchExc(() -> SecureRandom.getInstance(srAlgo), !(nsa(mech)),
|
||||
NoSuchAlgorithmException.class,
|
||||
String.format("PASS - It is expected to fail for"
|
||||
+ " getInstance(algorithm) when algorithm: '%s'"
|
||||
+ " is null or invalid.", mech)), mech);
|
||||
// Test for getInstance(algorithm, provider) method.
|
||||
checkAttributes(
|
||||
matchExc(() -> SecureRandom.getInstance(srAlgo,
|
||||
Security.getProvider(
|
||||
System.getProperty("test.provider.name", SUN_PROVIDER))),
|
||||
!(nsa(mech)),
|
||||
NoSuchAlgorithmException.class,
|
||||
String.format("PASS - It is expected to fail for"
|
||||
+ " getInstance(algorithm, provider) when"
|
||||
+ " algorithm:'%s' is null or invalid.", mech)),
|
||||
mech);
|
||||
// Test for getInstance(algorithm, providerName) method.
|
||||
checkAttributes(
|
||||
matchExc(() -> SecureRandom.getInstance(srAlgo,
|
||||
System.getProperty("test.provider.name", SUN_PROVIDER)),
|
||||
!(nsa(mech)), NoSuchAlgorithmException.class,
|
||||
String.format("PASS - It is expected to fail for "
|
||||
+ "getInstance(algorithm, providerName) when "
|
||||
+ "algorithm: '%s' is null or invalid.", mech)),
|
||||
mech);
|
||||
// Test for getInstance(algorithm, providerName) method.
|
||||
checkAttributes(
|
||||
matchExc(() -> SecureRandom.getInstance(
|
||||
srAlgo, INVALID_PROVIDER),
|
||||
!PASS, NoSuchProviderException.class,
|
||||
String.format("PASS - It is expected to fail for "
|
||||
+ "getInstance(algorithm, providerName) when "
|
||||
+ "provider name: '%s' is invalid and "
|
||||
+ "algorithm: '%s'", INVALID_PROVIDER, mech)),
|
||||
mech);
|
||||
|
||||
// Run the test for a set of SecureRandomParameters
|
||||
for (SecureRandomParameters param : Arrays.asList(null,
|
||||
DrbgParameters.instantiation(-1, NONE, null))) {
|
||||
|
||||
System.out.printf("%nRunning DRBG param getInstance() methods "
|
||||
+ "for algorithm: %s and DRBG param type: %s", mech,
|
||||
(param != null) ? param.getClass().getName() : param);
|
||||
|
||||
// Following Test are applicable for new DRBG methods only.
|
||||
// Test for getInstance(algorithm, params) method.
|
||||
// Tests are expected to pass for DRBG type with valid parameter
|
||||
// If it fails the expected exception type is derived from
|
||||
// getExcType(mech, param) method. If exception type is not
|
||||
// expected then the test will be considered as failure.
|
||||
checkAttributes(
|
||||
matchExc(() -> SecureRandom.getInstance(srAlgo, param),
|
||||
(isDRBG(mech)) && (isValidDRBGParam(param)),
|
||||
getExcType(mech, param),
|
||||
String.format("PASS - It is expected to fail "
|
||||
+ "for getInstance(algorithm, params) "
|
||||
+ "for algorithm: %s and parameter: %s",
|
||||
mech, param)),
|
||||
mech);
|
||||
// Test for getInstance(algorithm, params, provider) method.
|
||||
checkAttributes(
|
||||
matchExc(() -> SecureRandom.getInstance(srAlgo, param,
|
||||
Security.getProvider(System.getProperty(
|
||||
"test.provider.name", SUN_PROVIDER))),
|
||||
(isDRBG(mech)) && (isValidDRBGParam(param)),
|
||||
getExcType(mech, param),
|
||||
String.format("PASS - It is expected to fail "
|
||||
+ "for getInstance(algorithm, params, "
|
||||
+ "provider) for algorithm: %s and "
|
||||
+ "parameter: %s", mech, param)),
|
||||
mech);
|
||||
// Test for getInstance(algorithm, params, providerName) method.
|
||||
checkAttributes(
|
||||
matchExc(() -> SecureRandom.getInstance(srAlgo, param,
|
||||
System.getProperty("test.provider.name", SUN_PROVIDER)),
|
||||
(isDRBG(mech)) && (isValidDRBGParam(param)),
|
||||
getExcType(mech, param),
|
||||
String.format("PASS - It is expected to fail "
|
||||
+ "for getInstance(algorithm, params, "
|
||||
+ "providerName) for algorithm: %s and "
|
||||
+ "parameter: %s", mech, param)), mech);
|
||||
// getInstance(algorithm, params, providerName) when
|
||||
// providerName is invalid
|
||||
checkAttributes(
|
||||
matchExc(() -> SecureRandom.getInstance(srAlgo, param,
|
||||
INVALID_PROVIDER),
|
||||
!PASS, ((param == null)
|
||||
? IllegalArgumentException.class
|
||||
: NoSuchProviderException.class),
|
||||
String.format("PASS - It is expected to fail "
|
||||
+ "for getInstance(algorithm, params, "
|
||||
+ "providerName) when param is null or"
|
||||
+ " provider: %s is invalid for "
|
||||
+ "algorithm: '%s'", INVALID_PROVIDER,
|
||||
mech)), mech);
|
||||
// getInstance(algorithm, params, provider) when provider=null
|
||||
checkAttributes(
|
||||
matchExc(() -> SecureRandom.getInstance(srAlgo, param,
|
||||
(String) null),
|
||||
!PASS, IllegalArgumentException.class,
|
||||
String.format("PASS - It is expected to fail "
|
||||
+ "for getInstance(algorithm, params, "
|
||||
+ "providerName) when provider name "
|
||||
+ "is null")), mech);
|
||||
// getInstance(algorithm, params, providerName) when
|
||||
// providerName is empty.
|
||||
checkAttributes(
|
||||
matchExc(() -> SecureRandom.getInstance(
|
||||
srAlgo, param, ""),
|
||||
!PASS, IllegalArgumentException.class,
|
||||
String.format("PASS - It is expected to fail "
|
||||
+ "for getInstance(algorithm, params, "
|
||||
+ "providerName) when provider name "
|
||||
+ "is empty")), mech);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isValidDRBGParam(SecureRandomParameters param) {
|
||||
return (param instanceof DrbgParameters.Instantiation);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the mechanism should occur NoSuchAlgorithmException.
|
||||
*/
|
||||
private static boolean nsa(String mech) {
|
||||
return mech.equals(INVALID_ALGO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if the mechanism is DRBG type.
|
||||
* @param mech Mechanism name
|
||||
* @return True if the mechanism name is DRBG type else False.
|
||||
*/
|
||||
private static boolean isDRBG(String mech) {
|
||||
return mech.contains("_DRBG");
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of exception expected for a SecureRandom instance when exception
|
||||
* occurred while calling getInstance method with a fixed set of parameter.
|
||||
* @param mech Mechanism used to create a SecureRandom instance
|
||||
* @param param Parameter to getInstance() method
|
||||
* @return Exception type expected
|
||||
*/
|
||||
private static Class getExcType(String mech, SecureRandomParameters param) {
|
||||
return ((isDRBG(mech) && !isValidDRBGParam(param)) || param == null)
|
||||
? IllegalArgumentException.class
|
||||
: NoSuchAlgorithmException.class;
|
||||
}
|
||||
|
||||
private interface RunnableCode {
|
||||
|
||||
SecureRandom run() throws Exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a given code block and verify, if the exception type is expected.
|
||||
* @param r Code block to run
|
||||
* @param ex Expected exception type
|
||||
* @param shouldPass If the code execution expected to pass without failure
|
||||
* @param msg Message to log in case of expected failure
|
||||
*/
|
||||
private static SecureRandom matchExc(RunnableCode r, boolean shouldPass,
|
||||
Class ex, String msg) {
|
||||
SecureRandom sr = null;
|
||||
try {
|
||||
sr = r.run();
|
||||
if (!shouldPass) {
|
||||
throw new RuntimeException("Excecution should fail here.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.printf("%nOccured exception: %s - Expected exception: %s"
|
||||
+ " : ", e.getClass(), ex.getCanonicalName());
|
||||
if (ex.isAssignableFrom(e.getClass())) {
|
||||
System.out.printf("%n%s : Expected Exception: %s : ",
|
||||
e.getClass(), msg);
|
||||
} else if (shouldPass) {
|
||||
throw new RuntimeException(e);
|
||||
} else {
|
||||
System.out.printf("%nIgnore the following exception: %s%n",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
return sr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check specific attributes of a SecureRandom instance.
|
||||
*/
|
||||
private static void checkAttributes(SecureRandom sr, String mech) {
|
||||
if (sr == null) {
|
||||
return;
|
||||
}
|
||||
Asserts.assertEquals(sr.getAlgorithm(), (isDRBG(mech) ? "DRBG" : mech));
|
||||
String expectedProviderName = System.getProperty("test.provider.name", SUN_PROVIDER);
|
||||
Asserts.assertEquals(sr.getProvider().getName(), expectedProviderName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/* @test
|
||||
* @bug 8156709
|
||||
* @summary Cannot call setSeed on NativePRNG on Mac if EGD is /dev/urandom
|
||||
* @requires os.name == "Mac OS X"
|
||||
* @run main/othervm -Djava.security.egd=file:/dev/urandom MacNativePRNGSetSeed
|
||||
*/
|
||||
public class MacNativePRNGSetSeed {
|
||||
public static void main(String[] args) throws Exception {
|
||||
SecureRandom sr = SecureRandom.getInstance("NativePRNG");
|
||||
sr.setSeed(1);
|
||||
}
|
||||
}
|
||||
182
test/jdk/java/security/SecureRandom/MultiThreadTest.java
Normal file
182
test/jdk/java/security/SecureRandom/MultiThreadTest.java
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionService;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import static java.lang.Math.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8141039
|
||||
* @library /lib/testlibrary
|
||||
* @summary Test behavior of a shared SecureRandom object when it is operated
|
||||
* by multiple threads concurrently.
|
||||
* @run main/othervm -Djava.security.egd=file:/dev/urandom MultiThreadTest
|
||||
*/
|
||||
public class MultiThreadTest {
|
||||
|
||||
private static final byte[] GEN_RND_BYTES = {1};
|
||||
private static final String DRBG_CONFIG = "securerandom.drbg.config";
|
||||
private static final String DRBG_CONFIG_VALUE
|
||||
= Security.getProperty(DRBG_CONFIG);
|
||||
|
||||
private enum SEED {
|
||||
|
||||
NONE, RESEED, SETSEED
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
boolean success = true;
|
||||
for (int byteLen : GEN_RND_BYTES) {
|
||||
for (SEED reSeed : SEED.values()) {
|
||||
for (String mech : new String[]{
|
||||
"SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) {
|
||||
try {
|
||||
forEachMech(mech, byteLen, reSeed);
|
||||
} catch (Exception e) {
|
||||
success = false;
|
||||
e.printStackTrace(System.out);
|
||||
} finally {
|
||||
Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
throw new RuntimeException("At least one test failed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a number of threads to fetch random numbers of certain bits
|
||||
* generated through a shared SecureRandom instance.
|
||||
* @param mech Mechanism name
|
||||
* @param byteLen Number of bytes of random number to produce
|
||||
* @param reSeed Call reseed() before generating random numbers
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws InterruptedException
|
||||
* @throws ExecutionException
|
||||
*/
|
||||
private static void forEachMech(String mech, int byteLen, SEED reSeed)
|
||||
throws NoSuchAlgorithmException, InterruptedException,
|
||||
ExecutionException {
|
||||
|
||||
if ("SHA1PRNG".equals(mech) && SEED.RESEED.equals(reSeed)) {
|
||||
System.out.printf(
|
||||
"%nreseed() api is not supported for '%s'", mech);
|
||||
return;
|
||||
}
|
||||
System.out.printf("%nTest SecureRandom mechanism: '%s' with support of"
|
||||
+ " reseed: '%s'", mech, reSeed);
|
||||
int threadCount = (int) pow(2, 8 * byteLen);
|
||||
System.out.printf("%nCreating %s number of threads to generate secure "
|
||||
+ "random numbers concurrently.", threadCount);
|
||||
|
||||
ExecutorService executor
|
||||
= Executors.newCachedThreadPool(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = Executors.defaultThreadFactory()
|
||||
.newThread(r);
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
}
|
||||
});
|
||||
CompletionService<Integer> completionService
|
||||
= new ExecutorCompletionService<Integer>(executor);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
SecureRandom rnd = null;
|
||||
if (!mech.contains("_DRBG")) {
|
||||
rnd = SecureRandom.getInstance(mech);
|
||||
} else {
|
||||
Security.setProperty(DRBG_CONFIG, mech);
|
||||
rnd = SecureRandom.getInstance("DRBG");
|
||||
}
|
||||
try {
|
||||
for (int i = 0; i < threadCount; i++) {
|
||||
completionService.submit(new Task(rnd, latch, byteLen, reSeed));
|
||||
}
|
||||
latch.countDown();
|
||||
|
||||
for (int i = 0; i < threadCount; i++) {
|
||||
completionService.take();
|
||||
}
|
||||
} finally {
|
||||
executor.shutdown();
|
||||
}
|
||||
System.out.printf("%nCompleted Test for algorithm '%s' with thread "
|
||||
+ "counts to '%s' using reseeding '%s'",
|
||||
mech, threadCount, reSeed);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a Task to be executed by multiple thread to produce random numbers
|
||||
* from a shared SecureRandom instance.
|
||||
*/
|
||||
private static class Task implements Callable<Integer> {
|
||||
|
||||
private final SecureRandom random;
|
||||
private final CountDownLatch latch;
|
||||
private final SEED reSeed;
|
||||
private final int byteSize;
|
||||
|
||||
public Task(SecureRandom random, CountDownLatch latch, int byteSize,
|
||||
SEED reSeed) {
|
||||
this.random = random;
|
||||
this.latch = latch;
|
||||
this.byteSize = byteSize;
|
||||
this.reSeed = reSeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
latch.await();
|
||||
switch (this.reSeed) {
|
||||
case RESEED:
|
||||
this.random.reseed();
|
||||
break;
|
||||
case SETSEED:
|
||||
this.random.setSeed(1l);
|
||||
break;
|
||||
}
|
||||
byte[] bytes = new byte[byteSize];
|
||||
random.nextBytes(bytes);
|
||||
return new BigInteger(bytes).intValue();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
83
test/jdk/java/security/SecureRandom/NextBytesNull.java
Normal file
83
test/jdk/java/security/SecureRandom/NextBytesNull.java
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8155191
|
||||
* @summary check NPE is thrown for various methods of SecureRandom class,
|
||||
* e.g. SecureRandom(byte[]), nextBytes(byte[]), and setSeed(byte[]).
|
||||
* @run main NextBytesNull
|
||||
*/
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.SecureRandomSpi;
|
||||
|
||||
public class NextBytesNull {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String test = "SecureRandom(null)";
|
||||
try {
|
||||
new SecureRandom(null);
|
||||
throw new RuntimeException("Error: NPE not thrown for " + test);
|
||||
} catch (NullPointerException e) {
|
||||
System.out.println("OK, expected NPE thrown for " + test);
|
||||
}
|
||||
|
||||
// verify with an Spi impl which does not throw NPE
|
||||
SecureRandom sr = SecureRandom.getInstance("S1", new P());
|
||||
try {
|
||||
sr.nextBytes(null);
|
||||
throw new RuntimeException("Error: NPE not thrown");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("OK, expected NPE thrown for " + test);
|
||||
}
|
||||
try {
|
||||
sr.setSeed(null);
|
||||
throw new RuntimeException("Error: NPE not thrown for " + test);
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("OK, expected NPE thrown for " + test);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class P extends Provider {
|
||||
public P() {
|
||||
super("P", 1.0d, "Test Provider without Null Check");
|
||||
put("SecureRandom.S1", S.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public static final class S extends SecureRandomSpi {
|
||||
@Override
|
||||
protected void engineSetSeed(byte[] seed) {
|
||||
}
|
||||
@Override
|
||||
protected void engineNextBytes(byte[] bytes) {
|
||||
}
|
||||
@Override
|
||||
protected byte[] engineGenerateSeed(int numBytes) {
|
||||
return new byte[numBytes];
|
||||
}
|
||||
}
|
||||
}
|
||||
101
test/jdk/java/security/SecureRandom/NoSync.java
Normal file
101
test/jdk/java/security/SecureRandom/NoSync.java
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.security.Provider;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7004967
|
||||
* @run main/othervm -Djava.security.egd=file:/dev/urandom NoSync
|
||||
* @summary SecureRandom should be more explicit about threading
|
||||
*/
|
||||
public class NoSync {
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (Provider p : Security.getProviders()) {
|
||||
for (Provider.Service s : p.getServices()) {
|
||||
if (s.getType().equals("SecureRandom") &&
|
||||
!s.getAlgorithm().contains("Block")) {
|
||||
test(SecureRandom.getInstance(s.getAlgorithm(), p));
|
||||
}
|
||||
}
|
||||
}
|
||||
Security.setProperty("securerandom.drbg.config", "HMAC_DRBG");
|
||||
test(SecureRandom.getInstance("DRBG"));
|
||||
Security.setProperty("securerandom.drbg.config", "CTR_DRBG");
|
||||
test(SecureRandom.getInstance("DRBG"));
|
||||
}
|
||||
|
||||
static void test(SecureRandom sr) throws Exception {
|
||||
test(sr, 20, 3000);
|
||||
// All out-of-box impl should have the ThreadSafe attribute
|
||||
String attr = sr.getProvider().getProperty("SecureRandom."
|
||||
+ sr.getAlgorithm() + " ThreadSafe");
|
||||
if (!"true".equals(attr)) {
|
||||
throw new Exception("Not ThreadSafe: " + attr);
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(SecureRandom sr, int tnum, int rnum)
|
||||
throws Exception {
|
||||
|
||||
System.out.println(sr);
|
||||
System.out.println(sr.getAlgorithm() + " " + sr.getProvider().getName());
|
||||
|
||||
System.out.println(new Date());
|
||||
boolean reseed = sr.getParameters() != null;
|
||||
Thread[] threads = new Thread[tnum];
|
||||
AtomicBoolean failed = new AtomicBoolean(false);
|
||||
Thread.UncaughtExceptionHandler h = (t, e) -> {
|
||||
failed.set(true);
|
||||
e.printStackTrace();
|
||||
};
|
||||
for (int i = 0; i < threads.length; i++) {
|
||||
threads[i] = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int j = 0; j < rnum; j++) {
|
||||
sr.nextBytes(new byte[j%100+100]);
|
||||
sr.setSeed((long)j);
|
||||
if (reseed) {
|
||||
sr.reseed();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
threads[i].setUncaughtExceptionHandler(h);
|
||||
threads[i].start();
|
||||
}
|
||||
for (int i = 0; i < threads.length; i++) {
|
||||
threads[i].join();
|
||||
}
|
||||
System.out.println(new Date());
|
||||
System.out.println();
|
||||
if (failed.get()) {
|
||||
throw new RuntimeException("Failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
106
test/jdk/java/security/SecureRandom/Serialize.java
Normal file
106
test/jdk/java/security/SecureRandom/Serialize.java
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4102896
|
||||
* @summary Make sure that a SecureRandom object can be serialized
|
||||
* @run main/othervm Serialize
|
||||
*/
|
||||
|
||||
import java.security.*;
|
||||
import java.io.*;
|
||||
|
||||
public class Serialize {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
System.setProperty("java.security.egd", "file:/dev/urandom");
|
||||
|
||||
for (String alg: new String[]{
|
||||
"SHA1PRNG", "DRBG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG",
|
||||
"Hash_DRBG,SHA-512,192,pr_and_reseed"}) {
|
||||
|
||||
System.out.println("Testing " + alg);
|
||||
SecureRandom s1;
|
||||
|
||||
// A SecureRandom can be s11ned and des11ned at any time.
|
||||
|
||||
// Brand new.
|
||||
s1 = getInstance(alg);
|
||||
revive(s1).nextInt();
|
||||
if (alg.contains("DRBG")) {
|
||||
revive(s1).reseed();
|
||||
}
|
||||
|
||||
// Used
|
||||
s1 = getInstance(alg);
|
||||
s1.nextInt(); // state set
|
||||
revive(s1).nextInt();
|
||||
if (alg.contains("DRBG")) {
|
||||
revive(s1).reseed();
|
||||
}
|
||||
|
||||
// Automatically reseeded
|
||||
s1 = getInstance(alg);
|
||||
if (alg.contains("DRBG")) {
|
||||
s1.reseed();
|
||||
}
|
||||
revive(s1).nextInt();
|
||||
if (alg.contains("DRBG")) {
|
||||
revive(s1).reseed();
|
||||
}
|
||||
|
||||
// Manually seeded
|
||||
s1 = getInstance(alg);
|
||||
s1.setSeed(1L);
|
||||
revive(s1).nextInt();
|
||||
if (alg.contains("DRBG")) {
|
||||
revive(s1).reseed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static SecureRandom getInstance(String alg) throws Exception {
|
||||
if (alg.equals("SHA1PRNG") || alg.equals("DRBG")) {
|
||||
return SecureRandom.getInstance(alg);
|
||||
} else {
|
||||
String old = Security.getProperty("securerandom.drbg.config");
|
||||
try {
|
||||
Security.setProperty("securerandom.drbg.config", alg);
|
||||
return SecureRandom.getInstance("DRBG");
|
||||
} finally {
|
||||
Security.setProperty("securerandom.drbg.config", old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static SecureRandom revive(SecureRandom oldOne) throws Exception {
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
new ObjectOutputStream(bout).writeObject(oldOne);
|
||||
SecureRandom newOne = (SecureRandom) new ObjectInputStream(
|
||||
new ByteArrayInputStream(bout.toByteArray())).readObject();
|
||||
if (!oldOne.toString().equals(newOne.toString())) {
|
||||
throw new Exception(newOne + " is not " + oldOne);
|
||||
}
|
||||
return newOne;
|
||||
}
|
||||
}
|
||||
214
test/jdk/java/security/SecureRandom/SerializedSeedTest.java
Normal file
214
test/jdk/java/security/SecureRandom/SerializedSeedTest.java
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8141039
|
||||
* @library /test/lib
|
||||
* @summary When random number is generated through a SecureRandom instance
|
||||
* as well from its serialized instance in the same time then the
|
||||
* generated random numbers should be different when one or both are
|
||||
* reseeded.
|
||||
* @run main/othervm -Djava.security.egd=file:/dev/urandom SerializedSeedTest
|
||||
*/
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
public class SerializedSeedTest {
|
||||
|
||||
private static final byte[] SEED = "seed".getBytes();
|
||||
private static final String DRBG_CONFIG = "securerandom.drbg.config";
|
||||
private static final String DRBG_CONFIG_VALUE
|
||||
= Security.getProperty(DRBG_CONFIG);
|
||||
|
||||
public static void main(String[] args) {
|
||||
boolean success = true;
|
||||
|
||||
for (String mech : new String[]{
|
||||
"SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) {
|
||||
System.out.printf(
|
||||
"%nRunning test for SecureRandom mechanism: '%s'", mech);
|
||||
try {
|
||||
// Serialize without seed and compare generated random numbers
|
||||
// produced through original and serialized instances.
|
||||
SecureRandom orig = getSRInstance(mech);
|
||||
SecureRandom copy = deserializedCopy(orig);
|
||||
System.out.printf("%nSerialize without seed. Generated random"
|
||||
+ " numbers should be different.");
|
||||
check(orig, copy, false, mech);
|
||||
|
||||
// Serialize after default seed and compare generated random
|
||||
// numbers produced through original and serialized instances.
|
||||
orig = getSRInstance(mech);
|
||||
orig.nextInt(); // Default seeded
|
||||
copy = deserializedCopy(orig);
|
||||
System.out.printf("%nSerialize after default seed. Generated"
|
||||
+ " random numbers should be same till 20-bytes.");
|
||||
check(orig, copy, !isDRBG(mech), mech);
|
||||
|
||||
// Serialize after explicit seed and compare generated random
|
||||
// numbers produced through original and serialized instances.
|
||||
orig = getSRInstance(mech);
|
||||
orig.setSeed(SEED); // Explicitly seeded
|
||||
copy = deserializedCopy(orig);
|
||||
System.out.printf("%nSerialize after explicit seed. Generated "
|
||||
+ "random numbers should be same till 20-bytes.");
|
||||
check(orig, copy, !isDRBG(mech), mech);
|
||||
|
||||
// Serialize without seed but original is explicitly seeded
|
||||
// before generating any random number. Then compare generated
|
||||
// random numbers produced through original and serialized
|
||||
// instances.
|
||||
orig = getSRInstance(mech);
|
||||
copy = deserializedCopy(orig);
|
||||
orig.setSeed(SEED); // Explicitly seeded
|
||||
System.out.printf("%nSerialize without seed. When original is "
|
||||
+ "explicitly seeded before generating random numbers,"
|
||||
+ " Generated random numbers should be different.");
|
||||
check(orig, copy, false, mech);
|
||||
|
||||
// Serialize after default seed but original is explicitly
|
||||
// seeded before generating any random number. Then compare
|
||||
// generated random numbers produced through original and
|
||||
// serialized instances.
|
||||
orig = getSRInstance(mech);
|
||||
orig.nextInt(); // Default seeded
|
||||
copy = deserializedCopy(orig);
|
||||
orig.setSeed(SEED); // Explicitly seeded
|
||||
System.out.printf("%nSerialize after default seed but original "
|
||||
+ "is explicitly seeded before generating random number"
|
||||
+ ". Generated random numbers should be different.");
|
||||
check(orig, copy, false, mech);
|
||||
|
||||
// Serialize after explicit seed but original is explicitly
|
||||
// seeded again before generating random number. Then compare
|
||||
// generated random numbers produced through original and
|
||||
// serialized instances.
|
||||
orig = getSRInstance(mech);
|
||||
orig.setSeed(SEED); // Explicitly seeded
|
||||
copy = deserializedCopy(orig);
|
||||
orig.setSeed(SEED); // Explicitly seeded
|
||||
System.out.printf("%nSerialize after explicit seed but "
|
||||
+ "original is explicitly seeded again before "
|
||||
+ "generating random number. Generated random "
|
||||
+ "numbers should be different.");
|
||||
check(orig, copy, false, mech);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.out);
|
||||
success = false;
|
||||
} finally {
|
||||
Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE);
|
||||
}
|
||||
System.out.printf("%n------Completed Test for %s------", mech);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
throw new RuntimeException("At least one test failed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find if the mechanism is a DRBG mechanism.
|
||||
* @param mech Mechanism name
|
||||
* @return True for DRBG mechanism else False
|
||||
*/
|
||||
private static boolean isDRBG(String mech) {
|
||||
return mech.contains("_DRBG");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the similarity of random numbers generated though both original
|
||||
* as well as deserialized instance.
|
||||
*/
|
||||
private static void check(SecureRandom orig, SecureRandom copy,
|
||||
boolean equal, String mech) {
|
||||
int o = orig.nextInt();
|
||||
int c = copy.nextInt();
|
||||
System.out.printf("%nRandom number generated for mechanism: '%s' "
|
||||
+ "from original instance as: '%s' and from serialized "
|
||||
+ "instance as: '%s'", mech, o, c);
|
||||
if (equal) {
|
||||
Asserts.assertEquals(o, c, mech);
|
||||
} else {
|
||||
Asserts.assertNotEquals(o, c, mech);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a copy of SecureRandom instance through deserialization.
|
||||
* @param orig Original SecureRandom instance
|
||||
* @return Deserialized SecureRandom instance
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
private static SecureRandom deserializedCopy(SecureRandom orig)
|
||||
throws IOException, ClassNotFoundException {
|
||||
return deserialize(serialize(orig));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize the SecureRandom object.
|
||||
*/
|
||||
private static SecureRandom deserialize(byte[] serialized)
|
||||
throws IOException, ClassNotFoundException {
|
||||
SecureRandom sr = null;
|
||||
try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized);
|
||||
ObjectInputStream ois = new ObjectInputStream(bis)) {
|
||||
sr = (SecureRandom) ois.readObject();
|
||||
}
|
||||
return sr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the given SecureRandom object.
|
||||
*/
|
||||
private static byte[] serialize(SecureRandom sr) throws IOException {
|
||||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
|
||||
oos.writeObject(sr);
|
||||
return bos.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a SecureRandom instance for a given mechanism.
|
||||
*/
|
||||
private static SecureRandom getSRInstance(String mech)
|
||||
throws NoSuchAlgorithmException {
|
||||
if (!isDRBG(mech)) {
|
||||
return SecureRandom.getInstance(mech);
|
||||
} else {
|
||||
Security.setProperty(DRBG_CONFIG, mech);
|
||||
return SecureRandom.getInstance("DRBG");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
44
test/jdk/java/security/SecureRandom/TestStrong.java
Normal file
44
test/jdk/java/security/SecureRandom/TestStrong.java
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8364657
|
||||
* @summary verify the behavior of SecureRandom instance returned by
|
||||
* SecureRandom.getInstanceStrong()
|
||||
* @run main TestStrong
|
||||
*/
|
||||
public class TestStrong {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
final SecureRandom random = SecureRandom.getInstanceStrong();
|
||||
System.out.println("going to generate random seed using " + random);
|
||||
final byte[] seed = random.generateSeed(0);
|
||||
System.out.println("random seed generated");
|
||||
System.out.println("seed: " + Arrays.toString(seed));
|
||||
}
|
||||
}
|
||||
123
test/jdk/java/security/SecureRandom/ThreadSafe.java
Normal file
123
test/jdk/java/security/SecureRandom/ThreadSafe.java
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static jdk.test.lib.Utils.runAndCheckException;
|
||||
|
||||
import java.lang.Override;
|
||||
import java.security.Provider;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.SecureRandomSpi;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @bug 7004967 8329754
|
||||
* @summary SecureRandom should be more explicit about threading
|
||||
*/
|
||||
|
||||
public class ThreadSafe {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Provider p = new P();
|
||||
NoSync.test(SecureRandom.getInstance("S1", p), 5, 5);
|
||||
NoSync.test(SecureRandom.getInstance("AliasS1", p), 5, 5);
|
||||
|
||||
runAndCheckException(
|
||||
() -> NoSync.test(SecureRandom.getInstance("S2", p), 5, 5),
|
||||
RuntimeException.class);
|
||||
|
||||
runAndCheckException(
|
||||
() -> NoSync.test(SecureRandom.getInstance("AliasS2", p), 5, 5),
|
||||
RuntimeException.class);
|
||||
|
||||
NoSync.test(SecureRandom.getInstance("S3", p), 5, 5);
|
||||
NoSync.test(SecureRandom.getInstance("AliasS3", p), 5, 5);
|
||||
|
||||
runAndCheckException(
|
||||
() -> NoSync.test(SecureRandom.getInstance("S4", p), 5, 5),
|
||||
RuntimeException.class);
|
||||
|
||||
runAndCheckException(
|
||||
() -> NoSync.test(SecureRandom.getInstance("AliasS4", p), 5, 5),
|
||||
RuntimeException.class);
|
||||
}
|
||||
|
||||
public static class P extends Provider {
|
||||
public P() {
|
||||
|
||||
super("P", 1.0d, "Haha");
|
||||
|
||||
// Good. No attribute.
|
||||
put("SecureRandom.S1", S.class.getName());
|
||||
|
||||
// Good. Alias of S1, should pass because S1 is not marked as ThreadSafe
|
||||
put("Alg.alias.SecureRandom.AliasS1", "S1");
|
||||
|
||||
// Bad. Boasting ThreadSafe but isn't
|
||||
put("SecureRandom.S2", S.class.getName());
|
||||
put("SecureRandom.S2 ThreadSafe", "true");
|
||||
|
||||
//Bad. Alias of S2, should fail because S2 is marked as ThreadSafe
|
||||
put("alg.Alias.SecureRandom.AliasS2", "S2");
|
||||
|
||||
// Good. No attribute.
|
||||
putService(new Service(this, "SecureRandom", "S3",
|
||||
S.class.getName(), List.of("AliasS3"), null));
|
||||
|
||||
// Bad. Boasting ThreadSafe but isn't
|
||||
putService(new Service(this, "SecureRandom", "S4",
|
||||
S.class.getName(), List.of("AliasS4"), Map.of("ThreadSafe", "true")));
|
||||
}
|
||||
}
|
||||
|
||||
// This implementation is not itself thread safe.
|
||||
public static class S extends SecureRandomSpi {
|
||||
|
||||
@Override
|
||||
protected void engineSetSeed(byte[] seed) {
|
||||
return;
|
||||
}
|
||||
|
||||
private volatile boolean inCall = false;
|
||||
|
||||
@Override
|
||||
protected void engineNextBytes(byte[] bytes) {
|
||||
if (inCall) {
|
||||
throw new RuntimeException("IN CALL");
|
||||
}
|
||||
inCall = true;
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (Exception e) {
|
||||
// OK
|
||||
}
|
||||
inCall = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] engineGenerateSeed(int numBytes) {
|
||||
return new byte[numBytes];
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
test/jdk/java/security/SecureRandom/sha1prng-new.bin
Normal file
BIN
test/jdk/java/security/SecureRandom/sha1prng-new.bin
Normal file
Binary file not shown.
BIN
test/jdk/java/security/SecureRandom/sha1prng-old.bin
Normal file
BIN
test/jdk/java/security/SecureRandom/sha1prng-old.bin
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue