summaryrefslogtreecommitdiff
path: root/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java')
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java123
1 files changed, 117 insertions, 6 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 9db38670..711a3517 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,6 +2,7 @@ package at.gv.egiz.eaaf.core.impl.credential;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.security.Key;
@@ -12,13 +13,19 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.Security;
+import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
+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;
@@ -26,10 +33,12 @@ 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;
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.credential.SymmetricKeyConfiguration.SymmetricKeyType;
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;
@@ -53,6 +62,8 @@ 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
@@ -72,6 +83,43 @@ public class EaafKeyStoreFactory {
private boolean isHsmFacadeInitialized = false;
/**
+ * Get a new symmetric key based on a {@link SymmetricKeyConfiguration} object.
+ *
+ * @param config Symmetric key configuration
+ * @return {@link Pair} of a new {@link SecretKey} instance and an optional {@link Provider}.
+ * The {@link SecretKey} is {@link Nonnull}. If the {@link Provider} is not <code>null</code>
+ * this {@link SecretKey} requires a specific {@link Provider} for {@link Key} operations.
+ * @throws EaafException In case of a KeyStore initialization error
+ */
+ @Nonnull
+ public Pair<SecretKey, Provider> buildNewSymmetricKey(SymmetricKeyConfiguration config) throws EaafException {
+ 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);
+
+ } else {
+ log.error("HSMFacade can NOT be used for symmetric Key: {} because {} is not initialized",
+ config.getFriendlyName());
+ throw new EaafConfigurationException(ERRORCODE_00,
+ 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.
*
* @param config KeyStore configuration
@@ -241,24 +289,31 @@ public class EaafKeyStoreFactory {
@Nonnull
private Pair<KeyStore, Provider> getKeyStoreFromHsmFacade(KeyStoreConfiguration config)
throws EaafFactoryException, EaafConfigurationException {
- final String keyStoreName = checkConfigurationParameter(config.getKeyStoreName(),
- ERRORCODE_06, config.getFriendlyName(), "KeyStoreName missing for HSM Facade");
+ 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");
try {
final KeyStore keyStore = KeyStore.getInstance(HSM_FACADE_KEYSTORE_TYPE, HSM_FACADE_PROVIDER);
- keyStore.load(getHsmFacadeKeyStoreParameter(keyStoreName));
+ keyStore.load(getHsmFacadeKeyStoreParameter(validatedKeyStoreName));
return Pair.newInstance(keyStore, keyStore.getProvider());
} catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException
| NoSuchProviderException | EaafException e) {
log.error("Can not initialize KeyStore: {} with reason: {}",
- config.getFriendlyName(), e.getMessage());
+ friendlyName, e.getMessage());
throw new EaafFactoryException(ERRORCODE_06,
- new Object[] { config.getFriendlyName(), e.getMessage() }, e);
+ new Object[] {friendlyName, e.getMessage() }, e);
}
}
-
+
private KeyStore.LoadStoreParameter getHsmFacadeKeyStoreParameter(String keyStoreName) throws EaafException {
try {
Class<?> clazz = Class.forName(HSM_FACADE_KEYSTORELOADPARAMETERS_CLASS);
@@ -274,6 +329,62 @@ public class EaafKeyStoreFactory {
}
+ @Nonnull
+ 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"),
+ 10000, 128);
+ return Pair.newInstance(keyFactory.generateSecret(spec), null);
+
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException | UnsupportedEncodingException e) {
+ log.error("Passphrase based symmetric-key generation FAILED", e);
+ throw new EaafConfigurationException(ERRORCODE_KEY_00,
+ new Object[] { config.getFriendlyName(), e.getMessage() },
+ e);
+
+ }
+ }
+
+ @Nonnull
+ private Pair<SecretKey, Provider> getSymmetricKeyFromHsmFacade(SymmetricKeyConfiguration config)
+ throws EaafFactoryException, EaafConfigurationException, EaafKeyAccessException {
+ 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);
+ if (secretKey == null) {
+ 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,
+ config.getFriendlyName(), config.getKeyAlias(), e.getMessage());
+
+ } catch (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);