Support Java 25 with FIPS enabled (#47581)

Closes #47666

Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
Ricardo Martin
2026-04-01 09:57:25 +02:00
committed by GitHub
parent 3e3191d60c
commit 2daea53e70
7 changed files with 38 additions and 34 deletions
+12 -5
View File
@@ -2,9 +2,9 @@
set -x
rm -f /etc/system-fips
dnf install -y java-21-openjdk-devel
dnf install -y java-25-openjdk-devel
fips-mode-setup --enable --no-bootcfg
fips-mode-setup --is-enabled
fips-mode-setup --check | grep "FIPS mode is enabled."
if [ $? -ne 0 ]; then
exit 1
fi
@@ -16,8 +16,12 @@ if [ "$1" = "strict" ]; then
fi
echo "STRICT_OPTIONS: $STRICT_OPTIONS"
TESTS=`testsuite/integration-arquillian/tests/base/testsuites/suite.sh fips`
if [ $? -ne 0 ]; then
echo "Invalid tests to execute: $TESTS"
exit 1
fi
echo "Tests: $TESTS"
export JAVA_HOME=/etc/alternatives/java_sdk_21
export JAVA_HOME=/etc/alternatives/java_sdk_25
set -o pipefail
# Build adapter distributions
@@ -39,7 +43,10 @@ if [ $? -ne 0 ]; then
fi
# Profile app-server-wildfly needs to be explicitly set for FIPS tests
./mvnw test -Dsurefire.rerunFailingTestsCount=$SUREFIRE_RERUN_FAILING_COUNT -nsu -B -Pauth-server-quarkus,auth-server-fips140-2,app-server-wildfly -Dcom.redhat.fips=false $STRICT_OPTIONS -Dtest=$TESTS -pl testsuite/integration-arquillian/tests/base 2>&1 | misc/log/trimmer.sh
./mvnw test -Dsurefire.rerunFailingTestsCount=$SUREFIRE_RERUN_FAILING_COUNT -nsu -B -Pauth-server-quarkus,auth-server-fips140-2,app-server-wildfly -Dredhat.crypto-policies=false $STRICT_OPTIONS -Dtest=$TESTS -pl testsuite/integration-arquillian/tests/base 2>&1 | misc/log/trimmer.sh
if [ $? -ne 0 ]; then
exit 1
fi
# New Base Tests
./mvnw package -nsu -B -Dcom.redhat.fips=false -Dtest=$TESTSUITE_NAME -pl tests/base
./mvnw package -nsu -B -Dredhat.crypto-policies=false -Dtest=$TESTSUITE_NAME -pl tests/base
+6 -5
View File
@@ -1,19 +1,20 @@
#!/usr/bin/env bash
rm -f /etc/system-fips
dnf install -y java-21-openjdk-devel crypto-policies-scripts
dnf install -y java-25-openjdk-devel crypto-policies-scripts
fips-mode-setup --enable --no-bootcfg
fips-mode-setup --is-enabled
fips-mode-setup --check | grep "FIPS mode is enabled."
if [ $? -ne 0 ]; then
exit 1
fi
export JAVA_HOME=/etc/alternatives/java_sdk_21
export JAVA_HOME=/etc/alternatives/java_sdk_25
# Build all dependent modules
./mvnw install -nsu -B -am -pl crypto/default,crypto/fips1402 -DskipTests
./mvnw test -nsu -B -pl crypto/default,crypto/fips1402 -Dcom.redhat.fips=true
./mvnw test -nsu -B -pl crypto/default,crypto/fips1402 -Dredhat.crypto-policies=true
if [ $? -ne 0 ]; then
exit 1
fi
./mvnw test -nsu -B -pl crypto/default,crypto/fips1402 -Dcom.redhat.fips=true -Dorg.bouncycastle.fips.approved_only=true
./mvnw test -nsu -B -pl crypto/default,crypto/fips1402 -Dredhat.crypto-policies=true -Dorg.bouncycastle.fips.approved_only=true
+2 -2
View File
@@ -975,7 +975,7 @@ jobs:
sudo insmod fake_fips.ko
- name: Run crypto tests
run: docker run --rm --workdir /github/workspace -v "${{ github.workspace }}":"/github/workspace" -v "$HOME/.m2":"/root/.m2" registry.access.redhat.com/ubi8/ubi:latest .github/scripts/run-fips-ut.sh
run: docker run --rm --workdir /github/workspace -v "${{ github.workspace }}":"/github/workspace" -v "$HOME/.m2":"/root/.m2" registry.access.redhat.com/ubi9/ubi:latest .github/scripts/run-fips-ut.sh
fips-integration-tests:
name: FIPS IT
@@ -1002,7 +1002,7 @@ jobs:
sudo insmod fake_fips.ko
- name: Run base tests
run: docker run --rm --workdir /github/workspace -e "SUREFIRE_RERUN_FAILING_COUNT" -v "${{ github.workspace }}":"/github/workspace" -v "$HOME/.m2":"/root/.m2" registry.access.redhat.com/ubi8/ubi:latest .github/scripts/run-fips-it.sh ${{ matrix.mode }}
run: docker run --rm --workdir /github/workspace -e "SUREFIRE_RERUN_FAILING_COUNT" -v "${{ github.workspace }}":"/github/workspace" -v "$HOME/.m2":"/root/.m2" registry.access.redhat.com/ubi9/ubi:latest .github/scripts/run-fips-it.sh ${{ matrix.mode }}
- uses: ./.github/actions/upload-flaky-tests
name: Upload flaky tests
@@ -1,12 +1,14 @@
package org.keycloak.crypto.fips;
import java.io.IOException;
import java.lang.reflect.Method;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
@@ -34,6 +36,7 @@ import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
@@ -75,6 +78,9 @@ import org.jboss.logging.Logger;
public class FIPS1402Provider implements CryptoProvider {
private static final Logger log = Logger.getLogger(FIPS1402Provider.class);
private static final String FIPS_FILE = "/proc/sys/crypto/fips_enabled";
// The fips provider is different in 21 and 25
private static final String PKCS11_FIPS_NAME = "SunPKCS11(-NSS)?-FIPS";
private final BouncyCastleFipsProvider bcFipsProvider;
private final Map<String, Object> providers = new ConcurrentHashMap<>();
@@ -94,19 +100,19 @@ public class FIPS1402Provider implements CryptoProvider {
providers.put(CryptoConstants.ECDH_ES_A256KW, new BCFIPSEcdhEsAlgorithmProvider());
if (existingBcFipsProvider == null) {
final String isSystemFipsEnabled = isSystemFipsEnabled();
checkSecureRandom(() -> Security.insertProviderAt(this.bcFipsProvider, 1));
Provider bcJsseProvider = new BouncyCastleJsseProvider("fips:BCFIPS");
Security.insertProviderAt(bcJsseProvider, 2);
// force the key and trust manager factories if default values not present in BCJSSE
modifyKeyTrustManagerSecurityProperties(bcJsseProvider);
log.infof("FIPS1402Provider created: KC(%s%s, FIPS-JVM: %s)", bcFipsProvider,
CryptoServicesRegistrar.isInApprovedOnlyMode() ? " Approved Mode" : "",
isSystemFipsEnabled);
log.debugf("Inserted security providers: %s", Arrays.asList(this.bcFipsProvider.getName(),bcJsseProvider.getName()));
} else {
log.debugf("Security provider %s already loaded", existingBcFipsProvider.getName());
}
log.infof("FIPS1402Provider created: KC(%s%s, FIPS-JVM: %s)", bcFipsProvider,
CryptoServicesRegistrar.isInApprovedOnlyMode() ? " Approved Mode" : "",
isSystemFipsEnabled());
}
@@ -395,21 +401,14 @@ public class FIPS1402Provider implements CryptoProvider {
}
public static String isSystemFipsEnabled() {
Method isSystemFipsEnabled = null;
try {
Class<?> securityConfigurator = FIPS1402Provider.class.getClassLoader().loadClass("java.security.SystemConfigurator");
isSystemFipsEnabled = securityConfigurator.getDeclaredMethod("isSystemFipsEnabled");
isSystemFipsEnabled.setAccessible(true);
boolean isEnabled = (boolean) isSystemFipsEnabled.invoke(null);
return isEnabled ? "enabled" : "disabled";
// java 25 does not have any class and checks directly the file
// check kernel file is 1 and the first security provider is the FIPS one
try (InputStream is = Files.newInputStream(Paths.get(FIPS_FILE))) {
final String name = Security.getProviders()[0].getName();
return is.read() == '1' && Pattern.matches(PKCS11_FIPS_NAME, name) ? "enabled" : "disabled";
} catch (Throwable ignore) {
log.debug("Could not detect if FIPS is enabled from the host", ignore);
return "unknown";
} finally {
if (isSystemFipsEnabled != null) {
isSystemFipsEnabled.setAccessible(false);
}
}
}
}
@@ -125,4 +125,4 @@ FISH_COMPLETION
exit 0
fi
exec "$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 "$@"
exec "$JAVA" $KC_OPTS -cp $DIRNAME/client/keycloak-admin-cli-${project.version}.jar --add-opens=java.base/java.security=ALL-UNNAMED --enable-native-access=ALL-UNNAMED -Dkc.lib.dir=$DIRNAME/client/lib org.keycloak.client.admin.cli.KcAdmMain "$@"
@@ -27,4 +27,4 @@ if [ -z "$JAVA" ]; then
fi
DIRNAME="$(dirname "$RESOLVED_NAME")"
exec "$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.registration.cli.KcRegMain "$@"
exec "$JAVA" $KC_OPTS -cp $DIRNAME/client/keycloak-admin-cli-${project.version}.jar --add-opens=java.base/java.security=ALL-UNNAMED --enable-native-access=ALL-UNNAMED -Dkc.lib.dir=$DIRNAME/client/lib org.keycloak.client.registration.cli.KcRegMain "$@"
@@ -32,7 +32,4 @@ KcSamlSignedBrokerTest
KcSamlSpDescriptorTest
KerberosLdapTest
TrustStoreEmailTest
OID4VCJWTIssuerEndpointTest
OID4VCSdJwtIssuingEndpointTest
OID4VCJwtAuthorizationCodeFlowTest
OID4VCSdJwtAuthorizationCodeFlowTest