summaryrefslogtreecommitdiff
path: root/eaaf_modules
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_modules')
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java40
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java271
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/pom.xml7
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java2
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java82
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java54
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyCredentialProvider.java44
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/config/config_2.props12
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core.beans.xml3
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_spring_config.beans.xml3
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_1.props2
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_2.props12
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml3
13 files changed, 314 insertions, 221 deletions
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java
index f607f8cb..11fd41fb 100644
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java
@@ -7,17 +7,37 @@ public class Constants {
public static final String CONFIG_PROP_VDA_AUTHBLOCK_TRANSFORMATION_ID = CONFIG_PROP_PREFIX
+ ".vda.authblock.transformation.id";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_PATH = CONFIG_PROP_PREFIX + ".security.keystore.path";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD = CONFIG_PROP_PREFIX
- + ".security.keystore.password";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS = CONFIG_PROP_PREFIX + ".security.sign.alias";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD = CONFIG_PROP_PREFIX
- + ".security.sign.password";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS = CONFIG_PROP_PREFIX
- + ".security.encryption.alias";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD = CONFIG_PROP_PREFIX
- + ".security.encryption.password";
+
+ //KeyStore configuration
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_TYPE =
+ CONFIG_PROP_PREFIX + ".security.keystore.type";
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_NAME =
+ CONFIG_PROP_PREFIX + ".security.keystore.name";
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_PATH =
+ CONFIG_PROP_PREFIX + ".security.keystore.path";
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD =
+ CONFIG_PROP_PREFIX + ".security.keystore.password";
+
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS =
+ CONFIG_PROP_PREFIX + ".security.sign.alias";
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD =
+ CONFIG_PROP_PREFIX + ".security.sign.password";
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS =
+ CONFIG_PROP_PREFIX + ".security.encryption.alias";
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD =
+ CONFIG_PROP_PREFIX + ".security.encryption.password";
+ //TrustStore configuration
+ public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_TYPE =
+ CONFIG_PROP_PREFIX + ".security.truststore.type";
+ public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_NAME =
+ CONFIG_PROP_PREFIX + ".security.truststore.name";
+ public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_PATH =
+ CONFIG_PROP_PREFIX + ".security.truststore.path";
+ public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_PASSWORD =
+ CONFIG_PROP_PREFIX + ".security.truststore.password";
+
+
public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT = "default";
public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT = CONFIG_PROP_VDA_ENDPOINT_QUALeID
+ CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT;
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 0d2c1815..259c21bf 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
@@ -1,17 +1,12 @@
package at.gv.egiz.eaaf.modules.auth.sl20.utils;
import java.io.IOException;
-import java.net.MalformedURLException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.Enumeration;
import java.util.List;
import javax.annotation.Nonnull;
@@ -38,9 +33,13 @@ 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.utils.FileUtils;
-import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils;
+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;
@@ -53,88 +52,60 @@ import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException;
public class JsonSecurityUtils implements IJoseTools {
private static final Logger log = LoggerFactory.getLogger(JsonSecurityUtils.class);
- @Autowired(required = true)
- IConfiguration authConfig;
- private Key signPrivKey = null;
- private X509Certificate[] signCertChain = null;
-
- private Key encPrivKey = null;
- private X509Certificate[] encCertChain = null;
-
- private List<X509Certificate> trustedCerts = new ArrayList<>();
-
+ 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 static JsonMapper mapper = new JsonMapper();
@PostConstruct
- protected void initalize() {
+ protected void initalize() throws SL20Exception {
log.info("Initialize SL2.0 authentication security constrains ... ");
try {
- if (getKeyStoreFilePath() != null) {
- final KeyStore keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), getKeyStorePassword());
-
- // load signing key
- signPrivKey = keyStore.getKey(getSigningKeyAlias(), getSigningKeyPassword().toCharArray());
- final Certificate[] certChainSigning = keyStore.getCertificateChain(getSigningKeyAlias());
- signCertChain = new X509Certificate[certChainSigning.length];
- for (int i = 0; i < certChainSigning.length; i++) {
- if (certChainSigning[i] instanceof X509Certificate) {
- signCertChain[i] = (X509Certificate) certChainSigning[i];
- } else {
- log.warn("NO X509 certificate for signing: " + certChainSigning[i].getType());
- }
-
- }
-
- // load encryption key
- try {
- encPrivKey = keyStore.getKey(getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray());
- if (encPrivKey != null) {
- final Certificate[] certChainEncryption = keyStore.getCertificateChain(getEncryptionKeyAlias());
- encCertChain = new X509Certificate[certChainEncryption.length];
- for (int i = 0; i < certChainEncryption.length; i++) {
- if (certChainEncryption[i] instanceof X509Certificate) {
- encCertChain[i] = (X509Certificate) certChainEncryption[i];
- } else {
- log.warn("NO X509 certificate for encryption: " + certChainEncryption[i].getType());
- }
- }
- } else {
- log.info("No encryption key for SL2.0 found. End-to-End encryption is not used.");
- }
-
- } catch (final Exception e) {
- log.warn("No encryption key for SL2.0 found. End-to-End encryption is not used. Reason: " + e.getMessage(),
- e);
-
- }
-
- // load trusted certificates
- trustedCerts = readCertsFromKeyStore(keyStore);
-
- // some short validation
- if (signPrivKey == null || !(signPrivKey instanceof PrivateKey)) {
- log.info("Can NOT open privateKey for SL2.0 signing. KeyStore=" + getKeyStoreFilePath());
- throw new SL20Exception("sl20.03", new Object[] { "Can NOT open private key for signing" });
-
- }
-
- if (signCertChain == null || signCertChain.length == 0) {
- log.info("NO certificate for SL2.0 signing. KeyStore=" + getKeyStoreFilePath());
- throw new SL20Exception("sl20.03", new Object[] { "NO certificate for SL2.0 signing" });
-
- }
-
- log.info("SL2.0 authentication security constrains initialized.");
-
+ //load KeyStore
+ KeyStoreConfiguration keyStoreConfig = buildKeyStoreConfiguration();
+ keyStore = keystoreFactory.buildNewKeyStore(keyStoreConfig);
+
+ //load TrustStore
+ KeyStoreConfiguration trustStoreConfig = buildTrustStoreConfiguration();
+ trustStore = keystoreFactory.buildNewKeyStore(trustStoreConfig);
+
+ //validate KeyStore entries
+ EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore, getSigningKeyAlias(),
+ getSigningKeyPassword(), true, FRIENDLYNAME_KEYSTORE);
+ Pair<Key, X509Certificate[]> encCredentials =
+ EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore, 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<X509Certificate> trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore(trustStore);
+ if (trustedCerts.isEmpty()) {
+ log.info("No certificates in TrustStore: {}. Signature validation will FAIL!",
+ FRIENDLYNAME_TRUSTSTORE);
+
} else {
- log.info("NO SL2.0 authentication security configuration. Initialization was skipped");
+ log.info("Find #{} certificates in TrustStore: {}",
+ trustedCerts.size(), FRIENDLYNAME_TRUSTSTORE);
+
}
+
+ log.info("SL2.0 authentication security constrains initialized.");
} catch (final RuntimeException e) {
throw e;
} catch (final Exception e) {
- log.error("SL2.0 security constrains initialization FAILED.", e);
+ log.error("SL2.0 security constrains initialization FAILED.");
+ throw new SL20Exception("sl20.11", new Object[] {e.getMessage()}, e);
}
@@ -153,15 +124,18 @@ public class JsonSecurityUtils implements IJoseTools {
// set signing information
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
- jws.setKey(signPrivKey);
+ Pair<Key, X509Certificate[]> signingCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore,
+ getSigningKeyAlias(), getSigningKeyPassword(), true, FRIENDLYNAME_KEYSTORE);
+
+ jws.setKey(signingCred.getFirst());
// TODO:
- jws.setCertificateChainHeaderValue(signCertChain);
- jws.setX509CertSha256ThumbprintHeaderValue(signCertChain[0]);
+ jws.setCertificateChainHeaderValue(signingCred.getSecond());
+ jws.setX509CertSha256ThumbprintHeaderValue(signingCred.getSecond()[0]);
return jws.getCompactSerialization();
- } catch (final JoseException e) {
+ } catch (final JoseException | EaafKeyAccessException e) {
log.warn("Can NOT sign SL2.0 command.", e);
throw new SlCommandoBuildException("Can NOT sign SL2.0 command.", e);
@@ -172,7 +146,7 @@ public class JsonSecurityUtils implements IJoseTools {
@Override
public VerificationResult validateSignature(final String serializedContent, final KeyStore trustStore,
final AlgorithmConstraints algconstraints) throws JoseException, IOException, KeyStoreException {
- final List<X509Certificate> trustedCertificates = readCertsFromKeyStore(trustStore);
+ final List<X509Certificate> trustedCertificates = EaafKeyStoreUtils.readCertsFromKeyStore(trustStore);
return validateSignature(serializedContent, trustedCertificates, algconstraints);
}
@@ -244,7 +218,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, trustedCerts, algConstraints);
+ final VerificationResult result =
+ validateSignature(serializedContent, EaafKeyStoreUtils.readCertsFromKeyStore(trustStore), algConstraints);
if (!result.isValidSigned()) {
log.info("JWS signature invalide. Stopping authentication process ...");
@@ -256,7 +231,7 @@ public class JsonSecurityUtils implements IJoseTools {
log.debug("SL2.0 commando signature validation sucessfull");
return result;
- } catch (JoseException | JsonParseException e) {
+ } catch (JoseException | JsonParseException | KeyStoreException e) {
log.warn("SL2.0 commando signature validation FAILED", e);
throw new SL20SecurityException(new Object[] { e.getMessage() }, e);
@@ -284,6 +259,9 @@ public class JsonSecurityUtils implements IJoseTools {
// set payload
receiverJwe.setCompactSerialization(compactSerialization);
+ Pair<Key, X509Certificate[]> encryptionCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore,
+ getEncryptionKeyAlias(), getEncryptionKeyPassword(), true, FRIENDLYNAME_KEYSTORE);
+
// validate key from header against key from config
final List<X509Certificate> x5cCerts = receiverJwe.getCertificateChainHeaderValue();
final String x5t256 = receiverJwe.getX509CertSha256ThumbprintHeaderValue();
@@ -292,7 +270,7 @@ public class JsonSecurityUtils implements IJoseTools {
log.trace("Sorting received X509 certificates ... ");
final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
- if (!sortedX5cCerts.get(0).equals(encCertChain[0])) {
+ if (!sortedX5cCerts.get(0).equals(encryptionCred.getSecond()[0])) {
log.info("Certificate from JOSE header does NOT match encryption certificate");
try {
@@ -307,7 +285,7 @@ public class JsonSecurityUtils implements IJoseTools {
} else if (StringUtils.isNotEmpty(x5t256)) {
log.debug("Found x5t256 fingerprint in JOSE header .... ");
- final String certFingerPrint = X509Util.x5tS256(encCertChain[0]);
+ final String certFingerPrint = X509Util.x5tS256(encryptionCred.getSecond()[0]);
if (!certFingerPrint.equals(x5t256)) {
log.info("X5t256 from JOSE header does NOT match encryption certificate");
log.debug("X5t256 from JOSE header: " + x5t256 + " Encrytption cert: " + certFingerPrint);
@@ -324,12 +302,12 @@ public class JsonSecurityUtils implements IJoseTools {
}
// set key
- receiverJwe.setKey(encPrivKey);
+ receiverJwe.setKey(encryptionCred.getFirst());
// decrypt payload
return mapper.getMapper().readTree(receiverJwe.getPlaintextString());
- } catch (final JoseException e) {
+ } catch (final JoseException | EaafKeyAccessException e) {
log.warn("SL2.0 result decryption FAILED", e);
throw new SL20SecurityException(new Object[] { e.getMessage() }, e);
@@ -340,37 +318,74 @@ 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);
+
}
-
}
@Override
public X509Certificate getEncryptionCertificate() {
- // TODO: maybe update after SL2.0 update on encryption certificate parts
- if (encCertChain != null && encCertChain.length > 0) {
- return encCertChain[0];
- } else {
- return null;
+ Pair<Key, X509Certificate[]> encryptionCred;
+ try {
+ encryptionCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore,
+ getEncryptionKeyAlias(), getEncryptionKeyPassword(), false, FRIENDLYNAME_KEYSTORE);
+ if (encryptionCred != null && encryptionCred.getSecond().length > 0) {
+ return encryptionCred.getSecond()[0];
+
+ }
+
+ } catch (EaafKeyAccessException e) {
+ log.trace("Exception is skipped because Encryption is not mandatory on this level", e);
+
}
+
+ return null;
+
}
- private String getKeyStoreFilePath() throws EaafConfigurationException, MalformedURLException {
- return FileUtils.makeAbsoluteUrl(authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PATH),
- authConfig.getConfigurationRootDirectory());
+ private KeyStoreConfiguration buildKeyStoreConfiguration() throws EaafConfigurationException {
+ KeyStoreConfiguration config = new KeyStoreConfiguration();
+ config.setFriendlyName(FRIENDLYNAME_KEYSTORE);
+
+ config.setKeyStoreType(authConfig.getBasicConfiguration(
+ authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_TYPE),
+ KeyStoreType.JKS.getKeyStoreType()));
+ config.setKeyStoreName(
+ authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_NAME));
+ config.setSoftKeyStoreFilePath(
+ 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 String getKeyStorePassword() {
- String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD);
- if (value != null) {
- value = value.trim();
- }
-
- return value;
-
+
+ private KeyStoreConfiguration buildTrustStoreConfiguration() throws EaafConfigurationException {
+ KeyStoreConfiguration config = new KeyStoreConfiguration();
+ config.setFriendlyName(FRIENDLYNAME_TRUSTSTORE);
+
+ config.setKeyStoreType(authConfig.getBasicConfiguration(
+ authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_TRUSTSTORE_TYPE),
+ KeyStoreType.JKS.getKeyStoreType()));
+ config.setKeyStoreName(
+ authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_TRUSTSTORE_NAME));
+ config.setSoftKeyStoreFilePath(
+ 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).trim();
+ String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS);
if (value != null) {
value = value.trim();
}
@@ -378,18 +393,17 @@ public class JsonSecurityUtils implements IJoseTools {
return value;
}
- private String getSigningKeyPassword() {
- String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD).trim();
+ private char[] getSigningKeyPassword() {
+ String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD);
if (value != null) {
- value = value.trim();
+ return value.trim().toCharArray();
}
- return value;
+ return null;
}
private String getEncryptionKeyAlias() {
- String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS)
- .trim();
+ String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS);
if (value != null) {
value = value.trim();
}
@@ -397,36 +411,13 @@ public class JsonSecurityUtils implements IJoseTools {
return value;
}
- private String getEncryptionKeyPassword() {
- String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD)
- .trim();
+ private char[] getEncryptionKeyPassword() {
+ String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD);
if (value != null) {
- value = value.trim();
- }
-
- return value;
- }
-
- @Nonnull
- private List<X509Certificate> readCertsFromKeyStore(@Nonnull final KeyStore keyStore) throws KeyStoreException {
- final List<X509Certificate> result = new ArrayList<>();
-
- final Enumeration<String> aliases = keyStore.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 (cert != null && cert instanceof X509Certificate) {
- result.add((X509Certificate) cert);
- } else {
- log.info("Can not process entry: {}. Reason: {}", el, cert != null ? cert.getType() : "cert is null");
- }
-
- }
+ return value.trim().toCharArray();
}
- return Collections.unmodifiableList(result);
+ return null;
}
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/pom.xml b/eaaf_modules/eaaf_module_pvp2_core/pom.xml
index c9aac506..a81ad889 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/pom.xml
+++ b/eaaf_modules/eaaf_module_pvp2_core/pom.xml
@@ -22,7 +22,6 @@
<artifactId>eaaf-core</artifactId>
<version>${egiz.eaaf.version}</version>
</dependency>
-
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml-core</artifactId>
@@ -82,6 +81,12 @@
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ <version>1.4.01</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java
index 8a33b205..902f84c7 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java
@@ -406,6 +406,7 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec
private void addAndRemoveMetadataProvider() throws EaafConfigurationException {
log.info("EAAF chaining metadata resolver starting internal managment task .... ");
+
// get all actually loaded metadata providers
final Map<String, MetadataResolver> loadedproviders = getAllActuallyLoadedResolvers();
@@ -428,6 +429,7 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec
try {
if (StringUtils.isNotEmpty(metadataurl)
&& loadedproviders.containsKey(metadataurl)) {
+ // SAML2 SP is actually loaded, to nothing
loadedproviders.remove(metadataurl);
}
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 6959b6bd..cd77228c 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
@@ -19,8 +19,6 @@
package at.gv.egiz.eaaf.modules.pvp2.impl.utils;
-import java.io.IOException;
-import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
@@ -33,24 +31,24 @@ 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.utils.KeyStoreUtils;
+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.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.opensaml.security.credential.UsageType;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.ResourceLoader;
-
import lombok.extern.slf4j.Slf4j;
@Slf4j
@@ -63,6 +61,9 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi
@Autowired
protected IConfiguration basicConfig;
+ @Autowired
+ private EaafKeyStoreFactory keyStoreFactory;
+
private KeyStore keyStore = null;
/**
@@ -71,23 +72,25 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi
*
* @return keyStore friendlyName
*/
- public abstract String getFriendlyName();
+ public final String getFriendlyName() {
+ try {
+ return getBasicKeyStoreConfig().getFriendlyName();
+
+ } catch (EaafConfigurationException e) {
+ return "No KeyStoreName";
+
+ }
- /**
- * Get KeyStore.
- *
- * @return URL to the keyStore
- * @throws EaafException In case of an invalid filepath
- */
- @Nonnull
- public abstract String getKeyStoreFilePath() throws EaafException;
+ }
/**
- * Get keyStore password.
+ * Get the basic KeyStore configuration object for this SAML2 credential.
*
- * @return Password of the keyStore
+ * @return KeyStore configuration object
+ * @throws EaafConfigurationException In case of a configuration error
*/
- public abstract String getKeyStorePassword();
+ @Nonnull
+ public abstract KeyStoreConfiguration getBasicKeyStoreConfig() throws EaafConfigurationException;
/**
* Get alias of key for metadata signing.
@@ -154,8 +157,6 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi
}
}
-
-
/**
* Get Credentials to sign SAML2 messages, like AuthnRequest, Response,
* Assertions as some examples.
@@ -250,21 +251,36 @@ public abstract class AbstractCredentialProvider implements IPvp2CredentialProvi
}
- @Lazy
@PostConstruct
private void initialize() throws Exception {
try {
- final Resource ressource = resourceLoader.getResource(getKeyStoreFilePath());
- final InputStream is = ressource.getInputStream();
- keyStore = KeyStoreUtils.loadKeyStore(is, getKeyStorePassword());
+ final KeyStoreConfiguration keyStoreConfig = getBasicKeyStoreConfig();
+ keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+
+ if (JCEMapper.getProviderId() != null
+ && !JCEMapper.getProviderId().equals(keyStore.getProvider().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(),
+ JCEMapper.getProviderId());
+ throw new EaafConfigurationException(EaafKeyStoreFactory.ERRORCODE_06,
+ new Object[] { keyStoreConfig.getFriendlyName(),
+ "OpenSAML3.x can ONLY use a single type of CryptoProvider" });
+
+ }
- if (keyStore == null) {
- throw new EaafConfigurationException("module.00",
- new Object[] { getFriendlyName(), "KeyStore initialization failed. Maybe wrong password" });
+ // 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())
+ && JCEMapper.getProviderId() == null) {
+ log.info("Register CryptoProvider: {} as defaut for OpenSAML3.x",
+ keyStore.getProvider().getName());
+ JCEMapper.setProviderId(keyStore.getProvider().getName());
}
- } catch (IOException | KeyStoreException | EaafException e) {
+ } catch (final EaafException e) {
log.error("Can not initialize KeyStore for eIDAS authentication client.", e);
throw e;
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java
index b6171e97..22ee389f 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java
@@ -3,14 +3,8 @@ package at.gv.egiz.eaaf.modules.pvp2.test;
import java.security.cert.X509Certificate;
import java.util.List;
-import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
-import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfigMap;
-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.exception.CredentialsNotAvailableException;
-import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
-
import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.xml.security.algorithms.JCEMapper;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -23,6 +17,14 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafFactoryException;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfigMap;
+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.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
@@ -34,9 +36,14 @@ public class CredentialProviderTest {
private static final String PATH_JKS_WITH_TRUST_CERTS = "src/test/resources/data/junit.jks";
private static final String PATH_JKS_WITHOUT_TRUST_CERTS = "src/test/resources/data/junit_without_trustcerts.jks";
+ //private static final String HSMF_ALIAS_METADATA = "shibboleth-sign";
+ //private static final String HSMF_ALIAS_SIGN = "shibboleth-sign";
+ //private static final String HSMF_ALIAS_ENC = "shibboleth-sign";
+
private static final String ALIAS_METADATA = "meta";
private static final String ALIAS_SIGN = "sig";
private static final String ALIAS_ENC = "meta";
+
private static final String PASSWORD = "password";
@@ -59,6 +66,8 @@ public class CredentialProviderTest {
config.removeConfigValue(DummyCredentialProvider.KEY_ENCRYPTION_ALIAS);
config.removeConfigValue(DummyCredentialProvider.KEY_ENCRYPTION_PASSWORD);
+
+ JCEMapper.setProviderId(null);
}
@@ -86,7 +95,7 @@ public class CredentialProviderTest {
Assert.fail("No KeyStore not detected");
} catch (final BeansException e) {
- org.springframework.util.Assert.isInstanceOf(java.io.FileNotFoundException.class,
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class,
e.getCause(), "Wrong exception");
}
@@ -101,7 +110,7 @@ public class CredentialProviderTest {
Assert.fail("No KeyStore not detected");
} catch (final BeansException e) {
- org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class,
+ org.springframework.util.Assert.isInstanceOf(EaafFactoryException.class,
e.getCause(), "Wrong exception");
}
@@ -384,6 +393,33 @@ public class CredentialProviderTest {
@Test
@DirtiesContext
+ public void otherKeyStoreTypeAlreadyLoaded() throws CredentialsNotAvailableException {
+ config.putConfigValue(DummyCredentialProvider.KEYSTORE_PATH, PATH_JKS_WITHOUT_TRUST_CERTS);
+
+ config.putConfigValue(PvpConstants.CONFIG_PROP_SEC_SIGNING_RSA_ALG,
+ "RSA-SIG_" + RandomStringUtils.randomAlphabetic(10));
+ config.putConfigValue(PvpConstants.CONFIG_PROP_SEC_SIGNING_EC_ALG,
+ "EC-SIG_" + RandomStringUtils.randomAlphabetic(10));
+ config.putConfigValue(PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_KEY_RSA_ALG,
+ "RSA_ENC_" + RandomStringUtils.randomAlphabetic(10));
+ config.putConfigValue(PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_KEY_EC_ALG,
+ "EC-ENC_" + RandomStringUtils.randomAlphabetic(10));
+
+ try {
+ JCEMapper.setProviderId(RandomStringUtils.randomAlphabetic(5));
+
+ context.getBean(DummyCredentialProvider.class);
+
+ } catch (final BeansException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class,
+ e.getCause(), "Wrong exception");
+
+ }
+
+ }
+
+ @Test
+ @DirtiesContext
public void notKeyConfiguration() {
final DummyCredentialProvider credential = context.getBean(DummyCredentialProvider.class);
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyCredentialProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyCredentialProvider.java
index b9f1326d..0f8eff72 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyCredentialProvider.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyCredentialProvider.java
@@ -1,15 +1,12 @@
package at.gv.egiz.eaaf.modules.pvp2.test.dummy;
-import java.net.MalformedURLException;
+import org.springframework.beans.factory.annotation.Autowired;
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.utils.FileUtils;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType;
import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
-import org.springframework.beans.factory.annotation.Autowired;
-
public class DummyCredentialProvider extends AbstractCredentialProvider {
@Autowired IConfiguration basicConfig;
@@ -26,32 +23,26 @@ public class DummyCredentialProvider extends AbstractCredentialProvider {
public static final String KEY_ENCRYPTION_ALIAS = "key.enc.alias";
public static final String KEY_ENCRYPTION_PASSWORD = "key.enc.pass";
+ private static final String KEYSTORENAME = "jUnit test credential provider";
+
@Override
- public String getFriendlyName() {
- return "jUnit test credential provider";
+ public KeyStoreConfiguration getBasicKeyStoreConfig() {
+ KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.JKS);
+ keyStoreConfig.setFriendlyName(KEYSTORENAME);
+
+ keyStoreConfig.setSoftKeyStoreFilePath(getKeyStoreFilePath());
+ keyStoreConfig.setSoftKeyStorePassword(getKeyStorePassword());
+
+ return keyStoreConfig;
}
- @Override
- public String getKeyStoreFilePath() throws EaafException {
+ public String getKeyStoreFilePath() {
final String path = basicConfig.getBasicConfiguration(KEYSTORE_PATH);
-
- if (path != null) {
- try {
- return FileUtils.makeAbsoluteUrl(
- path,
- basicConfig.getConfigurationRootDirectory());
-
- } catch (final MalformedURLException e) {
- throw new EaafConfigurationException("internel test error", null, e);
-
- }
- }
-
- throw new EaafConfigurationException("No keyStore path", null);
-
+ return path;
+
}
- @Override
public String getKeyStorePassword() {
return basicConfig.getBasicConfiguration(KEYSTORE_PASSWORD);
}
@@ -86,4 +77,5 @@ public class DummyCredentialProvider extends AbstractCredentialProvider {
return basicConfig.getBasicConfiguration(KEY_ENCRYPTION_PASSWORD);
}
+
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/config/config_2.props b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/config/config_2.props
new file mode 100644
index 00000000..60cecebb
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/config/config_2.props
@@ -0,0 +1,12 @@
+keystore.path=classpath:/data/junit.jks
+keystore.pass=password
+key.metadata.alias=shibboleth-sign
+key.metadata.pass=password
+key.sig.alias=shibboleth-sign
+key.sig.pass=password
+key.enc.alias=
+key.enc.pass=
+
+client.http.connection.timeout.socket=2
+client.http.connection.timeout.connection=2
+client.http.connection.timeout.request=2 \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core.beans.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core.beans.xml
index 3b2d0a28..5e3f0b9b 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core.beans.xml
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core.beans.xml
@@ -19,4 +19,7 @@
<bean id="httpClientFactory"
class="at.gv.egiz.eaaf.core.impl.utils.HttpClientFactory" />
+ <bean id="eaafKeyStoreFactory"
+ class="at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory" />
+
</beans> \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_spring_config.beans.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_spring_config.beans.xml
index 5c1a6095..5319236b 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_spring_config.beans.xml
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_spring_config.beans.xml
@@ -14,4 +14,7 @@
class="at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfig" />
+ <bean id="eaafKeyStoreFactory"
+ class="at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory" />
+
</beans> \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_1.props b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_1.props
index 6324f190..164b8807 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_1.props
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_1.props
@@ -7,8 +7,6 @@ key.sig.pass=password
key.enc.alias=
key.enc.pass=
-pvp2.assertion.encryption.active=true
-
client.http.connection.timeout.socket=2
client.http.connection.timeout.connection=2
client.http.connection.timeout.request=2 \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_2.props b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_2.props
new file mode 100644
index 00000000..60cecebb
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/config/config_2.props
@@ -0,0 +1,12 @@
+keystore.path=classpath:/data/junit.jks
+keystore.pass=password
+key.metadata.alias=shibboleth-sign
+key.metadata.pass=password
+key.sig.alias=shibboleth-sign
+key.sig.pass=password
+key.enc.alias=
+key.enc.pass=
+
+client.http.connection.timeout.socket=2
+client.http.connection.timeout.connection=2
+client.http.connection.timeout.request=2 \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml
index f46b7747..99552053 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml
@@ -25,4 +25,7 @@
<bean id="dummyRevisionLogger"
class="at.gv.egiz.eaaf.core.impl.logging.DummyRevisionsLogger" />
+ <bean id="eaafKeyStoreFactory"
+ class="at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory" />
+
</beans> \ No newline at end of file