Skip to content

Commit 23d6aaf

Browse files
authored
Merge pull request ibmruntimes#360 from taoliult/openj9
Support provider fully-qualified class name in Restricted Security mode
2 parents a3d9ec5 + f9d5c86 commit 23d6aaf

File tree

4 files changed

+70
-97
lines changed

4 files changed

+70
-97
lines changed

closed/src/java.base/share/classes/openj9/internal/security/RestrictedSecurity.java

Lines changed: 41 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.security.MessageDigest;
2929
import java.security.NoSuchAlgorithmException;
3030
import java.security.PrivilegedAction;
31+
import java.security.Provider;
3132
import java.security.Provider.Service;
3233
import java.time.LocalDate;
3334
import java.time.format.DateTimeFormatter;
@@ -267,6 +268,12 @@ public static boolean isServiceAllowed(Service service) {
267268
*/
268269
public static boolean isProviderAllowed(String providerName) {
269270
if (securityEnabled) {
271+
// Remove argument, e.g. -NSS-FIPS, if present.
272+
int pos = providerName.indexOf('-');
273+
if (pos >= 0) {
274+
providerName = providerName.substring(0, pos);
275+
}
276+
270277
return restricts.isRestrictedProviderAllowed(providerName);
271278
}
272279
return true;
@@ -280,17 +287,17 @@ public static boolean isProviderAllowed(String providerName) {
280287
*/
281288
public static boolean isProviderAllowed(Class<?> providerClazz) {
282289
if (securityEnabled) {
283-
String providerName = providerClazz.getName();
290+
String providerClassName = providerClazz.getName();
284291

285292
// Check if the specified class extends java.security.Provider.
286293
if (java.security.Provider.class.isAssignableFrom(providerClazz)) {
287-
return restricts.isRestrictedProviderAllowed(providerName);
294+
return restricts.isRestrictedProviderAllowed(providerClassName);
288295
}
289296

290297
// For a class that doesn't extend java.security.Provider, no need to
291298
// check allowed or not allowed, always return true to load it.
292299
if (debug != null) {
293-
debug.println("The provider class " + providerName + " does not extend java.security.Provider.");
300+
debug.println("The provider class " + providerClassName + " does not extend java.security.Provider.");
294301
}
295302
}
296303
return true;
@@ -659,27 +666,6 @@ private static boolean isAsterisk(String string) {
659666
return "*".equals(string);
660667
}
661668

662-
/**
663-
* Get the provider name defined in provider construction method.
664-
*
665-
* @param providerName provider name or provider with packages
666-
* @return provider name defined in provider construction method
667-
*/
668-
private static String getProvidersSimpleName(String providerName) {
669-
if (providerName.equals("com.sun.security.sasl.Provider")) {
670-
// The main class for the SunSASL provider is com.sun.security.sasl.Provider.
671-
return "SunSASL";
672-
} else {
673-
// Remove the provider's class package names if present.
674-
int pos = providerName.lastIndexOf('.');
675-
if (pos >= 0) {
676-
providerName = providerName.substring(pos + 1);
677-
}
678-
// Provider without package names.
679-
return providerName;
680-
}
681-
}
682-
683669
/**
684670
* This class is used to save and operate on restricted security
685671
* properties which are loaded from the java.security file.
@@ -713,7 +699,7 @@ private static final class RestrictedSecurityProperties {
713699
// Provider with argument (provider name + optional argument).
714700
private final List<String> providers;
715701
// Provider without argument.
716-
private final List<String> providersSimpleName;
702+
private final List<String> providersFullyQualifiedClassName;
717703
// The map is keyed by provider name.
718704
private final Map<String, Constraint[]> providerConstraints;
719705

@@ -745,7 +731,7 @@ private RestrictedSecurityProperties(String profileID, ProfileParser parser) {
745731
this.jdkFipsMode = parser.getProperty("jdkFipsMode");
746732

747733
this.providers = new ArrayList<>(parser.providers);
748-
this.providersSimpleName = new ArrayList<>(parser.providersSimpleName);
734+
this.providersFullyQualifiedClassName = new ArrayList<>(parser.providersFullyQualifiedClassName);
749735
this.providerConstraints = parser.providerConstraints
750736
.entrySet()
751737
.stream()
@@ -767,30 +753,26 @@ private RestrictedSecurityProperties(String profileID, ProfileParser parser) {
767753
* @return true if the Service is allowed
768754
*/
769755
boolean isRestrictedServiceAllowed(Service service) {
770-
String providerName = service.getProvider().getName();
756+
Provider provider = service.getProvider();
757+
String providerClassName = provider.getClass().getName();
771758

772759
if (debug != null) {
773-
debug.println("Checking service " + service.toString() + " offered by provider " + providerName + ".");
760+
debug.println("Checking service " + service.toString() + " offered by provider " + providerClassName + ".");
774761
}
775762

776-
// Provider with argument, remove argument.
777-
// e.g. SunPKCS11-NSS-FIPS, remove argument -NSS-FIPS.
778-
int pos = providerName.indexOf('-');
779-
providerName = (pos < 0) ? providerName : providerName.substring(0, pos);
780-
781-
Constraint[] constraints = providerConstraints.get(providerName);
763+
Constraint[] constraints = providerConstraints.get(providerClassName);
782764

783765
if (constraints == null) {
784766
// Disallow unknown providers.
785767
if (debug != null) {
786768
debug.println("Security constraints check."
787-
+ " Disallow unknown provider: " + providerName);
769+
+ " Disallow unknown provider: " + providerClassName);
788770
}
789771
return false;
790772
} else if (constraints.length == 0) {
791773
// Allow this provider with no constraints.
792774
if (debug != null) {
793-
debug.println("No constraints for provider " + providerName + ".");
775+
debug.println("No constraints for provider " + providerClassName + ".");
794776
}
795777
return true;
796778
}
@@ -834,7 +816,7 @@ boolean isRestrictedServiceAllowed(Service service) {
834816
debug.println("The following service:"
835817
+ "\n\tService type: " + type
836818
+ "\n\tAlgorithm: " + algorithm
837-
+ "\nis allowed in provider: " + providerName);
819+
+ "\nis allowed in provider: " + providerClassName);
838820
}
839821
return true;
840822
}
@@ -864,7 +846,7 @@ boolean isRestrictedServiceAllowed(Service service) {
864846
+ "\n\tService type: " + type
865847
+ "\n\tAlgorithm: " + algorithm
866848
+ "\n\tAttribute: " + cAttribute
867-
+ "\nis NOT allowed in provider: " + providerName);
849+
+ "\nis NOT allowed in provider: " + providerClassName);
868850
}
869851
return false;
870852
}
@@ -878,7 +860,7 @@ boolean isRestrictedServiceAllowed(Service service) {
878860
+ "\n\tService type: " + type
879861
+ "\n\tAlgorithm: " + algorithm
880862
+ "\n\tAttribute: " + cAttribute
881-
+ "\nis allowed in provider: " + providerName);
863+
+ "\nis allowed in provider: " + providerClassName);
882864
}
883865
return true;
884866
}
@@ -889,42 +871,33 @@ boolean isRestrictedServiceAllowed(Service service) {
889871
debug.println("The following service:"
890872
+ "\n\tService type: " + type
891873
+ "\n\tAlgorithm: " + algorithm
892-
+ "\nis NOT allowed in provider: " + providerName);
874+
+ "\nis NOT allowed in provider: " + providerClassName);
893875
}
894876
return false;
895877
}
896878

