Doublecheck if we need to override properties in java.security

Closes https://github.com/keycloak/keycloak/issues/16702
This commit is contained in:
rmartinc 2023-02-14 15:14:25 +01:00 committed by Marek Posolda
parent d768e75be7
commit fbc9177f27
10 changed files with 51 additions and 52 deletions

View file

@ -14,4 +14,5 @@ echo "STRICT_OPTIONS: $STRICT_OPTIONS"
TESTS=`testsuite/integration-arquillian/tests/base/testsuites/suite.sh fips` TESTS=`testsuite/integration-arquillian/tests/base/testsuites/suite.sh fips`
echo "Tests: $TESTS" echo "Tests: $TESTS"
export JAVA_HOME=/etc/alternatives/java_sdk_17 export JAVA_HOME=/etc/alternatives/java_sdk_17
set -o pipefail
./mvnw test -Dsurefire.rerunFailingTestsCount=$SUREFIRE_RERUN_FAILING_COUNT -nsu -B -Pauth-server-quarkus,auth-server-fips140-2 -Dcom.redhat.fips=false $STRICT_OPTIONS -Dtest=$TESTS -pl testsuite/integration-arquillian/tests/base | misc/log/trimmer.sh ./mvnw test -Dsurefire.rerunFailingTestsCount=$SUREFIRE_RERUN_FAILING_COUNT -nsu -B -Pauth-server-quarkus,auth-server-fips140-2 -Dcom.redhat.fips=false $STRICT_OPTIONS -Dtest=$TESTS -pl testsuite/integration-arquillian/tests/base | misc/log/trimmer.sh

View file

@ -26,15 +26,18 @@ import java.security.cert.CollectionCertStoreParameters;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException; import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKeyFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SNIHostName; import javax.net.ssl.SNIHostName;
import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECParameters;
@ -87,6 +90,8 @@ public class FIPS1402Provider implements CryptoProvider {
checkSecureRandom(() -> Security.insertProviderAt(this.bcFipsProvider, 2)); checkSecureRandom(() -> Security.insertProviderAt(this.bcFipsProvider, 2));
Provider bcJsseProvider = new BouncyCastleJsseProvider("fips:BCFIPS"); Provider bcJsseProvider = new BouncyCastleJsseProvider("fips:BCFIPS");
Security.insertProviderAt(bcJsseProvider, 3); Security.insertProviderAt(bcJsseProvider, 3);
// force the key and trust manager factories if default values not present in BCJSSE
modifyKeyTrustManagerSecurityProperties(bcJsseProvider);
log.debugf("Inserted security providers: %s", Arrays.asList(this.bcFipsProvider.getName(),bcJsseProvider.getName())); log.debugf("Inserted security providers: %s", Arrays.asList(this.bcFipsProvider.getName(),bcJsseProvider.getName()));
} else { } else {
log.debugf("Security provider %s already loaded", existingBcFipsProvider.getName()); log.debugf("Security provider %s already loaded", existingBcFipsProvider.getName());
@ -289,4 +294,42 @@ public class FIPS1402Provider implements CryptoProvider {
} }
} }
} }
/**
* BCJSSE manages X.509, X509 and PKIX for KeyManagerFactory and
* TrustManagerFactory (names or aliases) while JSSE manages SunX509,
* NewSunX509 and PKIX for KeyManagerFactory and SunX509, PKIX, SunPKIX,
* X509 and X.509 for the TrustManagerFactory. As BCJSSE is used when
* fips enabled, the default implementations are changed to the ones
* provided by BC if selected ones are not present in the BCJSSE.
*
* @param bcJsseProvider The BCJSSE provider
*/
private static void modifyKeyTrustManagerSecurityProperties(Provider bcJsseProvider) {
boolean setKey = bcJsseProvider.getService(KeyManagerFactory.class.getSimpleName(), KeyManagerFactory.getDefaultAlgorithm()) == null;
boolean setTrust = bcJsseProvider.getService(TrustManagerFactory.class.getSimpleName(), TrustManagerFactory.getDefaultAlgorithm()) == null;
if (!setKey && !setTrust) {
return;
}
Set<Provider.Service> services = bcJsseProvider.getServices();
if (services != null) {
for (Provider.Service service : services) {
if (setKey && KeyManagerFactory.class.getSimpleName().equals(service.getType())) {
Security.setProperty("ssl.KeyManagerFactory.algorithm", service.getAlgorithm());
setKey = false;
if (!setTrust) {
return;
}
} else if (setTrust && TrustManagerFactory.class.getSimpleName().equals(service.getType())) {
Security.setProperty("ssl.TrustManagerFactory.algorithm", service.getAlgorithm());
setTrust = false;
if (!setKey) {
return;
}
}
}
}
throw new IllegalStateException("Provider " + bcJsseProvider.getName()
+ " does not provide KeyManagerFactory or TrustManagerFactory algorithms for TLS");
}
} }

