diff options
-rw-r--r-- | eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java | 203 | ||||
-rw-r--r-- | pom.xml | 42 |
2 files changed, 123 insertions, 122 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 743a7318..bd2b3cab 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 @@ -27,11 +27,6 @@ import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; -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.exception.EaafKeyAccessException; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; @@ -42,6 +37,12 @@ import at.gv.egiz.eaaf.core.impl.credential.SymmetricKeyConfiguration.SymmetricK 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 @@ -62,16 +63,16 @@ public class EaafKeyStoreFactory { 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"; - + public static final String ERRORCODE_KEY_00 = "internal.key.00"; private static final String HSM_FACADE_PROVIDER_CLASS = "at.asitplus.hsmfacade.provider.HsmFacadeProvider"; - private static final String HSM_FACADE_KEYSTORELOADPARAMETERS_CLASS + private static final String HSM_FACADE_KEYSTORELOADPARAMETERS_CLASS = "at.asitplus.hsmfacade.provider.RemoteKeyStoreLoadParameter"; private static final String HSM_FACADE_PROVIDER_METHOD_CONSTRUCT = "getInstance"; private static final String HSM_FACADE_PROVIDER_METHOD_INIT = "init"; private static final String HSM_FACADE_PROVIDER_METHOD_ISINITIALIZED = "isInitialized"; - private static final String HSM_FACADE_PROVIDER_INIT_ERROR_MSG + private static final String HSM_FACADE_PROVIDER_INIT_ERROR_MSG = "Has HSM-Facade class supported '{}' method: {}"; private static final String HSM_FACADE_PROVIDER = "HsmFacade"; private static final String HSM_FACADE_KEYSTORE_TYPE = "RemoteKeyStore"; @@ -94,10 +95,10 @@ public class EaafKeyStoreFactory { */ @Nonnull public Pair<SecretKey, Provider> buildNewSymmetricKey(SymmetricKeyConfiguration config) throws EaafException { - log.trace("Starting symmetric-key generation based on configuration object ... "); + log.trace("Starting symmetric-key generation based on configuration object ... "); if (SymmetricKeyType.PASSPHRASE.equals(config.getKeyType())) { return generatePassPhraseBasedSymmetricKey(config); - + } else if (SymmetricKeyType.HSMFACADE.equals(config.getKeyType())) { if (isHsmFacadeInitialized) { return getSymmetricKeyFromHsmFacade(config); @@ -109,17 +110,17 @@ public class EaafKeyStoreFactory { new Object[] { config.getFriendlyName() }); } - + } else { log.warn("Symmetric KeyType: {} is unrecognized", config.getKeyType()); throw new EaafConfigurationException(ERRORCODE_01, new Object[] { config.getFriendlyName() }); } - - + + } - + /** * Get a new KeyStore based on a KeyStore configuration-object. * @@ -172,46 +173,46 @@ public class EaafKeyStoreFactory { } @PostConstruct - private void initialize() throws EaafException { - Class<?> hsmProviderClazz = getHsmProviderClass(); - if (hsmProviderClazz != null) { + private void initialize() throws EaafException { + final Class<?> hsmProviderClazz = getHsmProviderClass(); + if (hsmProviderClazz != null) { final String hsmFacadeHost = basicConfig.getBasicConfiguration(CONFIG_PROP_HSM_FACADE_HOST); - Provider alreadyLoadedProvider = Security.getProvider(HSM_FACADE_PROVIDER); - if (alreadyLoadedProvider != null - && alreadyLoadedProvider.getClass().isAssignableFrom(hsmProviderClazz)) { + final Provider alreadyLoadedProvider = Security.getProvider(HSM_FACADE_PROVIDER); + if (alreadyLoadedProvider != null + && alreadyLoadedProvider.getClass().isAssignableFrom(hsmProviderClazz)) { log.info("Find already initialized Java SecurityProvider: {}", alreadyLoadedProvider.getName()); - //mark it as initialized if the state can not be determined + //mark it as initialized if the state can not be determined boolean isAlreadyInitialized = true; try { - Method initializeCheck = + final Method initializeCheck = alreadyLoadedProvider.getClass().getMethod(HSM_FACADE_PROVIDER_METHOD_ISINITIALIZED, new Class[]{}); isAlreadyInitialized = (boolean) initializeCheck.invoke(alreadyLoadedProvider); - - } catch (Exception e) { + + } catch (final Exception e) { log.warn("Can not determine state of alreay loaded HSM Facade. Mark it as 'initialized'"); log.debug("HSM Facade check error: {}", e.getMessage()); - + } isHsmFacadeInitialized = isAlreadyInitialized; - + if (isHsmFacadeInitialized) { log.info("HSM Facade is already initialized. {} can provide KeyStores based on remote HSM", EaafKeyStoreFactory.class.getSimpleName()); - + } else { log.info("HSM Facade is already loaded but not initialized. {} can NOT provide KeyStores based on remote HSM", EaafKeyStoreFactory.class.getSimpleName()); - + } - - } else if (StringUtils.isNotEmpty(hsmFacadeHost)) { + + } else if (StringUtils.isNotEmpty(hsmFacadeHost)) { log.debug("Find host for HSMFacade. Starting crypto provider initialization ... "); initializeHsmFacadeSecurityProvider(hsmProviderClazz, hsmFacadeHost); - + } else { log.info("HSM Facade is on ClassPath but not configurated. {} can only provide software keystores", EaafKeyStoreFactory.class.getSimpleName()); - + } } else { @@ -222,7 +223,7 @@ public class EaafKeyStoreFactory { } - private void initializeHsmFacadeSecurityProvider(Class<?> hsmProviderClazz, String hsmFacadeHost) + private void initializeHsmFacadeSecurityProvider(Class<?> hsmProviderClazz, String hsmFacadeHost) throws EaafException { try { final int port = Integer.parseUnsignedInt( @@ -231,40 +232,40 @@ public class EaafKeyStoreFactory { getConfigurationParameter(CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME); final String clientPassword = getConfigurationParameter(CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD); - - //initialize HSM-Facade by using JAVA Reflection, because in that case HSM-Facade + + //initialize HSM-Facade by using JAVA Reflection, because in that case HSM-Facade //has not be in ClassPath on every project - Method constructor = hsmProviderClazz.getMethod(HSM_FACADE_PROVIDER_METHOD_CONSTRUCT, new Class[]{}); - Method initMethod = hsmProviderClazz.getMethod(HSM_FACADE_PROVIDER_METHOD_INIT, + final Method constructor = hsmProviderClazz.getMethod(HSM_FACADE_PROVIDER_METHOD_CONSTRUCT, new Class[]{}); + final Method initMethod = hsmProviderClazz.getMethod(HSM_FACADE_PROVIDER_METHOD_INIT, X509Certificate.class, String.class, String.class, String.class, int.class); - if (initMethod != null && constructor != null) { - Object rawProvider = constructor.invoke(hsmProviderClazz); + if (initMethod != null && constructor != null) { + final Object rawProvider = constructor.invoke(hsmProviderClazz); initMethod.invoke( - rawProvider, getHsmFacadeTrustSslCertificate(), + rawProvider, getHsmFacadeTrustSslCertificate(), clientUsername, clientPassword, hsmFacadeHost, port); - - if (rawProvider instanceof Provider) { + + if (rawProvider instanceof Provider) { 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("Is HSM-Facade class type of 'java.security.Provider': {}", - rawProvider instanceof Provider); + log.warn("Is HSM-Facade class type of 'java.security.Provider': {}", + rawProvider instanceof Provider); throw new EaafException(ERRORCODE_10, new Object[] {HSM_FACADE_PROVIDER_CLASS}); - + } - - } else { - log.warn(HSM_FACADE_PROVIDER_INIT_ERROR_MSG, + + } else { + log.warn(HSM_FACADE_PROVIDER_INIT_ERROR_MSG, HSM_FACADE_PROVIDER_METHOD_CONSTRUCT, constructor != null); - log.warn(HSM_FACADE_PROVIDER_INIT_ERROR_MSG, + log.warn(HSM_FACADE_PROVIDER_INIT_ERROR_MSG, HSM_FACADE_PROVIDER_METHOD_INIT, initMethod != null); throw new EaafException(ERRORCODE_10, new Object[] {HSM_FACADE_PROVIDER_CLASS}); - + } - + //final HsmFacadeProvider provider = HsmFacadeProvider.Companion.getInstance(); //provider.init(getHsmFacadeTrustSslCertificate(), clientUsername, clientPassword, hsmFacadeHost, port); @@ -274,19 +275,19 @@ public class EaafKeyStoreFactory { } catch (final Exception e) { log.error("HSM Facade initialization FAILED with an generic error.", e); throw new EaafConfigurationException(ERRORCODE_03, new Object[] { e.getMessage() }, e); - + } - + } private Class<?> getHsmProviderClass() { try { return Class.forName(HSM_FACADE_PROVIDER_CLASS); - - } catch (ClassNotFoundException e1) { + + } catch (final ClassNotFoundException e1) { log.debug("No HSM-Facade implemenation in ClassPath. HSM-Facade will not be available"); return null; - + } } @@ -304,16 +305,16 @@ public class EaafKeyStoreFactory { if (config.isSkipMakeAbsolutPaths()) { log.debug("Use filepath from config: {}", keyStorePath); ressource = resourceLoader.getResource(keyStorePath); - + } else { final String absKeyStorePath = FileUtils.makeAbsoluteUrl(keyStorePath, basicConfig - .getConfigurationRootDirectory()); + .getConfigurationRootDirectory()); log.debug("Use filepath from config: {}", absKeyStorePath); - + ressource = resourceLoader.getResource(absKeyStorePath); - + } - + if (!ressource.exists()) { throw new EaafConfigurationException(ERRORCODE_05, new Object[] { config.getFriendlyName(), @@ -326,15 +327,15 @@ public class EaafKeyStoreFactory { is.close(); return Pair.newInstance(keyStore, null); - - } catch (EaafException e) { + + } catch (final EaafException e) { throw e; - - } catch (IOException e) { + + } catch (final IOException e) { throw new EaafFactoryException(ERRORCODE_06, new Object[] { config.getFriendlyName(), "KeyStore not valid or password wrong" }); - - } catch (Exception e) { + + } catch (final Exception e) { log.error("Software KeyStore initialization FAILED with an generic error.", e); throw new EaafConfigurationException(ERRORCODE_03, new Object[] { e.getMessage() }, e); @@ -345,14 +346,14 @@ public class EaafKeyStoreFactory { private Pair<KeyStore, Provider> getKeyStoreFromHsmFacade(KeyStoreConfiguration config) throws EaafFactoryException, EaafConfigurationException { return getKeyStoreFromHsmFacade(config.getKeyStoreName(), config.getFriendlyName()); - + } @Nonnull private Pair<KeyStore, Provider> getKeyStoreFromHsmFacade(String keyStoreName, String friendlyName) throws EaafFactoryException, EaafConfigurationException { final String validatedKeyStoreName = checkConfigurationParameter(keyStoreName, - ERRORCODE_06, friendlyName, "KeyStoreName missing for HSM Facade"); + ERRORCODE_06, friendlyName, "KeyStoreName missing for HSM Facade"); try { final KeyStore keyStore = KeyStore.getInstance(HSM_FACADE_KEYSTORE_TYPE, HSM_FACADE_PROVIDER); @@ -368,35 +369,35 @@ 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); + final Class<?> clazz = Class.forName(HSM_FACADE_KEYSTORELOADPARAMETERS_CLASS); + final Constructor<?> constructor = clazz.getConstructor(String.class); + final Object keyStoreParams = constructor.newInstance(keyStoreName); return (LoadStoreParameter) keyStoreParams; - - } catch (Exception e) { + + } catch (final 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); - + } - + } - + @Nonnull - private Pair<SecretKey, Provider> generatePassPhraseBasedSymmetricKey(SymmetricKeyConfiguration config) + private Pair<SecretKey, Provider> generatePassPhraseBasedSymmetricKey(SymmetricKeyConfiguration config) throws EaafConfigurationException { checkConfigurationParameter(config.getSoftKeyPassphrase(), ERRORCODE_KEY_00, config.getFriendlyName(), "passphrase missing"); checkConfigurationParameter(config.getSoftKeySalt(), ERRORCODE_KEY_00, config.getFriendlyName(), "salt missing"); - + try { final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA256"); final KeySpec spec = new PBEKeySpec( - config.getSoftKeyPassphrase().toCharArray(), - config.getSoftKeySalt().getBytes("UTF-8"), + config.getSoftKeyPassphrase().toCharArray(), + config.getSoftKeySalt().getBytes("UTF-8"), 10000, 128); return Pair.newInstance(keyFactory.generateSecret(spec), null); @@ -408,38 +409,38 @@ public class EaafKeyStoreFactory { } } - + @Nonnull - private Pair<SecretKey, Provider> getSymmetricKeyFromHsmFacade(SymmetricKeyConfiguration config) + private Pair<SecretKey, Provider> getSymmetricKeyFromHsmFacade(SymmetricKeyConfiguration config) throws EaafFactoryException, EaafConfigurationException, EaafKeyAccessException { - Pair<KeyStore, Provider> keyStore = getKeyStoreFromHsmFacade( + final Pair<KeyStore, Provider> keyStore = getKeyStoreFromHsmFacade( config.getKeyStoreName(), config.getFriendlyName()); - + checkConfigurationParameter(config.getKeyAlias(), ERRORCODE_KEY_00, config.getFriendlyName(), "keyAlias missing"); - + try { - SecretKey secretKey = (SecretKey) keyStore.getFirst().getKey(config.getKeyAlias(), null); + final SecretKey secretKey = (SecretKey) keyStore.getFirst().getKey(config.getKeyAlias(), null); if (secretKey == null) { - throw new EaafKeyAccessException(EaafKeyAccessException.ERROR_CODE_09, + throw new EaafKeyAccessException(EaafKeyAccessException.ERROR_CODE_09, config.getFriendlyName(), config.getKeyAlias(), "No SecretKey with Alias "); - - } - + + } + return Pair.newInstance(secretKey, keyStore.getSecond()); - + } catch (UnrecoverableKeyException | KeyStoreException | NoSuchAlgorithmException e) { - throw new EaafKeyAccessException(EaafKeyAccessException.ERROR_CODE_09, e, + throw new EaafKeyAccessException(EaafKeyAccessException.ERROR_CODE_09, e, config.getFriendlyName(), config.getKeyAlias(), e.getMessage()); - - } catch (ClassCastException e) { - throw new EaafKeyAccessException(EaafKeyAccessException.ERROR_CODE_09, + + } catch (final ClassCastException e) { + throw new EaafKeyAccessException(EaafKeyAccessException.ERROR_CODE_09, config.getFriendlyName(), config.getKeyAlias(), "Wrong SecretKey type "); - + } - + } - + private X509Certificate getHsmFacadeTrustSslCertificate() throws EaafConfigurationException { try { final String certFilePath = getConfigurationParameter(CONFIG_PROP_HSM_FACADE_SSLTRUST); @@ -11,7 +11,7 @@ <name>EGIZ EAAF components</name> - <properties> + <properties> <!-- General project properties --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> @@ -43,34 +43,34 @@ <iaik.prod.iaik_xades.version>2.13_moa</iaik.prod.iaik_xades.version> <iaik.prod.iaik_xsect.version>2.13_moa</iaik.prod.iaik_xsect.version> - <hsm-facade-provider.version>0.5.0</hsm-facade-provider.version> - <io.grpc-core.version>1.25.0</io.grpc-core.version> + <hsm-facade-provider.version>0.5.1</hsm-facade-provider.version> + <io.grpc-core.version>1.30.2</io.grpc-core.version> <!-- Other third-party libs --> - <org.springframework.version>5.1.5.RELEASE</org.springframework.version> - <org.opensaml.version>3.4.3</org.opensaml.version> - <org.apache.santuario.xmlsec.version>2.1.4</org.apache.santuario.xmlsec.version> - <org.bouncycastle.bcprov-jdk15on.version>1.65</org.bouncycastle.bcprov-jdk15on.version> - <org.bouncycastle.bctls-jdk15on.version>1.65</org.bouncycastle.bctls-jdk15on.version> - - <org.slf4j.version>1.7.25</org.slf4j.version> - <commons-codec.version>1.11</commons-codec.version> - <org.apache.commons-lang3.version>3.8.1</org.apache.commons-lang3.version> - <org.apache.commons-text.version>1.6</org.apache.commons-text.version> - <org.apache.commons-collections4>4.2</org.apache.commons-collections4> - <commons-fileupload.version>1.3.3</commons-fileupload.version> + <org.springframework.version>5.2.8.RELEASE</org.springframework.version> + <org.opensaml.version>3.4.5</org.opensaml.version> + <org.apache.santuario.xmlsec.version>2.2.0</org.apache.santuario.xmlsec.version> + <org.bouncycastle.bcprov-jdk15on.version>1.66</org.bouncycastle.bcprov-jdk15on.version> + <org.bouncycastle.bctls-jdk15on.version>1.66</org.bouncycastle.bctls-jdk15on.version> + + <org.slf4j.version>1.7.30</org.slf4j.version> + <commons-codec.version>1.14</commons-codec.version> + <org.apache.commons-lang3.version>3.11</org.apache.commons-lang3.version> + <org.apache.commons-text.version>1.9</org.apache.commons-text.version> + <org.apache.commons-collections4>4.4</org.apache.commons-collections4> + <commons-fileupload.version>1.4</commons-fileupload.version> <javax.servlet-api>3.0.1</javax.servlet-api> <org.apache.velocity.version>1.7</org.apache.velocity.version> <javax.annotation-api>1.3.2</javax.annotation-api> - <joda-time.version>2.10.1</joda-time.version> + <joda-time.version>2.10.6</joda-time.version> <jsr305.version>3.0.2</jsr305.version> - <com.google.guava.version>28.1-jre</com.google.guava.version> + <com.google.guava.version>29.0-jre</com.google.guava.version> - <httpclient.version>4.5.7</httpclient.version> - <httpcore.version>4.4.11</httpcore.version> + <httpclient.version>4.5.12</httpclient.version> + <httpcore.version>4.4.13</httpcore.version> - <com.fasterxml.jackson.core.version>2.9.8</com.fasterxml.jackson.core.version> - <org.bitbucket.b_c.jose4j.version>0.7.1</org.bitbucket.b_c.jose4j.version> + <com.fasterxml.jackson.core.version>2.11.1</com.fasterxml.jackson.core.version> + <org.bitbucket.b_c.jose4j.version>0.7.2</org.bitbucket.b_c.jose4j.version> <jaxen.jaxen.version>1.1.6</jaxen.jaxen.version> <xerces.version>2.11.0</xerces.version> |