Doublecheck if real FIPS host available in GH actions
Closes https://github.com/keycloak/keycloak/issues/15069
This commit is contained in:
parent
22e256149c
commit
5b626231d9
6 changed files with 142 additions and 15 deletions
6
.github/fake_fips/Makefile
vendored
Normal file
6
.github/fake_fips/Makefile
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
obj-m = fake_fips.o
|
||||
KVERSION = $(shell uname -r)
|
||||
all:
|
||||
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
|
||||
clean:
|
||||
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
|
72
.github/fake_fips/fake_fips.c
vendored
Normal file
72
.github/fake_fips/fake_fips.c
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* https://github.com/torvalds/linux/blob/master/crypto/fips.c
|
||||
* https://pointer-overloading.blogspot.com/2013/09/linux-creating-entry-in-proc-file.html
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sysctl.h>
|
||||
|
||||
int fips_enabled = 1;
|
||||
|
||||
static struct ctl_table crypto_sysctl_table[] = {
|
||||
{
|
||||
.procname = "fips_enabled",
|
||||
.data = &fips_enabled,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0444,
|
||||
.proc_handler = proc_dointvec
|
||||
},
|
||||
{}
|
||||
};
|
||||
static struct ctl_table crypto_dir_table[] = {
|
||||
{
|
||||
.procname = "crypto",
|
||||
.mode = 0555,
|
||||
.child = crypto_sysctl_table
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct ctl_table_header *crypto_sysctls;
|
||||
|
||||
static void crypto_proc_fips_init(void)
|
||||
{
|
||||
crypto_sysctls = register_sysctl_table(crypto_dir_table);
|
||||
}
|
||||
|
||||
static void crypto_proc_fips_exit(void)
|
||||
{
|
||||
unregister_sysctl_table(crypto_sysctls);
|
||||
}
|
||||
|
||||
static int __init fips_init(void)
|
||||
{
|
||||
crypto_proc_fips_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit fips_exit(void)
|
||||
{
|
||||
crypto_proc_fips_exit();
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
subsys_initcall(fips_init);
|
||||
module_exit(fips_exit);
|
17
.github/scripts/run-fips-it.sh
vendored
Executable file
17
.github/scripts/run-fips-it.sh
vendored
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
|
||||
dnf install -y java-17-openjdk-devel crypto-policies-scripts
|
||||
fips-mode-setup --enable --no-bootcfg
|
||||
fips-mode-setup --is-enabled
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
STRICT_OPTIONS=""
|
||||
if [ "$1" = "strict" ]; then
|
||||
STRICT_OPTIONS="-Dauth.server.fips.mode=strict -Dauth.server.supported.keystore.types=BCFKS -Dauth.server.keystore.type=bcfks -Dauth.server.supported.rsa.key.sizes=2048,4096"
|
||||
fi
|
||||
echo "STRICT_OPTIONS: $STRICT_OPTIONS"
|
||||
TESTS=`testsuite/integration-arquillian/tests/base/testsuites/suite.sh fips`
|
||||
echo "Tests: $TESTS"
|
||||
export JAVA_HOME=/etc/alternatives/java_sdk_17
|
||||
./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
|
15
.github/scripts/run-fips-ut.sh
vendored
Executable file
15
.github/scripts/run-fips-ut.sh
vendored
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
dnf install -y java-17-openjdk-devel crypto-policies-scripts
|
||||
fips-mode-setup --enable --no-bootcfg
|
||||
fips-mode-setup --is-enabled
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
echo "fips.provider.7=XMLDSig" >>/etc/alternatives/java_sdk_17/conf/security/java.security
|
||||
export JAVA_HOME=/etc/alternatives/java_sdk_17
|
||||
./mvnw test -nsu -B -am -pl crypto/default,crypto/fips1402 -Dcom.redhat.fips=true
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
./mvnw test -nsu -B -am -pl crypto/default,crypto/fips1402 -Dcom.redhat.fips=true -Dorg.bouncycastle.fips.approved_only=true
|
31
.github/workflows/ci.yml
vendored
31
.github/workflows/ci.yml
vendored
|
@ -390,15 +390,20 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Fake fips
|
||||
run: |
|
||||
cd .github/fake_fips
|
||||
make
|
||||
sudo insmod fake_fips.ko
|
||||
|
||||
- id: unit-test-setup
|
||||
name: Unit test setup
|
||||
uses: ./.github/actions/unit-test-setup
|
||||
with:
|
||||
jdk-version: 17
|
||||
|
||||
- name: Run crypto tests (BCFIPS non-approved mode)
|
||||
run: ./mvnw test -nsu -B -am -pl crypto/default,crypto/fips1402,crypto/elytron -Dcom.redhat.fips=true
|
||||
|
||||
- name: Run crypto tests (BCFIPS approved mode)
|
||||
run: ./mvnw test -nsu -B -am -pl crypto/default,crypto/fips1402,crypto/elytron -Dcom.redhat.fips=true -Dorg.bouncycastle.fips.approved_only=true
|
||||
- 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
|
||||
|
||||
- name: Upload JVM Heapdumps
|
||||
if: always()
|
||||
|
@ -424,21 +429,23 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Fake fips
|
||||
run: |
|
||||
cd .github/fake_fips
|
||||
make
|
||||
sudo insmod fake_fips.ko
|
||||
|
||||
- id: integration-test-setup
|
||||
name: Integration test setup
|
||||
uses: ./.github/actions/integration-test-setup
|
||||
with:
|
||||
jdk-version: 17
|
||||
|
||||
- name: Prepare Quarkus distribution with BCFIPS
|
||||
run: ./mvnw install -nsu -B -e -pl testsuite/integration-arquillian/servers/auth-server/quarkus -Pauth-server-quarkus,auth-server-fips140-2
|
||||
|
||||
- name: Run base tests
|
||||
run: |
|
||||
declare -A PARAMS
|
||||
PARAMS["non-strict"]=""
|
||||
PARAMS["strict"]="-Dauth.server.fips.mode=strict -Dauth.server.supported.keystore.types=BCFKS -Dauth.server.keystore.type=bcfks -Dauth.server.supported.rsa.key.sizes=2048,4096"
|
||||
TESTS=`testsuite/integration-arquillian/tests/base/testsuites/suite.sh fips`
|
||||
echo "Tests: $TESTS"
|
||||
./mvnw test -Dsurefire.rerunFailingTestsCount=${{ env.SUREFIRE_RERUN_FAILING_COUNT }} -nsu -B -Pauth-server-quarkus,auth-server-fips140-2 ${PARAMS["${{ matrix.mode }}"]} -Dtest=$TESTS -pl testsuite/integration-arquillian/tests/base | misc/log/trimmer.sh
|
||||
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 }}
|
||||
|
||||
- name: Upload JVM Heapdumps
|
||||
if: always()
|
||||
|
|
|
@ -11,13 +11,14 @@ import org.keycloak.common.profile.ProfileException;
|
|||
import org.keycloak.common.profile.PropertiesFileProfileConfigResolver;
|
||||
import org.keycloak.common.profile.PropertiesProfileConfigResolver;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -69,7 +70,12 @@ public class ProfileTest {
|
|||
}
|
||||
|
||||
Assert.assertEquals(Profile.ProfileName.DEFAULT, profile.getName());
|
||||
assertEquals(profile.getDisabledFeatures(), Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.DYNAMIC_SCOPES, Profile.Feature.DOCKER, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.MAP_STORAGE, Profile.Feature.DECLARATIVE_USER_PROFILE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL);
|
||||
Set<Profile.Feature> disabledFeatutes = new HashSet<>(Arrays.asList(Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.DYNAMIC_SCOPES, Profile.Feature.DOCKER, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.MAP_STORAGE, Profile.Feature.DECLARATIVE_USER_PROFILE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL));
|
||||
// KERBEROS can be disabled (i.e. FIPS mode disables SunJGSS provider)
|
||||
if (Profile.Feature.KERBEROS.getType() == Profile.Feature.Type.DISABLED_BY_DEFAULT) {
|
||||
disabledFeatutes.add(Profile.Feature.KERBEROS);
|
||||
}
|
||||
assertEquals(profile.getDisabledFeatures(), disabledFeatutes);
|
||||
assertEquals(profile.getPreviewFeatures(), Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.DECLARATIVE_USER_PROFILE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL);
|
||||
}
|
||||
|
||||
|
@ -226,8 +232,12 @@ public class ProfileTest {
|
|||
Assert.assertTrue(Profile.isFeatureEnabled(PREVIEW_FEATURE));
|
||||
}
|
||||
|
||||
public static void assertEquals(Set<Profile.Feature> actual, Collection<Profile.Feature> expected) {
|
||||
assertEquals(actual, expected.toArray(new Profile.Feature[0]));
|
||||
}
|
||||
|
||||
public static void assertEquals(Set<Profile.Feature> actual, Profile.Feature... expected) {
|
||||
Profile.Feature[] a = actual.toArray(new Profile.Feature[actual.size()]);
|
||||
Profile.Feature[] a = actual.toArray(new Profile.Feature[0]);
|
||||
Arrays.sort(a, new FeatureComparator());
|
||||
Arrays.sort(expected, new FeatureComparator());
|
||||
Assert.assertArrayEquals(a, expected);
|
||||
|
|
Loading…
Reference in a new issue