From f62bafa252e6e0dfaaa9ba4acbc34b47ee627e21 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Mon, 17 Feb 2020 17:54:04 +0100 Subject: update EaafKeyStoreFactory to get the Security Provider if the KeyStore depends on a special provider implementation --- .../core/impl/credential/EaafKeyStoreFactory.java | 35 ++++-- .../eaaf/core/impl/utils/HttpClientFactory.java | 29 ++--- .../test/credentials/EaafKeyStoreFactoryTest.java | 48 +++++--- .../modules/auth/sl20/utils/JsonSecurityUtils.java | 135 +++++++++++---------- .../impl/utils/AbstractCredentialProvider.java | 58 ++++----- 5 files changed, 167 insertions(+), 138 deletions(-) diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java index 5e6ca34b..5936e106 100644 --- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java @@ -2,10 +2,12 @@ package at.gv.egiz.eaaf.core.impl.credential; import java.io.IOException; import java.io.InputStream; +import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; +import java.security.Provider; import java.security.Security; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; @@ -15,11 +17,6 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.PostConstruct; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; - import at.asitplus.hsmfacade.provider.HsmFacadeProvider; import at.asitplus.hsmfacade.provider.RemoteKeyStoreLoadParameter; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; @@ -27,8 +24,15 @@ import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; import at.gv.egiz.eaaf.core.exceptions.EaafException; import at.gv.egiz.eaaf.core.exceptions.EaafFactoryException; import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; +import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.core.impl.utils.FileUtils; import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; + import lombok.extern.slf4j.Slf4j; @Slf4j @@ -64,10 +68,12 @@ public class EaafKeyStoreFactory { * Get a new KeyStore based on a KeyStore configuration-object. * * @param config KeyStore configuration - * @return new KeyStore instance + * @return {@link Pair} of a new KeyStore instance and an optional {@link Provider}. If the {@link Provider} + * is not null this {@link KeyStore} requires a specific {@link Provider} for {@link Key} operations. * @throws EaafException In case of a KeyStore initialization error */ - public KeyStore buildNewKeyStore(KeyStoreConfiguration config) throws EaafException { + @Nonnull + public Pair buildNewKeyStore(KeyStoreConfiguration config) throws EaafException { log.trace("Starting KeyStore generation based on configuration object ... "); if (KeyStoreType.PKCS12.equals(config.getKeyStoreType()) || KeyStoreType.JKS.equals(config.getKeyStoreType())) { @@ -127,7 +133,8 @@ public class EaafKeyStoreFactory { final HsmFacadeProvider provider = HsmFacadeProvider.Companion.getInstance(); provider.init(getHsmFacadeTrustSslCertificate(), clientUsername, clientPassword, hsmFacadeHost, port, hsmName); - Security.addProvider(provider); + //Security.addProvider(provider); + Security.insertProviderAt(provider, 0); isHsmFacadeInitialized = true; log.info("HSM Facade is initialized. {} can provide KeyStores based on remote HSM", EaafKeyStoreFactory.class.getSimpleName()); @@ -148,8 +155,9 @@ public class EaafKeyStoreFactory { } - private KeyStore getKeyStoreFromFileSystem(KeyStoreConfiguration config) throws EaafConfigurationException, - EaafFactoryException { + @Nonnull + private Pair getKeyStoreFromFileSystem(KeyStoreConfiguration config) + throws EaafConfigurationException, EaafFactoryException { try { final String keyStorePath = checkConfigurationParameter(config.getSoftKeyStoreFilePath(), ERRORCODE_06, config.getFriendlyName(), "Software-KeyStore missing filepath to KeyStore"); @@ -176,7 +184,7 @@ public class EaafKeyStoreFactory { } - return keyStore; + return Pair.newInstance(keyStore, null); } catch (KeyStoreException | IOException e) { log.error("Software KeyStore initialization FAILED with an generic error.", e); @@ -185,7 +193,8 @@ public class EaafKeyStoreFactory { } } - private KeyStore getKeyStoreFromHsmFacade(KeyStoreConfiguration config) + @Nonnull + private Pair getKeyStoreFromHsmFacade(KeyStoreConfiguration config) throws EaafFactoryException, EaafConfigurationException { final String keyStoreName = checkConfigurationParameter(config.getKeyStoreName(), ERRORCODE_06, config.getFriendlyName(), "KeyStoreName missing for HSM Facade"); @@ -193,7 +202,7 @@ public class EaafKeyStoreFactory { try { final KeyStore keyStore = KeyStore.getInstance(HSM_FACADE_KEYSTORE_TYPE, HSM_FACADE_PROVIDER); keyStore.load(new RemoteKeyStoreLoadParameter(keyStoreName)); - return keyStore; + return Pair.newInstance(keyStore, keyStore.getProvider()); } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException | NoSuchProviderException e) { diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java index ade0c28d..e681e705 100644 --- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java @@ -10,6 +10,13 @@ import javax.annotation.PostConstruct; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; + import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; @@ -38,12 +45,6 @@ import org.apache.http.ssl.SSLContexts; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ResourceLoader; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; -import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; -import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -51,10 +52,10 @@ public class HttpClientFactory implements IHttpClientFactory { @Autowired(required = true) private IConfiguration basicConfig; - + @Autowired(required = true) ResourceLoader resourceLoader; - + @Autowired private EaafKeyStoreFactory keyStoreFactory; public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE = @@ -79,7 +80,7 @@ public class HttpClientFactory implements IHttpClientFactory { "client.auth.ssl.keystore.path"; public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD = "client.auth.ssl.keystore.password"; - private static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_NAME = + private static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_NAME = "client.auth.ssl.keystore.name"; public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE = "client.auth.ssl.keystore.type"; @@ -269,18 +270,18 @@ public class HttpClientFactory implements IHttpClientFactory { .getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_NAME, StringUtils.EMPTY); try { - KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration(); + final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration(); keyStoreConfig.setKeyStoreType(keyStoreType); keyStoreConfig.setFriendlyName("HttpClient Keystore"); keyStoreConfig.setSoftKeyStoreFilePath(localKeyStorePath); keyStoreConfig.setSoftKeyStorePassword(keyStorePassword); keyStoreConfig.setKeyStoreName(keyStoreName); - + log.debug("Open keyStore with type: {}", keyStoreType); - KeyStore keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); - + final KeyStore keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig).getFirst(); + return keyStore; - + } catch (final EaafException e) { log.warn("Can NOT read keyStore: {} from filesystem", localKeyStorePath, null, e); throw new EaafConfigurationException("Can NOT read keyStore: {} from filesystem", diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EaafKeyStoreFactoryTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EaafKeyStoreFactoryTest.java index 01c3d6f1..5b6b8170 100644 --- a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EaafKeyStoreFactoryTest.java +++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EaafKeyStoreFactoryTest.java @@ -3,6 +3,7 @@ package at.gv.egiz.eaaf.core.test.credentials; import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; +import java.security.Provider; import java.security.cert.X509Certificate; import java.util.List; @@ -210,8 +211,10 @@ public class EaafKeyStoreFactoryTest { keyStoreConfig.setSoftKeyStoreFilePath(PATH_TO_SOFTWARE_KEYSTORE_JKS); keyStoreConfig.setSoftKeyStorePassword(SOFTWARE_KEYSTORE_PASSWORD); - final KeyStore keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); + final Pair keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); Assert.assertNotNull("KeyStore is null", keyStore); + Assert.assertNotNull("KeyStore is null", keyStore.getFirst()); + Assert.assertNull("KeyStore is null", keyStore.getSecond()); } @@ -274,8 +277,10 @@ public class EaafKeyStoreFactoryTest { keyStoreConfig.validate(); - final KeyStore keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); + final Pair keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); Assert.assertNotNull("KeyStore is null", keyStore); + Assert.assertNotNull("KeyStore is null", keyStore.getFirst()); + Assert.assertNull("KeyStore is null", keyStore.getSecond()); } @@ -292,24 +297,26 @@ public class EaafKeyStoreFactoryTest { keyStoreConfig.validate(); - final KeyStore keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); + final Pair keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); Assert.assertNotNull("KeyStore is null", keyStore); + Assert.assertNotNull("KeyStore is null", keyStore.getFirst()); + Assert.assertNull("KeyStore is null", keyStore.getSecond()); //read trusted certs - final List trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore(keyStore); + final List trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore(keyStore.getFirst()); Assert.assertNotNull("Trusted certs", trustedCerts); Assert.assertEquals("Trusted certs size", 2, trustedCerts.size()); //read priv. key final Pair privCred1 = EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore, "meta", "password".toCharArray(), true, "jUnit test"); + keyStore.getFirst(), "meta", "password".toCharArray(), true, "jUnit test"); Assert.assertNotNull("Credential 1", privCred1); Assert.assertNotNull("Credential 1 priv. key", privCred1.getFirst()); Assert.assertNotNull("Credential 1 certificate", privCred1.getSecond()); //read priv. key final Pair privCred2 = EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore, "sig", "password".toCharArray(), true, "jUnit test"); + keyStore.getFirst(), "sig", "password".toCharArray(), true, "jUnit test"); Assert.assertNotNull("Credential 2", privCred2); Assert.assertNotNull("Credential 2 priv. key", privCred2.getFirst()); Assert.assertNotNull("Credential 2 certificate", privCred2.getSecond()); @@ -317,17 +324,17 @@ public class EaafKeyStoreFactoryTest { //read priv. key final Pair privCred3 = EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore, "notexist", "password".toCharArray(), false, "jUnit test"); + keyStore.getFirst(), "notexist", "password".toCharArray(), false, "jUnit test"); Assert.assertNull("Credential 3", privCred3); //read priv. key final Pair privCred4 = EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore, "meta", "wrong".toCharArray(), false, "jUnit test"); + keyStore.getFirst(), "meta", "wrong".toCharArray(), false, "jUnit test"); Assert.assertNull("Credential 3", privCred4); try { EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore, "meta", "wrong".toCharArray(), true, "jUnit test"); + keyStore.getFirst(), "meta", "wrong".toCharArray(), true, "jUnit test"); Assert.fail("Wrong password not detected"); } catch (final EaafKeyAccessException e) { @@ -336,7 +343,7 @@ public class EaafKeyStoreFactoryTest { try { EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore, "wrong", "password".toCharArray(), true, "jUnit test"); + keyStore.getFirst(), "wrong", "password".toCharArray(), true, "jUnit test"); Assert.fail("Wrong alias not detected"); } catch (final EaafKeyAccessException e) { @@ -359,8 +366,10 @@ public class EaafKeyStoreFactoryTest { keyStoreConfig.validate(); - final KeyStore keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); + final Pair keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); Assert.assertNotNull("KeyStore is null", keyStore); + Assert.assertNotNull("KeyStore is null", keyStore.getFirst()); + Assert.assertNull("KeyStore is null", keyStore.getSecond()); } @@ -593,8 +602,10 @@ public class EaafKeyStoreFactoryTest { keyStoreConfig.validate(); try { - final KeyStore keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); + final Pair keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); Assert.assertNotNull("KeyStore is null", keyStore); + Assert.assertNotNull("KeyStore is null", keyStore.getFirst()); + Assert.assertNotNull("KeyStore is null", keyStore.getSecond()); } catch (final StatusRuntimeException e) { // because there is no mockup of HSM facade available @@ -618,31 +629,34 @@ public class EaafKeyStoreFactoryTest { keyStoreConfig.validate(); - final KeyStore keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); + final Pair keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); Assert.assertNotNull("KeyStore is null", keyStore); + Assert.assertNotNull("KeyStore is null", keyStore.getFirst()); + Assert.assertNotNull("KeyStore is null", keyStore.getSecond()); //read trusted certs - final List trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore(keyStore); + final List trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore( + keyStore.getFirst()); Assert.assertNotNull("Trusted certs", trustedCerts); Assert.assertEquals("Trusted certs size", 0, trustedCerts.size()); //read priv. key final Pair privCred1 = EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore, HSM_FACADE_KEY_ALIAS, null, true, "jUnit test"); + keyStore.getFirst(), HSM_FACADE_KEY_ALIAS, null, true, "jUnit test"); Assert.assertNotNull("Credential 1", privCred1); Assert.assertNotNull("Credential 1 priv. key", privCred1.getFirst()); Assert.assertNotNull("Credential 1 certificate", privCred1.getSecond()); //read priv. key final Pair privCred2 = EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore, HSM_FACADE_KEY_ALIAS, "shouldBeIgnord".toCharArray(), true, "jUnit test"); + keyStore.getFirst(), HSM_FACADE_KEY_ALIAS, "shouldBeIgnord".toCharArray(), true, "jUnit test"); Assert.assertNotNull("Credential 2", privCred2); Assert.assertNotNull("Credential 2 priv. key", privCred2.getFirst()); Assert.assertNotNull("Credential 2 certificate", privCred2.getSecond()); try { EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore, "notExist", "wrong".toCharArray(), true, "jUnit test"); + keyStore.getFirst(), "notExist", "wrong".toCharArray(), true, "jUnit test"); Assert.fail("Wrong password not detected"); } catch (final EaafKeyAccessException e) { diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java index 259c21bf..1668752a 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; +import java.security.Provider; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Collections; @@ -12,6 +13,22 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.PostConstruct; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exception.EaafKeyAccessException; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; +import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreUtils; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.impl.utils.X509Utils; +import at.gv.egiz.eaaf.modules.auth.sl20.Constants; +import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException; + import org.apache.commons.lang3.StringUtils; import org.jose4j.jwa.AlgorithmConstraints; import org.jose4j.jwa.AlgorithmConstraints.ConstraintType; @@ -32,35 +49,19 @@ import org.springframework.util.Base64Utils; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonNode; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.exception.EaafKeyAccessException; -import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; -import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; -import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreUtils; -import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; -import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; -import at.gv.egiz.eaaf.core.impl.data.Pair; -import at.gv.egiz.eaaf.core.impl.utils.X509Utils; -import at.gv.egiz.eaaf.modules.auth.sl20.Constants; -import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException; -import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException; - @Service public class JsonSecurityUtils implements IJoseTools { private static final Logger log = LoggerFactory.getLogger(JsonSecurityUtils.class); private static final String FRIENDLYNAME_KEYSTORE = "SL2.0 KeyStore"; private static final String FRIENDLYNAME_TRUSTSTORE = "SL2.0 TrustStore"; - + @Autowired(required = true) IConfiguration authConfig; @Autowired(required = true) EaafKeyStoreFactory keystoreFactory; - - private KeyStore keyStore; - private KeyStore trustStore; - + + private Pair keyStore; + private Pair trustStore; + private static JsonMapper mapper = new JsonMapper(); @PostConstruct @@ -68,36 +69,36 @@ public class JsonSecurityUtils implements IJoseTools { log.info("Initialize SL2.0 authentication security constrains ... "); try { //load KeyStore - KeyStoreConfiguration keyStoreConfig = buildKeyStoreConfiguration(); + final KeyStoreConfiguration keyStoreConfig = buildKeyStoreConfiguration(); keyStore = keystoreFactory.buildNewKeyStore(keyStoreConfig); - + //load TrustStore - KeyStoreConfiguration trustStoreConfig = buildTrustStoreConfiguration(); + final KeyStoreConfiguration trustStoreConfig = buildTrustStoreConfiguration(); trustStore = keystoreFactory.buildNewKeyStore(trustStoreConfig); - + //validate KeyStore entries - EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore, getSigningKeyAlias(), + EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore.getFirst(), getSigningKeyAlias(), getSigningKeyPassword(), true, FRIENDLYNAME_KEYSTORE); - Pair encCredentials = - EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore, getEncryptionKeyAlias(), + final Pair encCredentials = + EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore.getFirst(), getEncryptionKeyAlias(), getEncryptionKeyPassword(), false, FRIENDLYNAME_TRUSTSTORE); if (encCredentials == null) { log.info("No encryption key for SL2.0 found. End-to-End encryption is not used."); - + } - + //validate TrustStore - List trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore(trustStore); + final List trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore(trustStore.getFirst()); if (trustedCerts.isEmpty()) { - log.info("No certificates in TrustStore: {}. Signature validation will FAIL!", + log.info("No certificates in TrustStore: {}. Signature validation will FAIL!", FRIENDLYNAME_TRUSTSTORE); - + } else { - log.info("Find #{} certificates in TrustStore: {}", + log.info("Find #{} certificates in TrustStore: {}", trustedCerts.size(), FRIENDLYNAME_TRUSTSTORE); - + } - + log.info("SL2.0 authentication security constrains initialized."); } catch (final RuntimeException e) { @@ -124,9 +125,9 @@ public class JsonSecurityUtils implements IJoseTools { // set signing information jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); - Pair signingCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore, - getSigningKeyAlias(), getSigningKeyPassword(), true, FRIENDLYNAME_KEYSTORE); - + final Pair signingCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates( + keyStore.getFirst(), getSigningKeyAlias(), getSigningKeyPassword(), true, FRIENDLYNAME_KEYSTORE); + jws.setKey(signingCred.getFirst()); // TODO: @@ -218,8 +219,8 @@ public class JsonSecurityUtils implements IJoseTools { SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()])); - final VerificationResult result = - validateSignature(serializedContent, EaafKeyStoreUtils.readCertsFromKeyStore(trustStore), algConstraints); + final VerificationResult result = + validateSignature(serializedContent, EaafKeyStoreUtils.readCertsFromKeyStore(trustStore.getFirst()), algConstraints); if (!result.isValidSigned()) { log.info("JWS signature invalide. Stopping authentication process ..."); @@ -259,9 +260,9 @@ public class JsonSecurityUtils implements IJoseTools { // set payload receiverJwe.setCompactSerialization(compactSerialization); - Pair encryptionCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore, - getEncryptionKeyAlias(), getEncryptionKeyPassword(), true, FRIENDLYNAME_KEYSTORE); - + final Pair encryptionCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates( + keyStore.getFirst(), getEncryptionKeyAlias(), getEncryptionKeyPassword(), true, FRIENDLYNAME_KEYSTORE); + // validate key from header against key from config final List x5cCerts = receiverJwe.getCertificateChainHeaderValue(); final String x5t256 = receiverJwe.getX509CertSha256ThumbprintHeaderValue(); @@ -318,7 +319,7 @@ public class JsonSecurityUtils implements IJoseTools { } catch (final IOException e) { log.warn("Decrypted SL2.0 result can not be parsed.", e); throw new SlCommandoParserException("Decrypted SL2.0 result can not be parsed", e); - + } } @@ -326,28 +327,28 @@ public class JsonSecurityUtils implements IJoseTools { public X509Certificate getEncryptionCertificate() { Pair encryptionCred; try { - encryptionCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore, + encryptionCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore.getFirst(), getEncryptionKeyAlias(), getEncryptionKeyPassword(), false, FRIENDLYNAME_KEYSTORE); if (encryptionCred != null && encryptionCred.getSecond().length > 0) { return encryptionCred.getSecond()[0]; - + } - - } catch (EaafKeyAccessException e) { + + } catch (final EaafKeyAccessException e) { log.trace("Exception is skipped because Encryption is not mandatory on this level", e); - + } - + return null; - + } private KeyStoreConfiguration buildKeyStoreConfiguration() throws EaafConfigurationException { - KeyStoreConfiguration config = new KeyStoreConfiguration(); + final KeyStoreConfiguration config = new KeyStoreConfiguration(); config.setFriendlyName(FRIENDLYNAME_KEYSTORE); - + config.setKeyStoreType(authConfig.getBasicConfiguration( - authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_TYPE), + authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_TYPE), KeyStoreType.JKS.getKeyStoreType())); config.setKeyStoreName( authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_NAME)); @@ -355,20 +356,20 @@ public class JsonSecurityUtils implements IJoseTools { authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PATH)); config.setSoftKeyStorePassword( authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD)); - + //validate configuration state config.validate(); - + return config; - + } - + private KeyStoreConfiguration buildTrustStoreConfiguration() throws EaafConfigurationException { - KeyStoreConfiguration config = new KeyStoreConfiguration(); + final KeyStoreConfiguration config = new KeyStoreConfiguration(); config.setFriendlyName(FRIENDLYNAME_TRUSTSTORE); - + config.setKeyStoreType(authConfig.getBasicConfiguration( - authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_TRUSTSTORE_TYPE), + authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_TRUSTSTORE_TYPE), KeyStoreType.JKS.getKeyStoreType())); config.setKeyStoreName( authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_TRUSTSTORE_NAME)); @@ -376,13 +377,13 @@ public class JsonSecurityUtils implements IJoseTools { authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_TRUSTSTORE_PATH)); config.setSoftKeyStorePassword( authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_TRUSTSTORE_PASSWORD)); - + //validate configuration state config.validate(); - + return config; } - + private String getSigningKeyAlias() { String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS); @@ -394,7 +395,7 @@ public class JsonSecurityUtils implements IJoseTools { } private char[] getSigningKeyPassword() { - String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD); + final String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD); if (value != null) { return value.trim().toCharArray(); } @@ -412,7 +413,7 @@ public class JsonSecurityUtils implements IJoseTools { } private char[] getEncryptionKeyPassword() { - String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD); + final String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD); if (value != null) { return value.trim().toCharArray(); } diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java index cd77228c..26a5c5f6 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java @@ -21,6 +21,7 @@ package at.gv.egiz.eaaf.modules.pvp2.impl.utils; import java.security.KeyStore; import java.security.KeyStoreException; +import java.security.Provider; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.ArrayList; @@ -31,24 +32,25 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.PostConstruct; -import org.apache.commons.lang3.StringUtils; -import org.apache.xml.security.algorithms.JCEMapper; -import org.opensaml.security.credential.UsageType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.ResourceLoader; - import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; import at.gv.egiz.eaaf.core.exceptions.EaafException; import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; -import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; +import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.modules.pvp2.PvpConstants; import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; import at.gv.egiz.eaaf.modules.pvp2.api.utils.IPvp2CredentialProvider; import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException; import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.EaafKeyStoreX509CredentialAdapter; + +import org.apache.commons.lang3.StringUtils; +import org.apache.xml.security.algorithms.JCEMapper; +import org.opensaml.security.credential.UsageType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ResourceLoader; + import lombok.extern.slf4j.Slf4j; @Slf4j @@ -64,7 +66,7 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi @Autowired private EaafKeyStoreFactory keyStoreFactory; - private KeyStore keyStore = null; + private Pair keyStore = null; /** * Get a friendlyName for this keyStore implementation This friendlyName is used @@ -75,10 +77,10 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi public final String getFriendlyName() { try { return getBasicKeyStoreConfig().getFriendlyName(); - - } catch (EaafConfigurationException e) { + + } catch (final EaafConfigurationException e) { return "No KeyStoreName"; - + } } @@ -143,8 +145,9 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi @Override public EaafX509Credential getMetaDataSigningCredential() throws CredentialsNotAvailableException { try { - final EaafKeyStoreX509CredentialAdapter credentials = new EaafKeyStoreX509CredentialAdapter(keyStore, - getMetadataKeyAlias(), getPassCharArrayOrNull(getMetadataKeyPassword()), getFriendlyName()); + final EaafKeyStoreX509CredentialAdapter credentials = new EaafKeyStoreX509CredentialAdapter( + keyStore.getFirst(), getMetadataKeyAlias(), + getPassCharArrayOrNull(getMetadataKeyPassword()), getFriendlyName()); credentials.setUsageType(UsageType.SIGNING); credentials.setSignatureAlgorithmForSigning(selectSigningAlgorithm(credentials)); credentials.setKeyEncryptionAlgorithmForDataEncryption(selectKeyEncryptionAlgorithm(credentials)); @@ -167,8 +170,9 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi @Override public EaafX509Credential getMessageSigningCredential() throws CredentialsNotAvailableException { try { - final EaafKeyStoreX509CredentialAdapter credentials = new EaafKeyStoreX509CredentialAdapter(keyStore, - getSignatureKeyAlias(), getPassCharArrayOrNull(getSignatureKeyPassword()), getFriendlyName()); + final EaafKeyStoreX509CredentialAdapter credentials = new EaafKeyStoreX509CredentialAdapter( + keyStore.getFirst(), getSignatureKeyAlias(), + getPassCharArrayOrNull(getSignatureKeyPassword()), getFriendlyName()); credentials.setUsageType(UsageType.SIGNING); credentials.setSignatureAlgorithmForSigning(selectSigningAlgorithm(credentials)); credentials.setKeyEncryptionAlgorithmForDataEncryption(selectKeyEncryptionAlgorithm(credentials)); @@ -196,8 +200,9 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi } try { - final EaafKeyStoreX509CredentialAdapter credentials = new EaafKeyStoreX509CredentialAdapter(keyStore, - getEncryptionKeyAlias(), getPassCharArrayOrNull(getEncryptionKeyPassword()), getFriendlyName()); + final EaafKeyStoreX509CredentialAdapter credentials = new EaafKeyStoreX509CredentialAdapter( + keyStore.getFirst(), getEncryptionKeyAlias(), + getPassCharArrayOrNull(getEncryptionKeyPassword()), getFriendlyName()); credentials.setUsageType(UsageType.ENCRYPTION); credentials.setSignatureAlgorithmForSigning(selectSigningAlgorithm(credentials)); credentials.setKeyEncryptionAlgorithmForDataEncryption(selectKeyEncryptionAlgorithm(credentials)); @@ -226,12 +231,12 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi final List result = new ArrayList<>(); try { - final Enumeration aliases = keyStore.aliases(); + final Enumeration aliases = keyStore.getFirst().aliases(); while (aliases.hasMoreElements()) { final String el = aliases.nextElement(); log.trace("Process TrustStoreEntry: " + el); - if (keyStore.isCertificateEntry(el)) { - final Certificate cert = keyStore.getCertificate(el); + if (keyStore.getFirst().isCertificateEntry(el)) { + final Certificate cert = keyStore.getFirst().getCertificate(el); if (cert != null && cert instanceof X509Certificate) { result.add((X509Certificate) cert); @@ -257,10 +262,10 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi final KeyStoreConfiguration keyStoreConfig = getBasicKeyStoreConfig(); keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig); - if (JCEMapper.getProviderId() != null - && !JCEMapper.getProviderId().equals(keyStore.getProvider().getName())) { + if (JCEMapper.getProviderId() != null && keyStore.getSecond() != null + && !JCEMapper.getProviderId().equals(keyStore.getSecond().getName())) { log.error("OpenSAML3.x can ONLY use a single type of CryptoProvider in an application. " - + "Can NOT set: {}, because {} was already set", keyStore.getProvider().getName(), + + "Can NOT set: {}, because {} was already set", keyStore.getSecond().getName(), JCEMapper.getProviderId()); throw new EaafConfigurationException(EaafKeyStoreFactory.ERRORCODE_06, new Object[] { keyStoreConfig.getFriendlyName(), @@ -271,12 +276,11 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi // Set JCEMapper only in case of HSM based KeyStores because Software KeyStores // can use // the default SecurityProvider system in OpenSAML3.x signing engine - if (!KeyStoreType.JKS.equals(keyStoreConfig.getKeyStoreType()) - && !KeyStoreType.PKCS12.equals(keyStoreConfig.getKeyStoreType()) + if (keyStore.getSecond() != null && JCEMapper.getProviderId() == null) { log.info("Register CryptoProvider: {} as defaut for OpenSAML3.x", - keyStore.getProvider().getName()); - JCEMapper.setProviderId(keyStore.getProvider().getName()); + keyStore.getSecond().getName()); + JCEMapper.setProviderId(keyStore.getSecond().getName()); } -- cgit v1.2.3