Skip to content

Commit

Permalink
Merge pull request #769 from KostasTsiounis/setProperty_fips
Browse files Browse the repository at this point in the history
Check setting of security property when in FIPS mode
  • Loading branch information
keithc-ca authored Apr 17, 2024
2 parents 1824a6b + 7b67e7e commit 95a3a61
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ public final class RestrictedSecurity {

private static final Debug debug = Debug.getInstance("semerufips");

// Restricted security mode enable check, only supported on Linux x64.
// Restricted security mode enable check.
private static final boolean userEnabledFIPS;
private static boolean isFIPSSupported;
private static boolean isFIPSEnabled;

private static final boolean allowSetProperties;

private static final boolean isNSSSupported;
private static final boolean isOpenJCEPlusSupported;

Expand All @@ -71,6 +73,8 @@ public final class RestrictedSecurity {

private static RestrictedSecurityProperties restricts;

private static final Set<String> unmodifiableProperties = new HashSet<>();

private static final Map<String, List<String>> supportedPlatformsNSS = new HashMap<>();
private static final Map<String, List<String>> supportedPlatformsOpenJCEPlus = new HashMap<>();

Expand All @@ -89,7 +93,8 @@ public String[] run() {
return new String[] { System.getProperty("semeru.fips"),
System.getProperty("semeru.customprofile"),
System.getProperty("os.name"),
System.getProperty("os.arch") };
System.getProperty("os.arch"),
System.getProperty("semeru.fips.allowsetproperties") };
}
});

