Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check setting of security property when in FIPS mode #339

Merged
merged 1 commit into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -367,6 +373,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 @@ -468,10 +521,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 @@ -488,6 +541,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 @@ -588,10 +646,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 @@ -740,13 +798,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 @@ -1132,13 +1190,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 @@ -811,6 +811,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