Check null for new keySize and validity parameters when generating certificates (#41984)

Closes #41906


(cherry picked from commit 0ff7d551dd)

Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
Ricardo Martin
2025-08-20 07:54:56 +02:00
committed by GitHub
parent 08de42a57d
commit da51e2213f
4 changed files with 34 additions and 18 deletions

View File

@@ -109,6 +109,9 @@ public final class KeycloakModelUtils {
public static final int MAX_CLIENT_LOOKUPS_DURING_ROLE_RESOLVE = 25;
public static final int DEFAULT_RSA_KEY_SIZE = 4096;
public static final int DEFAULT_CERTIFICATE_VALIDITY_YEARS = 3;
private KeycloakModelUtils() {
}
@@ -221,8 +224,8 @@ public final class KeycloakModelUtils {
public static CertificateRepresentation generateKeyPairCertificate(String subject) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, 3);
return generateKeyPairCertificate(subject, 4096, calendar);
calendar.add(Calendar.YEAR, DEFAULT_CERTIFICATE_VALIDITY_YEARS);
return generateKeyPairCertificate(subject, DEFAULT_RSA_KEY_SIZE, calendar);
}
public static CertificateRepresentation generateKeyPairCertificate(String subject, int keysize, Calendar endDate) {

View File

@@ -18,7 +18,6 @@
package org.keycloak.services.resources.admin;
import com.google.common.base.Strings;
import jakarta.ws.rs.QueryParam;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.extensions.Extension;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
@@ -342,15 +341,15 @@ public class ClientAttributeCertificateResource {
throw new ErrorResponseException("password-missing", "Need to specify a store password for jks generation and download", Response.Status.BAD_REQUEST);
}
CertificateRepresentation info;
if (config.getKeySize() <= 0 || config.getValidity() <= 0) {
info = KeycloakModelUtils.generateKeyPairCertificate(client.getClientId());
}
else {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, config.getValidity());
info = KeycloakModelUtils.generateKeyPairCertificate(client.getClientId(), config.getKeySize(), calendar);
}
int keySize = config.getKeySize() != null && config.getKeySize() > 0
? config.getKeySize()
: KeycloakModelUtils.DEFAULT_RSA_KEY_SIZE;
int validity = config.getValidity() != null && config.getValidity() > 0
? config.getValidity()
: KeycloakModelUtils.DEFAULT_CERTIFICATE_VALIDITY_YEARS;
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, validity);
CertificateRepresentation info = KeycloakModelUtils.generateKeyPairCertificate(client.getClientId(), keySize, calendar);
byte[] rtn = getKeystore(config, info.getPrivateKey(), info.getCertificate());
info.setPrivateKey(null);

View File

@@ -37,9 +37,11 @@ import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -62,6 +64,8 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
@@ -373,7 +377,7 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe
}
}
protected void testClientWithGeneratedKeys(String format) throws Exception {
protected void testClientWithGeneratedKeys(String format, Integer keySize, Integer validity) throws Exception {
ClientRepresentation client = app3;
UserRepresentation user = defaultUser;
final String keyAlias = "somekey";
@@ -389,8 +393,12 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe
keyStoreConfig.setKeyPassword(keyPassword);
keyStoreConfig.setStorePassword(storePassword);
keyStoreConfig.setKeyAlias(keyAlias);
keyStoreConfig.setKeySize(4096);
keyStoreConfig.setValidity(3);
if (keySize != null) {
keyStoreConfig.setKeySize(keySize);
}
if (validity != null) {
keyStoreConfig.setValidity(validity);
}
client = getClient(testRealm.getRealm(), client.getId()).toRepresentation();
final String certOld = client.getAttributes().get(JWTClientAuthenticator.CERTIFICATE_ATTR);
@@ -408,6 +416,12 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe
assertCertificate(client, certOld,
KeycloakModelUtils.getPemFromCertificate(x509Cert));
MatcherAssert.assertThat(x509Cert.getPublicKey(), Matchers.instanceOf(RSAKey.class));
Assert.assertEquals(keySize == null ? 4096 : keySize, ((RSAKey) x509Cert.getPublicKey()).getModulus().bitLength());
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, validity == null ? 3 : validity);
MatcherAssert.assertThat(x509Cert.getNotAfter().getTime(), Matchers.allOf(
Matchers.greaterThan(calendar.getTime().getTime() - 5000), Matchers.lessThan(calendar.getTime().getTime() + 5000)));
// Try to login with the new keys

View File

@@ -337,19 +337,19 @@ public class ClientAuthSignedJWTTest extends AbstractClientAuthSignedJWTTest {
@Test
public void testClientWithGeneratedKeysJKS() throws Exception {
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.JKS);
testClientWithGeneratedKeys("JKS");
testClientWithGeneratedKeys("JKS", null, null);
}
@Test
public void testClientWithGeneratedKeysPKCS12() throws Exception {
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.PKCS12);
testClientWithGeneratedKeys("PKCS12");
testClientWithGeneratedKeys("PKCS12", 2048, null);
}
@Test
public void testClientWithGeneratedKeysBCFKS() throws Exception {
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.BCFKS);
testClientWithGeneratedKeys(KeystoreFormat.BCFKS.toString());
testClientWithGeneratedKeys(KeystoreFormat.BCFKS.toString(), 3072, 5);
}
@Test