From 8577b14115b819f4173b892a75094b708d03958a Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Tue, 5 May 2020 14:59:51 +0200 Subject: refactor HSM-Facade initialization to JAVA Reflection API to facilitate usage of eaaf_core_utils without HSM-Facade --- .../gv/egiz/eaaf/core/api/utils/IJsonMapper.java | 2 - eaaf_core_utils/pom.xml | 2 + .../core/impl/credential/EaafKeyStoreFactory.java | 89 +++++++++++++++++----- .../messages/eaaf_utils_message.properties | 1 + eaaf_modules/eaaf_module_pvp2_core/pom.xml | 20 +++-- 5 files changed, 86 insertions(+), 28 deletions(-) diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java index b3e0c88f..08c48435 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java @@ -3,8 +3,6 @@ package at.gv.egiz.eaaf.core.api.utils; import java.io.IOException; import java.io.InputStream; -import com.google.gson.JsonParseException; - import at.gv.egiz.eaaf.core.exceptions.EaafJsonMapperException; public interface IJsonMapper { diff --git a/eaaf_core_utils/pom.xml b/eaaf_core_utils/pom.xml index d933e309..1e700322 100644 --- a/eaaf_core_utils/pom.xml +++ b/eaaf_core_utils/pom.xml @@ -44,10 +44,12 @@ at.asitplus.hsmfacade provider + provided io.grpc grpc-core + provided org.bouncycastle 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 e60c326c..4abf23e0 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,8 +2,11 @@ package at.gv.egiz.eaaf.core.impl.credential; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.security.Key; import java.security.KeyStore; +import java.security.KeyStore.LoadStoreParameter; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; @@ -17,8 +20,11 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.PostConstruct; -import at.asitplus.hsmfacade.provider.HsmFacadeProvider; -import at.asitplus.hsmfacade.provider.RemoteKeyStoreLoadParameter; +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.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; import at.gv.egiz.eaaf.core.exceptions.EaafException; @@ -27,12 +33,6 @@ 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 @@ -52,7 +52,11 @@ public class EaafKeyStoreFactory { public static final String ERRORCODE_05 = "internal.keystore.05"; public static final String ERRORCODE_06 = "internal.keystore.06"; public static final String ERRORCODE_07 = "internal.keystore.07"; + public static final String ERRORCODE_10 = "internal.keystore.10"; + private static final String HSM_FACADE_PROVIDER_CLASS = "at.asitplus.hsmfacade.provider.HsmFacadeProvider"; + private static final String HSM_FACADE_KEYSTORELOADPARAMETERS_CLASS + = "at.asitplus.hsmfacade.provider.RemoteKeyStoreLoadParameter"; private static final String HSM_FACADE_PROVIDER = "HsmFacade"; private static final String HSM_FACADE_KEYSTORE_TYPE = "RemoteKeyStore"; @@ -115,10 +119,10 @@ public class EaafKeyStoreFactory { } @PostConstruct - private void initialize() throws EaafException { - + private void initialize() throws EaafException { + Class hsmProviderClazz = getHsmProviderClass(); final String hsmFacadeHost = basicConfig.getBasicConfiguration(CONFIG_PROP_HSM_FACADE_HOST); - if (StringUtils.isNotEmpty(hsmFacadeHost)) { + if (hsmProviderClazz != null && StringUtils.isNotEmpty(hsmFacadeHost)) { log.debug("Find host for HSMFacade. Starting crypto provider initialization ... "); try { final int port = Integer.parseUnsignedInt( @@ -127,14 +131,31 @@ public class EaafKeyStoreFactory { getConfigurationParameter(CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME); final String clientPassword = getConfigurationParameter(CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD); - - final HsmFacadeProvider provider = HsmFacadeProvider.Companion.getInstance(); - provider.init(getHsmFacadeTrustSslCertificate(), clientUsername, clientPassword, hsmFacadeHost, port); - //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()); + + //initialize HSM-Facade by using JAVA Reflection, because in that case HSM-Facade + //has not be in ClassPath on every project + Method initMethod = hsmProviderClazz.getMethod("init", + X509Certificate.class, String.class, String.class, String.class, int.class); + Object rawProvider = + hsmProviderClazz.getMethod("getInstance", new Class[]{}).invoke(hsmProviderClazz); + if (rawProvider instanceof Provider && initMethod != null) { + initMethod.invoke( + rawProvider, getHsmFacadeTrustSslCertificate(), + clientUsername, clientPassword, hsmFacadeHost, port); + Security.insertProviderAt((Provider) rawProvider, 0); + isHsmFacadeInitialized = true; + log.info("HSM Facade is initialized. {} can provide KeyStores based on remote HSM", + EaafKeyStoreFactory.class.getSimpleName()); + + } else { + log.warn("HSM-Facade class is type of 'java.security.Provider': {}", rawProvider instanceof Provider); + log.warn("HSM-Facade class is supported 'init' method: {}", rawProvider instanceof Provider); + throw new EaafException(ERRORCODE_10, new Object[] {HSM_FACADE_PROVIDER_CLASS}); + + } + + //final HsmFacadeProvider provider = HsmFacadeProvider.Companion.getInstance(); + //provider.init(getHsmFacadeTrustSslCertificate(), clientUsername, clientPassword, hsmFacadeHost, port); } catch (final EaafException e) { throw e; @@ -152,6 +173,17 @@ public class EaafKeyStoreFactory { } + private Class getHsmProviderClass() { + try { + return Class.forName(HSM_FACADE_PROVIDER_CLASS); + + } catch (ClassNotFoundException e1) { + log.debug("No HSM-Facade implemenation in ClassPath. HSM-Facade will not be available"); + return null; + + } + } + @Nonnull private Pair getKeyStoreFromFileSystem(KeyStoreConfiguration config) throws EaafConfigurationException, EaafFactoryException { @@ -198,11 +230,11 @@ public class EaafKeyStoreFactory { try { final KeyStore keyStore = KeyStore.getInstance(HSM_FACADE_KEYSTORE_TYPE, HSM_FACADE_PROVIDER); - keyStore.load(new RemoteKeyStoreLoadParameter(keyStoreName)); + keyStore.load(getHsmFacadeKeyStoreParameter(keyStoreName)); return Pair.newInstance(keyStore, keyStore.getProvider()); } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException - | NoSuchProviderException e) { + | NoSuchProviderException | EaafException e) { log.error("Can not initialize KeyStore: {} with reason: {}", config.getFriendlyName(), e.getMessage()); throw new EaafFactoryException(ERRORCODE_06, @@ -211,6 +243,21 @@ public class EaafKeyStoreFactory { } } + private KeyStore.LoadStoreParameter getHsmFacadeKeyStoreParameter(String keyStoreName) throws EaafException { + try { + Class clazz = Class.forName(HSM_FACADE_KEYSTORELOADPARAMETERS_CLASS); + Constructor constructor = clazz.getConstructor(String.class); + Object keyStoreParams = constructor.newInstance(keyStoreName); + return (LoadStoreParameter) keyStoreParams; + + } catch (Exception e) { + log.error("Can NOT build class: {} for HSM-Facade provider", HSM_FACADE_KEYSTORELOADPARAMETERS_CLASS, e); + throw new EaafException(ERRORCODE_10, new Object[] {HSM_FACADE_PROVIDER_CLASS}, e); + + } + + } + private X509Certificate getHsmFacadeTrustSslCertificate() throws EaafConfigurationException { try { final String certFilePath = getConfigurationParameter(CONFIG_PROP_HSM_FACADE_SSLTRUST); diff --git a/eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties b/eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties index b20c5f63..e0c86b03 100644 --- a/eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties +++ b/eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties @@ -11,6 +11,7 @@ internal.keystore.06=KeyStore: {0} initialization failed. Reason: {1} internal.keystore.07=Validation of KeyStore: {0} failed. Reason: {1} internal.keystore.08=Can not access Key: {1} in KeyStore: {0} internal.keystore.09=Can not access Key: {1} in KeyStore: {0} Reason: {2} +internal.keystore.10=HSM-Facade NOT INITIALIZED. Find HSM-Facade class: {0} put that looks WRONG. internal.httpclient.00=HttpClient:{0} uses http Basic-Auth, but 'Username' is NOT set internal.httpclient.01=HttpClient:{0} uses X509 client-auth, but 'KeyStoreConfig' is NOT set diff --git a/eaaf_modules/eaaf_module_pvp2_core/pom.xml b/eaaf_modules/eaaf_module_pvp2_core/pom.xml index e922dc39..d9d68a5d 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/pom.xml +++ b/eaaf_modules/eaaf_module_pvp2_core/pom.xml @@ -88,11 +88,21 @@ test - xml-apis - xml-apis - 1.4.01 - test - + xml-apis + xml-apis + 1.4.01 + test + + + at.asitplus.hsmfacade + provider + test + + + io.grpc + grpc-core + test + -- cgit v1.2.3