diff --git a/closed/src/java.base/share/classes/openj9/internal/security/RestrictedSecurity.java b/closed/src/java.base/share/classes/openj9/internal/security/RestrictedSecurity.java index 470401ff76a..ade69839ebb 100644 --- a/closed/src/java.base/share/classes/openj9/internal/security/RestrictedSecurity.java +++ b/closed/src/java.base/share/classes/openj9/internal/security/RestrictedSecurity.java @@ -35,6 +35,7 @@ import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Deque; +import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -994,6 +995,9 @@ private static final class ProfileParser { // The java.security properties. private final Properties securityProps; + private LinkedList profileCheckPropertyNames; + private LinkedList profileCheckProviderNames; + /** * * @param id the restricted security custom profile ID @@ -1016,8 +1020,13 @@ private ProfileParser(String id, Properties props) { parsedProfiles = new HashSet<>(); + profileCheckPropertyNames = new LinkedList<>(); + profileCheckProviderNames = new LinkedList<>(); + // Initialize the properties. init(profileID); + + checkProfileCheck(profileID); } private RestrictedSecurityProperties getProperties() { @@ -1040,12 +1049,16 @@ private void init(String profileID) { printStackTraceAndExit(profileID + " has already been parsed. Potential infinite recursion."); } + loadProfileCheck(profileID); + String potentialExtendsProfileID = parseProperty(securityProps.getProperty(profileID + ".extends")); if (potentialExtendsProfileID != null) { // If profile extends another profile. if (debug != null) { debug.println("\t'" + profileID + "' extends '" + potentialExtendsProfileID + "'."); } + profileCheckPropertyNames.remove(profileID + ".extends"); + // Check if extended profile exists. String extendsProfileID = null; if (potentialExtendsProfileID.indexOf('.') != potentialExtendsProfileID.lastIndexOf('.')) { @@ -1098,6 +1111,7 @@ private void init(String profileID) { // Save info to be hashed and expected result to be checked later. profilesHashes.put(profileID, hashValue); profilesInfo.put(profileID, allInfo); + profileCheckPropertyNames.remove(hashProperty); } else if (!isFIPS1402Profile(profileID)) { // A hash is mandatory, but not for older 140-2 profiles. printStackTraceAndExit(profileID + " is a base profile, so a hash value is mandatory."); @@ -1134,6 +1148,7 @@ private void update(String profileExtensionId) { // Save info to be hashed and expected result to be checked later. profilesHashes.put(profileID, hashValue); profilesInfo.put(profileID, allInfo); + profileCheckPropertyNames.remove(hashProperty); } } catch (Exception e) { if (debug != null) { @@ -1254,6 +1269,7 @@ private void initProviders(String profileID, List allInfo) { allInfo.add(property + "=" + providerInfo); parseProvider(providerInfo, pNum, false); + profileCheckProviderNames.remove(property); } if (providers.isEmpty()) { @@ -1284,6 +1300,7 @@ private void updateProviders(String profileExtensionId, List allInfo) { removedProvider = true; break; } + profileCheckProviderNames.remove(property); } } @@ -1311,6 +1328,7 @@ private void updateProviders(String profileExtensionId, List allInfo) { allInfo.add(property + "=" + providerInfo); parseProvider(providerInfo, i, false); + profileCheckProviderNames.remove(property); } } @@ -1634,6 +1652,7 @@ private boolean setProperty(String property, String propertyKey, List al newValue = value; } profileProperties.put(property, newValue); + profileCheckPropertyNames.remove(propertyKey); return true; } if (debug != null) { @@ -1706,6 +1725,32 @@ private static void checkProviderFormat(String providerInfo, boolean update) { printStackTraceAndExit("Provider format is incorrect: " + providerInfo); } } + + private void loadProfileCheck(String profileID) { + Enumeration pNames = securityProps.propertyNames(); + while (pNames.hasMoreElements()) { + String name = (String) pNames.nextElement(); + if (name.startsWith(profileID + '.') && name.contains(".jce.provider.")) { + profileCheckProviderNames.add(name); + } else if (name.startsWith(profileID + '.')) { + profileCheckPropertyNames.add(name); + } + } + } + + private void checkProfileCheck(String profileID) { + if (!profileCheckProviderNames.isEmpty()) { + printStackTraceAndExit( + "The order of providers in profile " + profileID + + " (or its base profile) is incorrect."); + } + if (!profileCheckPropertyNames.isEmpty()) { + printStackTraceAndExit( + "The property name: " + profileCheckPropertyNames.toString() + + " in profile " + profileID + + " may be misspelled."); + } + } } /**