Make https-trust-store-type set to bcfks by default in strict-mode
Closes #17119
This commit is contained in:
parent
e76418e3de
commit
4f068fcdcc
20 changed files with 72 additions and 50 deletions
|
@ -80,7 +80,6 @@ public class CryptoIntegration {
|
|||
.append(" Default keystore type: " + KeyStore.getDefaultType() + "\n")
|
||||
.append(" KeyManagerFactory.getDefaultAlgorithm(): " + KeyManagerFactory.getDefaultAlgorithm() + "\n")
|
||||
.append(" TrustManagerFactory.getDefaultAlgorithm(): " + TrustManagerFactory.getDefaultAlgorithm() + "\n")
|
||||
.append(" Default keystore type: " + KeyStore.getDefaultType() + "\n")
|
||||
.append(" keystore.type.compat: " + Security.getProperty("keystore.type.compat") + "\n");
|
||||
Stream.of("javax.net.ssl.trustStoreType", "javax.net.ssl.trustStore", "javax.net.ssl.trustStoreProvider",
|
||||
"javax.net.ssl.keyStoreType", "javax.net.ssl.keyStore", "javax.net.ssl.keyStoreProvider")
|
||||
|
|
|
@ -23,7 +23,7 @@ public class KeycloakFipsSecurityProvider extends Provider {
|
|||
super("KC(" +
|
||||
bcFipsProvider.toString() +
|
||||
(isInApprovedOnlyMode() ? " Approved Mode" : "") +
|
||||
(isSystemFipsEnabled() ? " FIPS-enabled JVM" : "") +
|
||||
", FIPS-JVM: " + isSystemFipsEnabled() +
|
||||
")", 1, "Keycloak pseudo provider");
|
||||
this.bcFipsProvider = bcFipsProvider;
|
||||
}
|
||||
|
@ -39,22 +39,22 @@ public class KeycloakFipsSecurityProvider extends Provider {
|
|||
}
|
||||
}
|
||||
|
||||
private static boolean isSystemFipsEnabled() {
|
||||
public static String isSystemFipsEnabled() {
|
||||
Method isSystemFipsEnabled = null;
|
||||
|
||||
try {
|
||||
Class<?> securityConfigurator = KeycloakFipsSecurityProvider.class.getClassLoader().loadClass("java.security.SystemConfigurator");
|
||||
isSystemFipsEnabled = securityConfigurator.getDeclaredMethod("isSystemFipsEnabled");
|
||||
isSystemFipsEnabled.setAccessible(true);
|
||||
return (boolean) isSystemFipsEnabled.invoke(null);
|
||||
boolean isEnabled = (boolean) isSystemFipsEnabled.invoke(null);
|
||||
return isEnabled ? "enabled" : "disabled";
|
||||
} catch (Throwable ignore) {
|
||||
logger.debug("Could not detect if FIPS is enabled from the host");
|
||||
logger.debug("Could not detect if FIPS is enabled from the host", ignore);
|
||||
return "unknown";
|
||||
} finally {
|
||||
if (isSystemFipsEnabled != null) {
|
||||
isSystemFipsEnabled.setAccessible(false);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,10 +97,11 @@ public class HttpOptions {
|
|||
.description("The password of the trust store file.")
|
||||
.build();
|
||||
|
||||
public static final Option HTTPS_TRUST_STORE_TYPE = new OptionBuilder<>("https-trust-store-type", File.class)
|
||||
public static final Option<String> HTTPS_TRUST_STORE_TYPE = new OptionBuilder<>("https-trust-store-type", String.class)
|
||||
.category(OptionCategory.HTTP)
|
||||
.description("The type of the trust store file. " +
|
||||
"If not given, the type is automatically detected based on the file name.")
|
||||
"If not given, the type is automatically detected based on the file name. " +
|
||||
"If '" + SecurityOptions.FIPS_MODE.getKey() + "' is set to '" + FipsMode.strict.name() + "' and no value is set, it defaults to 'BCFKS'.")
|
||||
.build();
|
||||
|
||||
public static final Option<Boolean> HTTP_SERVER_ENABLED = new OptionBuilder<>("http-server-enabled", Boolean.class)
|
||||
|
|
|
@ -98,6 +98,8 @@ final class HttpPropertyMappers {
|
|||
.build(),
|
||||
fromOption(HttpOptions.HTTPS_TRUST_STORE_TYPE)
|
||||
.to("quarkus.http.ssl.certificate.trust-store-file-type")
|
||||
.mapFrom(SecurityOptions.FIPS_MODE.getKey())
|
||||
.transformer(HttpPropertyMappers::resolveKeyStoreType)
|
||||
.paramLabel("type")
|
||||
.build()
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.it.cli.dist;
|
|||
|
||||
import java.nio.file.Path;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.crypto.fips.KeycloakFipsSecurityProvider;
|
||||
import org.keycloak.it.junit5.extension.CLIResult;
|
||||
import org.keycloak.it.junit5.extension.DistributionTest;
|
||||
import org.keycloak.it.junit5.extension.RawDistOnly;
|
||||
|
@ -38,7 +39,7 @@ public class FipsDistTest {
|
|||
CLIResult cliResult = dist.run("start", "--fips-mode=enabled");
|
||||
cliResult.assertStarted();
|
||||
cliResult.assertMessage("Java security providers: [ \n"
|
||||
+ " KC(BCFIPS version 1.000203) version 1.0 - class org.keycloak.crypto.fips.KeycloakFipsSecurityProvider");
|
||||
+ " KC(BCFIPS version 1.000203, FIPS-JVM: " + KeycloakFipsSecurityProvider.isSystemFipsEnabled() + ") version 1.0 - class org.keycloak.crypto.fips.KeycloakFipsSecurityProvider");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -53,7 +54,7 @@ public class FipsDistTest {
|
|||
cliResult.assertMessage(
|
||||
"org.bouncycastle.crypto.fips.FipsUnapprovedOperationError: password must be at least 112 bits");
|
||||
cliResult.assertMessage("Java security providers: [ \n"
|
||||
+ " KC(BCFIPS version 1.000203 Approved Mode) version 1.0 - class org.keycloak.crypto.fips.KeycloakFipsSecurityProvider");
|
||||
+ " KC(BCFIPS version 1.000203 Approved Mode, FIPS-JVM: " + KeycloakFipsSecurityProvider.isSystemFipsEnabled() + ") version 1.0 - class org.keycloak.crypto.fips.KeycloakFipsSecurityProvider");
|
||||
|
||||
dist.setEnvVar("KEYCLOAK_ADMIN_PASSWORD", "adminadminadmin");
|
||||
cliResult = dist.run("start", "--fips-mode=strict");
|
||||
|
@ -87,6 +88,21 @@ public class FipsDistTest {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHttpsBcfksTrustStoreInStrictMode(KeycloakDistribution dist) {
|
||||
runOnFipsEnabledDistribution(dist, () -> {
|
||||
dist.copyOrReplaceFileFromClasspath("/server.keystore.bcfks", Path.of("conf", "server.keystore"));
|
||||
|
||||
RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class);
|
||||
Path truststorePath = rawDist.getDistPath().resolve("conf").resolve("server.keystore").toAbsolutePath();
|
||||
|
||||
// https-trust-store-type should be automatically set to bcfks in fips-mode=strict
|
||||
CLIResult cliResult = dist.run("--verbose", "start", "--fips-mode=strict", "--https-key-store-password=passwordpassword",
|
||||
"--https-trust-store-file=" + truststorePath, "--https-trust-store-password=passwordpassword");
|
||||
cliResult.assertStarted();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnsupportedHttpsPkcs12KeyStoreInStrictMode(KeycloakDistribution dist) {
|
||||
runOnFipsEnabledDistribution(dist, () -> {
|
||||
|
@ -105,6 +121,21 @@ public class FipsDistTest {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHttpsPkcs12TrustStoreInNonApprovedMode(KeycloakDistribution dist) {
|
||||
runOnFipsEnabledDistribution(dist, () -> {
|
||||
dist.copyOrReplaceFileFromClasspath("/server.keystore.pkcs12", Path.of("conf", "server.keystore"));
|
||||
|
||||
RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class);
|
||||
Path truststorePath = rawDist.getDistPath().resolve("conf").resolve("server.keystore").toAbsolutePath();
|
||||
|
||||
// https-trust-store-type should be automatically set to pkcs12 in fips-mode=enabled
|
||||
CLIResult cliResult = dist.run("--verbose", "start", "--fips-mode=enabled", "--https-key-store-password=passwordpassword",
|
||||
"--https-trust-store-file=" + truststorePath, "--https-trust-store-password=passwordpassword");
|
||||
cliResult.assertStarted();
|
||||
});
|
||||
}
|
||||
|
||||
private void runOnFipsEnabledDistribution(KeycloakDistribution dist, Runnable runnable) {
|
||||
installBcFips(dist);
|
||||
runnable.run();
|
||||
|
|
|
@ -143,7 +143,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Health:
|
||||
|
||||
|
|
|
@ -143,7 +143,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Health:
|
||||
|
||||
|
|
|
@ -203,7 +203,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Health:
|
||||
|
||||
|
|
|
@ -203,7 +203,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Health:
|
||||
|
||||
|
|
|
@ -149,7 +149,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Health:
|
||||
|
||||
|
|
|
@ -149,7 +149,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Health:
|
||||
|
||||
|
|
|
@ -209,7 +209,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Health:
|
||||
|
||||
|
|
|
@ -209,7 +209,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Health:
|
||||
|
||||
|
|
|
@ -108,7 +108,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Proxy:
|
||||
|
||||
|
|
|
@ -108,7 +108,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Proxy:
|
||||
|
||||
|
|
|
@ -127,7 +127,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Proxy:
|
||||
|
||||
|
|
|
@ -127,7 +127,8 @@ HTTP/TLS:
|
|||
The password of the trust store file.
|
||||
--https-trust-store-type <type>
|
||||
The type of the trust store file. If not given, the type is automatically
|
||||
detected based on the file name.
|
||||
detected based on the file name. If 'fips-mode' is set to 'strict' and no
|
||||
value is set, it defaults to 'BCFKS'.
|
||||
|
||||
Proxy:
|
||||
|
||||
|
|
|
@ -979,5 +979,5 @@ For running testsuite with server using BCFIPS approved mode, those additional p
|
|||
```
|
||||
The log should contain `KeycloakFipsSecurityProvider` mentioning "Approved mode". Something like:
|
||||
```
|
||||
KC(BCFIPS version 1.000203 Approved Mode) version 1.0 - class org.keycloak.crypto.fips.KeycloakFipsSecurityProvider,
|
||||
KC(BCFIPS version 1.000203 Approved Mode, FIPS-JVM: enabled) version 1.0 - class org.keycloak.crypto.fips.KeycloakFipsSecurityProvider,
|
||||
```
|
||||
|
|
|
@ -327,18 +327,15 @@ public abstract class AbstractQuarkusDeployableContainer implements DeployableCo
|
|||
private void addFipsOptions(List<String> commands) {
|
||||
commands.add("--fips-mode=" + configuration.getFipsMode().toString());
|
||||
|
||||
log.debugf("Keystore file: %s, keystore type: %s, truststore file: %s, truststore type: %s",
|
||||
configuration.getKeystoreFile(), configuration.getKeystoreType(),
|
||||
configuration.getTruststoreFile(), configuration.getTruststoreType());
|
||||
log.debugf("Keystore file: %s, truststore file: %s",
|
||||
configuration.getKeystoreFile(),
|
||||
configuration.getTruststoreFile());
|
||||
commands.add("--https-key-store-file=" + configuration.getKeystoreFile());
|
||||
commands.add("--https-key-store-type=" + configuration.getKeystoreType());
|
||||
commands.add("--https-key-store-password=" + configuration.getKeystorePassword());
|
||||
commands.add("--https-trust-store-file=" + configuration.getTruststoreFile());
|
||||
commands.add("--https-trust-store-type=" + configuration.getTruststoreType());
|
||||
commands.add("--https-trust-store-password=" + configuration.getTruststorePassword());
|
||||
commands.add("--spi-truststore-file-file=" + configuration.getTruststoreFile());
|
||||
commands.add("--spi-truststore-file-password=" + configuration.getTruststorePassword());
|
||||
commands.add("--spi-truststore-file-type=" + configuration.getTruststoreType());
|
||||
|
||||
// BCFIPS approved mode requires passwords of at least 112 bits (14 characters) to be used. To bypass this, we use this by default
|
||||
// as testsuite uses shorter passwords everywhere
|
||||
|
|
|
@ -29,15 +29,11 @@ public class KeycloakQuarkusConfiguration implements ContainerConfiguration {
|
|||
|
||||
private String keystorePassword = System.getProperty("auth.server.keystore.password");
|
||||
|
||||
private String keystoreType = System.getProperty("auth.server.keystore.type");
|
||||
|
||||
|
||||
private String truststoreFile = System.getProperty("auth.server.truststore");
|
||||
|
||||
private String truststorePassword = System.getProperty("auth.server.truststore.password");
|
||||
|
||||
private String truststoreType = System.getProperty("auth.server.truststore.type");
|
||||
|
||||
private int debugPort = -1;
|
||||
private Path providersPath = Paths.get(System.getProperty("auth.server.home"));
|
||||
private int startupTimeoutInSeconds = 300;
|
||||
|
@ -121,14 +117,6 @@ public class KeycloakQuarkusConfiguration implements ContainerConfiguration {
|
|||
this.keystorePassword = keystorePassword;
|
||||
}
|
||||
|
||||
public String getKeystoreType() {
|
||||
return keystoreType;
|
||||
}
|
||||
|
||||
public void setKeystoreType(String keystoreType) {
|
||||
this.keystoreType = keystoreType;
|
||||
}
|
||||
|
||||
public String getTruststoreFile() {
|
||||
return truststoreFile;
|
||||
}
|
||||
|
@ -145,14 +133,6 @@ public class KeycloakQuarkusConfiguration implements ContainerConfiguration {
|
|||
this.truststorePassword = truststorePassword;
|
||||
}
|
||||
|
||||
public String getTruststoreType() {
|
||||
return truststoreType;
|
||||
}
|
||||
|
||||
public void setTruststoreType(String truststoreType) {
|
||||
this.truststoreType = truststoreType;
|
||||
}
|
||||
|
||||
public Path getProvidersPath() {
|
||||
return providersPath;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue