From 125124c2d92bbcedffdde3bdab4cebcf45c0cf15 Mon Sep 17 00:00:00 2001 From: mposolda Date: Wed, 11 Sep 2024 16:16:19 +0200 Subject: [PATCH] Error when deploying SAML application with the keys in PEM format inside keycloak-saml.xml closes #32817 Signed-off-by: mposolda --- adapters/saml/core/pom.xml | 10 +++ .../adapters/saml/config/PemUtils.java | 26 +++++-- .../adapters/saml/DeploymentBuilderTest.java | 47 ++++++++++++ .../src/test/resources/keystores/keystore.jks | Bin 0 -> 2852 bytes .../config/parsers/keycloak-saml-pem-keys.xml | 67 ++++++++++++++++++ .../employee-sig/WEB-INF/keycloak-saml.xml | 10 +-- 6 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 adapters/saml/core/src/test/java/org/keycloak/adapters/saml/DeploymentBuilderTest.java create mode 100755 adapters/saml/core/src/test/resources/keystores/keystore.jks create mode 100644 adapters/saml/core/src/test/resources/org/keycloak/adapters/saml/config/parsers/keycloak-saml-pem-keys.xml diff --git a/adapters/saml/core/pom.xml b/adapters/saml/core/pom.xml index ac557d8297..0abc994120 100755 --- a/adapters/saml/core/pom.xml +++ b/adapters/saml/core/pom.xml @@ -61,6 +61,16 @@ keycloak-common provided + + org.bouncycastle + bcprov-jdk18on + provided + + + org.bouncycastle + bcpkix-jdk18on + provided + org.jboss.logging jboss-logging diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/PemUtils.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/PemUtils.java index d60d1e3922..8b9b0f3cec 100644 --- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/PemUtils.java +++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/PemUtils.java @@ -26,15 +26,19 @@ import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; +import java.security.Provider; import java.security.PublicKey; +import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.jboss.logging.Logger; +import org.keycloak.common.crypto.CryptoConstants; import org.keycloak.common.util.Base64; -import org.keycloak.common.util.BouncyIntegration; import org.keycloak.common.util.PemException; /** @@ -42,6 +46,20 @@ import org.keycloak.common.util.PemException; */ public class PemUtils { + private static final Logger log = Logger.getLogger(PemUtils.class); + + static { + Provider existingBc = Security.getProvider(CryptoConstants.BC_PROVIDER_ID); + Provider bcProvider = existingBc == null ? new BouncyCastleProvider() : existingBc; + + if (existingBc == null) { + Security.addProvider(bcProvider); + log.debugv("Loaded {0} security provider", bcProvider.getClass().getName()); + } else { + log.debugv("Security provider {0} already loaded", bcProvider.getClass().getName()); + } + } + /** * Decode a X509 Certificate from a PEM string * @@ -124,12 +142,12 @@ public class PemUtils { private static PrivateKey decodePrivateKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(der); - KeyFactory kf = KeyFactory.getInstance("RSA", BouncyIntegration.PROVIDER); + KeyFactory kf = KeyFactory.getInstance("RSA", CryptoConstants.BC_PROVIDER_ID); return kf.generatePrivate(spec); } private static X509Certificate decodeCertificate(InputStream is) throws Exception { - CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyIntegration.PROVIDER); + CertificateFactory cf = CertificateFactory.getInstance("X.509", CryptoConstants.BC_PROVIDER_ID); X509Certificate cert = (X509Certificate) cf.generateCertificate(is); is.close(); return cert; @@ -138,7 +156,7 @@ public class PemUtils { private static PublicKey decodePublicKey(byte[] der, String type) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { X509EncodedKeySpec spec = new X509EncodedKeySpec(der); - KeyFactory kf = KeyFactory.getInstance("RSA", BouncyIntegration.PROVIDER); + KeyFactory kf = KeyFactory.getInstance("RSA", CryptoConstants.BC_PROVIDER_ID); return kf.generatePublic(spec); } } diff --git a/adapters/saml/core/src/test/java/org/keycloak/adapters/saml/DeploymentBuilderTest.java b/adapters/saml/core/src/test/java/org/keycloak/adapters/saml/DeploymentBuilderTest.java new file mode 100644 index 0000000000..993b71a11d --- /dev/null +++ b/adapters/saml/core/src/test/java/org/keycloak/adapters/saml/DeploymentBuilderTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2024 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. + * + */ + +package org.keycloak.adapters.saml; + +import java.io.InputStream; + +import org.junit.Assert; +import org.junit.Test; +import org.keycloak.adapters.saml.config.parsers.DeploymentBuilder; +import org.keycloak.adapters.saml.config.parsers.ResourceLoader; + +/** + * @author Marek Posolda + */ +public class DeploymentBuilderTest { + + @Test + public void testPropertiesBasedRoleMapper() throws Exception { + InputStream is = getClass().getResourceAsStream("config/parsers/keycloak-saml-pem-keys.xml"); + SamlDeployment deployment = new DeploymentBuilder().build(is, new ResourceLoader() { + @Override + public InputStream getResourceAsStream(String resource) { + return this.getClass().getClassLoader().getResourceAsStream(resource); + } + }); + Assert.assertNotNull(deployment); + Assert.assertNotNull(deployment.getSigningKeyPair().getPrivate()); + Assert.assertNotNull(deployment.getSigningKeyPair().getPublic()); + } +} diff --git a/adapters/saml/core/src/test/resources/keystores/keystore.jks b/adapters/saml/core/src/test/resources/keystores/keystore.jks new file mode 100755 index 0000000000000000000000000000000000000000..5554f13323d652911292acfdd81801563de7bbe5 GIT binary patch literal 2852 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 + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig/WEB-INF/keycloak-saml.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig/WEB-INF/keycloak-saml.xml index 6b63834cd3..9e053f7d04 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig/WEB-INF/keycloak-saml.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig/WEB-INF/keycloak-saml.xml @@ -25,10 +25,12 @@ forceAuthentication="false"> - - - - + + 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 +