mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8248505: Unexpected NoSuchAlgorithmException when using secure random impl from BCFIPS provider
Use getService(...) call for Provider.getDefaultSecureRandomService() Reviewed-by: weijun, coffeys, mullan
This commit is contained in:
parent
ca91da0e0c
commit
f4756fdf48
2 changed files with 65 additions and 23 deletions
|
@ -868,7 +868,7 @@ public abstract class Provider extends Properties {
|
||||||
// For backward compatibility, the registration ordering of
|
// For backward compatibility, the registration ordering of
|
||||||
// SecureRandom (RNG) algorithms needs to be preserved for
|
// SecureRandom (RNG) algorithms needs to be preserved for
|
||||||
// "new SecureRandom()" calls when this provider is used
|
// "new SecureRandom()" calls when this provider is used
|
||||||
private transient Set<Service> prngServices;
|
private transient Set<String> prngAlgos;
|
||||||
|
|
||||||
// Map<ServiceKey,Service>
|
// Map<ServiceKey,Service>
|
||||||
// used for services added via legacy methods, init on demand
|
// used for services added via legacy methods, init on demand
|
||||||
|
@ -1089,7 +1089,7 @@ public abstract class Provider extends Properties {
|
||||||
legacyChanged = false;
|
legacyChanged = false;
|
||||||
servicesChanged = false;
|
servicesChanged = false;
|
||||||
serviceSet = null;
|
serviceSet = null;
|
||||||
prngServices = null;
|
prngAlgos = null;
|
||||||
super.clear();
|
super.clear();
|
||||||
putId();
|
putId();
|
||||||
}
|
}
|
||||||
|
@ -1221,7 +1221,7 @@ public abstract class Provider extends Properties {
|
||||||
s.className = className;
|
s.className = className;
|
||||||
|
|
||||||
if (type.equals("SecureRandom")) {
|
if (type.equals("SecureRandom")) {
|
||||||
updateSecureRandomEntries(true, s);
|
updateSecureRandomEntries(true, s.algorithm);
|
||||||
}
|
}
|
||||||
} else { // attribute
|
} else { // attribute
|
||||||
// e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software");
|
// e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software");
|
||||||
|
@ -1383,25 +1383,25 @@ public abstract class Provider extends Properties {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
putPropertyStrings(s);
|
putPropertyStrings(s);
|
||||||
if (type.equals("SecureRandom")) {
|
if (type.equals("SecureRandom")) {
|
||||||
updateSecureRandomEntries(true, s);
|
updateSecureRandomEntries(true, s.algorithm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSecureRandomEntries(boolean doAdd, Service s) {
|
// keep tracks of the registered secure random algos and store them in order
|
||||||
|
private void updateSecureRandomEntries(boolean doAdd, String s) {
|
||||||
Objects.requireNonNull(s);
|
Objects.requireNonNull(s);
|
||||||
if (doAdd) {
|
if (doAdd) {
|
||||||
if (prngServices == null) {
|
if (prngAlgos == null) {
|
||||||
prngServices = new LinkedHashSet<Service>();
|
prngAlgos = new LinkedHashSet<String>();
|
||||||
}
|
}
|
||||||
prngServices.add(s);
|
prngAlgos.add(s);
|
||||||
} else {
|
} else {
|
||||||
prngServices.remove(s);
|
prngAlgos.remove(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug != null) {
|
if (debug != null) {
|
||||||
debug.println((doAdd? "Add":"Remove") + " SecureRandom algo " +
|
debug.println((doAdd? "Add":"Remove") + " SecureRandom algo " + s);
|
||||||
s.getAlgorithm());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1411,12 +1411,15 @@ public abstract class Provider extends Properties {
|
||||||
checkInitialized();
|
checkInitialized();
|
||||||
|
|
||||||
if (legacyChanged) {
|
if (legacyChanged) {
|
||||||
prngServices = null;
|
prngAlgos = null;
|
||||||
ensureLegacyParsed();
|
ensureLegacyParsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prngServices != null && !prngServices.isEmpty()) {
|
if (prngAlgos != null && !prngAlgos.isEmpty()) {
|
||||||
return prngServices.iterator().next();
|
// IMPORTANT: use the Service obj returned by getService(...) call
|
||||||
|
// as providers may override putService(...)/getService(...) and
|
||||||
|
// return their own Service objects
|
||||||
|
return getService("SecureRandom", prngAlgos.iterator().next());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1516,7 +1519,7 @@ public abstract class Provider extends Properties {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
removePropertyStrings(s);
|
removePropertyStrings(s);
|
||||||
if (type.equals("SecureRandom")) {
|
if (type.equals("SecureRandom")) {
|
||||||
updateSecureRandomEntries(false, s);
|
updateSecureRandomEntries(false, s.algorithm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,12 @@ import java.security.Provider;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.Provider.Service;
|
import java.security.Provider.Service;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import sun.security.provider.SunEntries;
|
import sun.security.provider.SunEntries;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 8228613 8246613
|
* @bug 8228613 8246613 8248505
|
||||||
* @summary Ensure that the default SecureRandom algo used is based
|
* @summary Ensure that the default SecureRandom algo used is based
|
||||||
* on the registration ordering, and falls to next provider
|
* on the registration ordering, and falls to next provider
|
||||||
* if none are found
|
* if none are found
|
||||||
|
@ -40,6 +39,9 @@ import sun.security.provider.SunEntries;
|
||||||
*/
|
*/
|
||||||
public class DefaultAlgo {
|
public class DefaultAlgo {
|
||||||
|
|
||||||
|
private static final String SR_IMPLCLASS =
|
||||||
|
"sun.security.provider.SecureRandom";
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
String[] algos = { "A", "B", "C" };
|
String[] algos = { "A", "B", "C" };
|
||||||
test3rdParty(algos);
|
test3rdParty(algos);
|
||||||
|
@ -51,7 +53,8 @@ public class DefaultAlgo {
|
||||||
private static void test3rdParty(String[] algos) {
|
private static void test3rdParty(String[] algos) {
|
||||||
Provider[] provs = {
|
Provider[] provs = {
|
||||||
new SampleLegacyProvider(algos),
|
new SampleLegacyProvider(algos),
|
||||||
new SampleServiceProvider(algos)
|
new SampleServiceProvider(algos),
|
||||||
|
new CustomProvider(algos)
|
||||||
};
|
};
|
||||||
for (Provider p : provs) {
|
for (Provider p : provs) {
|
||||||
checkDefault(p, algos);
|
checkDefault(p, algos);
|
||||||
|
@ -72,9 +75,10 @@ public class DefaultAlgo {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkDefault(Provider p, String ... algos) {
|
private static void checkDefault(Provider p, String ... algos) {
|
||||||
out.println(p.getName() + " with " + Arrays.toString(algos));
|
|
||||||
int pos = Security.insertProviderAt(p, 1);
|
|
||||||
String pName = p.getName();
|
String pName = p.getName();
|
||||||
|
out.println(pName + " with " + Arrays.toString(algos));
|
||||||
|
int pos = Security.insertProviderAt(p, 1);
|
||||||
|
|
||||||
boolean isLegacy = pName.equals("SampleLegacy");
|
boolean isLegacy = pName.equals("SampleLegacy");
|
||||||
try {
|
try {
|
||||||
if (isLegacy) {
|
if (isLegacy) {
|
||||||
|
@ -91,7 +95,13 @@ public class DefaultAlgo {
|
||||||
out.println("=> Test Passed");
|
out.println("=> Test Passed");
|
||||||
} finally {
|
} finally {
|
||||||
if (pos != -1) {
|
if (pos != -1) {
|
||||||
Security.removeProvider(p.getName());
|
Security.removeProvider(pName);
|
||||||
|
}
|
||||||
|
if (isLegacy) {
|
||||||
|
// add back the removed algos
|
||||||
|
for (String s : algos) {
|
||||||
|
p.put("SecureRandom." + s, SR_IMPLCLASS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +110,7 @@ public class DefaultAlgo {
|
||||||
SampleLegacyProvider(String[] listOfSupportedRNGs) {
|
SampleLegacyProvider(String[] listOfSupportedRNGs) {
|
||||||
super("SampleLegacy", "1.0", "test provider using legacy put");
|
super("SampleLegacy", "1.0", "test provider using legacy put");
|
||||||
for (String s : listOfSupportedRNGs) {
|
for (String s : listOfSupportedRNGs) {
|
||||||
put("SecureRandom." + s, "sun.security.provider.SecureRandom");
|
put("SecureRandom." + s, SR_IMPLCLASS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,8 +120,37 @@ public class DefaultAlgo {
|
||||||
super("SampleService", "1.0", "test provider using putService");
|
super("SampleService", "1.0", "test provider using putService");
|
||||||
for (String s : listOfSupportedRNGs) {
|
for (String s : listOfSupportedRNGs) {
|
||||||
putService(new Provider.Service(this, "SecureRandom", s,
|
putService(new Provider.Service(this, "SecureRandom", s,
|
||||||
"sun.security.provider.SecureRandom", null, null));
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue