summaryrefslogtreecommitdiff
path: root/eaaf_core_utils
diff options
context:
space:
mode:
authorThomas <>2023-05-08 17:24:41 +0200
committerThomas <>2023-05-08 17:24:41 +0200
commit1e5c2de3a4aafb476070478b27a18caf9efc051b (patch)
tree57abbdf5554a35725f49c3c7f0458aebea0faeea /eaaf_core_utils
parent632a2a06d450da92685811325e7967a4f7471cae (diff)
downloadEAAF-Components-1e5c2de3a4aafb476070478b27a18caf9efc051b.tar.gz
EAAF-Components-1e5c2de3a4aafb476070478b27a18caf9efc051b.tar.bz2
EAAF-Components-1e5c2de3a4aafb476070478b27a18caf9efc051b.zip
feat(core): add in-line method to KeyStoreFactory
The keystore type 'inline' can be used to build a keystore by using PEM encoded certificate and key files. Example: pkcs12:keystore?private=certs/key.pem&cert=certs/certificate.pem
Diffstat (limited to 'eaaf_core_utils')
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java39
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/KeyStoreConfiguration.java7
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/inline/InlineKeyStoreBuilder.java165
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/inline/InlineKeyStoreParser.java149
-rw-r--r--eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties5
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EaafKeyStoreFactoryTest.java83
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/InlineKeyStoreTest.java140
-rw-r--r--eaaf_core_utils/src/test/resources/data/certs/BRZStammCA201.pem33
-rw-r--r--eaaf_core_utils/src/test/resources/data/certs/invalidCertificate.pem19
-rw-r--r--eaaf_core_utils/src/test/resources/data/certs/privateEcKey.pem5
-rw-r--r--eaaf_core_utils/src/test/resources/data/certs/privateKey.pem28
-rw-r--r--eaaf_core_utils/src/test/resources/data/certs/selfSignedCertificate.pem19
-rw-r--r--eaaf_core_utils/src/test/resources/data/certs/selfSignedEcCertificate.pem11
13 files changed, 701 insertions, 2 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 623e9d2c..fc3fa19d 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
@@ -5,6 +5,9 @@ import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStore.LoadStoreParameter;
@@ -39,6 +42,7 @@ 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.credential.inline.InlineKeyStoreParser;
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;
@@ -64,6 +68,9 @@ public class EaafKeyStoreFactory {
public static final String ERRORCODE_07 = "internal.keystore.07";
public static final String ERRORCODE_10 = "internal.keystore.10";
public static final String ERRORCODE_11 = "internal.keystore.11";
+ public static final String ERRORCODE_12 = "internal.keystore.12";
+ public static final String ERRORCODE_13 = "internal.keystore.13";
+ public static final String ERRORCODE_14 = "internal.keystore.14";
public static final String ERRORCODE_KEY_00 = "internal.key.00";
@@ -142,6 +149,9 @@ public class EaafKeyStoreFactory {
|| KeyStoreType.JKS.equals(config.getKeyStoreType())) {
return getKeyStoreFromFileSystem(config);
+ } else if (KeyStoreType.INLINE.equals(config.getKeyStoreType())) {
+ return getKeyStoreFromInlineConfiguration(config);
+
} else if (KeyStoreType.HSMFACADE.equals(config.getKeyStoreType())) {
if (isHsmFacadeInitialized) {
return getKeyStoreFromHsmFacade(config);
@@ -339,6 +349,33 @@ public class EaafKeyStoreFactory {
}
@Nonnull
+ private Pair<KeyStore, Provider> getKeyStoreFromInlineConfiguration(KeyStoreConfiguration config)
+ throws EaafConfigurationException {
+ try {
+ log.debug("Loading keystore from in-line configuration URL ... ");
+ return Pair.newInstance(
+ InlineKeyStoreParser.buildKeyStore(
+ new URL(null,
+ config.getSoftKeyStoreFilePath(),
+ new InlineKeyStoreParser()),
+ resourceLoader,
+ basicConfig.getConfigurationRootDirectory()),
+ null);
+
+ } catch (MalformedURLException e) {
+ log.error("Inline KeyStore URL has no valid form.", e);
+ throw new EaafConfigurationException(ERRORCODE_13,
+ new Object[] { config.getSoftKeyStoreFilePath(), e.getMessage() }, e);
+
+ } catch (IOException | GeneralSecurityException e) {
+ log.error("Inline KeyStore initialization FAILED with an generic error.", e);
+ throw new EaafConfigurationException(ERRORCODE_13, new Object[] { e.getMessage() }, e);
+
+ }
+
+ }
+
+ @Nonnull
private Pair<KeyStore, Provider> getKeyStoreFromFileSystem(KeyStoreConfiguration config)
throws EaafConfigurationException, EaafFactoryException {
try {
@@ -384,7 +421,7 @@ public class EaafKeyStoreFactory {
} 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);
+ throw new EaafConfigurationException(ERRORCODE_12, new Object[] { e.getMessage() }, e);
}
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/KeyStoreConfiguration.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/KeyStoreConfiguration.java
index c1a1d917..7e66ca86 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/KeyStoreConfiguration.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/KeyStoreConfiguration.java
@@ -154,6 +154,11 @@ public class KeyStoreConfiguration {
checkConfigurationValue(keyStoreName, EaafKeyStoreFactory.ERRORCODE_07,
friendlyName, "Missing 'KeyName' for HSM-Facade");
+ } else if (KeyStoreType.INLINE.equals(keyStoreType)) {
+ log.trace("Validate in-line KeyStore ... ");
+ checkConfigurationValue(softKeyStoreFilePath, EaafKeyStoreFactory.ERRORCODE_07,
+ friendlyName, "Missing 'KeyPath' for in-line keystore");
+
} else if (KeyStoreType.PKCS12.equals(keyStoreType)
|| KeyStoreType.JKS.equals(keyStoreType)) {
log.trace("Validate software KeyStore ... ");
@@ -169,7 +174,7 @@ public class KeyStoreConfiguration {
}
public enum KeyStoreType {
- PKCS12("pkcs12"), JKS("jks"), HSMFACADE("hsmfacade"), PKCS11("pkcs11");
+ PKCS12("pkcs12"), JKS("jks"), HSMFACADE("hsmfacade"), PKCS11("pkcs11"), INLINE("inline");
private final String keyStoreType;
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/inline/InlineKeyStoreBuilder.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/inline/InlineKeyStoreBuilder.java
new file mode 100644
index 00000000..a1e3a824
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/inline/InlineKeyStoreBuilder.java
@@ -0,0 +1,165 @@
+package at.gv.egiz.eaaf.core.impl.credential.inline;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URI;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Objects;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.openssl.PEMKeyPair;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Convenience class to load keys and certificates in PEM-format into a
+ * {@link KeyStore} by providing the file paths.
+ */
+@Slf4j
+public class InlineKeyStoreBuilder {
+ private final KeyStore keyStore;
+ private final ResourceLoader loader;
+ private final URI configRootDir;
+
+ /**
+ * Create a new instance.
+ *
+ * @param type the type of the KeyStore to be built, e.g.
+ * "PKCS12"
+ * @param configRootDirectory Root directory for configuration
+ * @param resourceLoader Spring ResourceLoader
+ * @throws GeneralSecurityException if the empty KeyStore object could not be
+ * created
+ * @throws IOException if the empty KeyStore object could not be
+ * created
+ */
+ public InlineKeyStoreBuilder(String type, ResourceLoader resourceLoader,
+ URI configRootDirectory)
+ throws GeneralSecurityException, IOException {
+ loader = resourceLoader;
+ configRootDir = configRootDirectory;
+
+ keyStore = KeyStore.getInstance(type);
+ keyStore.load(null, null);
+
+ }
+
+ /**
+ * Sets a key entry, i.e. build a key store.
+ *
+ * @param privateKeyFile the path to the private key file
+ * @param certificateFiles the paths to the certificate files
+ * @throws GeneralSecurityException if a file could not be parsed
+ * @throws IOException if a file could not be read
+ * @throws EaafConfigurationException if a file could not be found
+ */
+ public void setKeyEntry(String privateKeyFile, String[] certificateFiles)
+ throws GeneralSecurityException, IOException, EaafConfigurationException {
+ final X509Certificate[] certificates = readCertificates(certificateFiles);
+ final PrivateKey privateKey = readPrivateKey(privateKeyFile);
+ keyStore.setKeyEntry("keyEntry", privateKey, new char[0], certificates);
+
+ }
+
+ /**
+ * Sets certificate entries, i.e. build a trust store.
+ *
+ * @param certificateFiles the path to the certificate files
+ * @throws GeneralSecurityException if a file could not be parsed
+ */
+ public void setCertificateEntries(String[] certificateFiles) throws GeneralSecurityException {
+
+ final X509Certificate[] certificates = readCertificates(certificateFiles);
+
+ for (int i = 0; i < certificates.length; i++) {
+ keyStore.setCertificateEntry("certificateEntry" + i, certificates[i]);
+ }
+ }
+
+ /**
+ * Sets a secret key, i.e. builds a keystore.
+ *
+ * @param secret the secret encoded as a Base64 string
+ * @throws KeyStoreException if the secret key could not be added to the store
+ */
+ public void setSecretEntry(final String secret) throws KeyStoreException {
+ final byte[] decodedKey = Base64.getDecoder().decode(secret);
+ final SecretKey key = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
+ keyStore.setEntry("secret", new KeyStore.SecretKeyEntry(key),
+ new KeyStore.PasswordProtection(new char[] {}));
+ }
+
+ public KeyStore getKeyStore() {
+ return keyStore;
+ }
+
+ private X509Certificate[] readCertificates(String[] certificateFiles) throws CertificateException {
+ final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+
+ return Arrays.stream(certificateFiles).map(certificateFile -> {
+ try (InputStream is = readResourceFromFile(certificateFile)) {
+ return (X509Certificate) certificateFactory.generateCertificate(is);
+
+ } catch (CertificateException | IOException | EaafConfigurationException e) {
+ log.error("Failed to load certificate file {}.", certificateFile, e);
+ return null;
+
+ }
+ }).filter(Objects::nonNull).toArray(X509Certificate[]::new);
+ }
+
+ private PrivateKey readPrivateKey(String filePath) throws IOException, EaafConfigurationException {
+ try (
+ Reader fileReader = new InputStreamReader(readResourceFromFile(filePath));
+ PEMParser pemParser = new PEMParser(fileReader)) {
+
+ final Object object = pemParser.readObject();
+ final JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
+
+ if (object instanceof PrivateKeyInfo) {
+ return converter.getPrivateKey((PrivateKeyInfo) object);
+
+ } else if (object instanceof PEMKeyPair) {
+ return converter.getKeyPair((PEMKeyPair) object).getPrivate();
+
+ } else {
+ throw new IllegalArgumentException("Unsupported object: " + object.getClass());
+
+ }
+ }
+ }
+
+ private InputStream readResourceFromFile(String filePath) throws IOException, EaafConfigurationException {
+ final String absKeyStorePath = FileUtils.makeAbsoluteUrl(filePath, configRootDir);
+ log.debug("Use filepath from config: {}", absKeyStorePath);
+ Resource ressource = loader.getResource(absKeyStorePath);
+
+ if (!ressource.exists()) {
+ throw new EaafConfigurationException("internal.keystore.15",
+ new Object[] { "RessourceLoader does NOT find File at: " + ressource.getURI() });
+
+ }
+
+ return ressource.getInputStream();
+
+ }
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/inline/InlineKeyStoreParser.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/inline/InlineKeyStoreParser.java
new file mode 100644
index 00000000..0ddc2680
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/inline/InlineKeyStoreParser.java
@@ -0,0 +1,149 @@
+package at.gv.egiz.eaaf.core.impl.credential.inline;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLDecoder;
+import java.net.URLStreamHandler;
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.springframework.core.io.ResourceLoader;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Parse in-line keystore configuration in BRZ format.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class InlineKeyStoreParser extends URLStreamHandler {
+
+ @Override
+ protected URLConnection openConnection(URL u) throws IOException {
+ log.error("openConnection is not implemented by {}", InlineKeyStoreParser.class);
+ return null;
+
+ }
+
+ /**
+ * Build a {@link KeyStore} object from an in-line configuration {@link URL}.
+ *
+ * @param configUrl configuration URL
+ * @param configRootDirectory Root directory for configuration
+ * @param resourceLoader Spring ResourceLoader
+ * @return KeyStore created by configuration URL
+ * @throws IOException In case of a configuration read error
+ * @throws GeneralSecurityException In case of a KeyStore configuration error
+ * @throws EaafConfigurationException If keyfile can not be found
+ */
+ public static KeyStore buildKeyStore(URL configUrl, ResourceLoader resourceLoader, URI configRootDirectory)
+ throws IOException, GeneralSecurityException, EaafConfigurationException {
+ log.trace("Parsing keystore config from URL: {}", configUrl);
+ InlineKeyStoreBuilder keyStoreBuilder = new InlineKeyStoreBuilder(
+ configUrl.getProtocol(), resourceLoader, configRootDirectory);
+
+ // parse basis properties from URL
+ final Map<String, List<String>> queryParams = parseQuery(configUrl.getQuery());
+ final String[] certificateFiles = queryParams.getOrDefault("cert", Collections.emptyList())
+ .toArray(String[]::new);
+
+ if ("keystore".equalsIgnoreCase(configUrl.getPath())) {
+ parseKeyStore(keyStoreBuilder, queryParams, certificateFiles);
+
+ } else if ("truststore".equalsIgnoreCase(configUrl.getPath())) {
+ keyStoreBuilder.setCertificateEntries(certificateFiles);
+
+ } else {
+ throw new IllegalArgumentException("Unknown store type: " + configUrl.getPath());
+
+ }
+
+ return keyStoreBuilder.getKeyStore();
+ }
+
+ /**
+ * Takes the <i>queryParams</i> and builds based on them a {@link KeyStore} with
+ * secret and/or private key.
+ *
+ * @param keyStoreBuilder
+ *
+ * @param queryParams a map of all query params
+ * @param certificateFiles list of certificates
+ * @throws GeneralSecurityException if private or secret key cannot be parsed
+ * @throws IOException if private or secret key cannot be parsed
+ * @throws EaafConfigurationException if keyfile can not be found
+ */
+ private static void parseKeyStore(InlineKeyStoreBuilder keyStoreBuilder,
+ final Map<String, List<String>> queryParams, final String[] certificateFiles)
+ throws GeneralSecurityException, IOException, EaafConfigurationException {
+ final List<String> privateKeyList = queryParams.get("private");
+ final List<String> secretKeyList = queryParams.get("inlineSecret");
+
+ if (privateKeyList == null && secretKeyList == null) {
+ throw new IllegalArgumentException("Neither secret key nor private key are configured!");
+
+ }
+
+ if (privateKeyList != null) {
+ if (privateKeyList.size() == 1) {
+ final String privateKeyFile = queryParams.get("private").get(0);
+ keyStoreBuilder.setKeyEntry(privateKeyFile, certificateFiles);
+
+ } else {
+ throw new IllegalArgumentException("Exactly one private key must be specified!");
+
+ }
+ }
+
+ if (secretKeyList != null) {
+ if (secretKeyList.size() == 1) {
+ final String secret = URLDecoder.decode(secretKeyList.get(0), StandardCharsets.UTF_8);
+ keyStoreBuilder.setSecretEntry(secret);
+
+ } else {
+ throw new IllegalArgumentException("Exactly one secret key must be specified!");
+
+ }
+ }
+ }
+
+ private static Map<String, List<String>> parseQuery(String query) {
+ if (query != null) {
+ final Map<String, List<String>> queryParams = Arrays
+ .stream(query.split("&")) // generate a stream of key=value pairs
+ .map(keyValuePair -> keyValuePair.split("=")) // map key=value strings to arrays
+ .map(keyValuePair -> new AbstractMap.SimpleEntry<String, String>(keyValuePair[0],
+ keyValuePair[1])) // map arrays to Entry objects
+ .collect(Collectors
+ .groupingBy(AbstractMap.SimpleEntry::getKey)) // group entries with identical keys to a map of
+ // lists
+ .entrySet().stream() // stream the map again
+ .map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey(),
+ entry.getValue().stream().map(AbstractMap.SimpleEntry::getValue).collect(Collectors
+ .toList()))) // map the lists of Entry objects to lists of Strings
+ .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey,
+ AbstractMap.SimpleEntry::getValue)); // collect the stream to a map
+
+ log.trace("Query map: {}", queryParams);
+ return queryParams;
+
+ } else {
+ log.warn("Empty query string");
+ return Collections.emptyMap();
+
+ }
+ }
+
+}
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 79f82af8..2cc4e22e 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
@@ -13,6 +13,11 @@ 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.keystore.11=KeyStore: {0} has a wrong configuration. Property: {0} Reason:{1}
+internal.keystore.12=Software KeyStore initialization failed with a generic error: {0}
+internal.keystore.13=Can not build KeyStore from in-line configuration. Reason: {0}
+internal.keystore.14=KeyStore with in-line configuration: {0} is not a valid URL. Reason: {1}
+internal.keystore.15=KeyStore with in-line configuration has an unknown query-parameter path. Reason: {0}
+
internal.key.00=Can not generate passphrase based symmetric-key: {0} Reason: {1}
internal.key.01=Can not use key from Keystore: {0} Reason: {1}
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 3e82c510..932beb31 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
@@ -1,5 +1,8 @@
package at.gv.egiz.eaaf.core.test.credentials;
+import static org.junit.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -385,6 +388,86 @@ public class EaafKeyStoreFactoryTest {
@Test
@DirtiesContext(methodMode = MethodMode.BEFORE_METHOD)
+ public void inlineKeyStoreMissingPath() throws EaafException {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.INLINE);
+
+ EaafConfigurationException error = assertThrows("wrong exception", EaafConfigurationException.class,
+ () -> keyStoreConfig.validate());
+ assertEquals("internal.keystore.07", error.getErrorId(), "wrong errorcode");
+
+ }
+
+ @Test
+ @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD)
+ public void inlineKeyStoreSuccess() throws EaafException {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.INLINE);
+ keyStoreConfig.setSoftKeyStoreFilePath(
+ "pkcs12:keystore?private=src/test/resources/data/certs/privateKey.pem"
+ + "&cert=src/test/resources/data/certs/selfSignedCertificate.pem"
+ + "&cert=src/test/resources/data/certs/issuingCa.pem&cert=certs/BRZStammCA201.pem");
+
+ keyStoreConfig.validate();
+
+ final Pair<KeyStore, Provider> keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.assertNotNull("KeyStore is null", keyStore);
+ Assert.assertNotNull("KeyStore is null", keyStore.getFirst());
+ Assert.assertNull("KeyStore is null", keyStore.getSecond());
+
+ }
+
+ @Test
+ @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD)
+ public void inlineKeyStoreEccSuccess() throws EaafException {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.INLINE);
+ keyStoreConfig.setSoftKeyStoreFilePath(
+ "pkcs12:keystore?private=src/test/resources/data/certs/privateEcKey.pem"
+ + "&cert=src/test/resources/data/certs/selfSignedEcCertificate.pem"
+ + "&cert=src/test/resources/data/certs/issuingCa.pem&cert=certs/BRZStammCA201.pem");
+
+ keyStoreConfig.validate();
+
+ final Pair<KeyStore, Provider> keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.assertNotNull("KeyStore is null", keyStore);
+ Assert.assertNotNull("KeyStore is null", keyStore.getFirst());
+ Assert.assertNull("KeyStore is null", keyStore.getSecond());
+
+ }
+
+ @Test
+ @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD)
+ public void inlineKeyStoreWrongKeys() throws EaafException {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.INLINE);
+ keyStoreConfig.setSoftKeyStoreFilePath(
+ "pkcs12:keystore?private=src/test/resources/data/certs/privateNotExist.pem"
+ + "&cert=src/test/resources/data/certs/selfSignedCertificate.pem"
+ + "&cert=src/test/resources/data/certs/issuingCa.pem&cert=certs/BRZStammCA201.pem");
+
+ keyStoreConfig.validate();
+
+ EaafConfigurationException error = assertThrows("wrong exception", EaafConfigurationException.class,
+ () -> keyStoreFactory.buildNewKeyStore(keyStoreConfig));
+ assertEquals("internal.keystore.15", error.getErrorId(), "wrong errorcode");
+
+ }
+
+ @Test
+ @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD)
public void symmetricSoftwareKeyWithOutConfig() {
final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/InlineKeyStoreTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/InlineKeyStoreTest.java
new file mode 100644
index 00000000..d4419956
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/InlineKeyStoreTest.java
@@ -0,0 +1,140 @@
+package at.gv.egiz.eaaf.core.test.credentials;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+
+import java.net.URL;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.annotation.DirtiesContext.ClassMode;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.credential.inline.InlineKeyStoreParser;
+import at.gv.egiz.eaaf.core.test.dummy.DummyAuthConfigMap;
+import lombok.SneakyThrows;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("/spring/test_eaaf_pvp_lazy.beans.xml")
+@DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD)
+public class InlineKeyStoreTest {
+
+ @Autowired
+ private DummyAuthConfigMap mapConfig;
+
+ @Autowired
+ private ResourceLoader resourceLoader;
+
+ @Test
+ @SneakyThrows
+ public void inlineKeyStoreEccSuccess() throws EaafException {
+ assertNotNull("no keystore", InlineKeyStoreParser.buildKeyStore(
+ new URL(null,
+ "pkcs12:keystore?private=src/test/resources/data/certs/privateEcKey.pem"
+ + "&cert=src/test/resources/data/certs/selfSignedEcCertificate.pem",
+ new InlineKeyStoreParser()),
+ resourceLoader,
+ mapConfig.getConfigurationRootDirectory()));
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void inlineTrustStoreSuccess() throws EaafException {
+ assertNotNull("no keystore", InlineKeyStoreParser.buildKeyStore(
+ new URL(null,
+ "pkcs12:truststore?"
+ + "cert=src/test/resources/data/certs/selfSignedEcCertificate.pem",
+ new InlineKeyStoreParser()),
+ resourceLoader,
+ mapConfig.getConfigurationRootDirectory()));
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void inlineKeyStoreSymSuccess() throws EaafException {
+ assertNotNull("no keystore", InlineKeyStoreParser.buildKeyStore(
+ new URL(null,
+ "pkcs12:keystore?"
+ + "inlineSecret=mxuqEAXci2cMNU5FCdbxIaNzJoMv%2FWds7j9gY992TTw%3D",
+ new InlineKeyStoreParser()),
+ resourceLoader,
+ mapConfig.getConfigurationRootDirectory()));
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void invalidCertFile() throws EaafException {
+ check("pkcs12:keystore?"
+ + "private=src/test/resources/data/certs/privateEcKey.pem"
+ + "&cert=src/test/resources/data/certs/invalidCertificate.pem");
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void missingKey() throws EaafException {
+ check("pkcs12:keystore?"
+ + "cert=src/test/resources/data/certs/selfSignedEcCertificate.pem"
+ + "&cert=src/test/resources/data/certs/BRZStammCA201.pem");
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void missingCert() throws EaafException {
+ check("pkcs12:keystore?"
+ + "private=src/test/resources/data/certs/privateEcKey.pem");
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void invalidType() throws EaafException {
+ check("pkcs12:unknown?"
+ + "private=src/test/resources/data/certs/privateEcKey.pem");
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void twoKeyFiles() throws EaafException {
+ check("pkcs12:keystore?"
+ + "cert=src/test/resources/data/certs/selfSignedEcCertificate.pem"
+ + "&private=src/test/resources/data/certs/privateEcKey.pem"
+ + "&private=src/test/resources/data/certs/privateEcKey.pem");
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void twoSymKeyFiles() throws EaafException {
+ check("pkcs12:keystore?"
+ + "inlineSecret=mxuqEAXci2cMNU5FCdbxIaNzJoMv%2FWds7j9gY992TTw%3D"
+ + "&inlineSecret=mxuqEAXci2cMNU5FCdbxIaNzJoMv%2FWds7j9gY992TTw%3D");
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void missingParams() throws EaafException {
+ check("pkcs12:keystore");
+
+ }
+
+ private void check(String url) {
+ assertThrows(IllegalArgumentException.class,
+ () -> InlineKeyStoreParser.buildKeyStore(
+ new URL(null, url, new InlineKeyStoreParser()), resourceLoader,
+ mapConfig.getConfigurationRootDirectory()));
+
+ }
+
+}
diff --git a/eaaf_core_utils/src/test/resources/data/certs/BRZStammCA201.pem b/eaaf_core_utils/src/test/resources/data/certs/BRZStammCA201.pem
new file mode 100644
index 00000000..2ff92f54
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/certs/BRZStammCA201.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgIIJXWL7AxEWoAwDQYJKoZIhvcNAQELBQAwXDELMAkGA1UE
+BhMCQVQxITAfBgNVBAoTGEJ1bmRlc3JlY2hlbnplbnRydW0gR21iSDEPMA0GA1UE
+CxMGQlJaIENBMRkwFwYDVQQDExBCUlotU3RhbW1DQS0yLTAxMB4XDTEzMDcwOTA3
+MDU1OVoXDTI4MDcwOTA3MDU1OVowXDELMAkGA1UEBhMCQVQxITAfBgNVBAoTGEJ1
+bmRlc3JlY2hlbnplbnRydW0gR21iSDEPMA0GA1UECxMGQlJaIENBMRkwFwYDVQQD
+ExBCUlotU3RhbW1DQS0yLTAxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
+AgEAx5iCz1dd/UHXQcI2l87ZGIXynvZv32NNKJfk2sw73Y51Zxn5WAoU92WLN7jH
+ajWVZYN4MqP/gOTpYTioFHVFIURrE3IjNQnaZt53lYBQW7Z7ZlDJG32pGNNeNEWG
+0rzrwRwpjdfVNf0eblw64kzfOVgLSvZjoSzpbkIHaB4WWTAdnvJTHZZl2zommKIH
+vTaf0nNv1lBWOCDO/uii+nrtFebnOcOmp09zwFoo78N8ujPmjpcO54EoKeczHr0P
+PEfEc+tFiPbIMbTG6UNudTXQHMsr/wumCn/ofuD2de2YhrIcl8n7yyIlmekTIQaj
+3w+P26WcLySYEzBXA+oZeDeoOzPDWEC18Jd61fe2VhTLTjZ2fi4ykpfjSgsrYjS4
+SFx/3z0Yj+Wv/XVZ7pnWzV4nrGfgL2cooz9ynTMNupt51qO9+zK7ScMeNzN5yPs9
+50N0XmKwFL1vJEIbz0df7ZTLACu5nRtg8yFf7yJJqG7JRRYoQbLZJWM7xHQU/5Mh
+cXLH4d5PHj8rlF5maubS3zqBEf+WtIUbt/NV952ETbk6qMLHpWXMU6cJ/xr8fAQE
+kL0rukJndtt/goSayN2OsXc3x7ZNN04C2u6J2M1mxe1Eykf+9xXB7dmgUHETnTEX
+tvGYsoBRgl/xKQ0PzwSUq+KnzDb990LFmoKIugmydCyomicCAwE4F6N9MHswHQYD
+VR0OBBYEFD2c5EOPAym+C0b8jPvP49gkuAWMMA8GA1UdEwEB/wQFMAMBAf8wHwYD
+VR0jBBgwFoAUPZzkQ48DKb4LRvyM+8/j2CS4BYwwGAYDVR0gBBEwDzANBgsrBgEE
+AbM4j10BATAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHVBo9N4
+G3oeYWfipKDMkEjIDd/XD0o4nl2DM1yb/ROzHvZAligFYl4sbcpjVLB0iB1ej27H
+lhXSRI41uUBVIV967c4Wp1RLmeA1n1O2dsdPByGe6B2pDQVo7hWIRaHmCRX3fOBN
+JkUuMMj5oGlP9OP2Vgl1c1bk2/CQlc3lwCEGLSkQQfgM6NEtIe+cwFZP91mFqDR9
+EQ1uTjBYmUq377bhqaPgQPDrzsHtOl0qxeOWrKn1mXdp9yiodlmEZ0WVkid90G6x
+MjYBZvC5Gl609IF/Rlip71y8kS7d36/+6e/AYudYP+oxggdCd4UF6dizor2HNePn
+O/R33dwSqdWroOTmFoCFFHRP11L3GOYqHdDEye03lBgzNKfEz+aKbnk+ic8fBvOm
+lY3sqro6q0GGIeVe7UVveO4X9MyAbk7qr1fhnuGSGe2PGh9/bWtpCcSy4YpWIGtC
+rbDchVB0HwuCuWbjWyvKcYSAdyomcUXtFv7PLejsS+qSMwHOYD2u08ob0a9jUVSz
+MGt1Za0cAuQbdyd2DS+tz/ZPJWUfhskArP2R3TvG0o2VYXaJggFSFBS1lCcbG1c0
+AxDwnb51qVrFnKNHtf41KkNkBurCW1ivp9gLD88KsDXdKMFp833d2CobiOQ7Qdyz
+hJ6g+4+HvoPh3ePls8vdtod51vXWXZFf3Rum
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/eaaf_core_utils/src/test/resources/data/certs/invalidCertificate.pem b/eaaf_core_utils/src/test/resources/data/certs/invalidCertificate.pem
new file mode 100644
index 00000000..bdabde6c
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/certs/invalidCertificate.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDCjCCAfKgAwIBAgIJAL1NdwD4ilEZMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
+BAMMD1Rlc3RDZXJ0aWZpY2F0ZTAeFw0yMjAzMDExNDU0NTBaFw0yMzAzMDExNDU0
+NTBaMBoxGDAWBgNVBAMMD1Rlc3RDZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAMfBJLAB0zebXutx4vHXRpwbw31SlABtOUvlcZLN0EDV
+TKO5NlIgSzlbjI1o+/KcEwIvT3J8MbqBTe7SCxiXKtiDCRPOWYLgGnCiEeyiRu8c
+hFFfvXER+Xh2o2H771tdIAglaNWrAREZNmr2iMNITXsvV1RJeEAnax8XviWAAdFg
+S7C+jDrRoN7YJ/74tKi+/UJJmjxQDtjds9oErcPvd7aj6RPc8p9SDx3WSL8A0/6y
+1AWavNYIbdQOY0xF4tGEnSm6ZLHlS3CZ2dvHlDdEhBEU4z0oSLjWn4Ty19oK46p7
+7YxHEGFKrQnXxICUMbG8KG1ycG4jE5XKT6vxkLdtYSMCAwEAAaNTMFEwHQYDVR0O
+BBYEFGJMN/2sdcWk2lhSfCHQZ9yX7BfnMB8GA1UdIwQYMBaAFGJMN/2sdcWk2lhS
+fCHQZ9yX7BfnMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACzj
+me1bqCbZXjPRIu7UCdIEqpeObd+c0Jd/Ba+tfeXymF1SKdxDo1MaVwHi+BpNfmYM
+9hCOTZcLlWY/ejD4XhhV2kYIo+7MxRrGP3B20+hJG+JiGmyDtsmEAWMJG+VZ5G+u
+fodyjuPl7KZXujdGwB2di9YIX//VRxyBka7ilq2vaabbcyapFVdB6s1mNEiFaLkrU0
+h7miSPA2p5KfStw4zJ62iyqhiouDUIpMOvblRTkgE4JToCjJn4cfo9gBmwtU1tg5
+VBlO992YteGRKN5FR1C0BkK/R5pnuhcifX7tPA+gGf/G2Jwv/m32huPylVojzVEz
+mH3QhlOXXl/1GbJ2vYc=
+-----END CERTIFICATE-----
diff --git a/eaaf_core_utils/src/test/resources/data/certs/privateEcKey.pem b/eaaf_core_utils/src/test/resources/data/certs/privateEcKey.pem
new file mode 100644
index 00000000..d26bf7d6
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/certs/privateEcKey.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIP3hE9RxmkYpQ+ic7FFJo26fHqMVzY/0idtQ4boi2z9BoAoGCCqGSM49
+AwEHoUQDQgAEN3saobVAMfR09+ngfs0y2QIaDUELTgvtPSgihR4Pr6z9e4HMaeGD
+vZXn7knl/dEk8KuhqTmg5Y3d41suKvN9yw==
+-----END EC PRIVATE KEY----- \ No newline at end of file
diff --git a/eaaf_core_utils/src/test/resources/data/certs/privateKey.pem b/eaaf_core_utils/src/test/resources/data/certs/privateKey.pem
new file mode 100644
index 00000000..acceb747
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/certs/privateKey.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHwSSwAdM3m17r
+ceLx10acG8N9UpQAbTlL5XGSzdBA1UyjuTZSIEs5W4yNaPvynBMCL09yfDG6gU3u
+0gsYlyrYgwkTzlmC4BpwohHsokbvHIRRX71xEfl4dqNh++9bXSAIJWjVqwERGTZq
+9ojDSE17L1dUSXhAJ2sfF74lgAHRYEuwvow60aDe2Cf++LSovv1CSZo8UA7Y3bPa
+BK3D73e2o+kT3PKfUg8d1ki/ANP+stQFmrzWCG3UDmNMReLRhJ0pumSx5Utwmdnb
+x5Q3RIQRFOM9KEi41p+E8tfaCuOqe+2MRxBhSq0J18SAlDGxvChtcnBuIxOVyk+r
+8ZC3bWEjAgMBAAECggEAPg9Cn7AheBA8YDfEw1AXrt5tUN08ABnvCCZjr7FjtxDN
+u7wKJV/FHy/TLgfk5s4YlcAvFamCJaiQltcI/X3RoOytAEtGwgNwE3g2y2brVNRu
+Q33UNHHaKNPrFMEZ7y+yiPVeaau0LCTCJF8txEYNVG0z24rr4jqc7E8LE0l+xxZw
+M1WVExtoXfqIfvfCCn/6ZCY0sDJyjMB+Xl5NIUU3nMbK3vzJh1n4vZMq3bSTLp/G
+ZKfxkKxpZwpZafLaSy4sjsUwdK79mwEvKYI7OBrUZ6LUOXUlMpiaFl6qUG5iVia+
+T6HW/vQFxQTAKTAXRsFvUGO4oAwPTkWal3VN+9xcUQKBgQDqWEAPpgXmjW2JqRzr
+8fcREN1+N8IZNqpaPpP5RZ//NvOz+yTibc/rEwjlcuSERS55YrkldEFsCROT9d7f
+CRkwNpF5Ciahy3ngUp9BNyb5gMXnNCPpgg1x/HRC62wJFvZzxE8cb2WhVq2eig/j
+GlldhAWtVOyfT/cas+fmW69NyQKBgQDaNpzIVnpJQZnP0Q8IHd4Alb9u4bm3iGM2
+0bwf4qBhOePjGQzZdgzlWJfLxLfnh31Gc3n/x+Vh7vEZCXoipjpEqp3SbDfjcYPg
+zvVLKcgp7xTPjFNPVmWkFbsP6HA5KBif/GV00kK7JM5TM5sr6rLYKoCnCdCOxcg7
+eyAw2at9iwKBgGxWpDcXz/6IP622qxJBaLFRFLT3Xhp99T+HUq2ZDKDWbNA2ORUd
+I1RQFnrNJOwpd5TSmTnBh0VE5PIwZvrBoA10DMjicn22LgAQ8mMZ9kC+0b9TkY6w
+ezrJNY6CfA2vufxHMzO4JEn0You61CFv2wSqtl0tt77nHxwPNBSBKohRAoGAV1ba
+g9kREvcd0C8V/CKwM728JG5Wfh4pz8w8pup3VNLt4nypRvTYDofaIeX30cTKIIOh
+xf3FUuBnQaUobGvqEIfVqV5FNFS/+x/6z/3GLvqRcszwn2WuQvGrsJ9RI59n08ka
+9poduXfu2SBjsD09HgZM/g6QmkSRczVB2iuVVycCgYEAiPUQtNmqPkHrIIbw69CK
+Pg3s3/L+Psl4yapuaREFcj1hgemOjsDPtwWCoFPbMnsn5MsiUyyhk5V9aeQL081a
+5r87dQxB2jSUAIurNj5nBz4oNqk1MhJMB1Eiv70+LT8rihHM33QYb2bgrwLjF3un
++cCXwCw5u64YJBBMeFRKW8Q=
+-----END PRIVATE KEY----- \ No newline at end of file
diff --git a/eaaf_core_utils/src/test/resources/data/certs/selfSignedCertificate.pem b/eaaf_core_utils/src/test/resources/data/certs/selfSignedCertificate.pem
new file mode 100644
index 00000000..a0e8b26c
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/certs/selfSignedCertificate.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDCjCCAfKgAwIBAgIJAL1NdwD4ilEZMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
+BAMMD1Rlc3RDZXJ0aWZpY2F0ZTAeFw0yMjAzMDExNDU0NTBaFw0yMzAzMDExNDU0
+NTBaMBoxGDAWBgNVBAMMD1Rlc3RDZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAMfBJLAB0zebXutx4vHXRpwbw31SlABtOUvlcZLN0EDV
+TKO5NlIgSzlbjI1o+/KcEwIvT3J8MbqBTe7SCxiXKtiDCRPOWYLgGnCiEeyiRu8c
+hFFfvXER+Xh2o2H771tdIAglaNWrAREZNmr2iMNITXsvV1RJeEAnax8XviWAAdFg
+S7C+jDrRoN7YJ/74tKi+/UJJmjxQDtjds9oErcPvd7aj6RPc8p9SDx3WSL8A0/6y
+1AWavNYIbdQOY0xF4tGEnSm6ZLHlS3CZ2dvHlDdEhBEU4z0oSLjWn4Ty19oK46p7
+7YxHEGFKrQnXxICUMbG8KG1ycG4jE5XKT6vxkLdtYSMCAwEAAaNTMFEwHQYDVR0O
+BBYEFGJMN/2sdcWk2lhSfCHQZ9yX7BfnMB8GA1UdIwQYMBaAFGJMN/2sdcWk2lhS
+fCHQZ9yX7BfnMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACzj
+me1bqCbZXjPRIu7UCdIEqpeObd+c0Jd/Ba+tfeXymF1SKdxDo1MaVwHi+BpNfmYM
+9hCOTZcLlWY/ejD4XhhV2kYIo+7MxRrGP3B20+hJG+JiGmyDtsmEAWMJG+VZ5G+u
+fodyjuPl7KZXujdGwB2di9YIX//VRxyBka7ilq2vxJayapFVdB6s1mNEiFaLkrU0
+h7miSPA2p5KfStw4zJ62iyqhiouDUIpMOvblRTkgE4JToCjJn4cfo9gBmwtU1tg5
+VBlO992YteGRKN5FR1C0BkK/R5pnuhcifX7tPA+gGf/G2Jwv/m32huPylVojzVEz
+mH3QhlOXXl/1GbJ2vYc=
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/eaaf_core_utils/src/test/resources/data/certs/selfSignedEcCertificate.pem b/eaaf_core_utils/src/test/resources/data/certs/selfSignedEcCertificate.pem
new file mode 100644
index 00000000..0661abe7
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/certs/selfSignedEcCertificate.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBgzCCASigAwIBAgIJALymKU17CVm/MAoGCCqGSM49BAMCMBwxGjAYBgNVBAMM
+EUVjVGVzdENlcnRpZmljYXRlMB4XDTIyMDMxNjE1NTE0NFoXDTIzMDMxNjE1NTE0
+NFowHDEaMBgGA1UEAwwRRWNUZXN0Q2VydGlmaWNhdGUwWTATBgcqhkjOPQIBBggq
+hkjOPQMBBwNCAAQ3exqhtUAx9HT36eB+zTLZAhoNQQtOC+09KCKFHg+vrP17gcxp
+4YO9lefuSeX90STwq6GpOaDljd3jWy4q833Lo1MwUTAdBgNVHQ4EFgQUFZbLWq9o
+08GPaT1p8QsWhSO3+ZEwHwYDVR0jBBgwFoAUFZbLWq9o08GPaT1p8QsWhSO3+ZEw
+DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNJADBGAiEApUpgRRjAO0F3Ti2L
+bZFC+MltwSZyD3Xg4volOvOlk8QCIQDU3B5qpTQ6+pAxu6PpPFog0VZCMR7Ol7cJ
+mjsOOak7TQ==
+-----END CERTIFICATE----- \ No newline at end of file