Only available RSA key sizes should be shown in admin console
Closes #16437
This commit is contained in:
parent
29888dbf1a
commit
16888eaeab
9 changed files with 58 additions and 19 deletions
|
@ -15,7 +15,6 @@ import java.security.cert.CertificateException;
|
|||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.CollectionCertStoreParameters;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
@ -124,4 +123,11 @@ public interface CryptoProvider {
|
|||
* @return decorated factory
|
||||
*/
|
||||
SSLSocketFactory wrapFactoryForTruststore(SSLSocketFactory delegate);
|
||||
|
||||
/**
|
||||
* @return Allowed key sizes of RSA key modulus, which this cryptoProvider supports
|
||||
*/
|
||||
default String[] getSupportedRsaKeySizes() {
|
||||
return new String[] {"1024", "2048", "4096"};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,4 +14,10 @@ public class Fips1402StrictCryptoProvider extends FIPS1402Provider {
|
|||
static {
|
||||
System.setProperty("org.bouncycastle.fips.approved_only", Boolean.TRUE.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSupportedRsaKeySizes() {
|
||||
// RSA key of 1024 bits not supported in BCFIPS approved mode
|
||||
return new String[] {"2048", "4096"};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ public abstract class AbstractGeneratedRsaKeyProviderFactory extends AbstractRsa
|
|||
public void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel model) throws ComponentValidationException {
|
||||
super.validateConfiguration(session, realm, model);
|
||||
|
||||
ConfigurationValidationHelper.check(model).checkList(Attributes.KEY_SIZE_PROPERTY, false);
|
||||
ConfigurationValidationHelper.check(model).checkList(Attributes.KEY_SIZE_PROPERTY.get(), false);
|
||||
|
||||
int size = model.get(Attributes.KEY_SIZE_KEY, 2048);
|
||||
|
||||
|
@ -103,6 +103,10 @@ public abstract class AbstractGeneratedRsaKeyProviderFactory extends AbstractRsa
|
|||
keyPair = KeyUtils.generateRsaKeyPair(size);
|
||||
model.put(Attributes.PRIVATE_KEY_KEY, PemUtils.encodeKey(keyPair.getPrivate()));
|
||||
} catch (Throwable t) {
|
||||
getLogger().warnf("Failed to generate keys for key provider '%s' in realm '%s'. Details: %s", model.getName(), realm.getName(), t.getMessage());
|
||||
if (getLogger().isDebugEnabled()) {
|
||||
getLogger().debug(t.getMessage(), t);
|
||||
}
|
||||
throw new ComponentValidationException("Failed to generate keys", t);
|
||||
}
|
||||
|
||||
|
@ -114,6 +118,10 @@ public abstract class AbstractGeneratedRsaKeyProviderFactory extends AbstractRsa
|
|||
Certificate certificate = CertificateUtils.generateV1SelfSignedCertificate(keyPair, realm.getName());
|
||||
model.put(Attributes.CERTIFICATE_KEY, PemUtils.encodeCertificate(certificate));
|
||||
} catch (Throwable t) {
|
||||
getLogger().warnf("Failed to generate certificate for key provider '%s' in realm '%s'. Details: %s", model.getName(), realm.getName(), t.getMessage());
|
||||
if (getLogger().isDebugEnabled()) {
|
||||
getLogger().debug(t.getMessage(), t);
|
||||
}
|
||||
throw new ComponentValidationException("Failed to generate certificate", t);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
package org.keycloak.keys;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.keycloak.common.crypto.CryptoIntegration;
|
||||
import org.keycloak.crypto.Algorithm;
|
||||
import org.keycloak.crypto.KeyUse;
|
||||
import org.keycloak.jose.jwe.JWEConstants;
|
||||
|
@ -45,7 +48,8 @@ public interface Attributes {
|
|||
ProviderConfigProperty CERTIFICATE_PROPERTY = new ProviderConfigProperty(CERTIFICATE_KEY, "X509 Certificate", "X509 Certificate encoded in PEM format", FILE_TYPE, null);
|
||||
|
||||
String KEY_SIZE_KEY = "keySize";
|
||||
ProviderConfigProperty KEY_SIZE_PROPERTY = new ProviderConfigProperty(KEY_SIZE_KEY, "Key size", "Size for the generated keys", LIST_TYPE, "2048", "1024", "2048", "4096");
|
||||
Supplier<ProviderConfigProperty> KEY_SIZE_PROPERTY = () -> new ProviderConfigProperty(KEY_SIZE_KEY, "Key size", "Size for the generated keys", LIST_TYPE, "2048",
|
||||
CryptoIntegration.getProvider().getSupportedRsaKeySizes());
|
||||
|
||||
String KEY_USE = "keyUse";
|
||||
ProviderConfigProperty KEY_USE_PROPERTY = new ProviderConfigProperty(KEY_USE, "Key use", "Whether the key should be used for signing or encryption.", LIST_TYPE,
|
||||
|
|
|
@ -37,11 +37,6 @@ public class GeneratedRsaEncKeyProviderFactory extends AbstractGeneratedRsaKeyPr
|
|||
|
||||
private static final String HELP_TEXT = "Generates RSA keys for key encryption and creates a self-signed certificate";
|
||||
|
||||
private static final List<ProviderConfigProperty> CONFIG_PROPERTIES = AbstractGeneratedRsaKeyProviderFactory.rsaKeyConfigurationBuilder()
|
||||
.property(Attributes.KEY_SIZE_PROPERTY)
|
||||
.property(Attributes.RS_ENC_ALGORITHM_PROPERTY)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public KeyProvider create(KeycloakSession session, ComponentModel model) {
|
||||
model.put(Attributes.KEY_USE, KeyUse.ENC.name());
|
||||
|
@ -55,7 +50,10 @@ public class GeneratedRsaEncKeyProviderFactory extends AbstractGeneratedRsaKeyPr
|
|||
|
||||
@Override
|
||||
public List<ProviderConfigProperty> getConfigProperties() {
|
||||
return CONFIG_PROPERTIES;
|
||||
return AbstractGeneratedRsaKeyProviderFactory.rsaKeyConfigurationBuilder()
|
||||
.property(Attributes.KEY_SIZE_PROPERTY.get())
|
||||
.property(Attributes.RS_ENC_ALGORITHM_PROPERTY)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,11 +37,6 @@ public class GeneratedRsaKeyProviderFactory extends AbstractGeneratedRsaKeyProvi
|
|||
|
||||
private static final String HELP_TEXT = "Generates RSA signature keys and creates a self-signed certificate";
|
||||
|
||||
private static final List<ProviderConfigProperty> CONFIG_PROPERTIES = AbstractGeneratedRsaKeyProviderFactory.rsaKeyConfigurationBuilder()
|
||||
.property(Attributes.KEY_SIZE_PROPERTY)
|
||||
.property(Attributes.RS_ALGORITHM_PROPERTY)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public KeyProvider create(KeycloakSession session, ComponentModel model) {
|
||||
if (model.getConfig().get(Attributes.KEY_USE) == null) {
|
||||
|
@ -58,7 +53,10 @@ public class GeneratedRsaKeyProviderFactory extends AbstractGeneratedRsaKeyProvi
|
|||
|
||||
@Override
|
||||
public List<ProviderConfigProperty> getConfigProperties() {
|
||||
return CONFIG_PROPERTIES;
|
||||
return AbstractGeneratedRsaKeyProviderFactory.rsaKeyConfigurationBuilder()
|
||||
.property(Attributes.KEY_SIZE_PROPERTY.get())
|
||||
.property(Attributes.RS_ALGORITHM_PROPERTY)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -992,6 +992,7 @@ For running testsuite with server using BCFIPS approved mode, those additional p
|
|||
-Dauth.server.fips.mode=strict \
|
||||
-Dauth.server.supported.keystore.types=BCFKS \
|
||||
-Dauth.server.keystore.type=bcfks
|
||||
-Dauth.server.supported.rsa.key.sizes=2048,4096
|
||||
```
|
||||
The log should contain `KeycloakFipsSecurityProvider` mentioning "Approved mode". Something like:
|
||||
```
|
||||
|
|
|
@ -19,11 +19,17 @@ package org.keycloak.testsuite.admin;
|
|||
|
||||
import org.junit.Test;
|
||||
import org.keycloak.common.Version;
|
||||
import org.keycloak.keys.Attributes;
|
||||
import org.keycloak.keys.GeneratedRsaKeyProviderFactory;
|
||||
import org.keycloak.keys.KeyProvider;
|
||||
import org.keycloak.representations.idm.ComponentTypeRepresentation;
|
||||
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.info.ProviderRepresentation;
|
||||
import org.keycloak.representations.info.ServerInfoRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.util.KeystoreUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -59,11 +65,21 @@ public class ServerInfoTest extends AbstractKeycloakTest {
|
|||
assertNotNull(info.getMemoryInfo());
|
||||
assertNotNull(info.getSystemInfo());
|
||||
assertNotNull(info.getCryptoInfo());
|
||||
String expectedSupportedKeystoreTypes = System.getProperty("auth.server.supported.keystore.types");
|
||||
if (expectedSupportedKeystoreTypes == null) {
|
||||
fail("Property 'auth.server.supported.keystore.types' not set");
|
||||
Assert.assertNames(info.getCryptoInfo().getSupportedKeystoreTypes(), KeystoreUtils.getSupportedKeystoreTypes());
|
||||
|
||||
String expectedSupportedRsaKeySizes = System.getProperty("auth.server.supported.rsa.key.sizes");
|
||||
if (expectedSupportedRsaKeySizes == null || expectedSupportedRsaKeySizes.trim().isEmpty()) {
|
||||
fail("Property 'auth.server.supported.rsa.key.sizes' not set");
|
||||
}
|
||||
Assert.assertNames(info.getCryptoInfo().getSupportedKeystoreTypes(), expectedSupportedKeystoreTypes.split(","));
|
||||
ComponentTypeRepresentation rsaGeneratedProviderInfo = info.getComponentTypes().get(KeyProvider.class.getName())
|
||||
.stream()
|
||||
.filter(componentType -> GeneratedRsaKeyProviderFactory.ID.equals(componentType.getId()))
|
||||
.findFirst().orElseThrow(() -> new RuntimeException("Not found provider with ID 'rsa-generated'"));
|
||||
ConfigPropertyRepresentation keySizeRep = rsaGeneratedProviderInfo.getProperties()
|
||||
.stream()
|
||||
.filter(configProp -> Attributes.KEY_SIZE_KEY.equals(configProp.getName()))
|
||||
.findFirst().orElseThrow(() -> new RuntimeException("Not found provider with ID 'rsa-generated'"));
|
||||
Assert.assertNames(keySizeRep.getOptions(), expectedSupportedRsaKeySizes.split(","));
|
||||
|
||||
assertEquals(Version.VERSION, info.getSystemInfo().getVersion());
|
||||
assertNotNull(info.getSystemInfo().getServerTime());
|
||||
|
|
|
@ -265,6 +265,7 @@
|
|||
<auth.server.quarkus.cluster.config>local</auth.server.quarkus.cluster.config>
|
||||
<auth.server.fips.mode>disabled</auth.server.fips.mode>
|
||||
<auth.server.supported.keystore.types>JKS,PKCS12,BCFKS</auth.server.supported.keystore.types>
|
||||
<auth.server.supported.rsa.key.sizes>1024,2048,4096</auth.server.supported.rsa.key.sizes>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
@ -690,6 +691,7 @@
|
|||
<auth.server.fips.mode>${auth.server.fips.mode}</auth.server.fips.mode>
|
||||
<auth.server.fips.keystore.type>${auth.server.fips.keystore.type}</auth.server.fips.keystore.type>
|
||||
<auth.server.supported.keystore.types>${auth.server.supported.keystore.types}</auth.server.supported.keystore.types>
|
||||
<auth.server.supported.rsa.key.sizes>${auth.server.supported.rsa.key.sizes}</auth.server.supported.rsa.key.sizes>
|
||||
|
||||
<!--
|
||||
~ Used for Wildfly Elytron 1.13.0.CR3+ RESTEasy client SSL truststore configuration.
|
||||
|
|
Loading…
Reference in a new issue