View file

@ -48,7 +48,7 @@ public class KeycloakFipsSecurityProvider extends Provider {
isSystemFipsEnabled.setAccessible(true); isSystemFipsEnabled.setAccessible(true);
return (boolean) isSystemFipsEnabled.invoke(null); return (boolean) isSystemFipsEnabled.invoke(null);
} catch (Throwable ignore) { } catch (Throwable ignore) {
logger.warn("Could not detect if FIPS is enabled from the host"); logger.debug("Could not detect if FIPS is enabled from the host");
} finally { } finally {
if (isSystemFipsEnabled != null) { if (isSystemFipsEnabled != null) {
isSystemFipsEnabled.setAccessible(false); isSystemFipsEnabled.setAccessible(false);

View file

@ -5,4 +5,4 @@ if "%OS%" == "Windows_NT" (
) else ( ) else (
set DIRNAME=.\ set DIRNAME=.\
) )
java %KC_OPTS% -cp "%DIRNAME%\client\keycloak-admin-cli-${project.version}.jar" -Dkc.lib.dir="%DIRNAME%\client\lib" org.keycloak.client.admin.cli.KcAdmMain %* java %KC_OPTS% -cp "%DIRNAME%\client\keycloak-admin-cli-${project.version}.jar" --add-opens=java.base/java.security=ALL-UNNAMED -Dkc.lib.dir="%DIRNAME%\client\lib" org.keycloak.client.admin.cli.KcAdmMain %*

View file

@ -29,4 +29,4 @@ if [ "x$JAVA" = "x" ]; then
fi fi
fi fi
"$JAVA" $KC_OPTS -cp $DIRNAME/client/keycloak-admin-cli-${project.version}.jar -Dkc.lib.dir=$DIRNAME/client/lib org.keycloak.client.admin.cli.KcAdmMain "$@" "$JAVA" $KC_OPTS -cp $DIRNAME/client/keycloak-admin-cli-${project.version}.jar --add-opens=java.base/java.security=ALL-UNNAMED -Dkc.lib.dir=$DIRNAME/client/lib org.keycloak.client.admin.cli.KcAdmMain "$@"

View file

@ -5,4 +5,4 @@ if "%OS%" == "Windows_NT" (
) else ( ) else (
set DIRNAME=.\ set DIRNAME=.\
) )
java %KC_OPTS% -cp "%DIRNAME%\client\keycloak-client-registration-cli-${project.version}.jar" -Dkc.lib.dir="%DIRNAME%\client\lib" org.keycloak.client.registration.cli.KcRegMain %* java %KC_OPTS% -cp "%DIRNAME%\client\keycloak-client-registration-cli-${project.version}.jar" --add-opens=java.base/java.security=ALL-UNNAMED -Dkc.lib.dir="%DIRNAME%\client\lib" org.keycloak.client.registration.cli.KcRegMain %*

View file

@ -28,4 +28,4 @@ if [ "x$JAVA" = "x" ]; then
fi fi
DIRNAME=`dirname "$RESOLVED_NAME"` DIRNAME=`dirname "$RESOLVED_NAME"`
"$JAVA" $KC_OPTS -cp $DIRNAME/client/keycloak-client-registration-cli-${project.version}.jar -Dkc.lib.dir=$DIRNAME/client/lib org.keycloak.client.registration.cli.KcRegMain "$@" "$JAVA" $KC_OPTS -cp $DIRNAME/client/keycloak-client-registration-cli-${project.version}.jar --add-opens=java.base/java.security=ALL-UNNAMED -Dkc.lib.dir=$DIRNAME/client/lib org.keycloak.client.registration.cli.KcRegMain "$@"

View file

@ -81,7 +81,7 @@ if not "x%JAVA_OPTS%" == "x" (
if not "x%JAVA_ADD_OPENS%" == "x" ( if not "x%JAVA_ADD_OPENS%" == "x" (
echo "JAVA_ADD_OPENS already set in environment; overriding default settings with values: %JAVA_ADD_OPENS%" echo "JAVA_ADD_OPENS already set in environment; overriding default settings with values: %JAVA_ADD_OPENS%"
) else ( ) else (
set "JAVA_ADD_OPENS=--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED" set "JAVA_ADD_OPENS=--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED"
) )
set "JAVA_OPTS=%JAVA_OPTS% %JAVA_ADD_OPENS%" set "JAVA_OPTS=%JAVA_OPTS% %JAVA_ADD_OPENS%"

View file

@ -92,7 +92,7 @@ fi
# See also https://github.com/wildfly/wildfly-core/blob/7e5624cf92ebe4b64a4793a8c0b2a340c0d6d363/core-feature-pack/common/src/main/resources/content/bin/common.sh#L57-L60 # See also https://github.com/wildfly/wildfly-core/blob/7e5624cf92ebe4b64a4793a8c0b2a340c0d6d363/core-feature-pack/common/src/main/resources/content/bin/common.sh#L57-L60
if [ "x$JAVA_ADD_OPENS" = "x" ]; then if [ "x$JAVA_ADD_OPENS" = "x" ]; then
JAVA_ADD_OPENS="--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED" JAVA_ADD_OPENS="--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED"
else else
echo "JAVA_ADD_OPENS already set in environment; overriding default settings with values: $JAVA_ADD_OPENS" echo "JAVA_ADD_OPENS already set in environment; overriding default settings with values: $JAVA_ADD_OPENS"
fi fi

View file

@ -4,14 +4,6 @@
# NOTE: Each property is specified 2 times. This is so the same file can be used on both FIPS based RHEL host (which uses "fips" prefixed properties by default) # NOTE: Each property is specified 2 times. This is so the same file can be used on both FIPS based RHEL host (which uses "fips" prefixed properties by default)
# and the non-fips based (EG. when running the tests on GH actions) # and the non-fips based (EG. when running the tests on GH actions)
#
# List of providers and their preference orders (see above). Used on the host without FIPS (EG. when running the tests on GH actions)
# Uses only BouncyCastle FIPS providers to make sure to use only FIPS compliant cryptography.
#
#security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
#security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
#security.provider.3=
# #
# Security providers used when global crypto-policies are set to FIPS (Usually it is used when FIPS enabled on system/JVM level) # Security providers used when global crypto-policies are set to FIPS (Usually it is used when FIPS enabled on system/JVM level)
# #
@ -19,41 +11,4 @@
# However once it is present, there won't be a need to override this and this part can be fully commented/removed. # However once it is present, there won't be a need to override this and this part can be fully commented/removed.
# TODO: Comment/remove this once https://bugzilla.redhat.com/show_bug.cgi?id=1940064 is fixed and OpenJDK 17 updated to corresponding version where XMLDSig is available by default # TODO: Comment/remove this once https://bugzilla.redhat.com/show_bug.cgi?id=1940064 is fixed and OpenJDK 17 updated to corresponding version where XMLDSig is available by default
# #
fips.provider.1=SunPKCS11 ${java.home}/conf/security/nss.fips.cfg
fips.provider.2=SUN
fips.provider.3=SunEC
fips.provider.4=SunJSSE
fips.provider.5=SunJCE
fips.provider.6=SunRsaSign
fips.provider.7=XMLDSig fips.provider.7=XMLDSig
# Commented this provider for now (and also other providers) as it uses lots of non-FIPS services.
# See https://access.redhat.com/documentation/en-us/openjdk/11/html-single/configuring_openjdk_11_on_rhel_with_fips/index#ref_openjdk-default-fips-configuration_openjdk
# fips.provider.2=SUN
#
# Default keystore type.
#
keystore.type=PKCS12
fips.keystore.type=PKCS12
# This is needed especially if we cannot add security provider "com.sun.net.ssl.internal.ssl.Provider BCFIPS" as a security provider.
# OpenJDK has "SunX509" as default algorithm, but that one is not supported by BCJSSE. So adding the Sun provider delegating to BCFIPS is needed (as above)
# or changing default algorithm as described here
ssl.KeyManagerFactory.algorithm=PKIX
fips.ssl.KeyManagerFactory.algorithm=PKIX
ssl.TrustManagerFactory.algorithm=PKIX
fips.ssl.TrustManagerFactory.algorithm=PKIX
#
# Controls compatibility mode for JKS and PKCS12 keystore types.
#
# When set to 'true', both JKS and PKCS12 keystore types support loading
# keystore files in either JKS or PKCS12 format. When set to 'false' the
# JKS keystore type supports loading only JKS keystore files and the PKCS12
# keystore type supports loading only PKCS12 keystore files.
#
# This is set to true as when set to false on OpenJDK 17 and PKCS12 is default keystore type, loading of default truststore (from java cacerts) fails.
#keystore.type.compat=false
#fips.keystore.type.compat=false