From a5e5f4cf9c82f385ecf2c99fb72fb5a6e2757ec4 Mon Sep 17 00:00:00 2001 From: Stan Silvert Date: Tue, 1 Nov 2016 13:54:34 -0400 Subject: [PATCH 1/2] KEYCLOAK-3817: More detailed errors when loading keys from JKS --- .../keys/JavaKeystoreKeyProvider.java | 20 +++++++++++++++++-- .../keys/JavaKeystoreKeyProviderFactory.java | 5 ++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/services/src/main/java/org/keycloak/keys/JavaKeystoreKeyProvider.java b/services/src/main/java/org/keycloak/keys/JavaKeystoreKeyProvider.java index d7fa87544d..8c98bb4556 100644 --- a/services/src/main/java/org/keycloak/keys/JavaKeystoreKeyProvider.java +++ b/services/src/main/java/org/keycloak/keys/JavaKeystoreKeyProvider.java @@ -24,11 +24,17 @@ import org.keycloak.component.ComponentModel; import org.keycloak.models.RealmModel; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.security.KeyPair; import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; +import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; /** @@ -61,8 +67,18 @@ public class JavaKeystoreKeyProvider extends AbstractRsaKeyProvider { String kid = KeyUtils.createKeyId(keyPair.getPublic()); return new Keys(kid, keyPair, certificate); - } catch (Exception e) { - throw new RuntimeException("Failed to load keys", e); + } catch (KeyStoreException kse) { + throw new RuntimeException("KeyStore error on server. " + kse.getMessage(), kse); + } catch (FileNotFoundException fnfe) { + throw new RuntimeException("File not found on server. " + fnfe.getMessage(), fnfe); + } catch (IOException ioe) { + throw new RuntimeException("IO error on server. " + ioe.getMessage(), ioe); + } catch (NoSuchAlgorithmException nsae) { + throw new RuntimeException("Algorithm not available on server. " + nsae.getMessage(), nsae); + } catch (CertificateException ce) { + throw new RuntimeException("Certificate error on server. " + ce.getMessage(), ce); + } catch (UnrecoverableKeyException uke) { + throw new RuntimeException("Keystore on server can not be recovered. " + uke.getMessage(), uke); } } diff --git a/services/src/main/java/org/keycloak/keys/JavaKeystoreKeyProviderFactory.java b/services/src/main/java/org/keycloak/keys/JavaKeystoreKeyProviderFactory.java index 518d321783..cbc003e4e3 100644 --- a/services/src/main/java/org/keycloak/keys/JavaKeystoreKeyProviderFactory.java +++ b/services/src/main/java/org/keycloak/keys/JavaKeystoreKeyProviderFactory.java @@ -26,6 +26,7 @@ import org.keycloak.provider.ConfigurationValidationHelper; import org.keycloak.provider.ProviderConfigProperty; import java.util.List; +import org.jboss.logging.Logger; import static org.keycloak.provider.ProviderConfigProperty.STRING_TYPE; @@ -33,6 +34,7 @@ import static org.keycloak.provider.ProviderConfigProperty.STRING_TYPE; * @author Stian Thorgersen */ public class JavaKeystoreKeyProviderFactory extends AbstractRsaKeyProviderFactory { + private static final Logger logger = Logger.getLogger(JavaKeystoreKeyProviderFactory.class); public static final String ID = "java-keystore"; @@ -76,7 +78,8 @@ public class JavaKeystoreKeyProviderFactory extends AbstractRsaKeyProviderFactor new JavaKeystoreKeyProvider(session.getContext().getRealm(), model) .loadKeys(session.getContext().getRealm(), model); } catch (Throwable t) { - throw new ComponentValidationException("Failed to load keys", t); + logger.error("Failed to load keys.", t); + throw new ComponentValidationException("Failed to load keys. " + t.getMessage(), t); } } From 1b8947245112db16952020a0e4b1042def9b2e5e Mon Sep 17 00:00:00 2001 From: Stan Silvert Date: Wed, 2 Nov 2016 14:21:54 -0400 Subject: [PATCH 2/2] KEYCLOAK-3817: Fix tests --- .../testsuite/keys/JavaKeystoreKeyProviderTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/JavaKeystoreKeyProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/JavaKeystoreKeyProviderTest.java index cac8a27b31..5c54213aab 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/JavaKeystoreKeyProviderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/JavaKeystoreKeyProviderTest.java @@ -123,7 +123,7 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle("keystore", "/nosuchfile"); Response response = adminClient.realm("test").components().add(rep); - assertErrror(response, "Failed to load keys"); + assertErrror(response, "Failed to load keys. File not found on server."); } @Test @@ -132,7 +132,7 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle("keystore", "invalid"); Response response = adminClient.realm("test").components().add(rep); - assertErrror(response, "Failed to load keys"); + assertErrror(response, "Failed to load keys. File not found on server."); } @Test @@ -141,7 +141,7 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle("keyAlias", "invalid"); Response response = adminClient.realm("test").components().add(rep); - assertErrror(response, "Failed to load keys"); + assertErrror(response, "Failed to load keys. Error creating X509v1Certificate."); } @Test @@ -150,7 +150,7 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle("keyPassword", "invalid"); Response response = adminClient.realm("test").components().add(rep); - assertErrror(response, "Failed to load keys"); + assertErrror(response, "Failed to load keys. Keystore on server can not be recovered."); } protected void assertErrror(Response response, String error) { @@ -159,7 +159,7 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { } ErrorRepresentation errorRepresentation = response.readEntity(ErrorRepresentation.class); - assertEquals(error, errorRepresentation.getErrorMessage()); + assertTrue(errorRepresentation.getErrorMessage().startsWith(error)); } protected ComponentRepresentation createRep(String name, long priority) {