897879
/**
898880
* Check if the provider is allowed in restricted security mode.
899881
*
900-
* @param providerName the provider to check
882+
* @param providerClassName the provider to check
901883
* @return true if the provider is allowed
902884
*/
903-
boolean isRestrictedProviderAllowed(String providerName) {
885+
boolean isRestrictedProviderAllowed(String providerClassName) {
904886
if (debug != null) {
905-
debug.println("Checking the provider " + providerName + " in restricted security mode.");
906-
}
907-
908-
// Remove argument, e.g. -NSS-FIPS, if present.
909-
int pos = providerName.indexOf('-');
910-
if (pos >= 0) {
911-
providerName = providerName.substring(0, pos);
887+
debug.println("Checking the provider " + providerClassName + " in restricted security mode.");
912888
}
913889

914-
// Provider name defined in provider construction method.
915-
providerName = getProvidersSimpleName(providerName);
916-
917-
// Check if the provider is in restricted security provider list.
918-
// If not, the provider won't be registered.
919-
if (providersSimpleName.contains(providerName)) {
890+
// Check if the provider fully-qualified cLass name is in restricted
891+
// security provider list. If not, the provider won't be registered.
892+
if (providersFullyQualifiedClassName.contains(providerClassName)) {
920893
if (debug != null) {
921-
debug.println("The provider " + providerName + " is allowed in restricted security mode.");
894+
debug.println("The provider " + providerClassName + " is allowed in restricted security mode.");
922895
}
923896
return true;
924897
}
925898

926899
if (debug != null) {
927-
debug.println("The provider " + providerName + " is not allowed in restricted security mode.");
900+
debug.println("The provider " + providerClassName + " is not allowed in restricted security mode.");
928901

929902
debug.println("Stack trace:");
930903
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
@@ -963,8 +936,8 @@ private void listUsedProfile() {
963936
for (int providerPosition = 0; providerPosition < providers.size(); providerPosition++) {
964937
printProperty(profileID + ".jce.provider." + (providerPosition + 1) + ": ",
965938
providers.get(providerPosition));
966-
String providerSimpleName = providersSimpleName.get(providerPosition);
967-
for (Constraint providerConstraint : providerConstraints.get(providerSimpleName)) {
939+
String providerFullyQualifiedClassName = providersFullyQualifiedClassName.get(providerPosition);
940+
for (Constraint providerConstraint : providerConstraints.get(providerFullyQualifiedClassName)) {
968941
System.out.println("\t" + providerConstraint.toString());
969942
}
970943
}
@@ -1007,7 +980,7 @@ private static final class ProfileParser {
1007980
// Provider with argument (provider name + optional argument).
1008981
private final List<String> providers;
1009982
// Provider without argument.
1010-
private final List<String> providersSimpleName;
983+
private final List<String> providersFullyQualifiedClassName;
1011984
// The map is keyed by provider name.
1012985
private final Map<String, List<Constraint>> providerConstraints;
1013986

@@ -1035,7 +1008,7 @@ private ProfileParser(String id, Properties props) {
10351008
profileProperties = new HashMap<>();
10361009

10371010
providers = new ArrayList<>();
1038-
providersSimpleName = new ArrayList<>();
1011+
providersFullyQualifiedClassName = new ArrayList<>();
10391012
providerConstraints = new HashMap<>();
10401013

10411014
profilesHashes = new HashMap<>();
@@ -1193,21 +1166,13 @@ private void parseProvider(String providerInfo, int providerPos, boolean update)
11931166
}
11941167
providerName = providerName.trim();
11951168

1196-
// Remove argument, e.g. -NSS-FIPS, if present.
1197-
pos = providerName.indexOf('-');
1198-
if (pos >= 0) {
1199-
providerName = providerName.substring(0, pos);
1200-
}
1201-
1202-
// Provider name defined in provider construction method.
1203-
providerName = getProvidersSimpleName(providerName);
12041169
boolean providerChanged = false;
12051170
if (update) {
1206-
String previousProviderName = providersSimpleName.get(providerPos - 1);
1171+
String previousProviderName = providersFullyQualifiedClassName.get(providerPos - 1);
12071172
providerChanged = !previousProviderName.equals(providerName);
1208-
providersSimpleName.set(providerPos - 1, providerName);
1173+
providersFullyQualifiedClassName.set(providerPos - 1, providerName);
12091174
} else {
1210-
providersSimpleName.add(providerPos - 1, providerName);
1175+
providersFullyQualifiedClassName.add(providerPos - 1, providerName);
12111176
}
12121177

12131178
if (debug != null) {
@@ -1223,14 +1188,14 @@ private void removeProvider(String profileExtensionId, int providerPos) {
12231188
debug.println("\t\tRemoving provider in position " + providerPos);
12241189
}
12251190

1226-
int numOfExistingProviders = providersSimpleName.size();
1191+
int numOfExistingProviders = providersFullyQualifiedClassName.size();
12271192

12281193
// If this is the last provider, remove from all lists.
12291194
if (providerPos == numOfExistingProviders) {
12301195
if (debug != null) {
12311196
debug.println("\t\t\tLast provider. Only one to be removed.");
12321197
}
1233-
String providerRemoved = providersSimpleName.remove(providerPos - 1);
1198+
String providerRemoved = providersFullyQualifiedClassName.remove(providerPos - 1);
12341199
providers.remove(providerPos - 1);
12351200
providerConstraints.remove(providerRemoved);
12361201

@@ -1254,7 +1219,7 @@ private void removeProvider(String profileExtensionId, int providerPos) {
12541219
}
12551220

12561221
// Remove all of the providers that are set to empty.
1257-
String providerRemoved = providersSimpleName.remove(i - 1);
1222+
String providerRemoved = providersFullyQualifiedClassName.remove(i - 1);
12581223
providers.remove(i - 1);
12591224
providerConstraints.remove(providerRemoved);
12601225

@@ -1303,7 +1268,7 @@ private void initProviders(String profileID, List<String> allInfo) {
13031268

13041269
private void updateProviders(String profileExtensionId, List<String> allInfo) {
13051270
boolean removedProvider = false;
1306-
int numOfExistingProviders = providersSimpleName.size();
1271+
int numOfExistingProviders = providersFullyQualifiedClassName.size();
13071272
// Deal with update of existing providers.
13081273
for (int i = 1; i <= numOfExistingProviders; i++) {
13091274
String property = profileExtensionId + ".jce.provider." + i;

src/java.base/share/classes/sun/security/jca/ProviderConfig.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
/*
2727
* ===========================================================================
28-
* (c) Copyright IBM Corp. 2023, 2023 All Rights Reserved
28+
* (c) Copyright IBM Corp. 2023, 2024 All Rights Reserved
2929
* ===========================================================================
3030
*/
3131

@@ -170,13 +170,11 @@ public String toString() {
170170
*/
171171
@SuppressWarnings("deprecation")
172172
Provider getProvider() {
173-
if (!RestrictedSecurity.isProviderAllowed(provName)) {
174-
// We're in restricted security mode which does not allow this provider,
175-
// return without loading.
176-
return null;
177-
}
178173
// volatile variable load
179174
Provider p = provider;
175+
// There is RestrictedSecurity check in the ServiceLoader before the
176+
// provider is initialized. So the check has already occurred for the
177+
// provider where provider != null.
180178
if (p != null) {
181179
return p;
182180
}
@@ -189,6 +187,11 @@ Provider getProvider() {
189187
if (shouldLoad() == false) {
190188
return null;
191189
}
190+
if (!RestrictedSecurity.isProviderAllowed(provName)) {
191+
// We're in restricted security mode which does not allow this provider,
192+
// return without loading.
193+
return null;
194+
}
192195

193196
// Create providers which are in java.base directly
194197
if (provName.equals("SUN") || provName.equals("sun.security.provider.Sun")) {
@@ -368,8 +371,12 @@ public Provider load(String pn) {
368371
if (debug != null) {
369372
debug.println("Found SL Provider named " + pName);
370373
}
371-
if (pName.equals(pn)) {
374+
if (p.getClass().getName().equals(pn)) {
372375
return p;
376+
} else if (pName.equals(pn)) {
377+
if (!RestrictedSecurity.isEnabled()) {
378+
return p;
379+
}
373380
}
374381
} catch (SecurityException | ServiceConfigurationError |
375382
InvalidParameterException ex) {

src/java.base/share/classes/sun/security/jca/ProviderList.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
/*
2727
* ===========================================================================
28-
* (c) Copyright IBM Corp. 2023, 2023 All Rights Reserved
28+
* (c) Copyright IBM Corp. 2023, 2024 All Rights Reserved
2929
* ===========================================================================
3030
*/
3131

@@ -116,15 +116,14 @@ public static ProviderList add(ProviderList providerList, Provider p) {
116116

117117
public static ProviderList insertAt(ProviderList providerList, Provider p,
118118
int position) {
119-
String providerName = p.getName();
120-
if (providerList.getProvider(providerName) != null) {
121-
return providerList;
122-
}
123-
if (!RestrictedSecurity.isProviderAllowed(providerName)) {
119+
if (!RestrictedSecurity.isProviderAllowed(p.getClass())) {
124120
// We're in restricted security mode which does not allow this provider,
125121
// return without adding.
126122
return providerList;
127123
}
124+
if (providerList.getProvider(p.getName()) != null) {
125+
return providerList;
126+
}
128127
List<ProviderConfig> list = new ArrayList<>
129128
(Arrays.asList(providerList.configs));
130129
int n = list.size();
@@ -157,7 +156,7 @@ public static ProviderList newList(Provider ... providers) {
157156
if (RestrictedSecurity.isEnabled()) {
158157
List<Provider> allowedProviders = new ArrayList<>();
159158
for (Provider p : providers) {
160-
if (RestrictedSecurity.isProviderAllowed(p.getName())) {
159+
if (RestrictedSecurity.isProviderAllowed(p.getClass())) {
161160
// This provider is allowed, add it the list.
162161
allowedProviders.add(p);
163162
}

0 commit comments

Comments
 (0)