Expand Down Expand Up @@ -128,6 +133,7 @@ public String[] run() {
isFIPSSupported = isNSSSupported;

userEnabledFIPS = Boolean.parseBoolean(props[0]);
allowSetProperties = Boolean.parseBoolean(props[4]);

if (userEnabledFIPS) {
if (isFIPSSupported) {
Expand Down Expand Up @@ -369,6 +375,53 @@ private static void checkFIPSCompatibility(Properties props) {
}
}

/**
* Check whether a security property can be set.
*
* A security property that is set by a RestrictedSecurity profile,
* while FIPS security mode is enabled, cannot be reset programmatically.
*
* Every time an attempt to set a security property is made, a check is
* performed. If the above scenario holds true, a SecurityException is
* thrown.
*
* One can override this behaviour and allow the user to set any security
* property through the use of {@code -Dsemeru.fips.allowsetproperties=true}.
*
* @param key the security property that the user wants to set
* @throws SecurityException
* if the security property is set by the profile and cannot
* be altered
*/
public static void checkSetSecurityProperty(String key) {
if (debug != null) {
debug.println("RestrictedSecurity: Checking whether property '"
+ key + "' can be set.");
}

/*
* Only disallow setting of security properties that are set by the active profile,
* if FIPS has been enabled.
*
* Allow any change, if the 'semeru.fips.allowsetproperties' flag is set to true.
*/
if (unmodifiableProperties.contains(key)) {
if (debug != null) {
debug.println("RestrictedSecurity: Property '" + key + "' cannot be set.");
debug.println("If you want to override the check and allow all security"
+ "properties to be set, use '-Dsemeru.fips.allowsetproperties=true'.");
debug.println("BEWARE: You might not be FIPS compliant if you select to override!");
}
throw new SecurityException("FIPS mode: User-specified '" + key
+ "' cannot override profile definition.");
}

if (debug != null) {
debug.println("RestrictedSecurity: Property '"
+ key + "' can be set without issue.");
}
}

/**
* Remove the security providers and only add restricted security providers.
*
Expand Down Expand Up @@ -470,10 +523,10 @@ private static void setProperties(Properties props) {
// JDK properties name as key, restricted security properties value as value.
propsMapping.put("jdk.tls.disabledNamedCurves", restricts.jdkTlsDisabledNamedCurves);
propsMapping.put("jdk.tls.disabledAlgorithms", restricts.jdkTlsDisabledAlgorithms);
propsMapping.put("jdk.tls.ephemeralDHKeySize", restricts.jdkTlsDphemeralDHKeySize);
propsMapping.put("jdk.tls.ephemeralDHKeySize", restricts.jdkTlsEphemeralDHKeySize);
propsMapping.put("jdk.tls.legacyAlgorithms", restricts.jdkTlsLegacyAlgorithms);
propsMapping.put("jdk.certpath.disabledAlgorithms", restricts.jdkCertpathDisabledAlgorithms);
propsMapping.put("jdk.security.legacyAlgorithm", restricts.jdkSecurityLegacyAlgorithm);
propsMapping.put("jdk.security.legacyAlgorithms", restricts.jdkSecurityLegacyAlgorithms);
String fipsMode = System.getProperty("com.ibm.fips.mode");
if (fipsMode == null) {
System.setProperty("com.ibm.fips.mode", restricts.jdkFipsMode);
Expand All @@ -490,6 +543,11 @@ private static void setProperties(Properties props) {
propsOldValue = "";
}

if ((propsNewValue != null) && userEnabledFIPS && !allowSetProperties) {
// Add to set of properties set by the active profile.
unmodifiableProperties.add(jdkPropsName);
}

if (!isNullOrBlank(propsNewValue)) {
String values = isNullOrBlank(propsOldValue) ? propsNewValue : (propsOldValue + ", " + propsNewValue);
props.setProperty(jdkPropsName, values);
Expand Down Expand Up @@ -590,10 +648,10 @@ private static final class RestrictedSecurityProperties {
// Security properties.
private String jdkTlsDisabledNamedCurves;
private String jdkTlsDisabledAlgorithms;
private String jdkTlsDphemeralDHKeySize;
private String jdkTlsEphemeralDHKeySize;
private String jdkTlsLegacyAlgorithms;
private String jdkCertpathDisabledAlgorithms;
private String jdkSecurityLegacyAlgorithm;
private String jdkSecurityLegacyAlgorithms;
private String keyStoreType;
private String keyStore;

Expand Down Expand Up @@ -742,13 +800,13 @@ private void initProperties() {
securityProps.getProperty(profileID + ".tls.disabledNamedCurves"));
jdkTlsDisabledAlgorithms = parseProperty(
securityProps.getProperty(profileID + ".tls.disabledAlgorithms"));
jdkTlsDphemeralDHKeySize = parseProperty(
jdkTlsEphemeralDHKeySize = parseProperty(
securityProps.getProperty(profileID + ".tls.ephemeralDHKeySize"));
jdkTlsLegacyAlgorithms = parseProperty(
securityProps.getProperty(profileID + ".tls.legacyAlgorithms"));
jdkCertpathDisabledAlgorithms = parseProperty(
securityProps.getProperty(profileID + ".jce.certpath.disabledAlgorithms"));
jdkSecurityLegacyAlgorithm = parseProperty(
jdkSecurityLegacyAlgorithms = parseProperty(
securityProps.getProperty(profileID + ".jce.legacyAlgorithms"));
keyStoreType = parseProperty(
securityProps.getProperty(profileID + ".keystore.type"));
Expand Down Expand Up @@ -1135,13 +1193,17 @@ private void printProperty(String name, String value) {
}

/**
* Check if the input string is null. If null return "".
* Trim input string if not null.
*
* @param string the input string
* @return "" if the string is null
* @return the string trimmed or null
*/
private static String parseProperty(String string) {
return (string != null) ? string.trim() : "";
if (string != null) {
string = string.trim();
}

return string;
}

/**
Expand Down
6 changes: 5 additions & 1 deletion src/java.base/share/classes/java/security/Security.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

/*
* ===========================================================================
* (c) Copyright IBM Corp. 2022, 2023 All Rights Reserved
* (c) Copyright IBM Corp. 2022, 2024 All Rights Reserved
* ===========================================================================
*/

Expand Down Expand Up @@ -791,6 +791,10 @@ public static String getProperty(String key) {
*/
public static void setProperty(String key, String datum) {
check("setProperty." + key);

// Check whether the change to the property is allowed.
RestrictedSecurity.checkSetSecurityProperty(key);

props.put(key, datum);
invalidateSMCache(key); /* See below. */

Expand Down

0 comments on commit 95a3a61

Please sign in to comment.