summaryrefslogtreecommitdiff
path: root/eaaf_core_utils
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_core_utils')
-rw-r--r--eaaf_core_utils/pom.xml222
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/exception/EaafKeyAccessException.java22
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java263
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreUtils.java147
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/KeyStoreConfiguration.java225
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/SpConfigurationImpl.java183
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java93
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/EaafUtilsMessageSource.java16
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/SimpleStatusMessager.java61
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ArrayUtils.java62
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java113
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataUrlBuilder.java93
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java257
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java178
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java666
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpUtils.java118
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/IHttpClientFactory.java31
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java262
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java699
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java77
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java61
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java284
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java378
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java64
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java54
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java181
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java101
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIdUtils.java139
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java87
-rw-r--r--eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties15
-rw-r--r--eaaf_core_utils/src/main/resources/spring/eaaf_utils.beans.xml22
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/EaafUtilsMessageSourceTest.java39
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/JUnitTestStatusMessenger.java96
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/utils/test/KeyValueUtilsTest.java448
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/TestConstants.java7
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EaafKeyStoreFactoryTest.java655
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyStoreConfigurationTest.java190
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/dummy/DummyAuthConfigMap.java142
-rw-r--r--eaaf_core_utils/src/test/resources/data/hsm_facade_trust_root.crt10
-rw-r--r--eaaf_core_utils/src/test/resources/data/junit.jksbin0 -> 3980 bytes
-rw-r--r--eaaf_core_utils/src/test/resources/data/junit_without_trustcerts.jksbin0 -> 2733 bytes
-rw-r--r--eaaf_core_utils/src/test/resources/data/junit_without_trustcerts.p12bin0 -> 3204 bytes
-rw-r--r--eaaf_core_utils/src/test/resources/data/test.crt3
-rw-r--r--eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_lazy.beans.xml23
-rw-r--r--eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_not_lazy.beans.xml19
45 files changed, 4599 insertions, 2207 deletions
diff --git a/eaaf_core_utils/pom.xml b/eaaf_core_utils/pom.xml
index b3531699..fa5fa412 100644
--- a/eaaf_core_utils/pom.xml
+++ b/eaaf_core_utils/pom.xml
@@ -1,17 +1,19 @@
<?xml version="1.0"?>
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>at.gv.egiz</groupId>
<artifactId>eaaf</artifactId>
- <version>1.0.13.2</version>
+ <version>1.1.0</version>
</parent>
<groupId>at.gv.egiz.eaaf</groupId>
<artifactId>eaaf_core_utils</artifactId>
<name>Utils for EAAF core components</name>
<description>Core component Utils for identity managment implementations</description>
-
+
<licenses>
<license>
<name>European Union Public License, version 1.2 (EUPL-1.2)</name>
@@ -28,74 +30,88 @@
<organizationUrl>https://www.egiz.gv.at</organizationUrl>
</developer>
</developers>
-
+
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
-
- <dependencies>
- <dependency>
- <groupId>at.gv.egiz.eaaf</groupId>
- <artifactId>eaaf_core_api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpclient</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpcore</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.code.findbugs</groupId>
- <artifactId>jsr305</artifactId>
- </dependency>
- <dependency>
- <groupId>joda-time</groupId>
- <artifactId>joda-time</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- <scope>test</scope>
- </dependency>
-
+
+ <dependencies>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_core_api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>at.asitplus.hsmfacade</groupId>
+ <artifactId>provider</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
-
- <build>
- <finalName>eaaf_core_utils</finalName>
-
- <resources>
- <resource>
- <directory>src/main/resources</directory>
- </resource>
- </resources>
-
+
+ <build>
+ <finalName>eaaf_core_utils</finalName>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -106,45 +122,45 @@
<target>1.8</target>
</configuration>
<executions>
- <execution>
- <goals>
- <goal>compile</goal>
- <goal>testCompile</goal>
- </goals>
- </execution>
+ <execution>
+ <goals>
+ <goal>compile</goal>
+ <goal>testCompile</goal>
+ </goals>
+ </execution>
</executions>
</plugin>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>3.1.0</version>
- <executions>
- <execution>
- <goals>
- <goal>test-jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.1.0</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
<!-- enable co-existence of testng and junit -->
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>${surefire.version}</version>
- <configuration>
- <threadCount>1</threadCount>
- </configuration>
- <dependencies>
- <dependency>
- <groupId>org.apache.maven.surefire</groupId>
- <artifactId>surefire-junit47</artifactId>
- <version>${surefire.version}</version>
- </dependency>
- </dependencies>
- </plugin>
-
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.version}</version>
+ <configuration>
+ <threadCount>1</threadCount>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-junit47</artifactId>
+ <version>${surefire.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+
</plugins>
</build>
-
-
+
+
</project>
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/exception/EaafKeyAccessException.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/exception/EaafKeyAccessException.java
new file mode 100644
index 00000000..f9abd6d9
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/exception/EaafKeyAccessException.java
@@ -0,0 +1,22 @@
+package at.gv.egiz.eaaf.core.exception;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+
+public class EaafKeyAccessException extends EaafException {
+
+ private static final long serialVersionUID = -2641273589744430903L;
+
+ public static final String ERROR_CODE_08 = "internal.keystore.08";
+ public static final String ERROR_CODE_09 = "internal.keystore.09";
+
+ public EaafKeyAccessException(String errorCode, String... params) {
+ super(errorCode, new Object[] {params});
+
+ }
+
+ public EaafKeyAccessException(String errorCode, Throwable e, String... params) {
+ super(errorCode, new Object[] {params}, e);
+
+ }
+
+}
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
new file mode 100644
index 00000000..e60c326c
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java
@@ -0,0 +1,263 @@
+package at.gv.egiz.eaaf.core.impl.credential;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.PostConstruct;
+
+import at.asitplus.hsmfacade.provider.HsmFacadeProvider;
+import at.asitplus.hsmfacade.provider.RemoteKeyStoreLoadParameter;
+import 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.exceptions.EaafFactoryException;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
+import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class EaafKeyStoreFactory {
+
+ public static final String CONFIG_PROP_HSM_FACADE_HOST = "security.hsmfacade.host";
+ public static final String CONFIG_PROP_HSM_FACADE_PORT = "security.hsmfacade.port";
+ public static final String CONFIG_PROP_HSM_FACADE_SSLTRUST = "security.hsmfacade.trustedsslcert";
+ public static final String CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME = "security.hsmfacade.username";
+ public static final String CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD = "security.hsmfacade.password";
+
+ public static final String ERRORCODE_00 = "internal.keystore.00";
+ public static final String ERRORCODE_01 = "internal.keystore.01";
+ public static final String ERRORCODE_02 = "internal.keystore.02";
+ public static final String ERRORCODE_03 = "internal.keystore.03";
+ public static final String ERRORCODE_04 = "internal.keystore.04";
+ public static final String ERRORCODE_05 = "internal.keystore.05";
+ public static final String ERRORCODE_06 = "internal.keystore.06";
+ public static final String ERRORCODE_07 = "internal.keystore.07";
+
+ private static final String HSM_FACADE_PROVIDER = "HsmFacade";
+ private static final String HSM_FACADE_KEYSTORE_TYPE = "RemoteKeyStore";
+
+ @Autowired
+ private IConfiguration basicConfig;
+ @Autowired
+ private ResourceLoader resourceLoader;
+
+ private boolean isHsmFacadeInitialized = false;
+
+ /**
+ * Get a new KeyStore based on a KeyStore configuration-object.
+ *
+ * @param config KeyStore configuration
+ * @return {@link Pair} of a new {@link KeyStore} instance and an optional {@link Provider}.
+ * The {@link KeyStore} is {@link Nonnull}. If the {@link Provider} is not <code>null</code>
+ * this {@link KeyStore} requires a specific {@link Provider} for {@link Key} operations.
+ * @throws EaafException In case of a KeyStore initialization error
+ */
+ @Nonnull
+ public Pair<KeyStore, Provider> buildNewKeyStore(KeyStoreConfiguration config) throws EaafException {
+ log.trace("Starting KeyStore generation based on configuration object ... ");
+ if (KeyStoreType.PKCS12.equals(config.getKeyStoreType())
+ || KeyStoreType.JKS.equals(config.getKeyStoreType())) {
+ return getKeyStoreFromFileSystem(config);
+
+ } else if (KeyStoreType.HSMFACADE.equals(config.getKeyStoreType())) {
+ if (isHsmFacadeInitialized) {
+ return getKeyStoreFromHsmFacade(config);
+
+ } else {
+ log.error("HSMFacade can NOT be used for KeyStore: {} because {} is not initialized",
+ config.getFriendlyName());
+ throw new EaafConfigurationException(ERRORCODE_00,
+ new Object[] { config.getFriendlyName() });
+
+ }
+
+ } else if (KeyStoreType.PKCS11.equals(config.getKeyStoreType())) {
+ log.warn("KeyStoreType: {} is NOT supported", config.getKeyStoreType());
+ throw new EaafConfigurationException(ERRORCODE_02,
+ new Object[] { config.getFriendlyName(), config.getKeyStoreType() });
+
+ } else {
+ log.warn("KeyStoreType: {} is unrecognized", config.getKeyStoreType());
+ throw new EaafConfigurationException(ERRORCODE_01,
+ new Object[] { config.getFriendlyName() });
+
+ }
+ }
+
+ /**
+ * Get the initialization state of the HSM Facade module.
+ *
+ * @return true if HSM Facade is available, otherwise false
+ */
+ public boolean isHsmFacadeInitialized() {
+ return isHsmFacadeInitialized;
+
+ }
+
+ @PostConstruct
+ private void initialize() throws EaafException {
+
+ final String hsmFacadeHost = basicConfig.getBasicConfiguration(CONFIG_PROP_HSM_FACADE_HOST);
+ if (StringUtils.isNotEmpty(hsmFacadeHost)) {
+ log.debug("Find host for HSMFacade. Starting crypto provider initialization ... ");
+ try {
+ final int port = Integer.parseUnsignedInt(
+ getConfigurationParameter(CONFIG_PROP_HSM_FACADE_PORT));
+ final String clientUsername =
+ getConfigurationParameter(CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME);
+ final String clientPassword =
+ getConfigurationParameter(CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD);
+
+ final HsmFacadeProvider provider = HsmFacadeProvider.Companion.getInstance();
+ provider.init(getHsmFacadeTrustSslCertificate(), clientUsername, clientPassword, hsmFacadeHost, port);
+ //Security.addProvider(provider);
+ Security.insertProviderAt(provider, 0);
+ isHsmFacadeInitialized = true;
+ log.info("HSM Facade is initialized. {} can provide KeyStores based on remote HSM",
+ EaafKeyStoreFactory.class.getSimpleName());
+
+ } catch (final EaafException e) {
+ throw e;
+
+ } 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);
+ }
+
+ } else {
+ log.info("HSM Facade is not configurated. {} can only provide software keystores",
+ EaafKeyStoreFactory.class.getSimpleName());
+
+ }
+
+ }
+
+ @Nonnull
+ private Pair<KeyStore, Provider> getKeyStoreFromFileSystem(KeyStoreConfiguration config)
+ throws EaafConfigurationException, EaafFactoryException {
+ try {
+ final String keyStorePath = checkConfigurationParameter(config.getSoftKeyStoreFilePath(),
+ ERRORCODE_06, config.getFriendlyName(), "Software-KeyStore missing filepath to KeyStore");
+
+ final String keyStorePassword = checkConfigurationParameter(config.getSoftKeyStorePassword(),
+ ERRORCODE_06, config.getFriendlyName(), "Software-KeyStore missing Password for KeyStore");
+
+ final String absKeyStorePath = FileUtils.makeAbsoluteUrl(keyStorePath, basicConfig
+ .getConfigurationRootDirectory());
+ final Resource ressource = resourceLoader.getResource(absKeyStorePath);
+ if (!ressource.exists()) {
+ throw new EaafConfigurationException(ERRORCODE_05,
+ new Object[] { config.getFriendlyName(),
+ "File not found at: " + absKeyStorePath });
+
+ }
+
+ final InputStream is = ressource.getInputStream();
+ final KeyStore keyStore = KeyStoreUtils.loadKeyStore(is, keyStorePassword);
+ is.close();
+ if (keyStore == null) {
+ throw new EaafFactoryException(ERRORCODE_06,
+ new Object[] { config.getFriendlyName(), "KeyStore not valid or password wrong" });
+
+ }
+
+ return Pair.newInstance(keyStore, null);
+
+ } catch (KeyStoreException | IOException e) {
+ log.error("Software KeyStore initialization FAILED with an generic error.", e);
+ throw new EaafConfigurationException(ERRORCODE_03, new Object[] { e.getMessage() }, e);
+
+ }
+ }
+
+ @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");
+
+ try {
+ final KeyStore keyStore = KeyStore.getInstance(HSM_FACADE_KEYSTORE_TYPE, HSM_FACADE_PROVIDER);
+ keyStore.load(new RemoteKeyStoreLoadParameter(keyStoreName));
+ return Pair.newInstance(keyStore, keyStore.getProvider());
+
+ } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException
+ | NoSuchProviderException e) {
+ log.error("Can not initialize KeyStore: {} with reason: {}",
+ config.getFriendlyName(), e.getMessage());
+ throw new EaafFactoryException(ERRORCODE_06,
+ new Object[] { config.getFriendlyName(), e.getMessage() }, e);
+
+ }
+ }
+
+ private X509Certificate getHsmFacadeTrustSslCertificate() throws EaafConfigurationException {
+ try {
+ final String certFilePath = getConfigurationParameter(CONFIG_PROP_HSM_FACADE_SSLTRUST);
+
+ final String absolutCertFilePath = FileUtils.makeAbsoluteUrl(
+ certFilePath, basicConfig.getConfigurationRootDirectory());
+ final Resource certFile = resourceLoader.getResource(absolutCertFilePath);
+
+ if (!certFile.exists()) {
+ throw new EaafConfigurationException(ERRORCODE_05,
+ new Object[] { CONFIG_PROP_HSM_FACADE_SSLTRUST,
+ "File not found at: " + absolutCertFilePath });
+
+ }
+
+ return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(certFile
+ .getInputStream());
+
+ } catch (final EaafConfigurationException e) {
+ throw e;
+
+ } catch (CertificateException | IOException e) {
+ log.error("Can not load trusted server-certificate for HSM-Facade. Reason: {}", e.getMessage());
+ throw new EaafConfigurationException(ERRORCODE_05,
+ new Object[] { CONFIG_PROP_HSM_FACADE_SSLTRUST, e.getMessage() }, e);
+
+ }
+ }
+
+ @Nonnull
+ private String getConfigurationParameter(@Nonnull String configParamKey)
+ throws EaafConfigurationException {
+ return checkConfigurationParameter(
+ basicConfig.getBasicConfiguration(configParamKey), ERRORCODE_04, configParamKey);
+
+ }
+
+ @Nonnull
+ private String checkConfigurationParameter(@Nullable String configParam, @Nonnull String errorCode,
+ @Nonnull String... errorParams)
+ throws EaafConfigurationException {
+ if (StringUtils.isEmpty(configParam)) {
+ throw new EaafConfigurationException(errorCode, new Object[] { errorParams });
+
+ }
+ return configParam;
+
+ }
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreUtils.java
new file mode 100644
index 00000000..b4b44724
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreUtils.java
@@ -0,0 +1,147 @@
+package at.gv.egiz.eaaf.core.impl.credential;
+
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+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;
+import javax.annotation.Nullable;
+
+import at.gv.egiz.eaaf.core.exception.EaafKeyAccessException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class EaafKeyStoreUtils {
+ private static final String ERROR_MSG_REASON = "Maybe 'Alias' is not valid";
+ private static final String ERROR_MSG_1 = "Can NOT access key: {} in KeyStore: {}. Reason: {}";
+ private static final String ERROR_MSG_2 = "Key: {} will be NOT available";
+
+ /**
+ * Read all certificates from a {@link KeyStore}.
+ *
+ * @param keyStore KeyStore with certificates
+ * @return {@link List} of {@link X509Certificate}, but never null
+ * @throws KeyStoreException In case of an error during KeyStore operations
+ */
+ @Nonnull
+ public static 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 Collections.unmodifiableList(result);
+ }
+
+ /**
+ * Get a specific private Key and the corresponding certificate from a {@link KeyStore}.
+ *
+ * @param keyStore KeyStore with certificates
+ * @param keyAlias Alias of the entry
+ * @param keyPassword Password to access the Key
+ * @param isRequired if true, the method throw an {@link EaafKeyAccessException}
+ * if the key is not available or invalid
+ * @param friendlyName Name of the KeyStore for logging purposes
+ * @return A {@link Pair} of {@link Key} and {@link X509Certificate} for this alias,
+ * or maybe null if isRequired was <code>false</code>
+ * @throws EaafKeyAccessException In case of an error during KeyStore operations
+ */
+ @Nullable
+ public static Pair<Key, X509Certificate[]> getPrivateKeyAndCertificates(@Nonnull KeyStore keyStore,
+ @Nonnull String keyAlias, @Nullable char[] keyPassword, boolean isRequired, @Nonnull String friendlyName)
+ throws EaafKeyAccessException {
+ try {
+ Key privKey = keyStore.getKey(keyAlias, keyPassword);
+ if (privKey != null) {
+ final Certificate[] certChainSigning = keyStore.getCertificateChain(keyAlias);
+ X509Certificate[] certChain = new X509Certificate[certChainSigning.length];
+
+ for (int i = 0; i < certChainSigning.length; i++) {
+ if (certChainSigning[i] instanceof X509Certificate) {
+ certChain[i] = (X509Certificate) certChainSigning[i];
+ } else {
+ log.warn("NO X509 certificate for signing: " + certChainSigning[i].getType());
+ }
+
+ }
+
+ Pair<Key, X509Certificate[]> keyResult = Pair.newInstance(privKey, certChain);
+ validateKeyResult(keyResult, friendlyName, keyAlias);
+ return keyResult;
+
+ } else {
+ if (isRequired) {
+ log.warn(ERROR_MSG_1,
+ keyAlias, friendlyName, ERROR_MSG_REASON);
+ throw new EaafKeyAccessException(EaafKeyAccessException.ERROR_CODE_09,
+ friendlyName, keyAlias, ERROR_MSG_REASON);
+
+ } else {
+ log.info(ERROR_MSG_1,
+ keyAlias, friendlyName, ERROR_MSG_REASON);
+ log.info(ERROR_MSG_2, keyAlias);
+
+ }
+ }
+
+ } catch (KeyStoreException | UnrecoverableKeyException | NoSuchAlgorithmException e) {
+ if (isRequired) {
+ log.warn(ERROR_MSG_1,
+ keyAlias, friendlyName, e.getMessage());
+ throw new EaafKeyAccessException(
+ EaafKeyAccessException.ERROR_CODE_09, e, friendlyName, keyAlias, e.getMessage());
+
+ } else {
+ log.info(ERROR_MSG_1,
+ keyAlias, friendlyName, e.getMessage());
+ log.info(ERROR_MSG_2, keyAlias);
+
+ }
+ }
+
+ return null;
+
+ }
+
+ private static void validateKeyResult(Pair<Key, X509Certificate[]> keyResult,
+ String friendlyName, String keyAlias) throws EaafKeyAccessException {
+ // some short validation
+ if (!(keyResult.getFirst() instanceof PrivateKey)) {
+ log.info("PrivateKey: {} in KeyStore: {} is of wrong type", keyAlias, friendlyName);
+ throw new EaafKeyAccessException(
+ EaafKeyAccessException.ERROR_CODE_09,
+ friendlyName, keyAlias, "Wrong PrivateKey type ");
+
+ }
+
+ if (keyResult.getSecond() == null || keyResult.getSecond().length == 0) {
+ log.info("NO certificate for Key: {} in KeyStore: {}", keyAlias, friendlyName);
+ throw new EaafKeyAccessException(
+ EaafKeyAccessException.ERROR_CODE_09,
+ friendlyName, keyAlias, "NO certificate for PrivateKey");
+
+ }
+ }
+}
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
new file mode 100644
index 00000000..970efd22
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/KeyStoreConfiguration.java
@@ -0,0 +1,225 @@
+package at.gv.egiz.eaaf.core.impl.credential;
+
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+
+import org.apache.commons.lang3.StringUtils;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Getter
+@Setter
+public class KeyStoreConfiguration {
+
+ public static final String PROP_CONFIG_KEYSTORE_TYPE =
+ "keystore.type";
+
+ public static final String PROP_CONFIG_HSMFACADE_NAME =
+ "keystore.name";
+
+ public static final String PROP_CONFIG_SOFTWARE_KEYSTORE_PATH =
+ "keystore.path";
+ public static final String PROP_CONFIG_SOFTWARE_KEYSTORE_PASSORD =
+ "keystore.password";
+
+ /**
+ * FriendlyName for this KeyStore. Mainly used for logging.
+ */
+ private String friendlyName;
+
+ /**
+ * General type of the KeyStore that should be generated.
+ */
+ private KeyStoreType keyStoreType;
+
+ /**
+ * Name of the KeyStore in HSM Facade.
+ */
+ private String keyStoreName;
+
+ /**
+ * Path to software KeyStore in case of a PKCS12 or JKS KeyStore.
+ */
+ private String softKeyStoreFilePath;
+
+ /**
+ * Password of a software KeyStore in case of a PKCS12 or JKS KeyStore.
+ */
+ private String softKeyStorePassword;
+
+ /**
+ * Build a {@link KeyStoreConfiguration} from a configuration map. <br>
+ * <p>
+ * The configuration parameters defined in this class are used to load the
+ * configuration.
+ * </p>
+ *
+ * @param config Configuration
+ * @param friendlyName FriendlyName for this KeyStore
+ * @return Configuration object for {@link EaafKeyStoreFactory}
+ * @throws EaafConfigurationException In case of a configuration error.
+ */
+ public static KeyStoreConfiguration buildFromConfigurationMap(Map<String, String> config,
+ String friendlyName) throws EaafConfigurationException {
+
+ final KeyStoreConfiguration internalConfig = new KeyStoreConfiguration();
+ internalConfig.setFriendlyName(friendlyName);
+
+ final KeyStoreType internalKeyStoreType = KeyStoreType.fromString(
+ getConfigurationParameter(config, PROP_CONFIG_KEYSTORE_TYPE));
+ if (internalKeyStoreType != null) {
+ internalConfig.setKeyStoreType(internalKeyStoreType);
+
+ } else {
+ log.error("KeyStore: {} sets an unknown KeyStore type: {}",
+ friendlyName, getConfigurationParameter(config, PROP_CONFIG_KEYSTORE_TYPE));
+ throw new EaafConfigurationException(EaafKeyStoreFactory.ERRORCODE_01,
+ new Object[] { friendlyName });
+
+ }
+
+ if (internalKeyStoreType.equals(KeyStoreType.HSMFACADE)) {
+ log.trace("Set-up HSM-Facade KeyStore ... ");
+ internalConfig.setKeyStoreName(
+ getConfigurationParameter(config, PROP_CONFIG_HSMFACADE_NAME));
+
+ } else if (internalKeyStoreType.equals(KeyStoreType.PKCS12)
+ || internalKeyStoreType.equals(KeyStoreType.JKS)) {
+ log.trace("Set-up software KeyStore ... ");
+ internalConfig.setSoftKeyStoreFilePath(
+ getConfigurationParameter(config, PROP_CONFIG_SOFTWARE_KEYSTORE_PATH));
+ internalConfig.setSoftKeyStorePassword(
+ getConfigurationParameter(config, PROP_CONFIG_SOFTWARE_KEYSTORE_PASSORD));
+
+ } else {
+ log.info("Configuration of type: {} not supported yet", internalKeyStoreType);
+ throw new EaafConfigurationException(EaafKeyStoreFactory.ERRORCODE_02,
+ new Object[] { friendlyName, config.get(PROP_CONFIG_KEYSTORE_TYPE) });
+
+ }
+
+ return internalConfig;
+ }
+
+ /**
+ * Set the Type of the KeyStore based on String identifier.
+ *
+ * @param keyStoreType String based KeyStore type
+ * @throws EaafConfigurationException In case of an unknown KeyStore type
+ */
+ public void setKeyStoreType(@Nonnull String keyStoreType) throws EaafConfigurationException {
+ final KeyStoreType internalKeyStoreType = KeyStoreType.fromString(keyStoreType);
+ if (internalKeyStoreType != null) {
+ setKeyStoreType(internalKeyStoreType);
+
+ } else {
+ log.error("KeyStore: {} sets an unknown KeyStore type: {}",
+ friendlyName, keyStoreType);
+ throw new EaafConfigurationException(EaafKeyStoreFactory.ERRORCODE_01,
+ new Object[] { friendlyName });
+
+ }
+
+ }
+
+ /**
+ * Set the Type of the KeyStore based on String identifier.
+ *
+ * @param type String based KeyStore type
+ */
+ public void setKeyStoreType(@Nonnull KeyStoreType type) {
+ this.keyStoreType = type;
+
+ }
+
+ /**
+ * Validate the internal state of this configuration object.
+ *
+ * @throws EaafConfigurationException In case of a configuration error
+ */
+ public void validate() throws EaafConfigurationException {
+ if (KeyStoreType.HSMFACADE.equals(keyStoreType)) {
+ log.trace("Validate HSM-Facade KeyStore ... ");
+ checkConfigurationValue(keyStoreName, EaafKeyStoreFactory.ERRORCODE_07,
+ friendlyName, "Missing 'KeyName' for HSM-Facade");
+
+ } else if (KeyStoreType.PKCS12.equals(keyStoreType)
+ || KeyStoreType.JKS.equals(keyStoreType)) {
+ log.trace("Validate software KeyStore ... ");
+ checkConfigurationValue(softKeyStoreFilePath, EaafKeyStoreFactory.ERRORCODE_07,
+ friendlyName, "Missing 'KeyPath' for software keystore");
+ checkConfigurationValue(softKeyStorePassword, EaafKeyStoreFactory.ERRORCODE_07,
+ friendlyName, "Missing 'KeyPassword' for software keystore");
+
+ } else {
+ log.info("Validation of type: {} not supported yet", keyStoreType);
+
+ }
+ }
+
+ public enum KeyStoreType {
+ PKCS12("pkcs12"), JKS("jks"), HSMFACADE("hsmfacade"), PKCS11("pkcs11");
+
+ private final String keyStoreType;
+
+ KeyStoreType(final String keyStoreType) {
+ this.keyStoreType = keyStoreType;
+ }
+
+ /**
+ * Get Type of this KeyStore.
+ *
+ * @return
+ */
+ public String getKeyStoreType() {
+ return this.keyStoreType;
+ }
+
+ /**
+ * Get KeyStore type from String representation.
+ *
+ * @param s Config parameter
+ * @return
+ */
+ public static KeyStoreType fromString(final String s) {
+ try {
+ return KeyStoreType.valueOf(s.toUpperCase());
+
+ } catch (IllegalArgumentException | NullPointerException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getKeyStoreType();
+
+ }
+ }
+
+ @Nonnull
+ private static String getConfigurationParameter(@Nonnull Map<String, String> config,
+ @Nonnull String configParamKey)
+ throws EaafConfigurationException {
+ final String configValue = config.get(configParamKey);
+ checkConfigurationValue(configValue, EaafKeyStoreFactory.ERRORCODE_04, configParamKey);
+ return configValue;
+
+ }
+
+ private static void checkConfigurationValue(String configValue, String errorCode, String... params)
+ throws EaafConfigurationException {
+ if (StringUtils.isEmpty(configValue)) {
+ throw new EaafConfigurationException(errorCode,
+ params);
+
+ }
+
+ }
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/SpConfigurationImpl.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/SpConfigurationImpl.java
new file mode 100644
index 00000000..de54d103
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/SpConfigurationImpl.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.core.impl.idp.conf;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+
+public class SpConfigurationImpl implements ISpConfiguration {
+ private static final long serialVersionUID = 688541755446463453L;
+
+ private static final Logger log = LoggerFactory.getLogger(SpConfigurationImpl.class);
+
+ private final Map<String, String> spConfiguration;
+ private final List<String> targetAreasWithNoInteralBaseIdRestriction;
+ private final List<String> targetAreasWithNoBaseIdTransmissionRestriction;
+
+ /**
+ * Service-provider configuration holder.
+ *
+ * @param spConfig Key/value based configuration
+ * @param authConfig Basic application configuration
+ */
+ public SpConfigurationImpl(final Map<String, String> spConfig, final IConfiguration authConfig) {
+ this.spConfiguration = spConfig;
+
+ // set oa specific restrictions
+ targetAreasWithNoInteralBaseIdRestriction = Collections
+ .unmodifiableList(KeyValueUtils.getListOfCsvValues(authConfig.getBasicConfiguration(
+ CONFIG_KEY_RESTRICTIONS_BASEID_INTERNAL, EaafConstants.URN_PREFIX_CDID)));
+
+ targetAreasWithNoBaseIdTransmissionRestriction = Collections
+ .unmodifiableList(KeyValueUtils.getListOfCsvValues(authConfig.getBasicConfiguration(
+ CONFIG_KEY_RESTRICTIONS_BASEID_TRANSMISSION, EaafConstants.URN_PREFIX_CDID)));
+
+ if (log.isTraceEnabled()) {
+ log.trace("Internal policy for OA: " + getUniqueIdentifier());
+ for (final String el : targetAreasWithNoInteralBaseIdRestriction) {
+ log.trace(" Allow baseID processing for prefix " + el);
+ }
+ for (final String el : targetAreasWithNoBaseIdTransmissionRestriction) {
+ log.trace(" Allow baseID transfer for prefix " + el);
+ }
+
+ }
+ }
+
+ @Override
+ public final Map<String, String> getFullConfiguration() {
+ return this.spConfiguration;
+
+ }
+
+ @Override
+ public final String getConfigurationValue(final String key) {
+ if (key == null) {
+ return null;
+ } else {
+ return this.spConfiguration.get(key);
+ }
+
+ }
+
+ @Override
+ public final String getConfigurationValue(final String key, final String defaultValue) {
+ final String value = getConfigurationValue(key);
+ if (value == null) {
+ return defaultValue;
+ } else {
+ return value;
+ }
+ }
+
+ @Override
+ public final boolean isConfigurationValue(final String key) {
+ return isConfigurationValue(key, false);
+
+ }
+
+ @Override
+ public final boolean isConfigurationValue(final String key, final boolean defaultValue) {
+ final String value = getConfigurationValue(key);
+ if (value != null) {
+ return Boolean.parseBoolean(value);
+
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public final boolean containsConfigurationKey(final String key) {
+ if (key == null) {
+ return false;
+ } else {
+ return this.spConfiguration.containsKey(key);
+ }
+
+ }
+
+ @Override
+ public String getUniqueIdentifier() {
+ return getConfigurationValue(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER);
+
+ }
+
+ @Override
+ public boolean hasBaseIdInternalProcessingRestriction() {
+ return false;
+
+ }
+
+ @Override
+ public boolean hasBaseIdTransferRestriction() {
+ return true;
+
+ }
+
+ @Override
+ public final List<String> getTargetsWithNoBaseIdInternalProcessingRestriction() {
+ return this.targetAreasWithNoInteralBaseIdRestriction;
+ }
+
+ @Override
+ public final List<String> getTargetsWithNoBaseIdTransferRestriction() {
+ return this.targetAreasWithNoBaseIdTransmissionRestriction;
+ }
+
+ @Override
+ public List<String> getRequiredLoA() {
+ log.warn(
+ "Method not implemented: " + SpConfigurationImpl.class.getName() + " 'getRequiredLoA()'");
+ return null;
+ }
+
+ @Override
+ public String getLoAMatchingMode() {
+ log.warn("Method not implemented: " + SpConfigurationImpl.class.getName()
+ + " 'getLoAMatchingMode()'");
+ return null;
+ }
+
+ @Override
+ public String getAreaSpecificTargetIdentifier() {
+ log.warn("Method not implemented: " + SpConfigurationImpl.class.getName()
+ + " 'getAreaSpecificTargetIdentifier()'");
+ return null;
+ }
+
+ @Override
+ public String getFriendlyName() {
+ log.warn(
+ "Method not implemented: " + SpConfigurationImpl.class.getName() + " 'getFriendlyName()'");
+ return null;
+ }
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java
index a297367f..67d87b0d 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/support/SecureRandomHolder.java
@@ -1,61 +1,58 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.support;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
- * Holder for a secure random instance following the initialization on demand holder design pattern. The secure random
- * instance is a singleton that is initialized on first usage.
- *
+ * Holder for a secure random instance following the initialization on demand
+ * holder design pattern. The secure random instance is a singleton that is
+ * initialized on first usage.
+ *
* @author tknall
- *
+ *
*/
public class SecureRandomHolder {
- private SecureRandomHolder() {
- }
-
- private static final SecureRandom SRND_INSTANCE;
- static {
- try {
- SRND_INSTANCE = SecureRandom.getInstance("SHA1PRNG");
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("Unable to instantiate SHA1PRNG.", e);
- }
- }
-
- /**
- * Returns a secure random generator instance.
- * @return The secure random instance.
- */
- public static SecureRandom getInstance() {
- return SecureRandomHolder.SRND_INSTANCE;
- }
-
-} \ No newline at end of file
+ private SecureRandomHolder() {
+
+ }
+
+ private static final SecureRandom SRND_INSTANCE;
+
+ static {
+ try {
+ SRND_INSTANCE = SecureRandom.getInstance("SHA1PRNG");
+ } catch (final NoSuchAlgorithmException e) {
+ throw new RuntimeException("Unable to instantiate SHA1PRNG.", e);
+ }
+ }
+
+ /**
+ * Returns a secure random generator instance.
+ *
+ * @return The secure random instance.
+ */
+ public static SecureRandom getInstance() {
+ return SecureRandomHolder.SRND_INSTANCE;
+ }
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/EaafUtilsMessageSource.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/EaafUtilsMessageSource.java
new file mode 100644
index 00000000..5aa5b3b5
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/EaafUtilsMessageSource.java
@@ -0,0 +1,16 @@
+package at.gv.egiz.eaaf.core.impl.logging;
+
+import java.util.Arrays;
+import java.util.List;
+
+import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation;
+
+public class EaafUtilsMessageSource implements IMessageSourceLocation {
+
+ @Override
+ public List<String> getMessageSourceLocation() {
+ return Arrays.asList("classpath:messages/eaaf_utils_message");
+
+ }
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/SimpleStatusMessager.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/SimpleStatusMessager.java
index d36c79b9..0d394d19 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/SimpleStatusMessager.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/logging/SimpleStatusMessager.java
@@ -5,40 +5,41 @@ import java.text.MessageFormat;
import at.gv.egiz.eaaf.core.api.IStatusMessenger;
/**
- * Simple {@link IStatusMessenger} implementation that formats messages by using {@link MessageFormat}
- *
+ * Simple {@link IStatusMessenger} implementation that formats messages by
+ * using. {@link MessageFormat}
+ *
* @author tlenz
*
*/
public class SimpleStatusMessager implements IStatusMessenger {
- private static final String NOTSUPPORTED = "Error response-codes not supported";
- private static final String NULLMESSAGE = "No error-message provided";
-
- @Override
- public String getMessage(String messageId, Object[] parameters) {
- return getMessageWithoutDefault(messageId, parameters);
-
- }
-
- @Override
- public String getMessageWithoutDefault(String messageId, Object[] parameters) {
- if (messageId != null) {
- return MessageFormat.format(messageId, parameters);
-
- }
-
- return NULLMESSAGE;
- }
-
- @Override
- public String getResponseErrorCode(Throwable throwable) {
- return NOTSUPPORTED;
- }
-
- @Override
- public String mapInternalErrorToExternalError(String intErrorCode) {
- return NOTSUPPORTED;
- }
+ private static final String NOTSUPPORTED = "Error response-codes not supported";
+ private static final String NULLMESSAGE = "No error-message provided";
+
+ @Override
+ public String getMessage(final String messageId, final Object[] parameters) {
+ return getMessageWithoutDefault(messageId, parameters);
+
+ }
+
+ @Override
+ public String getMessageWithoutDefault(final String messageId, final Object[] parameters) {
+ if (messageId != null) {
+ return MessageFormat.format(messageId, parameters);
+
+ }
+
+ return NULLMESSAGE;
+ }
+
+ @Override
+ public String getResponseErrorCode(final Throwable throwable) {
+ return NOTSUPPORTED;
+ }
+
+ @Override
+ public String mapInternalErrorToExternalError(final String intErrorCode) {
+ return NOTSUPPORTED;
+ }
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ArrayUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ArrayUtils.java
index 8585bc05..1da82f43 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ArrayUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ArrayUtils.java
@@ -1,44 +1,42 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
package at.gv.egiz.eaaf.core.impl.utils;
import java.util.List;
public class ArrayUtils {
- /**
- * Check if a String 's' is part of a List 'l' in qualsIgnoreCase mode
- *
- * @param s Search String
- * @param l List of String elements
- * @return true if 's' is in 'l', otherwise false
- */
- public static boolean containsCaseInsensitive(String s, List<String> l){
- if (l == null || s == null)
- return false;
-
- return l.stream().anyMatch(x -> x.equalsIgnoreCase(s));
-
+ /**
+ * Check if a String 's' is part of a List 'l' in qualsIgnoreCase mode.
+ *
+ * @param s Search String
+ * @param l List of String elements
+ * @return true if 's' is in 'l', otherwise false
+ */
+ public static boolean containsCaseInsensitive(final String s, final List<String> l) {
+ if (l == null || s == null) {
+ return false;
}
+ return l.stream().anyMatch(x -> x.equalsIgnoreCase(s));
+
+ }
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java
deleted file mode 100644
index a81fafbc..00000000
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataURLBuilder.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*******************************************************************************
- * Copyright 2014 Federal Chancellery Austria
- * MOA-ID has been developed in a cooperation between BRZ, the Federal
- * Chancellery Austria - ICT staff unit, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- ******************************************************************************/
-/*
- * Copyright 2003 Federal Chancellery Austria
- * MOA-ID has been developed in a cooperation between BRZ, the Federal
- * Chancellery Austria - ICT staff unit, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- */
-
-
-package at.gv.egiz.eaaf.core.impl.utils;
-
-import org.apache.commons.lang3.StringUtils;
-
-import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
-
-/**
- * Builds a DataURL parameter meant for the security layer implementation
- * to respond to.
- *
- * @author Paul Ivancsics
- * @version $Id$
- */
-public class DataURLBuilder {
-
- /**
- * Constructor for DataURLBuilder.
- */
- public DataURLBuilder() {
- super();
- }
-
- /**
- * Constructs a data URL for <code>VerifyIdentityLink</code> or <code>VerifyAuthenticationBlock</code>,
- * including the <code>MOASessionID</code> as a parameter.
- *
- * @param authBaseURL base URL (context path) of the MOA ID Authentication component,
- * including a trailing <code>'/'</code>
- * @param authServletName request part of the data URL
- * @param pendingReqId sessionID to be included in the dataURL
- * @return String
- */
- public String buildDataURL(String authBaseURL, String authServletName, String pendingReqId) {
- String dataURL;
- if (!authBaseURL.endsWith("/"))
- authBaseURL += "/";
-
- if (authServletName.startsWith("/"))
- authServletName = authServletName.substring(1);
-
- dataURL = authBaseURL + authServletName;
-
- if (StringUtils.isNotEmpty(pendingReqId))
- dataURL = addParameter(dataURL, EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReqId);
-
- return dataURL;
- }
-
- /**
- * Method addParameter.
- * @param urlString represents the url
- * @param paramname is the parameter to be added
- * @param value is the value of that parameter
- * @return String
- */
- private String addParameter(String urlString, String paramname, String value) {
- String url = urlString;
- if (paramname != null) {
- if (url.indexOf("?") < 0)
- url += "?";
- else
- url += "&";
- url += paramname + "=" + value;
- }
- return url;
- }
-}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataUrlBuilder.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataUrlBuilder.java
new file mode 100644
index 00000000..ef1f3fdc
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DataUrlBuilder.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria MOA-ID has been developed in a cooperation between
+ * BRZ, the Federal Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at: http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+
+/**
+ * Builds a DataURL parameter meant for the security layer implementation to
+ * respond to.
+ *
+ * @author Paul Ivancsics
+ * @version $Id$
+ */
+public class DataUrlBuilder {
+
+ /**
+ * Constructor for DataURLBuilder.
+ */
+ public DataUrlBuilder() {
+ super();
+ }
+
+ /**
+ * Constructs a data URL for <code>VerifyIdentityLink</code> or
+ * <code>VerifyAuthenticationBlock</code>, including the
+ * <code>MOASessionID</code> as a parameter.
+ *
+ * @param authBaseUrl base URL (context path) of the MOA ID Authentication
+ * component, including a trailing <code>'/'</code>
+ * @param authServletName request part of the data URL
+ * @param pendingReqId sessionID to be included in the dataURL
+ * @return String
+ */
+ public String buildDataUrl(String authBaseUrl, String authServletName,
+ final String pendingReqId) {
+ String dataUrl;
+ if (!authBaseUrl.endsWith("/")) {
+ authBaseUrl += "/";
+ }
+
+ if (authServletName.startsWith("/")) {
+ authServletName = authServletName.substring(1);
+ }
+
+ dataUrl = authBaseUrl + authServletName;
+
+ if (StringUtils.isNotEmpty(pendingReqId)) {
+ dataUrl =
+ addParameter(dataUrl, EaafConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReqId);
+ }
+
+ return dataUrl;
+ }
+
+ /**
+ * Method addParameter.
+ *
+ * @param urlString represents the url
+ * @param paramname is the parameter to be added
+ * @param value is the value of that parameter
+ * @return String
+ */
+ private String addParameter(final String urlString, final String paramname, final String value) {
+ String url = urlString;
+ if (paramname != null) {
+ if (url.indexOf("?") < 0) {
+ url += "?";
+ } else {
+ url += "&";
+ }
+ url += paramname + "=" + value;
+ }
+ return url;
+ }
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java
index 6ac51ac4..7cb551e2 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java
@@ -1,30 +1,21 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
package at.gv.egiz.eaaf.core.impl.utils;
@@ -44,16 +35,16 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileUtils {
- private static final Logger log = LoggerFactory.getLogger(FileUtils.class);
-
-
+ private static final Logger log = LoggerFactory.getLogger(FileUtils.class);
+
/**
* Reads a file, given by URL, into a byte array.
+ *
* @param urlString file URL
* @return file content
* @throws IOException on any exception thrown
*/
- public static byte[] readURL(String urlString) throws IOException {
+ public static byte[] readUrl(final String urlString) throws IOException {
final URL url = new URL(urlString);
final InputStream in = new BufferedInputStream(url.openStream());
final byte[] content = StreamUtils.readStream(in);
@@ -63,114 +54,142 @@ public class FileUtils {
/**
* Reads a file from a resource.
+ *
* @param name resource name
* @return file content as a byte array
* @throws IOException on any exception thrown
*/
- public static byte[] readResource(String name) throws IOException {
+ public static byte[] readResource(final String name) throws IOException {
final ClassLoader cl = FileUtils.class.getClassLoader();
final BufferedInputStream in = new BufferedInputStream(cl.getResourceAsStream(name));
final byte[] content = StreamUtils.readStream(in);
in.close();
return content;
}
+
/**
* Reads a file from a resource.
- * @param name filename
+ *
+ * @param name filename
* @param encoding character encoding
* @return file content
* @throws IOException on any exception thrown
*/
- public static String readResource(String name, String encoding) throws IOException {
+ public static String readResource(final String name, final String encoding) throws IOException {
final byte[] content = readResource(name);
return new String(content, encoding);
}
-
-
- /**
- * Returns the absolute URL of a given url which is relative to the parameter root
- * @param url
- * @param root
- * @return String
- * @throws MalformedURLException
- */
- public static String makeAbsoluteURL(String url, URI root) throws MalformedURLException {
- if (root != null)
- return makeAbsoluteURL(url, root.toURL().toString());
- else
- return makeAbsoluteURL(url, StringUtils.EMPTY);
-
- }
-
- /**
- * Returns the absolute URL of a given url which is relative to the parameter root
- * @param url
- * @param root
- * @return String
- */
- public static String makeAbsoluteURL(String url, String root) {
- //if url is relative to rootConfigFileDirName make it absolute
-
- log.trace("Making AbsoluteURL URL: " + url + " Root-Path: " + root);
-
- if (StringUtils.isEmpty(root))
- root = null;
-
- File keyFile;
- String newURL = url;
-
- if(null == url) return null;
-
- if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")
- || url.startsWith("ftp:") || url.startsWith("classpath:")) {
- return url;
-
- } else {
- // check if absolute - if not make it absolute
- keyFile = new File(url);
- if (!keyFile.isAbsolute()) {
- keyFile = new File(root, url);
-
- if (keyFile.toString().startsWith("file:"))
- newURL = keyFile.toString();
-
- else
- newURL = keyFile.toURI().toString();
-
- }
- return newURL;
- }
- }
-
-
- private static void copy( InputStream fis, OutputStream fos )
- {
- try
- {
- final byte[] buffer = new byte[ 0xFFFF ];
- for ( int len; (len = fis.read(buffer)) != -1; )
- fos.write( buffer, 0, len );
- }
- catch( final IOException e ) {
- System.err.println( e );
- }
- finally {
- if ( fis != null )
- try { fis.close(); } catch ( final IOException e ) { e.printStackTrace(); }
- if ( fos != null )
- try { fos.close(); } catch ( final IOException e ) { e.printStackTrace(); }
- }
- }
-
- public static void copyFile(File src, File dest)
- {
- try
- {
- copy( new FileInputStream( src ), new FileOutputStream( dest ) );
- }
- catch( final IOException e ) {
- e.printStackTrace();
- }
- }
-
+
+ /**
+ * Returns the absolute URL of a given url which is relative to the parameter
+ * root.
+ *
+ * @param url Filepath
+ * @param root configuration root context
+ * @return absolut filepath
+ * @throws MalformedURLException In case of a filepath error
+ */
+ public static String makeAbsoluteUrl(final String url, final URI root)
+ throws MalformedURLException {
+ if (root != null) {
+ return makeAbsoluteUrl(url, root.toURL().toString());
+ } else {
+ return makeAbsoluteUrl(url, StringUtils.EMPTY);
+ }
+
+ }
+
+ /**
+ * Returns the absolute URL of a given url which is relative to the parameter
+ * root.
+ *
+ * @param url Filepath
+ * @param root configuration root context
+ * @return absolut filepath
+ */
+ public static String makeAbsoluteUrl(final String url, String root) {
+ // if url is relative to rootConfigFileDirName make it absolute
+
+ log.trace("Making AbsoluteURL URL: " + url + " Root-Path: " + root);
+
+ if (StringUtils.isEmpty(root)) {
+ root = null;
+ }
+
+ File keyFile;
+ String newUrl = url;
+
+ if (null == url) {
+ return null;
+ }
+
+ if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")
+ || url.startsWith("ftp:") || url.startsWith("classpath:")) {
+ return url;
+
+ } else {
+ // check if absolute - if not make it absolute
+ keyFile = new File(url);
+ if (!keyFile.isAbsolute()) {
+ keyFile = new File(root, url);
+
+ if (keyFile.toString().startsWith("file:")) {
+ newUrl = keyFile.toString();
+ } else {
+ newUrl = keyFile.toURI().toString();
+ }
+
+ }
+ return newUrl;
+ }
+ }
+
+ private static void copy(final InputStream fis, final OutputStream fos) {
+ try {
+ final byte[] buffer = new byte[0xFFFF];
+ for (int len; (len = fis.read(buffer)) != -1;) {
+ fos.write(buffer, 0, len);
+ }
+ } catch (final IOException e) {
+ System.err.println(e);
+
+ }
+ }
+
+ /**
+ * Copy file from source to destination.
+ *
+ * @param src File source
+ * @param dest file destination
+ */
+ public static void copyFile(final File src, final File dest) {
+ InputStream fis = null;
+ OutputStream fos = null;
+
+ try {
+ fis = new FileInputStream(src);
+ fos = new FileOutputStream(src);
+ copy(fis, fos);
+
+ } catch (final IOException e) {
+ e.printStackTrace();
+
+ } finally {
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ }
+ if (fos != null) {
+ try {
+ fos.close();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java
deleted file mode 100644
index cf1abaa7..00000000
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HTTPUtils.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*******************************************************************************
- * Copyright 2014 Federal Chancellery Austria
- * MOA-ID has been developed in a cooperation between BRZ, the Federal
- * Chancellery Austria - ICT staff unit, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- ******************************************************************************/
-/*
- * Copyright 2003 Federal Chancellery Austria
- * MOA-ID has been developed in a cooperation between BRZ, the Federal
- * Chancellery Austria - ICT staff unit, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- */
-
-
-package at.gv.egiz.eaaf.core.impl.utils;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.lang3.StringUtils;
-
-
-/**
- *
- * @author Rudolf Schamberger
- *
- */
-public class HTTPUtils {
-
-// /**
-// * Utility used to obtainin correct encoded HTTP content.
-// * Reads a given Content adressed by HTTP-URL into String.
-// * Content encoding is considered by using the Content-Type HTTP header charset value.
-// * @param URL HTTP URL to read from.
-// * @return String representation of content
-// * @throws IOException on data-reading problems
-// */
-// public static String readHttpURL(String URL)
-// throws IOException {
-//
-// URL url = new URL(URL);
-// HttpURLConnection conn = (HttpURLConnection)url.openConnection();
-// conn.setRequestMethod("GET");
-// String contentType = conn.getContentType();
-// RE regExp = null;
-// try {
-// regExp = new RE("(;.*charset=)(\"*)(.*[^\"])");
-// } catch (RESyntaxException e) {
-// //RESyntaxException is not possible = expr. is costant
-// }
-// boolean charsetSupplied = regExp.match(contentType);
-// String encoding = "ISO-8859-1"; //default HTTP encoding
-// if (charsetSupplied) {
-// encoding = regExp.getParen(3);
-// }
-// InputStream instream = new BufferedInputStream(conn.getInputStream());
-// InputStreamReader isr = new InputStreamReader(instream, encoding);
-// Reader in = new BufferedReader(isr);
-// int ch;
-// StringBuffer buffer = new StringBuffer();
-// while ((ch = in.read()) > -1) {
-// buffer.append((char)ch);
-// }
-// in.close();
-// conn.disconnect();
-// return buffer.toString();
-// }
-
- /**
- * Helper method to retrieve server URL including context path
- * @param request HttpServletRequest
- * @return Server URL including context path (e.g. http://localhost:8443/moa-id-auth
- */
- public static String getBaseURL(HttpServletRequest request) {
- StringBuffer buffer = new StringBuffer(getServerURL(request));
-
- // add context path if available
- String contextPath = request.getContextPath();
- if (!StringUtils.isEmpty(contextPath)) {
- buffer.append(contextPath);
- }
-
- return buffer.toString();
- }
-
- /**
- * Helper method to retrieve server URL
- * @param request HttpServletRequest
- * @return Server URL (e.g. http://localhost:8443)
- */
- public static String getServerURL(HttpServletRequest request) {
- StringBuffer buffer = new StringBuffer();
-
- // get protocol
- String protocol = request.getScheme();
- buffer.append(protocol).append("://");
-
- // server name
- buffer.append(request.getServerName());
-
- // add port if necessary
- int port = request.getServerPort();
- if ((protocol.equals("http") && port != 80) || (protocol.equals("https") && port != 443)) {
- buffer.append(':');
- buffer.append(port);
- }
-
- return buffer.toString();
- }
-
- /**
- * Extract the IDP PublicURLPrefix from authrequest
- *
- * @param req HttpServletRequest
- * @return PublicURLPrefix <String> which ends always without /
- */
- public static String extractAuthURLFromRequest(HttpServletRequest req) {
- String authURL = req.getScheme() + "://" + req.getServerName();
- if ((req.getScheme().equalsIgnoreCase("https") && req.getServerPort()!=443) || (req.getScheme().equalsIgnoreCase("http") && req.getServerPort()!=80)) {
- authURL = authURL.concat(":" + req.getServerPort());
- }
- authURL = authURL.concat(req.getContextPath());
- return authURL;
-
- }
-
- /**
- * Extract the IDP requested URL from authrequest
- *
- * @param req HttpServletRequest
- * @return RequestURL <String> which ends always without /
- */
- public static String extractAuthServletPathFromRequest(HttpServletRequest req) {
- return extractAuthURLFromRequest(req).concat(req.getServletPath());
-
- }
-
- public static String addURLParameter(String url, String paramname,
- String paramvalue) {
- String param = paramname + "=" + paramvalue;
- if (url.indexOf("?") < 0)
- return url + "?" + param;
- else
- return url + "&" + param;
- }
-
-}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java
index a8cfa7c1..e681e705 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java
@@ -1,18 +1,22 @@
package at.gv.egiz.eaaf.core.impl.utils;
-import java.io.IOException;
-import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
import javax.annotation.PostConstruct;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
+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.credential.EaafKeyStoreFactory;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType;
+
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
@@ -38,345 +42,329 @@ import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
-import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
-import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
+import lombok.extern.slf4j.Slf4j;
+@Slf4j
public class HttpClientFactory implements IHttpClientFactory {
- private static final Logger log = LoggerFactory.getLogger(HttpClientFactory.class);
- @Autowired(required=true) private IConfiguration basicConfig;
- @Autowired(required=true) ResourceLoader resourceLoader;
-
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE = "client.http.connection.pool.use";
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL = "client.http.connection.pool.maxtotal";
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE = "client.http.connection.pool.maxperroute";
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET = "client.http.connection.timeout.socket";
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION = "client.http.connection.timeout.connection";
- public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST = "client.http.connection.timeout.request";
- public static final String PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL = "client.http.ssl.hostnameverifier.trustall";
-
- public static final String PROP_CONFIG_CLIENT_MODE = "client.authmode";
- public static final String PROP_CONFIG_CLIENT_AUTH_HTTP_USERNAME = "client.auth.http.username";
- public static final String PROP_CONFIG_CLIENT_AUTH_HTTP_PASSORD = "client.auth.http.password";
- public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PATH = "client.auth.ssl.keystore.path";
- public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD = "client.auth.ssl.keystore.password";
- public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE = "client.auth.ssl.keystore.type";
- public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEY_PASSWORD = "client.auth.ssl.key.password";
- public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEY_ALIAS = "client.auth.ssl.key.alias";
-
- // default configuration values
- public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET = "15";
- public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION = "15";
- public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST = "30";
- public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL = "500";
- public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE = "100";
-
- public enum ClientAuthMode {
- NONE("none"),
- PASSWORD("password"),
- SSL("ssl");
-
- private final String mode;
-
- private ClientAuthMode(String mode) {
- this.mode = mode;
- }
-
- /**
- * Get the PVP mode
- *
- * @return
- */
- public String getMode() {
- return this.mode;
- }
-
- public static ClientAuthMode fromString(String s) {
- try {
- return ClientAuthMode.valueOf(s.toUpperCase());
-
- } catch (IllegalArgumentException|NullPointerException e) {
- return null;
- }
- }
-
- @Override
- public String toString() {
- return getMode();
-
- }
-
- };
-
- public enum KeyStoreType {
- PKCS12("pkcs12"),
- JKS("jks");
-
- private final String type;
-
- private KeyStoreType (String type) {
- this.type = type;
- }
-
- /**
- * Get the PVP mode
- *
- * @return
- */
- public String getType() {
- return this.type;
- }
-
- public static KeyStoreType fromString(String s) {
- try {
- return KeyStoreType.valueOf(s.toUpperCase());
-
- } catch (IllegalArgumentException|NullPointerException e) {
- return null;
- }
- }
-
- @Override
- public String toString() {
- return getType();
-
- }
-
- };
-
- private HttpClientBuilder httpClientBuilder = null;
-
- /* (non-Javadoc)
- * @see at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory#getHttpClient()
- */
- @Override
- public CloseableHttpClient getHttpClient() {
- return getHttpClient(true);
-
- }
-
- @Override
- public CloseableHttpClient getHttpClient(boolean followRedirects) {
- RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
- if (!followRedirects)
- redirectStrategy = new RedirectStrategy() {
-
- @Override
- public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context)
- throws ProtocolException {
- return false;
- }
-
- @Override
- public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context)
- throws ProtocolException {
- return null;
- }
- };
-
- return httpClientBuilder
- .setRedirectStrategy(redirectStrategy)
- .build();
-
- }
-
- @PostConstruct
- private void initalize() {
- //initialize http client
- log.trace("Initializing HTTP Client-builder ... ");
- httpClientBuilder = HttpClients.custom();
-
- //set default request configuration
- final RequestConfig requestConfig = RequestConfig.custom()
- .setConnectTimeout(Integer.valueOf(basicConfig.getBasicConfiguration(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION,
- DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION)) * 1000)
- .setConnectionRequestTimeout(Integer.valueOf(basicConfig.getBasicConfiguration(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST,
- DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST)) * 1000)
- .setSocketTimeout(Integer.valueOf(basicConfig.getBasicConfiguration(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET,
- DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET)) * 1000)
- .build();
- httpClientBuilder.setDefaultRequestConfig(requestConfig);
-
- ClientAuthMode clientAuthMode = ClientAuthMode.fromString(
- basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_MODE, ClientAuthMode.NONE.getMode()));
- if (clientAuthMode == null) {
- log.warn("Can Not parse ClientAuthMode! Set mode to default value");
- clientAuthMode = ClientAuthMode.NONE;
-
- }
-
- //inject basic http authentication if required
- log.info("Client authentication-mode is set to: {}", clientAuthMode);
- injectBasicAuthenticationIfRequired(clientAuthMode);
-
- //inject authentication if required
- final LayeredConnectionSocketFactory sslConnectionFactory = getSSLContext(clientAuthMode);
-
- //set pool connection if required
- injectConnectionPoolIfRequired(sslConnectionFactory);
-
-
- }
-
- private void injectBasicAuthenticationIfRequired(ClientAuthMode clientAuthMode) {
- if (clientAuthMode.equals(ClientAuthMode.PASSWORD)) {
- final CredentialsProvider provider = new BasicCredentialsProvider();
-
- final String username = basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_HTTP_USERNAME);
- final String password = basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_HTTP_PASSORD);
-
- if (StringUtils.isEmpty(username)) {
- log.warn("Http basic authentication was activated but NOT username was set!");
-
- }
-
- log.trace("Injecting basic authentication with username: {} and password: {}", username, password);
- final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
- provider.setCredentials(AuthScope.ANY, credentials);
- httpClientBuilder.setDefaultCredentialsProvider(provider);
- log.info("Basic http authentication was injected with username: {}", username);
-
- } else {
- log.trace("Injection of Http Basic authentication was skipped");
-
- }
-
- }
-
- private SSLContext buildSSLContextWithSSLClientAuthentication() throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, EAAFConfigurationException {
- log.trace("Injecting SSL client-authentication into http client ... ");
- final KeyStore keystore = getSSLAuthKeyStore();
- final String keyPasswordString = basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEY_PASSWORD);
- log.trace("Open SSL Client-Auth keystore with password: {}", keyPasswordString);
- final char[] keyPassword = (keyPasswordString == null) ? StringUtils.EMPTY.toCharArray() : keyPasswordString.toCharArray();
- return SSLContexts.custom().loadKeyMaterial(keystore, keyPassword).build();
-
- }
-
- private KeyStore getSSLAuthKeyStore() throws EAAFConfigurationException {
- final KeyStoreType keyStoreType = KeyStoreType.fromString(
- basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE, KeyStoreType.PKCS12.getType()));
- final String localKeyStorePath = basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PATH, StringUtils.EMPTY);
- final String keyStorePassword = basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD, StringUtils.EMPTY);
-
- try {
- log.debug("Open keyStore with type: {}", keyStoreType);
- KeyStore clientStore;
- if (keyStoreType.equals(KeyStoreType.PKCS12)) {
- clientStore = KeyStore.getInstance("pkcs12");
- } else {
- clientStore = KeyStore.getInstance("JKS");
- }
-
-
- log.debug("Read keyStore path: {} from configuration", localKeyStorePath);
- if (StringUtils.isNotEmpty(localKeyStorePath)) {
- final String absFilePath = FileUtils.makeAbsoluteURL(localKeyStorePath, basicConfig.getConfigurationRootDirectory());
- final Resource ressource = resourceLoader.getResource(absFilePath);
- final InputStream is = ressource.getInputStream();
- log.trace("Load keyStore: {} with password: {}", absFilePath, keyStorePassword);
- clientStore.load(is, keyStorePassword.toCharArray());
- is.close();
-
- return clientStore;
-
- } else {
- log.warn("Path to keyStore for SSL Client-Authentication is empty or null");
- throw new EAAFConfigurationException("Path to keyStore for SSL Client-Authentication is empty or null", new Object[] {});
-
- }
-
- } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
- log.warn("Can NOT read keyStore: {} from filesystem", localKeyStorePath, null, e);
- throw new EAAFConfigurationException("Can NOT read keyStore: {} from filesystem", new Object[] {localKeyStorePath}, e);
-
- }
-
- }
-
- private LayeredConnectionSocketFactory getSSLContext(ClientAuthMode clientAuthMode) {
- SSLContext sslContext = null;
- try {
- if (clientAuthMode.equals(ClientAuthMode.SSL)) {
- sslContext = buildSSLContextWithSSLClientAuthentication();
-
- } else {
- log.trace("Initializing default SSL Context ... ");
- sslContext = SSLContext.getDefault();
-
- }
-
- //set hostname verifier
- HostnameVerifier hostnameVerifier = null;
- if (basicConfig.getBasicConfigurationBoolean(
- PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL,
- false)) {
- hostnameVerifier = new NoopHostnameVerifier();
- log.warn("HTTP client-builder deactivates SSL Host-name verification!");
-
- }
-
- final LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext , hostnameVerifier);
-
- return sslSocketFactory;
-
- } catch (final NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException | KeyStoreException | EAAFConfigurationException e) {
- log.warn("HTTP client-builder can NOT initialze SSL-Context", e);
-
- }
-
- log.info("HTTP client-builder successfuly initialized");
- return null;
-
- }
-
- private void injectConnectionPoolIfRequired(LayeredConnectionSocketFactory sslConnectionFactory) {
- if (basicConfig.getBasicConfigurationBoolean(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE,
- true)) {
- PoolingHttpClientConnectionManager pool;
-
- //set socketFactoryRegistry if SSLConnectionFactory is Set
- if (sslConnectionFactory != null) {
- final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
- .register("http", PlainConnectionSocketFactory.getSocketFactory())
- .register("https", sslConnectionFactory)
- .build();
- log.trace("Inject SSLSocketFactory into pooled connection");
- pool = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
-
- } else {
- pool = new PoolingHttpClientConnectionManager();
-
- }
-
- pool.setDefaultMaxPerRoute(Integer.valueOf(basicConfig.getBasicConfiguration(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE,
- DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE)));
- pool.setMaxTotal(Integer.valueOf(basicConfig.getBasicConfiguration(
- PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL,
- DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL)));
-
- httpClientBuilder.setConnectionManager(pool);
- log.debug("Initalize http-client pool with, maxTotal: {} maxPerRoute: {}", pool.getMaxTotal(), pool.getDefaultMaxPerRoute());
-
- } else if (sslConnectionFactory != null) {
- log.trace("Inject SSLSocketFactory without connection pool");
- httpClientBuilder.setSSLSocketFactory(sslConnectionFactory );
-
- }
-
-
- }
-
-
-
+
+ @Autowired(required = true)
+ private IConfiguration basicConfig;
+
+ @Autowired(required = true)
+ ResourceLoader resourceLoader;
+
+ @Autowired private EaafKeyStoreFactory keyStoreFactory;
+
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE =
+ "client.http.connection.pool.use";
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL =
+ "client.http.connection.pool.maxtotal";
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE =
+ "client.http.connection.pool.maxperroute";
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET =
+ "client.http.connection.timeout.socket";
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION =
+ "client.http.connection.timeout.connection";
+ public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST =
+ "client.http.connection.timeout.request";
+ public static final String PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL =
+ "client.http.ssl.hostnameverifier.trustall";
+
+ public static final String PROP_CONFIG_CLIENT_MODE = "client.authmode";
+ public static final String PROP_CONFIG_CLIENT_AUTH_HTTP_USERNAME = "client.auth.http.username";
+ public static final String PROP_CONFIG_CLIENT_AUTH_HTTP_PASSORD = "client.auth.http.password";
+ public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PATH =
+ "client.auth.ssl.keystore.path";
+ public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD =
+ "client.auth.ssl.keystore.password";
+ private static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_NAME =
+ "client.auth.ssl.keystore.name";
+ public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE =
+ "client.auth.ssl.keystore.type";
+ public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEY_PASSWORD =
+ "client.auth.ssl.key.password";
+ public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEY_ALIAS = "client.auth.ssl.key.alias";
+
+ // default configuration values
+ public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET = "15";
+ public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION = "15";
+ public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST = "30";
+ public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL = "500";
+ public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE = "100";
+
+ public enum ClientAuthMode {
+ NONE("none"), PASSWORD("password"), SSL("ssl");
+
+ private final String mode;
+
+ ClientAuthMode(final String mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * Get the PVP mode.
+ *
+ * @return
+ */
+ public String getMode() {
+ return this.mode;
+ }
+
+ /**
+ * Get http-client authentication mode from String representation.
+ *
+ * @param s Config parameter
+ * @return
+ */
+ public static ClientAuthMode fromString(final String s) {
+ try {
+ return ClientAuthMode.valueOf(s.toUpperCase());
+
+ } catch (IllegalArgumentException | NullPointerException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getMode();
+
+ }
+
+ }
+
+ private HttpClientBuilder httpClientBuilder = null;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory#getHttpClient()
+ */
+ @Override
+ public CloseableHttpClient getHttpClient() {
+ return getHttpClient(true);
+
+ }
+
+ @Override
+ public CloseableHttpClient getHttpClient(final boolean followRedirects) {
+ RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+ if (!followRedirects) {
+ redirectStrategy = new RedirectStrategy() {
+
+ @Override
+ public boolean isRedirected(final HttpRequest request, final HttpResponse response,
+ final HttpContext context) throws ProtocolException {
+ return false;
+ }
+
+ @Override
+ public HttpUriRequest getRedirect(final HttpRequest request, final HttpResponse response,
+ final HttpContext context) throws ProtocolException {
+ return null;
+ }
+ };
+ }
+
+ return httpClientBuilder.setRedirectStrategy(redirectStrategy).build();
+
+ }
+
+ @PostConstruct
+ private void initalize() {
+ // initialize http client
+ log.trace("Initializing HTTP Client-builder ... ");
+ httpClientBuilder = HttpClients.custom();
+
+ // set default request configuration
+ final RequestConfig requestConfig =
+ RequestConfig.custom()
+ .setConnectTimeout(
+ Integer.parseInt(basicConfig.getBasicConfiguration(
+ PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION,
+ DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION)) * 1000)
+ .setConnectionRequestTimeout(Integer.parseInt(basicConfig.getBasicConfiguration(
+ PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST,
+ DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST)) * 1000)
+ .setSocketTimeout(Integer.parseInt(
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET,
+ DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET))
+ * 1000)
+ .build();
+ httpClientBuilder.setDefaultRequestConfig(requestConfig);
+
+ ClientAuthMode clientAuthMode = ClientAuthMode.fromString(
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_MODE, ClientAuthMode.NONE.getMode()));
+ if (clientAuthMode == null) {
+ log.warn("Can Not parse ClientAuthMode! Set mode to default value");
+ clientAuthMode = ClientAuthMode.NONE;
+
+ }
+
+ // inject basic http authentication if required
+ log.info("Client authentication-mode is set to: {}", clientAuthMode);
+ injectBasicAuthenticationIfRequired(clientAuthMode);
+
+ // inject authentication if required
+ final LayeredConnectionSocketFactory sslConnectionFactory = getSslContext(clientAuthMode);
+
+ // set pool connection if required
+ injectConnectionPoolIfRequired(sslConnectionFactory);
+
+ }
+
+ private void injectBasicAuthenticationIfRequired(final ClientAuthMode clientAuthMode) {
+ if (clientAuthMode.equals(ClientAuthMode.PASSWORD)) {
+ final CredentialsProvider provider = new BasicCredentialsProvider();
+
+ final String username =
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_HTTP_USERNAME);
+ final String password =
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_HTTP_PASSORD);
+
+ if (StringUtils.isEmpty(username)) {
+ log.warn("Http basic authentication was activated but NOT username was set!");
+
+ }
+
+ log.trace("Injecting basic authentication with username: {} and password: {}", username,
+ password);
+ final UsernamePasswordCredentials credentials =
+ new UsernamePasswordCredentials(username, password);
+ provider.setCredentials(AuthScope.ANY, credentials);
+ httpClientBuilder.setDefaultCredentialsProvider(provider);
+ log.info("Basic http authentication was injected with username: {}", username);
+
+ } else {
+ log.trace("Injection of Http Basic authentication was skipped");
+
+ }
+
+ }
+
+ private SSLContext buildSslContextWithSslClientAuthentication()
+ throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException,
+ KeyStoreException, EaafConfigurationException {
+ log.trace("Injecting SSL client-authentication into http client ... ");
+ final KeyStore keystore = getSslAuthKeyStore();
+ final String keyPasswordString =
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEY_PASSWORD);
+ log.trace("Open SSL Client-Auth keystore with password: {}", keyPasswordString);
+ final char[] keyPassword = keyPasswordString == null ? StringUtils.EMPTY.toCharArray()
+ : keyPasswordString.toCharArray();
+ return SSLContexts.custom().loadKeyMaterial(keystore, keyPassword).build();
+
+ }
+
+ private KeyStore getSslAuthKeyStore() throws EaafConfigurationException {
+ final String keyStoreType = basicConfig.getBasicConfiguration(
+ PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE, KeyStoreType.PKCS12.getKeyStoreType());
+ final String localKeyStorePath = basicConfig
+ .getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PATH, StringUtils.EMPTY);
+ final String keyStorePassword = basicConfig
+ .getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD, StringUtils.EMPTY);
+ final String keyStoreName = basicConfig
+ .getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_NAME, StringUtils.EMPTY);
+
+ try {
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(keyStoreType);
+ keyStoreConfig.setFriendlyName("HttpClient Keystore");
+ keyStoreConfig.setSoftKeyStoreFilePath(localKeyStorePath);
+ keyStoreConfig.setSoftKeyStorePassword(keyStorePassword);
+ keyStoreConfig.setKeyStoreName(keyStoreName);
+
+ log.debug("Open keyStore with type: {}", keyStoreType);
+ final KeyStore keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig).getFirst();
+
+ return keyStore;
+
+ } catch (final EaafException e) {
+ log.warn("Can NOT read keyStore: {} from filesystem", localKeyStorePath, null, e);
+ throw new EaafConfigurationException("Can NOT read keyStore: {} from filesystem",
+ new Object[] { localKeyStorePath }, e);
+
+ }
+
+ }
+
+ private LayeredConnectionSocketFactory getSslContext(final ClientAuthMode clientAuthMode) {
+ SSLContext sslContext = null;
+ try {
+ if (clientAuthMode.equals(ClientAuthMode.SSL)) {
+ sslContext = buildSslContextWithSslClientAuthentication();
+
+ } else {
+ log.trace("Initializing default SSL Context ... ");
+ sslContext = SSLContext.getDefault();
+
+ }
+
+ // set hostname verifier
+ HostnameVerifier hostnameVerifier = null;
+ if (basicConfig.getBasicConfigurationBoolean(
+ PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL, false)) {
+ hostnameVerifier = new NoopHostnameVerifier();
+ log.warn("HTTP client-builder deactivates SSL Host-name verification!");
+
+ }
+
+ final LayeredConnectionSocketFactory sslSocketFactory =
+ new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
+
+ return sslSocketFactory;
+
+ } catch (final NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException
+ | KeyStoreException | EaafConfigurationException e) {
+ log.warn("HTTP client-builder can NOT initialze SSL-Context", e);
+
+ }
+
+ log.info("HTTP client-builder successfuly initialized");
+ return null;
+
+ }
+
+ private void injectConnectionPoolIfRequired(
+ final LayeredConnectionSocketFactory sslConnectionFactory) {
+ if (basicConfig.getBasicConfigurationBoolean(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE,
+ true)) {
+ PoolingHttpClientConnectionManager pool;
+
+ // set socketFactoryRegistry if SSLConnectionFactory is Set
+ if (sslConnectionFactory != null) {
+ final Registry<ConnectionSocketFactory> socketFactoryRegistry =
+ RegistryBuilder.<ConnectionSocketFactory>create()
+ .register("http", PlainConnectionSocketFactory.getSocketFactory())
+ .register("https", sslConnectionFactory).build();
+ log.trace("Inject SSLSocketFactory into pooled connection");
+ pool = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+
+ } else {
+ pool = new PoolingHttpClientConnectionManager();
+
+ }
+
+ pool.setDefaultMaxPerRoute(Integer.parseInt(
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE,
+ DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE)));
+ pool.setMaxTotal(Integer.parseInt(
+ basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL,
+ DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL)));
+
+ httpClientBuilder.setConnectionManager(pool);
+ log.debug("Initalize http-client pool with, maxTotal: {} maxPerRoute: {}", pool.getMaxTotal(),
+ pool.getDefaultMaxPerRoute());
+
+ } else if (sslConnectionFactory != null) {
+ log.trace("Inject SSLSocketFactory without connection pool");
+ httpClientBuilder.setSSLSocketFactory(sslConnectionFactory);
+
+ }
+
+ }
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpUtils.java
new file mode 100644
index 00000000..66356ba0
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpUtils.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria MOA-ID has been developed in a cooperation between
+ * BRZ, the Federal Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at: http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+
+public class HttpUtils {
+
+ /**
+ * Helper method to retrieve server URL including context path.
+ *
+ * @param request HttpServletRequest
+ * @return Server URL including context path (e.g.
+ * http://localhost:8443/moa-id-auth
+ */
+ public static String getBaseUrl(final HttpServletRequest request) {
+ final StringBuffer buffer = new StringBuffer(getServerUrl(request));
+
+ // add context path if available
+ final String contextPath = request.getContextPath();
+ if (!StringUtils.isEmpty(contextPath)) {
+ buffer.append(contextPath);
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * Helper method to retrieve server URL.
+ *
+ * @param request HttpServletRequest
+ * @return Server URL (e.g. http://localhost:8443)
+ */
+ public static String getServerUrl(final HttpServletRequest request) {
+ final StringBuffer buffer = new StringBuffer();
+
+ // get protocol
+ final String protocol = request.getScheme();
+ buffer.append(protocol).append("://");
+
+ // server name
+ buffer.append(request.getServerName());
+
+ // add port if necessary
+ final int port = request.getServerPort();
+ if (protocol.equals("http") && port != 80 || protocol.equals("https") && port != 443) {
+ buffer.append(':');
+ buffer.append(port);
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * Extract the IDP PublicURLPrefix from authrequest.
+ *
+ * @param req HttpServletRequest
+ * @return PublicURLPrefix which ends always without /
+ */
+ public static String extractAuthUrlFromRequest(final HttpServletRequest req) {
+ String authUrl = req.getScheme() + "://" + req.getServerName();
+ if (req.getScheme().equalsIgnoreCase("https") && req.getServerPort() != 443
+ || req.getScheme().equalsIgnoreCase("http") && req.getServerPort() != 80) {
+ authUrl = authUrl.concat(":" + req.getServerPort());
+ }
+ authUrl = authUrl.concat(req.getContextPath());
+ return authUrl;
+
+ }
+
+ /**
+ * Extract the IDP requested URL from authrequest.
+ *
+ * @param req HttpServletRequest
+ * @return RequestURL which ends always without /
+ */
+ public static String extractAuthServletPathFromRequest(final HttpServletRequest req) {
+ return extractAuthUrlFromRequest(req).concat(req.getServletPath());
+
+ }
+
+ /**
+ * Add a http GET parameter to URL.
+ *
+ * @param url URL
+ * @param paramname Name of the parameter.
+ * @param paramvalue Value of the parameter.
+ * @return
+ */
+ public static String addUrlParameter(final String url, final String paramname,
+ final String paramvalue) {
+ final String param = paramname + "=" + paramvalue;
+ if (url.indexOf("?") < 0) {
+ return url + "?" + param;
+ } else {
+ return url + "&" + param;
+ }
+ }
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/IHttpClientFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/IHttpClientFactory.java
index 1975fb52..f922e1ac 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/IHttpClientFactory.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/IHttpClientFactory.java
@@ -4,18 +4,21 @@ import org.apache.http.impl.client.CloseableHttpClient;
public interface IHttpClientFactory {
- /**
- * Return an instance of a Apache HTTP client that follows http redirects automatically
- *
- * @return
- */
- CloseableHttpClient getHttpClient();
+ /**
+ * Return an instance of a Apache HTTP client that follows http redirects
+ * automatically.
+ *
+ * @return
+ */
+ CloseableHttpClient getHttpClient();
- /**
- * Return an instance of a Apache HTTP client
- * @param followRedirects
- * @return
- */
- CloseableHttpClient getHttpClient(boolean followRedirects);
-
-} \ No newline at end of file
+ /**
+ * Return an instance of a Apache HTTP client.
+ *
+ * @param followRedirects if <code>false</code>, the client does not flow 30x
+ * http redirects
+ * @return
+ */
+ CloseableHttpClient getHttpClient(boolean followRedirects);
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java
index e3d74066..99b87819 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyStoreUtils.java
@@ -1,36 +1,26 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
package at.gv.egiz.eaaf.core.impl.utils;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -42,88 +32,127 @@ import java.security.cert.CertificateFactory;
/**
* Utility for creating and loading key stores.
- *
+ *
* @author Paul Ivancsics
* @version $Id$
*/
public class KeyStoreUtils {
-
- /**
- * JAVA KeyStore
- */
- private static final String KEYSTORE_TYPE_JKS = "JKS";
-
- /**
- * PKCS12 KeyStore
- */
- private static final String KEYSTORE_TYPE_PKCS12 = "PKCS12";
-
-
+
+ /**
+ * JAVA KeyStore.
+ */
+ private static final String KEYSTORE_TYPE_JKS = "JKS";
+
+ /**
+ * PKCS12 KeyStore.
+ */
+ private static final String KEYSTORE_TYPE_PKCS12 = "PKCS12";
/**
* Loads a key store from file.
- *
+ *
* @param keystoreType key store type
- * @param urlString URL of key store
- * @param password password protecting the key store
+ * @param urlString URL of key store
+ * @param password password protecting the key store
* @return key store loaded
- * @throws IOException thrown while reading the key store from file
+ * @throws IOException thrown while reading the key store from file
* @throws GeneralSecurityException thrown while creating the key store
*/
- public static KeyStore loadKeyStore(
- String keystoreType,
- String urlString,
- String password)
- throws IOException, GeneralSecurityException {
-
- URL keystoreURL = new URL(urlString);
- InputStream in = keystoreURL.openStream();
+ public static KeyStore loadKeyStore(final String keystoreType, final String urlString,
+ final String password) throws IOException, GeneralSecurityException {
+
+ final URL keystoreUrl = new URL(urlString);
+ final InputStream in = keystoreUrl.openStream();
return loadKeyStore(keystoreType, in, password);
}
+
+ /**
+ * Load a KeyStore from Filesystem.
+ *
+ * @param keyStorePath Path to KeyStore
+ * @param password KeyStore password
+ * @return KeyStore
+ * @throws KeyStoreException In case of a keystore error
+ * @throws IOException In case of a general read error
+ */
+ public static KeyStore loadKeyStore(final String keyStorePath, final String password)
+ throws KeyStoreException, IOException {
+ final URL keystoreUrl = new URL(keyStorePath);
+ final InputStream in = keystoreUrl.openStream();
+ final InputStream isBuffered = new BufferedInputStream(in);
+ return loadKeyStore(isBuffered, password);
+
+ }
+
/**
- * Loads a key store from an <code>InputStream</code>, and
- * closes the <code>InputStream</code>.
- *
+ * Loads a key store from an <code>InputStream</code>, and closes the
+ * <code>InputStream</code>.
+ *
* @param keystoreType key store type
- * @param in input stream
- * @param password password protecting the key store
+ * @param in input stream
+ * @param password password protecting the key store
* @return key store loaded
- * @throws IOException thrown while reading the key store from the stream
+ * @throws IOException thrown while reading the key store from the
+ * stream
* @throws GeneralSecurityException thrown while creating the key store
*/
- public static KeyStore loadKeyStore(
- String keystoreType,
- InputStream in,
- String password)
- throws IOException, GeneralSecurityException {
+ public static KeyStore loadKeyStore(final String keystoreType, final InputStream in,
+ final String password) throws IOException, GeneralSecurityException {
char[] chPassword = null;
- if (password != null)
+ if (password != null) {
chPassword = password.toCharArray();
- KeyStore ks = KeyStore.getInstance(keystoreType);
+ }
+ final KeyStore ks = KeyStore.getInstance(keystoreType);
ks.load(in, chPassword);
in.close();
return ks;
}
+
+ /**
+ * Loads a keyStore without knowing the keyStore type.
+ *
+ * @param is input stream
+ * @param password Password protecting the keyStore
+ * @return keyStore loaded
+ * @throws KeyStoreException thrown if keyStore cannot be loaded
+ * @throws IOException In case of a general error
+ */
+ public static KeyStore loadKeyStore(final InputStream is, final String password)
+ throws KeyStoreException, IOException {
+ is.mark(1024 * 1024);
+ KeyStore ks = null;
+ try {
+ try {
+ ks = loadKeyStore(KEYSTORE_TYPE_PKCS12, is, password);
+ } catch (final IOException e2) {
+ is.reset();
+ ks = loadKeyStore(KEYSTORE_TYPE_JKS, is, password);
+ }
+ } catch (final Exception e) {
+ e.printStackTrace();
+
+ }
+ return ks;
+
+ }
+
/**
- * Creates a key store from X509 certificate files, aliasing them with
- * the index in the <code>String[]</code>, starting with <code>"0"</code>.
- *
- * @param keyStoreType key store type
+ * Creates a key store from X509 certificate files, aliasing them with the index
+ * in the <code>String[]</code>, starting with <code>"0"</code>.
+ *
+ * @param keyStoreType key store type
* @param certFilenames certificate filenames
* @return key store created
- * @throws IOException thrown while reading the certificates from file
- * @throws GeneralSecurityException thrown while creating the key store
+ * @throws Exception In case of an error
*/
- public static KeyStore createKeyStore(
- String keyStoreType,
- String[] certFilenames)
- throws IOException, GeneralSecurityException {
+ public static KeyStore createKeyStore(final String keyStoreType, final String[] certFilenames)
+ throws Exception {
- KeyStore ks = KeyStore.getInstance(keyStoreType);
+ final KeyStore ks = KeyStore.getInstance(keyStoreType);
ks.load(null, null);
for (int i = 0; i < certFilenames.length; i++) {
- Certificate cert = loadCertificate(certFilenames[i]);
+ final Certificate cert = loadCertificate(certFilenames[i]);
ks.setCertificateEntry("" + i, cert);
}
return ks;
@@ -131,69 +160,34 @@ public class KeyStoreUtils {
/**
* Loads an X509 certificate from file.
+ *
* @param certFilename filename
* @return the certificate loaded
- * @throws IOException thrown while reading the certificate from file
- * @throws GeneralSecurityException thrown while creating the certificate
+ * @throws Exception In case of an IO exception
*/
- private static Certificate loadCertificate(String certFilename)
- throws IOException, GeneralSecurityException {
+ private static Certificate loadCertificate(final String certFilename)
+ throws Exception {
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream(certFilename);
+ final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+ final Certificate cert = certFactory.generateCertificate(in);
+ in.close();
+ return cert;
- FileInputStream in = new FileInputStream(certFilename);
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- Certificate cert = certFactory.generateCertificate(in);
- in.close();
- return cert;
- }
-
-
- /**
- * Loads a keyStore without knowing the keyStore type
- * @param keyStorePath URL to the keyStore
- * @param password Password protecting the keyStore
- * @return keyStore loaded
- * @throws KeyStoreException thrown if keyStore cannot be loaded
- * @throws FileNotFoundException
- * @throws IOException
- */
- public static KeyStore loadKeyStore(String keyStorePath, String password) throws KeyStoreException, IOException{
-
- //InputStream is = new FileInputStream(keyStorePath);
- URL keystoreURL = new URL(keyStorePath);
- InputStream in = keystoreURL.openStream();
- InputStream isBuffered = new BufferedInputStream(in);
- return loadKeyStore(isBuffered, password);
-
- }
-
- /**
- * Loads a keyStore without knowing the keyStore type
- * @param in input stream
- * @param password Password protecting the keyStore
- * @return keyStore loaded
- * @throws KeyStoreException thrown if keyStore cannot be loaded
- * @throws FileNotFoundException
- * @throws IOException
- */
-public static KeyStore loadKeyStore(InputStream is, String password) throws KeyStoreException, IOException{
- is.mark(1024*1024);
- KeyStore ks = null;
- try {
- try {
- ks = loadKeyStore(KEYSTORE_TYPE_PKCS12, is, password);
- } catch (IOException e2) {
- is.reset();
- ks = loadKeyStore(KEYSTORE_TYPE_JKS, is, password);
- }
- } catch(Exception e) {
- e.printStackTrace();
-
- }
- return ks;
-
- }
-
-
+ } catch (final Exception e) {
+ throw e;
+
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java
index e753f19f..0c5eeb40 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.utils;
import java.util.ArrayList;
@@ -44,332 +37,344 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
+ * Utils to operate on Key/Value based configurations.
+ *
* @author tlenz
*
*/
public class KeyValueUtils {
- private static final Logger log = LoggerFactory.getLogger(KeyValueUtils.class);
-
- public static final String KEY_DELIMITER = ".";
- public static final String CSV_DELIMITER = ",";
- public static final String KEYVVALUEDELIMITER = "=";
- public static final String DEFAULT_VALUE = "default";
-
- /**
- * Convert Java properties into a Map<String, String>
- * <br><br>
- * <b>Important:</b> The key/values from properties must be of type String!
- *
- * @param properties
- * @return
- */
- public static Map<String, String> convertPropertiesToMap(Properties properties) {
- return new HashMap<String, String>((Map) properties);
-
- //INFO Java8 solution ;)
-// return properties.entrySet().stream().collect(
-// Collectors.toMap(
-// e -> e.getKey().toString(),
-// e -> e.getValue().toString()
-// )
-// );
-
- }
-
- /**
- * Extract the first child of an input key after a the prefix
- *
- * @param key Full input key
- * @param prefix Prefix
- * @return Child key {String} if it exists or null
- */
- public static String getFirstChildAfterPrefix(String key, String prefix) {
- final String idAfterPrefix = removePrefixFromKey(key, prefix);
- if (idAfterPrefix != null) {
- final int index = idAfterPrefix.indexOf(KEY_DELIMITER);
- if (index > 0) {
- final String adding = idAfterPrefix.substring(0, index);
- if (!(adding.isEmpty())) {
- return adding;
-
- }
- } else if (!(idAfterPrefix.isEmpty())) {
- return idAfterPrefix;
-
- }
-
- }
- return null;
- }
-
- /**
- * Extract the prefix from an input key
- *
- * @param key Full input key
- * @param suffix Suffix of this key
- * @return Prefix {String} of the key or null if input key does not ends with postfix string
- */
- public static String getPrefixFromKey(String key, String suffix) {
- if (key != null && suffix != null && key.endsWith(suffix)) {
- final String idPreforeSuffix = key.substring(0, key.length()-suffix.length());
- if (idPreforeSuffix.endsWith(KEY_DELIMITER))
- return idPreforeSuffix.substring(0, idPreforeSuffix.length()-1);
- else
- return idPreforeSuffix;
- }
- return null;
-
- }
-
- /**
- * Remove a prefix string from a key
- *
- * @param key Full input key
- * @param prefix Prefix, which should be removed
- * @return The suffix of the input key or null if the input does not starts with the prefix
- */
- public static String removePrefixFromKey(String key, String prefix) {
- if (prefix == null)
- prefix = new String();
-
- if (key!=null && key.startsWith(prefix)) {
- String afterPrefix = key.substring(prefix.length());
- final int index = afterPrefix.indexOf(KEY_DELIMITER);
-
- if (index == 0) {
- afterPrefix = afterPrefix.substring(1);
-
- }
- return afterPrefix;
-
- }
- return null;
- }
-
- /**
- * Remove a prefix string from all keys in {Map<String, String>} of key/value pairs
- *
- * @param keys Input data of key/value pairs
- * @param prefix Prefix which should be removed
- * @return {Map<String, String>} of key/value pairs without prefix in key, but never null
- */
- public static Map<String, String> removePrefixFromKeys(Map<String, String> keys, String prefix) {
- final Map<String, String> result = new HashMap<String, String>();
- final Iterator<Entry<String, String>> interator = keys.entrySet().iterator();
- while(interator.hasNext()) {
- final Entry<String, String> el = interator.next();
- final String newKey = removePrefixFromKey(el.getKey(), prefix);
- if (StringUtils.isNotEmpty(newKey)) {
- result.put(newKey, el.getValue());
- }
- }
-
- return result;
- }
-
- /**
- * Get a subset of key/value pairs which starts with a prefix string
- * The Prefix is removed from the key
- *
- * @param keys Input data of key/value pairs
- * @param prefix Prefix string
- * @return {Map<String, String>} of key/value pairs without prefix in key, but never null
- */
- public static Map<String, String> getSubSetWithPrefix(Map<String, String> keys, String prefix) {
- return removePrefixFromKeys(keys, prefix);
- }
-
-
- /**
- * Add a prefix to key/value pairs to make the key absolute according to key namespace convention
- *
- * @param input Input key/value pairs which should be updated
- * @param prefix Key prefix, which should be added if the key is not absolute
- * @param absolutIdentifier Key identifier, which indicates an absolute key
- * @return {Map<String, String>} of key/value pairs in which all keys are absolute but never null
- */
- public static Map<String, String> makeKeysAbsolut(Map<String, String> input, String prefix, String absolutIdentifier) {
- final Map<String, String> result = new HashMap<String, String>();
- final Iterator<Entry<String, String>> interator = input.entrySet().iterator();
- while(interator.hasNext()) {
- final Entry<String, String> el = interator.next();
- if (!el.getKey().startsWith(absolutIdentifier)) {
- //key is not absolute -> add prefix
- result.put(prefix
- + KEY_DELIMITER
- + el.getKey(),
- el.getValue());
-
- } else {
- //key is absolute
- result.put(el.getKey(), el.getValue());
- }
- }
- return result;
- }
-
- /**
- * Get the parent key string from an input key
- *
- * @param key input key
- * @return parent key or the empty String if no parent exists
- */
- public static String getParentKey(String key) {
- if (StringUtils.isNotEmpty(key)) {
- final int index = key.lastIndexOf(KEY_DELIMITER);
- if (index > 0) {
- return key.substring(0, index);
-
- }
- }
-
- return new String();
- }
-
- /**
- * Find the highest free list counter
- *
- * @param input Array of list keys
- * @param listPrefix {String} prefix of the list
- * @return {int} highest free list counter
- */
- public static int findNextFreeListCounter(String[] input,
- String listPrefix) {
- final List<Integer> counters = new ArrayList<Integer>();
- if (input == null || input.length == 0)
- return 0;
-
- else {
- for (final String key : input) {
- final String listIndex = getFirstChildAfterPrefix(key, listPrefix);
- counters.add(Integer.parseInt(listIndex));
-
- }
- Collections.sort(counters);
- return counters.get(counters.size()-1) + 1;
- }
- }
-
- /**
- * Find the highest free list counter
- *
- * @param keySet {Set<String>} of list keys
- * @param listPrefix {String} prefix of the list
- * @return {int} highest free list counter
- */
- public static int findNextFreeListCounter(Set<String> keySet,
- String listPrefix) {
- if (keySet.isEmpty())
- return 0;
-
- final String[] array = new String[keySet.size()];
- keySet.toArray(array);
- return findNextFreeListCounter(array, listPrefix);
- }
-
-
- /**
- * Normalize a CSV encoded list of value of an key/value pair
- *
- * This method removes all whitespace at the begin or the
- * end of CSV values and remove newLine signs at the end of value.
- * The ',' is used as list delimiter
- *
- * @param value CSV encoded input data
- * @return normalized CSV encoded data or null if {value} is null or empty
- */
- public static String normalizeCSVValueString(String value) {
- String normalizedCodes = null;
- if (StringUtils.isNotEmpty(value)) {
- final String[] codes = value.split(CSV_DELIMITER);
- for (final String el: codes) {
- if (normalizedCodes == null)
- normalizedCodes = StringUtils.chomp(el.trim());
- else
- normalizedCodes += "," + StringUtils.chomp(el.trim());
-
- }
- }
- return normalizedCodes;
- }
-
-
- /**
- * Check a String if it is a comma separated list of values
- *
- * This method uses the ',' as list delimiter.
- *
- * @param value CSV encoded input data
- * @return true if the input data contains a ',' and has more then 1 list element, otherwise false
- */
- public static boolean isCSVValueString(String value) {
- if (StringUtils.isNotEmpty(value)) {
- final String[] codes = value.split(CSV_DELIMITER);
- if (codes.length >= 2) {
- if (StringUtils.isNotEmpty(codes[1].trim()))
- return true;
-
- }
- }
-
- return false;
- }
-
- /**
- * Convert a CSV list to a List of CSV values
- * <br><br>
- * This method removes all whitespace at the begin or the
- * end of CSV values and remove newLine signs at the end of value.
- * The ',' is used as list delimiter
- *
- * @param csv CSV encoded input data
- * @return List of CSV normalized values, but never null
- */
- @Nonnull
- public static List<String> getListOfCSVValues(@Nullable String csv) {
- final List<String> list = new ArrayList<String>();
- if (StringUtils.isNotEmpty(csv)) {
- final String[] values = csv.split(CSV_DELIMITER);
- for (final String el: values)
- list.add(el.trim());
-
- }
-
- return list;
- }
-
- /**
- * Convert a List of String elements to a Map of Key/Value pairs
- * <br>
- * Every List element used as a key/value pair and the '=' sign represents the delimiter between key and value
- *
- * @param elements List of key/value elements
- * @return Map of Key / Value pairs, but never null
- */
- public static Map<String, String> convertListToMap(List<String> elements) {
- final Map<String, String> map = new HashMap<String, String>();
- for (final String el : elements) {
- if (el.contains(KEYVVALUEDELIMITER)) {
- final String[] split = el.split(KEYVVALUEDELIMITER);
- map.put(split[0], split[1]);
-
- } else
- log.debug("Key/Value Mapper: '" + el + "' contains NO '='. Ignore it.");
-
- }
-
- return map;
- }
-
- /**
- * This method remove all newline delimiter (\n or \r\n) from input data
- *
- * @param value Input String
- * @return Input String without newline characters
- */
- public static String removeAllNewlineFromString(String value) {
- return value.replaceAll("(\\t|\\r?\\n)+", "");
-
- }
-
+ private static final Logger log = LoggerFactory.getLogger(KeyValueUtils.class);
+
+ public static final String KEY_DELIMITER = ".";
+ public static final String CSV_DELIMITER = ",";
+ public static final String KEYVVALUEDELIMITER = "=";
+ public static final String DEFAULT_VALUE = "default";
+
+ /**
+ * Convert Java properties into a Map String/String. <br>
+ * <b>Important:</b> The key/values from properties must be of type String!
+ *
+ * @param properties Java {@link Properties} that should be converted
+ * @return
+ */
+ public static Map<String, String> convertPropertiesToMap(final Properties properties) {
+ return new HashMap<String, String>((Map) properties);
+
+ // INFO Java8 solution ;)
+ // return properties.entrySet().stream().collect(
+ // Collectors.toMap(
+ // e -> e.getKey().toString(),
+ // e -> e.getValue().toString()
+ // )
+ // );
+
+ }
+
+ /**
+ * Extract the first child of an input key after a the prefix.
+ *
+ * @param key Full input key
+ * @param prefix Prefix
+ * @return Child key {String} if it exists or null
+ */
+ public static String getFirstChildAfterPrefix(final String key, final String prefix) {
+ final String idAfterPrefix = removePrefixFromKey(key, prefix);
+ if (idAfterPrefix != null) {
+ final int index = idAfterPrefix.indexOf(KEY_DELIMITER);
+ if (index > 0) {
+ final String adding = idAfterPrefix.substring(0, index);
+ if (!adding.isEmpty()) {
+ return adding;
+
+ }
+ } else if (!idAfterPrefix.isEmpty()) {
+ return idAfterPrefix;
+
+ }
+
+ }
+ return null;
+ }
+
+ /**
+ * Extract the prefix from an input key.
+ *
+ * @param key Full input key
+ * @param suffix Suffix of this key
+ * @return Prefix {String} of the key or null if input key does not ends with
+ * postfix string
+ */
+ public static String getPrefixFromKey(final String key, final String suffix) {
+ if (key != null && suffix != null && key.endsWith(suffix)) {
+ final String idPreforeSuffix = key.substring(0, key.length() - suffix.length());
+ if (idPreforeSuffix.endsWith(KEY_DELIMITER)) {
+ return idPreforeSuffix.substring(0, idPreforeSuffix.length() - 1);
+ } else {
+ return idPreforeSuffix;
+ }
+ }
+ return null;
+
+ }
+
+ /**
+ * Remove a prefix string from a key.
+ *
+ * @param key Full input key
+ * @param prefix Prefix, which should be removed
+ * @return The suffix of the input key or null if the input does not starts with
+ * the prefix
+ */
+ public static String removePrefixFromKey(final String key, String prefix) {
+ if (prefix == null) {
+ prefix = StringUtils.EMPTY;
+
+ }
+
+ if (key != null && key.startsWith(prefix)) {
+ String afterPrefix = key.substring(prefix.length());
+ final int index = afterPrefix.indexOf(KEY_DELIMITER);
+
+ if (index == 0) {
+ afterPrefix = afterPrefix.substring(1);
+
+ }
+ return afterPrefix;
+
+ }
+ return null;
+ }
+
+ /**
+ * Remove a prefix string from all keys in Map String/String of key/value pairs.
+ *
+ * @param keys Input data of key/value pairs
+ * @param prefix Prefix which should be removed
+ * @return Map String/String of key/value pairs without prefix in key, but never
+ * null
+ */
+ public static Map<String, String> removePrefixFromKeys(final Map<String, String> keys,
+ final String prefix) {
+ final Map<String, String> result = new HashMap<>();
+ final Iterator<Entry<String, String>> interator = keys.entrySet().iterator();
+ while (interator.hasNext()) {
+ final Entry<String, String> el = interator.next();
+ final String newKey = removePrefixFromKey(el.getKey(), prefix);
+ if (StringUtils.isNotEmpty(newKey)) {
+ result.put(newKey, el.getValue());
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Get a subset of key/value pairs which starts with a prefix string The Prefix
+ * is removed from the key.
+ *
+ * @param keys Input data of key/value pairs
+ * @param prefix Prefix string
+ * @return Map String/String of key/value pairs without prefix in key, but never
+ * null
+ */
+ public static Map<String, String> getSubSetWithPrefix(final Map<String, String> keys,
+ final String prefix) {
+ return removePrefixFromKeys(keys, prefix);
+ }
+
+ /**
+ * Add a prefix to key/value pairs to make the key absolute according to key
+ * namespace convention.
+ *
+ * @param input Input key/value pairs which should be updated
+ * @param prefix Key prefix, which should be added if the key is not
+ * absolute
+ * @param absolutIdentifier Key identifier, which indicates an absolute key
+ * @return Map String/String of key/value pairs in which all keys are absolute
+ * but never null
+ */
+ public static Map<String, String> makeKeysAbsolut(final Map<String, String> input,
+ final String prefix, final String absolutIdentifier) {
+ final Map<String, String> result = new HashMap<>();
+ final Iterator<Entry<String, String>> interator = input.entrySet().iterator();
+ while (interator.hasNext()) {
+ final Entry<String, String> el = interator.next();
+ if (!el.getKey().startsWith(absolutIdentifier)) {
+ // key is not absolute -> add prefix
+ result.put(prefix + KEY_DELIMITER + el.getKey(), el.getValue());
+
+ } else {
+ // key is absolute
+ result.put(el.getKey(), el.getValue());
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get the parent key string from an input key.
+ *
+ * @param key input key
+ * @return parent key or the empty String if no parent exists
+ */
+ public static String getParentKey(final String key) {
+ if (StringUtils.isNotEmpty(key)) {
+ final int index = key.lastIndexOf(KEY_DELIMITER);
+ if (index > 0) {
+ return key.substring(0, index);
+
+ }
+ }
+
+ return StringUtils.EMPTY;
+ }
+
+ /**
+ * Find the highest free list counter.
+ *
+ * @param input Array of list keys
+ * @param listPrefix {String} prefix of the list
+ * @return {int} highest free list counter
+ */
+ public static int findNextFreeListCounter(final String[] input, final String listPrefix) {
+ final List<Integer> counters = new ArrayList<>();
+ if (input == null || input.length == 0) {
+ return 0;
+ } else {
+ for (final String key : input) {
+ final String listIndex = getFirstChildAfterPrefix(key, listPrefix);
+ counters.add(Integer.parseInt(listIndex));
+
+ }
+ Collections.sort(counters);
+ return counters.get(counters.size() - 1) + 1;
+ }
+ }
+
+ /**
+ * Find the highest free list counter.
+ *
+ * @param keySet Set of list keys
+ * @param listPrefix {String} prefix of the list
+ * @return {int} highest free list counter
+ */
+ public static int findNextFreeListCounter(final Set<String> keySet, final String listPrefix) {
+ if (keySet.isEmpty()) {
+ return 0;
+ }
+
+ final String[] array = new String[keySet.size()];
+ keySet.toArray(array);
+ return findNextFreeListCounter(array, listPrefix);
+ }
+
+ /**
+ * Normalize a CSV encoded list of value of an key/value pair.
+ *
+ * <p>
+ * This method removes all whitespace at the begin or the end of CSV values and
+ * remove newLine signs at the end of value. The ',' is used as list delimiter
+ * </p>
+ *
+ * @param value CSV encoded input data
+ * @return normalized CSV encoded data or null if {value} is null or empty
+ */
+ public static String normalizeCsvValueString(final String value) {
+ String normalizedCodes = null;
+ if (StringUtils.isNotEmpty(value)) {
+ final String[] codes = value.split(CSV_DELIMITER);
+ for (final String el : codes) {
+ if (normalizedCodes == null) {
+ normalizedCodes = StringUtils.chomp(el.trim());
+ } else {
+ normalizedCodes += "," + StringUtils.chomp(el.trim());
+ }
+
+ }
+ }
+ return normalizedCodes;
+ }
+
+ /**
+ * Check a String if it is a comma separated list of values.
+ *
+ * <p>
+ * This method uses the ',' as list delimiter.
+ * </p>
+ *
+ * @param value CSV encoded input data
+ * @return true if the input data contains a ',' and has more then 1 list
+ * element, otherwise false
+ */
+ public static boolean isCsvValueString(final String value) {
+ if (StringUtils.isNotEmpty(value)) {
+ final String[] codes = value.split(CSV_DELIMITER);
+ if (codes.length >= 2
+ && StringUtils.isNotEmpty(codes[1].trim())) {
+ return true;
+
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert a CSV list to a List of CSV values. <br>
+ * <br>
+ * This method removes all whitespace at the begin or the end of CSV values and
+ * remove newLine signs at the end of value. The ',' is used as list delimiter
+ *
+ * @param csv CSV encoded input data
+ * @return List of CSV normalized values, but never null
+ */
+ @Nonnull
+ public static List<String> getListOfCsvValues(@Nullable final String csv) {
+ final List<String> list = new ArrayList<>();
+ if (StringUtils.isNotEmpty(csv)) {
+ final String[] values = csv.split(CSV_DELIMITER);
+ for (final String el : values) {
+ list.add(el.trim());
+ }
+
+ }
+
+ return list;
+ }
+
+ /**
+ * Convert a List of String elements to a Map of Key/Value pairs. <br>
+ * Every List element used as a key/value pair and the '=' sign represents the
+ * delimiter between key and value
+ *
+ * @param elements List of key/value elements
+ * @return Map of Key / Value pairs, but never null
+ */
+ public static Map<String, String> convertListToMap(final List<String> elements) {
+ final Map<String, String> map = new HashMap<>();
+ for (final String el : elements) {
+ if (el.contains(KEYVVALUEDELIMITER)) {
+ final String[] split = el.split(KEYVVALUEDELIMITER);
+ map.put(split[0], split[1]);
+
+ } else {
+ log.debug("Key/Value Mapper: '" + el + "' contains NO '='. Ignore it.");
+ }
+
+ }
+
+ return map;
+ }
+
+ /**
+ * This method remove all newline delimiter (\n or \r\n) from input data.
+ *
+ * @param value Input String
+ * @return Input String without newline characters
+ */
+ public static String removeAllNewlineFromString(final String value) {
+ return value.replaceAll("(\\t|\\r?\\n)+", "");
+
+ }
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java
index ec57b92a..5d2a11d0 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeIteratorAdapter.java
@@ -1,30 +1,21 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
package at.gv.egiz.eaaf.core.impl.utils;
@@ -38,55 +29,46 @@ import org.w3c.dom.traversal.NodeIterator;
/**
* A <code>NodeIterator</code> implementation based on a
* <code>ListIterator</code>.
- *
+ *
* @see java.util.ListIterator
* @see org.w3c.dom.traversal.NodeIterator
- *
+ *
*/
public class NodeIteratorAdapter implements NodeIterator {
/** The <code>ListIterator</code> to wrap. */
- private ListIterator nodeIterator;
+ private final ListIterator nodeIterator;
/**
* Create a new <code>NodeIteratorAdapter</code>.
+ *
* @param nodeIterator The <code>ListIterator</code> to iterate over.
*/
- public NodeIteratorAdapter(ListIterator nodeIterator) {
+ public NodeIteratorAdapter(final ListIterator nodeIterator) {
this.nodeIterator = nodeIterator;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#getRoot()
- */
+ @Override
public Node getRoot() {
return null;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#getWhatToShow()
- */
+ @Override
public int getWhatToShow() {
return NodeFilter.SHOW_ALL;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#getFilter()
- */
+ @Override
public NodeFilter getFilter() {
return null;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#getExpandEntityReferences()
- */
+ @Override
public boolean getExpandEntityReferences() {
return false;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#nextNode()
- */
+ @Override
public Node nextNode() throws DOMException {
if (nodeIterator.hasNext()) {
return (Node) nodeIterator.next();
@@ -94,9 +76,7 @@ public class NodeIteratorAdapter implements NodeIterator {
return null;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#previousNode()
- */
+ @Override
public Node previousNode() throws DOMException {
if (nodeIterator.hasPrevious()) {
return (Node) nodeIterator.previous();
@@ -104,10 +84,9 @@ public class NodeIteratorAdapter implements NodeIterator {
return null;
}
- /**
- * @see org.w3c.dom.traversal.NodeIterator#detach()
- */
+ @Override
public void detach() {
+
}
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java
index 69045aaa..83a6725c 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/NodeListAdapter.java
@@ -1,30 +1,21 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
package at.gv.egiz.eaaf.core.impl.utils;
@@ -35,34 +26,30 @@ import org.w3c.dom.NodeList;
/**
* A <code>NodeList</code> implementation based on a <code>List</code>.
- *
+ *
* @see java.util.List
* @see org.w3c.dom.NodeList
*/
public class NodeListAdapter implements NodeList {
/** The <code>List</code> to wrap. */
- private List nodeList;
-
+ private final List nodeList;
+
/**
* Create a new <code>NodeListAdapter</code>.
- *
- * @param nodeList The <code>List</code> containing the nodes.
+ *
+ * @param nodeList The <code>List</code> containing the nodes.
*/
- public NodeListAdapter(List nodeList) {
+ public NodeListAdapter(final List nodeList) {
this.nodeList = nodeList;
}
- /**
- * @see org.w3c.dom.NodeList#item(int)
- */
- public Node item(int index) {
+ @Override
+ public Node item(final int index) {
return (Node) nodeList.get(index);
}
- /**
- * @see org.w3c.dom.NodeList#getLength()
- */
+ @Override
public int getLength() {
return nodeList.size();
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java
index e236b3a9..aedbbb7f 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/Random.java
@@ -1,29 +1,25 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
package at.gv.egiz.eaaf.core.impl.utils;
-
+import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
@@ -38,139 +34,151 @@ import org.slf4j.LoggerFactory;
import at.gv.egiz.eaaf.core.impl.idp.process.support.SecureRandomHolder;
-
/**
- * Random number generator used to generate ID's
+ * Random number generator used to generate ID's.
+ *
* @author Paul Ivancsics
* @version $Id$
*/
public class Random {
- private static final Logger log = LoggerFactory.getLogger(Random.class);
-
- private final static char[] allowedPreFix =
- {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
- private static final DateFormat dateFormater = new SimpleDateFormat("yyyyddMM");
-
- /** random number generator used */
- private static SecureRandom random;
- //private static SeedGenerator seedgenerator;
-
- static {
- try {
- random = SecureRandom.getInstance("SHA256PRNG-FIPS186");
-
- } catch (NoSuchAlgorithmException e) {
- log.warn("Can NOT initialize SecureRandom with: 'SHA256PRNG-FIPS186'. Use 'StrongSecureRandom' as backup");
- random = SecureRandomHolder.getInstance();
-
- }
-
-
- //random = iaik.security.random.SHA256FIPS186Random.getDefault();
- }
-
- /**
- * Generate a unique process reference-value [160bit], which always starts with a letter
- * <br>
- * This unique ID consists of single letter, a 64bit date String[yyyyddMM],
- * and a 88bit random value.
- *
- * @return 160bit ID, which is hex encoded
- */
- public static String nextProcessReferenceValue() {
- //pre-process all three parts of a unique reference value
- String now = dateFormater.format(new Date()); //8 bytes = 64bit
- byte[] randValue = nextByteRandom(11);
- char preFix = allowedPreFix[Math.abs(random.nextInt() % allowedPreFix.length)];
-
- //generate ID
- String returnValue = preFix + new String(Hex.encodeHex(ArrayUtils.addAll(now.getBytes(), randValue))); // 20 bytes = 160 bits
- if (returnValue.length() > 40)
- return returnValue.substring(0, 40);
- else
- return returnValue;
-
- }
-
-
-
- /**
- * Creates a new random number [256bit], and encode it as hex value.
- *
- * @return random hex encoded value [256bit]
- */
- public static String nextHexRandom32() {
- return new String(Hex.encodeHex(nextByteRandom(32))); // 32 bytes = 256 bits
-
- }
-
- /**
- * Creates a new random number [128bit], and encode it as hex value.
- *
- * @return random hex encoded value [128bit]
- */
- public static String nextHexRandom16() {
- return new String(Hex.encodeHex(nextByteRandom(16))); // 16 bytes = 128 bits
-
- }
-
- /**
- * Creates a new random number [64bit], to be used as an ID.
- *
- * @return random long as a String [64bit]
- */
- public static String nextLongRandom() {
- return "".concat(String.valueOf(Math.abs(generateLongRandom(32)))); // 32 bytes = 256 bits
-
- }
-
+ private static final Logger log = LoggerFactory.getLogger(Random.class);
+
+ private static final char[] allowedPreFix =
+ { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+ 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
+
+ /** random number generator used. */
+ private static SecureRandom random;
+ // private static SeedGenerator seedgenerator;
+
+ static {
+ try {
+ random = SecureRandom.getInstance("SHA256PRNG-FIPS186");
+
+ } catch (final NoSuchAlgorithmException e) {
+ log.warn(
+ "Can NOT initialize SecureRandom with: 'SHA256PRNG-FIPS186'. Use 'StrongSecureRandom' as backup");
+ random = SecureRandomHolder.getInstance();
+
+ }
+
+ // random = iaik.security.random.SHA256FIPS186Random.getDefault();
+ }
+
+ /**
+ * Generate a unique process reference-value [160bit], which always starts with
+ * a letter <br>
+ * This unique ID consists of single letter, a 64bit date String[yyyyddMM], and
+ * a 88bit random value.
+ *
+ * @return 160bit ID, which is hex encoded
+ */
+ public static String nextProcessReferenceValue() {
+ // pre-process all three parts of a unique reference value
+ final DateFormat dateFormater = new SimpleDateFormat("yyyyddMM");
+ final String now = dateFormater.format(new Date()); // 8 bytes = 64bit
+ final byte[] randValue = nextByteRandom(11);
+ final char preFix = allowedPreFix[Math.abs(random.nextInt() % allowedPreFix.length)];
+
+ // generate ID
+ String returnValue;
+ try {
+ returnValue = preFix + new String(Hex.encodeHex(ArrayUtils.addAll(now.getBytes("UTF-8"), randValue)));
+
+ // 20 bytes = 160 bits
+ if (returnValue.length() > 40) {
+ return returnValue.substring(0, 40);
+ } else {
+ return returnValue;
+ }
+
+ } catch (final UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+
+ }
+
+ }
+
+ /**
+ * Creates a new random number [256bit], and encode it as hex value.
+ *
+ * @return random hex encoded value [256bit]
+ */
+ public static String nextHexRandom32() {
+ return new String(Hex.encodeHex(nextByteRandom(32))); // 32 bytes = 256 bits
+
+ }
+
+ /**
+ * Creates a new random number [128bit], and encode it as hex value.
+ *
+ * @return random hex encoded value [128bit]
+ */
+ public static String nextHexRandom16() {
+ return new String(Hex.encodeHex(nextByteRandom(16))); // 16 bytes = 128 bits
+
+ }
+
+ /**
+ * Creates a new random number [64bit], to be used as an ID.
+ *
+ * @return random long as a String [64bit]
+ */
+ public static String nextLongRandom() {
+ return "".concat(String.valueOf(Math.abs(generateLongRandom(32)))); // 32 bytes = 256 bits
+
+ }
+
/**
* Creates a new random number, to be used as an ID.
- *
+ *
* @return random long as a String [64bit]
*/
- @Deprecated
- public static String nextRandom() {
- long l = ByteBuffer.wrap(nextByteRandom(32)).getLong(); // 32 bytes = 256 bits
- return "" + Math.abs(l);
-
+ @Deprecated
+ public static String nextRandom() {
+ final long l = ByteBuffer.wrap(nextByteRandom(32)).getLong(); // 32 bytes = 256 bits
+ return "" + Math.abs(l);
+
}
-
-/**
- * Creates a new random byte[]
- *
- * @param size Size of random number in byte
- * @return
- */
-public static byte[] nextBytes(int size) {
- return nextByteRandom(size);
-
-}
-
+
+ /**
+ * Creates a new random byte[].
+ *
+ * @param size Size of random number in byte
+ * @return
+ */
+ public static byte[] nextBytes(final int size) {
+ return nextByteRandom(size);
+
+ }
+
+ /**
+ * initialize random-number generator.
+ */
public static void seedRandom() {
- //TODO: implement reflection on IAIK Seed generator
-// seedgenerator = iaik.security.random.AutoSeedGenerator.getDefault();
-// if (seedgenerator.seedAvailable())
-// random.setSeed(seedgenerator.getSeed());
-
- random.setSeed(System.nanoTime());
+ // TODO: implement reflection on IAIK Seed generator
+ // seedgenerator = iaik.security.random.AutoSeedGenerator.getDefault();
+ // if (seedgenerator.seedAvailable())
+ // random.setSeed(seedgenerator.getSeed());
+
+ random.setSeed(System.nanoTime());
}
-
- private static long generateLongRandom(int size) {
- return ByteBuffer.wrap(nextByteRandom(size)).getLong();
- }
-
+
+ private static long generateLongRandom(final int size) {
+ return ByteBuffer.wrap(nextByteRandom(size)).getLong();
+ }
+
/**
- * Generate a new random number
- *
+ * Generate a new random number.
+ *
* @param size Size of random number in byte
* @return
*/
- private static synchronized byte[] nextByteRandom(int size) {
- byte[] b = new byte[size];
- random.nextBytes(b);
- return b;
-
+ private static synchronized byte[] nextByteRandom(final int size) {
+ final byte[] b = new byte[size];
+ random.nextBytes(b);
+ return b;
+
}
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java
index f0ef9b38..bc770a8c 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java
@@ -1,6 +1,7 @@
package at.gv.egiz.eaaf.core.impl.utils;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
@@ -27,188 +28,211 @@ import org.springframework.lang.Nullable;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
-import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFIllegalStateException;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafIllegalStateException;
import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException;
/**
- * PendingRequestId generation strategy based on signed tokens that facilitates extended token validation
- *
+ * PendingRequestId generation strategy based on signed tokens that facilitates
+ * extended token validation.
+ *
* @author tlenz
*
*/
-public class SecurePendingRequestIdGenerationStrategy implements IPendingRequestIdGenerationStrategy {
- private static final Logger log = LoggerFactory.getLogger(SecurePendingRequestIdGenerationStrategy.class);
-
- @Autowired(required=true) IConfiguration baseConfig;
-
- public static final String CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET = "core.pendingrequestid.digist.secret";
- public static final String CONFIG_PROP_PENDINGREQUESTID_DIGIST_ALGORITHM = "core.pendingrequestid.digist.algorithm";
- public static final String CONFIG_PROP_PENDINGREQUESTID_MAX_LIFETIME = "core.pendingrequestid.maxlifetime";
-
- public static final String DEFAULT_PENDINGREQUESTID_DIGIST_ALGORITHM = "HmacSHA256";
- public static final String DEFAULT_PENDINGREQUESTID_MAX_LIFETIME = "300";
-
- private static final int ENCODED_TOKEN_PARTS = 3;
- private static final String TOKEN_SEPARATOR = "|";
- private static final DateTimeFormatter TOKEN_TEXTUAL_DATE_FORMAT =
- DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss SSS");
-
- private int maxPendingRequestIdLifeTime = 300;
- private final int maxPendingReqIdSize = 1024;
- private String digistAlgorithm = null;
- private SecretKey key = null;
- private final byte[] salt = "notRequiredInThisScenario".getBytes();
-
- @Override
- public String generateExternalPendingRequestId() throws EAAFException {
- try {
- final String toSign = buildInternalToken(Random.nextLongRandom(), DateTime.now());
- final StringBuilder externalPendingRequestId= new StringBuilder();
- externalPendingRequestId.append(toSign);
- externalPendingRequestId.append(TOKEN_SEPARATOR);
- externalPendingRequestId.append(Base64.getEncoder().encodeToString(calculateHMAC(toSign)));
- return Base64.getUrlEncoder().encodeToString(externalPendingRequestId.toString().getBytes("UTF-8"));
-
- } catch (final UnsupportedEncodingException e) {
- throw new EAAFException("internal.99", new Object[] {e.getMessage()}, e);
-
- }
-
- }
-
- @Override
- public String getPendingRequestIdWithOutChecks(String externalPendingReqId) throws PendingReqIdValidationException {
- final String[] tokenElements = extractTokens(externalPendingReqId);
- return tokenElements[1];
-
- }
-
- @Override
- public String validateAndGetPendingRequestId(String externalPendingReqId) throws PendingReqIdValidationException {
- try {
- final String[] tokenElements = extractTokens(externalPendingReqId);
- final String internalPendingReqId = tokenElements[1];
- final DateTime timeStamp = TOKEN_TEXTUAL_DATE_FORMAT.parseDateTime(tokenElements[0]);
-
- log.trace("Checking HMAC from externalPendingReqId ... ");
- final byte[] tokenDigest = Base64.getDecoder().decode(tokenElements[2]);
- final byte[] refDigist = calculateHMAC(buildInternalToken(internalPendingReqId, timeStamp));
- if (!Arrays.equals(tokenDigest, refDigist)) {
- log.warn("Digest of Token does NOT match");
- log.debug("Token: {} | Ref: {}", tokenDigest, refDigist);
- throw new PendingReqIdValidationException(null, "Digest of pendingRequestId does NOT match");
-
- }
- log.debug("PendingRequestId HMAC digest check successful");
-
- log.trace("Checking valid period ... ");
- final DateTime now = DateTime.now();
- if (timeStamp.withFieldAdded(
- DurationFieldType.seconds(), maxPendingRequestIdLifeTime).isBefore(now)) {
- log.warn("Token exceeds the valid period");
- log.debug("Token: {} | Now: {}", timeStamp, now );
- throw new PendingReqIdValidationException(internalPendingReqId, "PendingRequestId exceeds the valid period");
-
- }
- log.debug("Token valid-period check successful");
-
- return internalPendingReqId;
-
-
- } catch (final IllegalArgumentException | EAAFIllegalStateException e) {
- log.warn("Token is NOT a valid String. Msg: {}", e.getMessage());
- log.debug("TokenValue: {}", externalPendingReqId);
- throw new PendingReqIdValidationException(null, "PendingReqId is NOT a valid String", e);
-
- }
- }
-
- @NonNull
- private String[] extractTokens(@Nullable String externalPendingReqId) throws PendingReqIdValidationException {
- if (StringUtils.isEmpty(externalPendingReqId)) {
- log.info("PendingReqId is 'null' or empty");
- throw new PendingReqIdValidationException(null, "PendingReqId is 'null' or empty");
-
- }
-
- log.trace("RAW external pendingReqId: {}", externalPendingReqId);
- final byte[] externalPendingReqIdBytes = Base64.getUrlDecoder().decode(externalPendingReqId);
-
- if (externalPendingReqIdBytes.length > maxPendingReqIdSize) {
- log.warn("pendingReqId size exceeds {}", maxPendingReqIdSize);
- throw new PendingReqIdValidationException(null, "pendingReqId exceeds max.size: " + maxPendingReqIdSize);
-
- }
-
- final String stringToken = new String(externalPendingReqIdBytes);
- if (StringUtils.countMatches(stringToken, TOKEN_SEPARATOR) == ENCODED_TOKEN_PARTS - 1) {
- final String[] tokenElements = StringUtils.split(stringToken,
- TOKEN_SEPARATOR, ENCODED_TOKEN_PARTS);
- return tokenElements;
-
- } else {
- log.warn("PendingRequestId has an unvalid format");
- log.debug("PendingRequestId: {}", stringToken);
- throw new PendingReqIdValidationException(null, "PendingReqId has an unvalid format");
-
- }
-
- }
-
-
- @PostConstruct
- private void initialize() throws EAAFConfigurationException {
- log.debug("Initializing " + this.getClass().getName() + " ... ");
-
- final String pendingReqIdDigistSecret = baseConfig.getBasicConfiguration(CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET);
- if (StringUtils.isEmpty(pendingReqIdDigistSecret))
- throw new EAAFConfigurationException("config.08", new Object[] {CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET});
-
- digistAlgorithm = baseConfig.getBasicConfiguration(CONFIG_PROP_PENDINGREQUESTID_DIGIST_ALGORITHM, DEFAULT_PENDINGREQUESTID_DIGIST_ALGORITHM);
-
- maxPendingRequestIdLifeTime = Integer.valueOf(
- baseConfig.getBasicConfiguration(CONFIG_PROP_PENDINGREQUESTID_MAX_LIFETIME, DEFAULT_PENDINGREQUESTID_MAX_LIFETIME));
-
- try {
- final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA256");
- final KeySpec spec = new PBEKeySpec(pendingReqIdDigistSecret.toCharArray(), salt, 10000, 128);
- key = keyFactory.generateSecret(spec);
-
-
- } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
- log.error("Can NOT initialize TokenService with configuration object", e);
- throw new EAAFConfigurationException("config.09",
- new Object[] { CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET,
- "Can NOT generate HMAC key"},
- e);
-
- }
-
- log.info(this.getClass().getName() + " initialized with digistAlg: {} and maxLifeTime: {}", digistAlgorithm, maxPendingRequestIdLifeTime);
-
- }
-
- private String buildInternalToken(String internalPendingReqId, DateTime now) {
- return new StringBuilder()
- .append(TOKEN_TEXTUAL_DATE_FORMAT.print(now))
- .append(TOKEN_SEPARATOR)
- .append(internalPendingReqId).toString();
- }
-
- private byte[] calculateHMAC(String toSign) throws EAAFIllegalStateException {
- try {
- final Mac mac = Mac.getInstance(digistAlgorithm);
- mac.init(key);
- return mac.doFinal(toSign.getBytes("UTF-8"));
-
- } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
- log.error("Can NOT generate secure pendingRequestId", e);
- throw new EAAFIllegalStateException(new Object[] {"Can NOT caluclate digist for secure pendingRequestId"}, e);
-
- }
-
- }
+public class SecurePendingRequestIdGenerationStrategy
+ implements IPendingRequestIdGenerationStrategy {
+ private static final Logger log =
+ LoggerFactory.getLogger(SecurePendingRequestIdGenerationStrategy.class);
+
+ @Autowired(required = true)
+ IConfiguration baseConfig;
+
+ public static final String CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET =
+ "core.pendingrequestid.digist.secret";
+ public static final String CONFIG_PROP_PENDINGREQUESTID_DIGIST_ALGORITHM =
+ "core.pendingrequestid.digist.algorithm";
+ public static final String CONFIG_PROP_PENDINGREQUESTID_MAX_LIFETIME =
+ "core.pendingrequestid.maxlifetime";
+
+ public static final String DEFAULT_PENDINGREQUESTID_DIGIST_ALGORITHM = "HmacSHA256";
+ public static final String DEFAULT_PENDINGREQUESTID_MAX_LIFETIME = "300";
+
+ private static final int ENCODED_TOKEN_PARTS = 3;
+ private static final String TOKEN_SEPARATOR = "|";
+ private static final DateTimeFormatter TOKEN_TEXTUAL_DATE_FORMAT =
+ DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss SSS");
+
+ private int maxPendingRequestIdLifeTime = 300;
+ private final int maxPendingReqIdSize = 1024;
+ private String digistAlgorithm = null;
+ private SecretKey key = null;
+ private final byte[] salt = "notRequiredInThisScenario".getBytes(Charset.defaultCharset());
+
+ @Override
+ public String generateExternalPendingRequestId() throws EaafException {
+ try {
+ final String toSign = buildInternalToken(Random.nextLongRandom(), DateTime.now());
+ final StringBuilder externalPendingRequestId = new StringBuilder();
+ externalPendingRequestId.append(toSign);
+ externalPendingRequestId.append(TOKEN_SEPARATOR);
+ externalPendingRequestId.append(Base64.getEncoder().encodeToString(calculateHmac(toSign)));
+ return Base64.getUrlEncoder()
+ .encodeToString(externalPendingRequestId.toString().getBytes("UTF-8"));
+
+ } catch (final UnsupportedEncodingException e) {
+ throw new EaafException("internal.99", new Object[] { e.getMessage() }, e);
+
+ }
+
+ }
+
+ @Override
+ public String getPendingRequestIdWithOutChecks(final String externalPendingReqId)
+ throws PendingReqIdValidationException {
+ try {
+ final String[] tokenElements = extractTokens(externalPendingReqId);
+ return tokenElements[1];
+
+ } catch (final UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+
+ }
+ }
+
+ @Override
+ public String validateAndGetPendingRequestId(final String externalPendingReqId)
+ throws PendingReqIdValidationException {
+ try {
+ final String[] tokenElements = extractTokens(externalPendingReqId);
+ final String internalPendingReqId = tokenElements[1];
+ final DateTime timeStamp = TOKEN_TEXTUAL_DATE_FORMAT.parseDateTime(tokenElements[0]);
+
+ log.trace("Checking HMAC from externalPendingReqId ... ");
+ final byte[] tokenDigest = Base64.getDecoder().decode(tokenElements[2]);
+ final byte[] refDigist = calculateHmac(buildInternalToken(internalPendingReqId, timeStamp));
+ if (!Arrays.equals(tokenDigest, refDigist)) {
+ log.warn("Digest of Token does NOT match");
+ log.debug("Token: {} | Ref: {}", tokenDigest, refDigist);
+ throw new PendingReqIdValidationException(null,
+ "Digest of pendingRequestId does NOT match");
+
+ }
+ log.debug("PendingRequestId HMAC digest check successful");
+
+ log.trace("Checking valid period ... ");
+ final DateTime now = DateTime.now();
+ if (timeStamp.withFieldAdded(DurationFieldType.seconds(), maxPendingRequestIdLifeTime)
+ .isBefore(now)) {
+ log.warn("Token exceeds the valid period");
+ log.debug("Token: {} | Now: {}", timeStamp, now);
+ throw new PendingReqIdValidationException(internalPendingReqId,
+ "PendingRequestId exceeds the valid period");
+
+ }
+ log.debug("Token valid-period check successful");
+
+ return internalPendingReqId;
+
+ } catch (final IllegalArgumentException | EaafIllegalStateException e) {
+ log.warn("Token is NOT a valid String. Msg: {}", e.getMessage());
+ log.debug("TokenValue: {}", externalPendingReqId);
+ throw new PendingReqIdValidationException(null, "PendingReqId is NOT a valid String", e);
+
+ } catch (final UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+
+ }
+ }
+
+ @NonNull
+ private String[] extractTokens(@Nullable final String externalPendingReqId)
+ throws PendingReqIdValidationException, UnsupportedEncodingException {
+ if (StringUtils.isEmpty(externalPendingReqId)) {
+ log.info("PendingReqId is 'null' or empty");
+ throw new PendingReqIdValidationException(null, "PendingReqId is 'null' or empty");
+
+ }
+
+ log.trace("RAW external pendingReqId: {}", externalPendingReqId);
+ final byte[] externalPendingReqIdBytes = Base64.getUrlDecoder().decode(externalPendingReqId);
+
+ if (externalPendingReqIdBytes.length > maxPendingReqIdSize) {
+ log.warn("pendingReqId size exceeds {}", maxPendingReqIdSize);
+ throw new PendingReqIdValidationException(null,
+ "pendingReqId exceeds max.size: " + maxPendingReqIdSize);
+
+ }
+
+ final String stringToken = new String(externalPendingReqIdBytes, "UTF-8");
+ if (StringUtils.countMatches(stringToken, TOKEN_SEPARATOR) == ENCODED_TOKEN_PARTS - 1) {
+ final String[] tokenElements =
+ StringUtils.split(stringToken, TOKEN_SEPARATOR, ENCODED_TOKEN_PARTS);
+ return tokenElements;
+
+ } else {
+ log.warn("PendingRequestId has an unvalid format");
+ log.debug("PendingRequestId: {}", stringToken);
+ throw new PendingReqIdValidationException(null, "PendingReqId has an unvalid format");
+
+ }
+
+ }
+
+ @PostConstruct
+ private void initialize() throws EaafConfigurationException {
+ log.debug("Initializing " + this.getClass().getName() + " ... ");
+
+ final String pendingReqIdDigistSecret =
+ baseConfig.getBasicConfiguration(CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET);
+ if (StringUtils.isEmpty(pendingReqIdDigistSecret)) {
+ throw new EaafConfigurationException("config.08",
+ new Object[] { CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET });
+ }
+
+ digistAlgorithm = baseConfig.getBasicConfiguration(
+ CONFIG_PROP_PENDINGREQUESTID_DIGIST_ALGORITHM, DEFAULT_PENDINGREQUESTID_DIGIST_ALGORITHM);
+
+ maxPendingRequestIdLifeTime =
+ Integer.parseInt(baseConfig.getBasicConfiguration(CONFIG_PROP_PENDINGREQUESTID_MAX_LIFETIME,
+ DEFAULT_PENDINGREQUESTID_MAX_LIFETIME));
+
+ try {
+ final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA256");
+ final KeySpec spec = new PBEKeySpec(pendingReqIdDigistSecret.toCharArray(), salt, 10000, 128);
+ key = keyFactory.generateSecret(spec);
+
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+ log.error("Can NOT initialize TokenService with configuration object", e);
+ throw new EaafConfigurationException("config.09",
+ new Object[] { CONFIG_PROP_PENDINGREQUESTID_DIGIST_SECRET, "Can NOT generate HMAC key" },
+ e);
+
+ }
+
+ log.info(this.getClass().getName() + " initialized with digistAlg: {} and maxLifeTime: {}",
+ digistAlgorithm, maxPendingRequestIdLifeTime);
+
+ }
+
+ private String buildInternalToken(final String internalPendingReqId, final DateTime now) {
+ return new StringBuilder().append(TOKEN_TEXTUAL_DATE_FORMAT.print(now)).append(TOKEN_SEPARATOR)
+ .append(internalPendingReqId).toString();
+ }
+
+ private byte[] calculateHmac(final String toSign) throws EaafIllegalStateException {
+ try {
+ final Mac mac = Mac.getInstance(digistAlgorithm);
+ mac.init(key);
+ return mac.doFinal(toSign.getBytes("UTF-8"));
+
+ } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
+ log.error("Can NOT generate secure pendingRequestId", e);
+ throw new EaafIllegalStateException(
+ new Object[] { "Can NOT caluclate digist for secure pendingRequestId" }, e);
+
+ }
+
+ }
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java
index 38e873e2..c8865465 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ServletUtils.java
@@ -1,43 +1,41 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
package at.gv.egiz.eaaf.core.impl.utils;
import javax.servlet.http.HttpServletRequest;
public class ServletUtils {
-
-
- public static String getBaseUrl( HttpServletRequest request ) {
- if ( ( request.getServerPort() == 80 ) ||
- ( request.getServerPort() == 443 ) )
- return request.getScheme() + "://" +
- request.getServerName() +
- request.getContextPath();
- else
- return request.getScheme() + "://" +
- request.getServerName() + ":" + request.getServerPort() +
- request.getContextPath();
- }
-
+
+ /**
+ * Get Context URL from http request.
+ *
+ * @param request http Request
+ * @return Context URL
+ */
+ public static String getBaseUrl(final HttpServletRequest request) {
+ if (request.getServerPort() == 80 || request.getServerPort() == 443) {
+ return request.getScheme() + "://" + request.getServerName() + request.getContextPath();
+ } else {
+ return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ + request.getContextPath();
+ }
+ }
+
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java
index 6b8fe9b7..78f0cdec 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java
@@ -6,33 +6,37 @@ import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException;
/**
- * Simple pendingRequestId generation strategy that facilitates no extended validation
- *
+ * Simple pendingRequestId generation strategy that facilitates no extended
+ * validation.
+ *
* @author tlenz
*
*/
-public class SimplePendingRequestIdGenerationStrategy implements IPendingRequestIdGenerationStrategy {
-
- @Override
- public String generateExternalPendingRequestId() {
- return Random.nextLongRandom();
-
- }
-
- @Override
- public String validateAndGetPendingRequestId(String pendingReqId) throws PendingReqIdValidationException {
- return getPendingRequestIdWithOutChecks(pendingReqId);
-
- }
-
- @Override
- public String getPendingRequestIdWithOutChecks(String externalPendingReqId) throws PendingReqIdValidationException {
- if (StringUtils.isEmpty(externalPendingReqId))
- throw new PendingReqIdValidationException(externalPendingReqId, "PendingRequestId is empty or null");
-
-
-
- return externalPendingReqId;
- }
+public class SimplePendingRequestIdGenerationStrategy
+ implements IPendingRequestIdGenerationStrategy {
+
+ @Override
+ public String generateExternalPendingRequestId() {
+ return Random.nextLongRandom();
+
+ }
+
+ @Override
+ public String validateAndGetPendingRequestId(final String pendingReqId)
+ throws PendingReqIdValidationException {
+ return getPendingRequestIdWithOutChecks(pendingReqId);
+
+ }
+
+ @Override
+ public String getPendingRequestIdWithOutChecks(final String externalPendingReqId)
+ throws PendingReqIdValidationException {
+ if (StringUtils.isEmpty(externalPendingReqId)) {
+ throw new PendingReqIdValidationException(externalPendingReqId,
+ "PendingRequestId is empty or null");
+ }
+
+ return externalPendingReqId;
+ }
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java
index 530da777..22a6de2b 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/StreamUtils.java
@@ -1,30 +1,21 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
package at.gv.egiz.eaaf.core.impl.utils;
@@ -32,38 +23,37 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.PrintStream;
/**
* Utility methods for streams.
- *
+ *
* @author Patrick Peck
* @version $Id$
*/
public class StreamUtils {
-
+
/**
* Compare the contents of two <code>InputStream</code>s.
- *
+ *
* @param is1 The 1st <code>InputStream</code> to compare.
* @param is2 The 2nd <code>InputStream</code> to compare.
* @return boolean <code>true</code>, if both streams contain the exactly the
- * same content, <code>false</code> otherwise.
+ * same content, <code>false</code> otherwise.
* @throws IOException An error occurred reading one of the streams.
*/
- public static boolean compareStreams(InputStream is1, InputStream is2)
- throws IOException {
-
- byte[] buf1 = new byte[256];
- byte[] buf2 = new byte[256];
+ public static boolean compareStreams(final InputStream is1, final InputStream is2)
+ throws IOException {
+
+ final byte[] buf1 = new byte[256];
+ final byte[] buf2 = new byte[256];
int length1;
int length2;
-
+
try {
while (true) {
length1 = is1.read(buf1);
length2 = is2.read(buf2);
-
+
if (length1 != length2) {
return false;
}
@@ -74,128 +64,127 @@ public class StreamUtils {
return false;
}
}
- } catch (IOException e) {
+ } catch (final IOException e) {
throw e;
} finally {
// close both streams
try {
is1.close();
is2.close();
- } catch (IOException e) {
- // ignore this
+ } catch (final IOException e) {
+ e.printStackTrace();
+
}
}
}
-
+
/**
* Compare two byte arrays, up to a given maximum length.
- *
- * @param b1 1st byte array to compare.
- * @param b2 2nd byte array to compare.
+ *
+ * @param b1 1st byte array to compare.
+ * @param b2 2nd byte array to compare.
* @param length The maximum number of bytes to compare.
* @return <code>true</code>, if the byte arrays are equal, <code>false</code>
- * otherwise.
+ * otherwise.
*/
- private static boolean compareBytes(byte[] b1, byte[] b2, int length) {
+ private static boolean compareBytes(final byte[] b1, final byte[] b2, final int length) {
if (b1.length != b2.length) {
return false;
}
-
+
for (int i = 0; i < b1.length && i < length; i++) {
if (b1[i] != b2[i]) {
return false;
}
}
-
+
return true;
}
/**
* Reads a byte array from a stream.
+ *
* @param in The <code>InputStream</code> to read.
* @return The bytes contained in the given <code>InputStream</code>.
* @throws IOException on any exception thrown
*/
- public static byte[] readStream(InputStream in) throws IOException {
+ public static byte[] readStream(final InputStream in) throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
copyStream(in, out, null);
-
- /*
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- int b;
- while ((b = in.read()) >= 0)
- out.write(b);
-
- */
+
+ /*
+ * ByteArrayOutputStream out = new ByteArrayOutputStream(); int b; while ((b =
+ * in.read()) >= 0) out.write(b);
+ *
+ */
in.close();
return out.toByteArray();
}
/**
* Reads a <code>String</code> from a stream, using given encoding.
- * @param in The <code>InputStream</code> to read.
- * @param encoding The character encoding to use for converting the bytes
- * of the <code>InputStream</code> into a <code>String</code>.
- * @return The content of the given <code>InputStream</code> converted into
- * a <code>String</code>.
+ *
+ * @param in The <code>InputStream</code> to read.
+ * @param encoding The character encoding to use for converting the bytes of the
+ * <code>InputStream</code> into a <code>String</code>.
+ * @return The content of the given <code>InputStream</code> converted into a
+ * <code>String</code>.
* @throws IOException on any exception thrown
*/
- public static String readStream(InputStream in, String encoding) throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
+ public static String readStream(final InputStream in, final String encoding) throws IOException {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
copyStream(in, out, null);
/*
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- int b;
- while ((b = in.read()) >= 0)
- out.write(b);
- */
+ * ByteArrayOutputStream out = new ByteArrayOutputStream(); int b; while ((b =
+ * in.read()) >= 0) out.write(b);
+ */
in.close();
return out.toString(encoding);
}
-
+
/**
- * Reads all data (until EOF is reached) from the given source to the
+ * Reads all data (until EOF is reached) from the given source to the
* destination stream. If the destination stream is null, all data is dropped.
- * It uses the given buffer to read data and forward it. If the buffer is
- * null, this method allocates a buffer.
+ * It uses the given buffer to read data and forward it. If the buffer is null,
+ * this method allocates a buffer.
*
- * @param source The stream providing the data.
- * @param destination The stream that takes the data. If this is null, all
- * data from source will be read and discarded.
- * @param buffer The buffer to use for forwarding. If it is null, the method
- * allocates a buffer.
- * @exception IOException If reading from the source or writing to the
+ * @param source The stream providing the data.
+ * @param destination The stream that takes the data. If this is null, all data
+ * from source will be read and discarded.
+ * @param buffer The buffer to use for forwarding. If it is null, the
+ * method allocates a buffer.
+ * @exception IOException If reading from the source or writing to the
* destination fails.
*/
- private static void copyStream(InputStream source, OutputStream destination, byte[] buffer) throws IOException {
+ private static void copyStream(final InputStream source, final OutputStream destination,
+ byte[] buffer) throws IOException {
if (source == null) {
throw new NullPointerException("Argument \"source\" must not be null.");
}
if (buffer == null) {
buffer = new byte[8192];
}
-
+
if (destination != null) {
int bytesRead;
while ((bytesRead = source.read(buffer)) >= 0) {
destination.write(buffer, 0, bytesRead);
}
- } else {
- while (source.read(buffer) >= 0);
- }
- }
-
- /**
- * Gets the stack trace of the <code>Throwable</code> passed in as a string.
- * @param t The <code>Throwable</code>.
- * @return a String representing the stack trace of the <code>Throwable</code>.
- */
- public static String getStackTraceAsString(Throwable t)
- {
- ByteArrayOutputStream stackTraceBIS = new ByteArrayOutputStream();
- t.printStackTrace(new PrintStream(stackTraceBIS));
- return new String(stackTraceBIS.toByteArray());
+ }
}
+
+ // /**
+ // * Gets the stack trace of the <code>Throwable</code> passed in as a string.
+ // *
+ // * @param t The <code>Throwable</code>.
+ // * @return a String representing the stack trace of the
+ // <code>Throwable</code>.
+ // */
+ // public static String getStackTraceAsString(final Throwable t) {
+ // final ByteArrayOutputStream stackTraceBis = new ByteArrayOutputStream();
+ // t.printStackTrace(new PrintStream(stackTraceBis));
+ // return new String(stackTraceBis.toByteArray());
+ // }
}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java
deleted file mode 100644
index 2e016848..00000000
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIDUtils.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-package at.gv.egiz.eaaf.core.impl.utils;
-
-
-import at.gv.egiz.eaaf.core.api.IRequest;
-
-/**
- * @author tlenz
- *
- */
-public class TransactionIDUtils {
-
- //MDC variables for logging
- public static final String MDC_TRANSACTION_ID = "transactionId";
- public static final String MDC_SESSION_ID = "sessionId";
- public static final String MDC_SERVICEPROVIDER_ID = "oaId";
-
- /**
- * Set all MDC variables from pending request to this threat context<br>
- * These includes SessionID, TransactionID, and unique service-provider identifier
- *
- * @param pendingRequest
- */
- public static void setAllLoggingVariables(IRequest pendingRequest) {
- setTransactionId(pendingRequest.getUniqueTransactionIdentifier());
- setSessionId(pendingRequest.getUniqueSessionIdentifier());
- setServiceProviderId(pendingRequest.getServiceProviderConfiguration().getUniqueIdentifier());
-
- }
-
- /**
- * Remove all MDC variables from this threat context
- *
- */
- public static void removeAllLoggingVariables() {
- removeSessionId();
- removeTransactionId();
- removeServiceProviderId();
-
- }
-
-
- public static void setServiceProviderId(String oaUniqueId) {
- org.slf4j.MDC.put(MDC_SERVICEPROVIDER_ID, oaUniqueId);
-
- }
-
- public static void removeServiceProviderId() {
- org.slf4j.MDC.remove(MDC_SERVICEPROVIDER_ID);
-
- }
-
- public static void setTransactionId(String pendingRequestID) {
- org.slf4j.MDC.put(MDC_TRANSACTION_ID,
- "TID-" + pendingRequestID);
-
- }
-
- public static void removeTransactionId() {
- org.slf4j.MDC.remove(MDC_TRANSACTION_ID);
-
- }
-
- public static void setSessionId(String uniqueSessionId) {
- org.slf4j.MDC.put(MDC_SESSION_ID,
- "SID-" + uniqueSessionId);
-
- }
-
- public static void removeSessionId() {
- org.slf4j.MDC.remove(MDC_SESSION_ID);
-
- }
-
-
-}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIdUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIdUtils.java
new file mode 100644
index 00000000..4cbcfa70
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/TransactionIdUtils.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.core.impl.utils;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+
+/**
+ * Transaction Identifier Utils.
+ *
+ * @author tlenz
+ *
+ */
+public class TransactionIdUtils {
+
+ // MDC variables for logging
+ /**
+ * To correlate technical logs over one single transactions.
+ */
+ public static final String MDC_TRANSACTION_ID = "transactionId";
+
+ /**
+ * To correlate technical logs over a set of transactions, like SSO.
+ */
+ public static final String MDC_SESSION_ID = "sessionId";
+
+ /**
+ * Unique application identifier that is processed in this transaction.
+ */
+ public static final String MDC_SERVICEPROVIDER_ID = "oaId";
+
+ /**
+ * Set all MDC variables from pending request to this threat context.<br>
+ * These includes SessionID, TransactionID, and unique service-provider
+ * identifier
+ *
+ * @param pendingRequest Http request object
+ */
+ public static void setAllLoggingVariables(final IRequest pendingRequest) {
+ setTransactionId(pendingRequest.getUniqueTransactionIdentifier());
+ setSessionId(pendingRequest.getUniqueSessionIdentifier());
+ setServiceProviderId(pendingRequest.getServiceProviderConfiguration().getUniqueIdentifier());
+
+ }
+
+ /**
+ * Remove all MDC variables from this threat context.
+ *
+ */
+ public static void removeAllLoggingVariables() {
+ removeSessionId();
+ removeTransactionId();
+ removeServiceProviderId();
+
+ }
+
+ /**
+ * Set unique service-provider identifier for Logging purposes.
+ *
+ * @param oaUniqueId Unique application Id
+ */
+ public static void setServiceProviderId(final String oaUniqueId) {
+ org.slf4j.MDC.put(MDC_SERVICEPROVIDER_ID, oaUniqueId);
+
+ }
+
+ /**
+ * Remove service-provider identifier for Logging.
+ */
+ public static void removeServiceProviderId() {
+ org.slf4j.MDC.remove(MDC_SERVICEPROVIDER_ID);
+
+ }
+
+ /**
+ * Get Id to correlate technical logs over one single transactions.
+ *
+ * @return Unique transaction Id
+ */
+ public static String getTransactionId() {
+ return org.slf4j.MDC.get(MDC_TRANSACTION_ID);
+
+ }
+
+ /**
+ * Set Id to correlate technical logs over one single transactions.
+ *
+ * @param transactionId Unique transaction Id
+ */
+ public static void setTransactionId(final String transactionId) {
+ org.slf4j.MDC.put(MDC_TRANSACTION_ID, transactionId);
+
+ }
+
+ /**
+ * Remove transactionId for Logging.
+ */
+ public static void removeTransactionId() {
+ org.slf4j.MDC.remove(MDC_TRANSACTION_ID);
+
+ }
+
+ /**
+ * Set Id to correlate technical logs over a set of transactions, like SSO.
+ *
+ * @param uniqueSessionId Unique Id
+ */
+ public static void setSessionId(final String uniqueSessionId) {
+ org.slf4j.MDC.put(MDC_SESSION_ID, uniqueSessionId);
+
+ }
+
+ /**
+ * Remove sessionId for Logging.
+ *
+ */
+ public static void removeSessionId() {
+ org.slf4j.MDC.remove(MDC_SESSION_ID);
+
+ }
+
+
+}
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java
index b3fb42c4..72c183bf 100644
--- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java
@@ -7,56 +7,45 @@ import javax.security.auth.x500.X500Principal;
public class X509Utils {
- /**
- * Sorts the Certificate Chain by IssuerDN and SubjectDN. The [0]-Element should be the Hostname,
- * the last Element should be the Root Certificate.
- *
- * @param certs
- * The first element must be the correct one.
- * @return sorted Certificate Chain
- */
- public static List<X509Certificate> sortCertificates(
- List<X509Certificate> certs)
- {
- int length = certs.size();
- if (certs.size() <= 1)
- {
- return certs;
- }
+ /**
+ * Sorts the Certificate Chain by IssuerDN and SubjectDN. The [0]-Element should
+ * be the Hostname, the last Element should be the Root Certificate.
+ *
+ * @param certs The first element must be the correct one.
+ * @return sorted Certificate Chain
+ */
+ public static List<X509Certificate> sortCertificates(final List<X509Certificate> certs) {
+ final int length = certs.size();
+ if (certs.size() <= 1) {
+ return certs;
+ }
- for (X509Certificate cert : certs)
- {
- if (cert == null)
- {
- throw new NullPointerException();
- }
- }
+ for (final X509Certificate cert : certs) {
+ if (cert == null) {
+ throw new NullPointerException();
+ }
+ }
- for (int i = 0; i < length; i++)
- {
- boolean found = false;
- X500Principal issuer = certs.get(i).getIssuerX500Principal();
- for (int j = i + 1; j < length; j++)
- {
- X500Principal subject = certs.get(j).getSubjectX500Principal();
- if (issuer.equals(subject))
- {
- // sorting necessary?
- if (i + 1 != j)
- {
- X509Certificate tmp = certs.get(i + 1);
- certs.set(i + 1, certs.get(j));
- certs.set(j, tmp);
- }
- found = true;
- }
- }
- if (!found)
- {
- break;
- }
- }
+ for (int i = 0; i < length; i++) {
+ boolean found = false;
+ final X500Principal issuer = certs.get(i).getIssuerX500Principal();
+ for (int j = i + 1; j < length; j++) {
+ final X500Principal subject = certs.get(j).getSubjectX500Principal();
+ if (issuer.equals(subject)) {
+ // sorting necessary?
+ if (i + 1 != j) {
+ final X509Certificate tmp = certs.get(i + 1);
+ certs.set(i + 1, certs.get(j));
+ certs.set(j, tmp);
+ }
+ found = true;
+ }
+ }
+ if (!found) {
+ break;
+ }
+ }
- return certs;
- }
+ return certs;
+ }
}
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
new file mode 100644
index 00000000..f531e02d
--- /dev/null
+++ b/eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties
@@ -0,0 +1,15 @@
+internal.configuration.00=Wrong configuration. Missing property: {0}
+internal.configuration.01=Wrong configuration property: {0}. Reason: {1}
+
+internal.keystore.00=HSM-Facade NOT INITIALIZED. KeyStore:{0} initialization failed
+internal.keystore.01=KeyStore:{0} configuration has an unsupported type in configuration.
+internal.keystore.02=Type:{1} of KeyStore:{0} is NOT SUPPORTED yet.
+internal.keystore.03=HSM-Facade initialization failed with a generic error: {0}
+internal.keystore.04=HSM-Facade has a wrong configuration. Missing property: {0}
+internal.keystore.05=HSM-Facade has a wrong configuration. Property: {0} Reason:{1}
+internal.keystore.06=KeyStore: {0} initialization failed. Reason: {1}
+internal.keystore.07=Validation of KeyStore: {0} failed. Reason: {1}
+internal.keystore.08=Can not access Key: {1} in KeyStore: {0}
+internal.keystore.09=Can not access Key: {1} in KeyStore: {0} Reason: {2}
+
+
diff --git a/eaaf_core_utils/src/main/resources/spring/eaaf_utils.beans.xml b/eaaf_core_utils/src/main/resources/spring/eaaf_utils.beans.xml
new file mode 100644
index 00000000..ab631e34
--- /dev/null
+++ b/eaaf_core_utils/src/main/resources/spring/eaaf_utils.beans.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" >
+
+ <bean id="eaafHttpClientFactory"
+ class="at.gv.egiz.eaaf.core.impl.utils.HttpClientFactory" />
+
+ <bean id="eaafKeyStoreFactory"
+ class="at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory" />
+
+ <bean id="eaafUtilsMessageSource"
+ class="at.gv.egiz.eaaf.core.impl.logging.EaafUtilsMessageSource" />
+
+</beans> \ No newline at end of file
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/EaafUtilsMessageSourceTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/EaafUtilsMessageSourceTest.java
new file mode 100644
index 00000000..53ea54dc
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/EaafUtilsMessageSourceTest.java
@@ -0,0 +1,39 @@
+package at.gv.egiz.eaaf.core.impl.logging;
+
+import java.util.List;
+
+import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("/spring/test_eaaf_pvp_not_lazy.beans.xml")
+public class EaafUtilsMessageSourceTest {
+
+ @Autowired
+ private ResourceLoader loader;
+ @Autowired(required = false)
+ private List<IMessageSourceLocation> messageSources;
+
+ @Test
+ public void checkMessageSources() {
+ Assert.assertNotNull("No messageSource", messageSources);
+
+ for (final IMessageSourceLocation messageSource : messageSources) {
+ Assert.assertNotNull("No sourcePath", messageSource.getMessageSourceLocation());
+
+ for (final String el : messageSource.getMessageSourceLocation()) {
+ final Resource messages = loader.getResource(el + ".properties");
+ Assert.assertTrue("Source not exist", messages.exists());
+
+ }
+ }
+ }
+}
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/JUnitTestStatusMessenger.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/JUnitTestStatusMessenger.java
index 5cdd404c..9c1d0c82 100644
--- a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/JUnitTestStatusMessenger.java
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/logging/JUnitTestStatusMessenger.java
@@ -8,49 +8,55 @@ import at.gv.egiz.eaaf.core.api.IStatusMessenger;
public class JUnitTestStatusMessenger implements IStatusMessenger {
- private final Map<String, String> msgStore = new HashMap<>();
-
- @Override
- public String getMessage(String messageId, Object[] parameters) {
- final String msg = getMessageWithoutDefault(messageId, parameters);
- if (msg != null) {
- return msg;
-
- } else {
- return MessageFormat.format(messageId, parameters);
-
- }
-
- }
-
- @Override
- public String getMessageWithoutDefault(String messageId, Object[] parameters) {
- if (messageId != null) {
- if (msgStore.containsKey(messageId)) {
- return MessageFormat.format(msgStore.get(messageId), parameters);
-
- }
- }
-
- return null;
- }
-
- @Override
- public String getResponseErrorCode(Throwable throwable) {
- return null;
- }
-
- @Override
- public String mapInternalErrorToExternalError(String intErrorCode) {
- return null;
- }
-
- public void addMsg(String msgCode, String msg) {
- if (!msgStore.containsKey(msgCode)) {
- msgStore.put(msgCode, msg);
-
- }
-
- }
-
+ private final Map<String, String> msgStore = new HashMap<>();
+
+ @Override
+ public String getMessage(final String messageId, final Object[] parameters) {
+ final String msg = getMessageWithoutDefault(messageId, parameters);
+ if (msg != null) {
+ return msg;
+
+ } else {
+ return MessageFormat.format(messageId, parameters);
+
+ }
+
+ }
+
+ @Override
+ public String getMessageWithoutDefault(final String messageId, final Object[] parameters) {
+ if (messageId != null) {
+ if (msgStore.containsKey(messageId)) {
+ return MessageFormat.format(msgStore.get(messageId), parameters);
+
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getResponseErrorCode(final Throwable throwable) {
+ return null;
+ }
+
+ @Override
+ public String mapInternalErrorToExternalError(final String intErrorCode) {
+ return null;
+ }
+
+ /**
+ * Add a message into Message-Store.
+ *
+ * @param msgCode message-code
+ * @param msg message
+ */
+ public void addMsg(final String msgCode, final String msg) {
+ if (!msgStore.containsKey(msgCode)) {
+ msgStore.put(msgCode, msg);
+
+ }
+
+ }
+
}
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/utils/test/KeyValueUtilsTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/utils/test/KeyValueUtilsTest.java
new file mode 100644
index 00000000..58788392
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/utils/test/KeyValueUtilsTest.java
@@ -0,0 +1,448 @@
+package at.gv.egiz.eaaf.core.impl.utils.test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import com.google.common.collect.Sets;
+
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class KeyValueUtilsTest {
+
+ @Test
+ public void getFirstChildTest_1() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(4);
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(key, prefix);
+ Assert.assertEquals("First child not match", child, resut);
+
+ }
+
+ @Test
+ public void getFirstChildTest_2() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child;
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(key, prefix);
+ Assert.assertEquals("First child not match", child, resut);
+
+ }
+
+ @Test
+ public void getFirstChildTest_3() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child;
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(key, key);
+ Assert.assertNull("First child not null", resut);
+
+ }
+
+ @Test
+ public void getFirstChildTest_4() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child;
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(
+ RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER + key, key);
+ Assert.assertNull("First child not null", resut);
+
+ }
+
+ @Test
+ public void getFirstChildTest_5() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = child + KeyValueUtils.KEY_DELIMITER + prefix;
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(key, null);
+ Assert.assertEquals("First child not match", child, resut);
+
+ }
+
+ @Test
+ public void getFirstChildTest_6() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child;
+ final String resut = KeyValueUtils.getFirstChildAfterPrefix(key, key);
+ Assert.assertNull("First child not null", resut);
+
+ }
+
+ @Test
+ public void getPrefixFromKey_1() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + child;
+ final String resut = KeyValueUtils.getPrefixFromKey(key, child);
+ Assert.assertEquals("Prefix not match", prefix, resut);
+
+ }
+
+ @Test
+ public void getPrefixFromKey_2() {
+ final String child = RandomStringUtils.randomAlphabetic(2);
+ final String resut = KeyValueUtils.getPrefixFromKey(null, child);
+ Assert.assertNull("Prefix not null", resut);
+
+ }
+
+ @Test
+ public void getPrefixFromKey_3() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String key = prefix + KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(4);
+ final String resut = KeyValueUtils.getPrefixFromKey(key, RandomStringUtils.randomAlphabetic(5));
+ Assert.assertNull("Prefix not null", resut);
+
+ }
+
+ @Test
+ public void getPrefixFromKey_4() {
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String child = KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(2);
+ final String key = prefix + child;
+ final String resut = KeyValueUtils.getPrefixFromKey(key, child);
+ Assert.assertEquals("Prefix not match", prefix, resut);
+
+ }
+
+ @Test
+ public void getPrefixFromKey_5() {
+ final String key = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String resut = KeyValueUtils.getPrefixFromKey(key, null);
+ Assert.assertNull("Prefix not null", resut);
+
+ }
+
+ @Test
+ public void getRemovePrefixesFromKeys_1() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final Map<String, String> testMap = generateTestMap(testPrefix, 5, 5);
+
+ final Map<String, String> result = KeyValueUtils.removePrefixFromKeys(testMap, testPrefix);
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ Assert.assertEquals("Result size not match", 5, result.size());
+ final Iterator<Entry<String, String>> it = result.entrySet().iterator();
+ while (it.hasNext()) {
+ final Entry<String, String> next = it.next();
+ Assert.assertNotNull("Key is null", next.getKey());
+ Assert.assertNotNull("Value is null", next.getValue());
+ Assert.assertTrue("Key is null", testMap.containsKey(testPrefix + "." + next.getKey()));
+ Assert.assertEquals("Value not match", testMap.get(testPrefix + "." + next.getKey()),
+ next.getValue());
+
+ }
+
+ }
+
+ @Test
+ public void getSubSetWithPrefixTest_1() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final Map<String, String> testMap = generateTestMap(testPrefix, 5, 5);
+
+ final Map<String, String> result = KeyValueUtils.getSubSetWithPrefix(testMap, testPrefix);
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ Assert.assertEquals("Result size not match", 5, result.size());
+ final Iterator<Entry<String, String>> it = result.entrySet().iterator();
+ while (it.hasNext()) {
+ final Entry<String, String> next = it.next();
+ Assert.assertNotNull("Key is null", next.getKey());
+ Assert.assertNotNull("Value is null", next.getValue());
+ Assert.assertTrue("Key is null", testMap.containsKey(testPrefix + "." + next.getKey()));
+ Assert.assertEquals("Value not match", testMap.get(testPrefix + "." + next.getKey()),
+ next.getValue());
+
+ }
+
+ }
+
+ @Test
+ public void makeKeysAbsolutTest_1() {
+ final String absTestPrefixtestPrefix = RandomStringUtils.randomAlphabetic(4)
+ + KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(6)
+ + KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(5);
+ final String prefix = absTestPrefixtestPrefix + "." + RandomStringUtils.randomAlphabetic(4);
+ final Map<String, String> testMap = generateTestMap(prefix, 5, 5);
+ final Map<String, String> result =
+ KeyValueUtils.makeKeysAbsolut(testMap, absTestPrefixtestPrefix, prefix);
+
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ Assert.assertEquals("Result size not match", 10, result.size());
+ final Iterator<Entry<String, String>> it = result.entrySet().iterator();
+ while (it.hasNext()) {
+ final Entry<String, String> next = it.next();
+ Assert.assertNotNull("Key is null", next.getKey());
+ Assert.assertNotNull("Value is null", next.getValue());
+ if (testMap.containsKey(next.getKey())) {
+ Assert.assertEquals("Value not match", testMap.get(next.getKey()), next.getValue());
+ } else {
+ Assert.assertTrue("Key not found",
+ testMap.containsKey(next.getKey().substring(absTestPrefixtestPrefix.length() + 1)));
+ Assert.assertEquals("Value not match",
+ testMap.get(next.getKey().substring(absTestPrefixtestPrefix.length() + 1)),
+ next.getValue());
+ }
+ }
+ }
+
+ @Test
+ public void getParentKeyTest_1() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final String result =
+ KeyValueUtils.getParentKey(testPrefix + "." + RandomStringUtils.randomAlphabetic(5));
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertEquals("Parent not match", testPrefix, result);
+
+ }
+
+ @Test
+ public void getParentKeyTest_2() {
+ final String result = KeyValueUtils.getParentKey(RandomStringUtils.randomAlphabetic(5));
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertTrue("Result not empty", result.isEmpty());
+
+ }
+
+ @Test
+ public void findNextFreeListCoutnerTest_1() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final java.util.List<String> propList = new ArrayList<>();
+ propList.add(testPrefix + ".1");
+ propList.add(testPrefix + ".2");
+ propList.add(testPrefix + ".0");
+ propList.add(testPrefix + ".4");
+ propList.add(testPrefix + ".3");
+
+ final int result = KeyValueUtils.findNextFreeListCounter(Sets.newHashSet(propList), testPrefix);
+ Assert.assertEquals("Next free element not fount", 5, result);
+
+ }
+
+ @Test
+ public void findNextFreeListCoutnerTest_2() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final java.util.List<String> propList = new ArrayList<>();
+ propList.add(testPrefix + ".1");
+ propList.add(testPrefix + ".5");
+ propList.add(testPrefix + ".0");
+ propList.add(testPrefix + ".4");
+ propList.add(testPrefix + ".3");
+
+ final int result = KeyValueUtils.findNextFreeListCounter(Sets.newHashSet(propList), testPrefix);
+ Assert.assertEquals("Next free element not fount", 6, result);
+
+ }
+
+ @Test
+ public void findNextFreeListCoutnerTest_3() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final java.util.List<String> propList = new ArrayList<>();
+
+ final int result = KeyValueUtils.findNextFreeListCounter(Sets.newHashSet(propList), testPrefix);
+ Assert.assertEquals("Next free element not fount", 0, result);
+
+ }
+
+ @Test
+ public void findNextFreeListCoutnerTest_4() {
+ final String testPrefix = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ final java.util.List<String> propList = new ArrayList<>();
+
+ final int result =
+ KeyValueUtils.findNextFreeListCounter(propList.stream().toArray(String[]::new), testPrefix);
+ Assert.assertEquals("Next free element not fount", 0, result);
+
+ }
+
+ @Test
+ public void normalizeCsvValueStringTest_1() {
+ final String csv1 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv2 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv3 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv4 = RandomStringUtils.randomAlphanumeric(5);
+ final String testValue = " " + csv1 + " ," + csv2 + "," + csv3 + "\n," + csv4 + " ";
+
+ final String result = KeyValueUtils.normalizeCsvValueString(testValue);
+
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ final String[] check = result.split(",");
+ Assert.assertEquals("Result size wrong", 4, check.length);
+ Assert.assertEquals("Result 1 wrong", csv1, check[0]);
+ Assert.assertEquals("Result 2 wrong", csv2, check[1]);
+ Assert.assertEquals("Result 3 wrong", csv3, check[2]);
+ Assert.assertEquals("Result 4 wrong", csv4, check[3]);
+
+ }
+
+ @Test
+ public void isCsvValueStringTest_1() {
+ final String csv1 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv2 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv3 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv4 = RandomStringUtils.randomAlphanumeric(5);
+ final String testValue = " " + csv1 + " ," + csv2 + "," + csv3 + "\n," + csv4 + " ";
+ final boolean result = KeyValueUtils.isCsvValueString(testValue);
+ Assert.assertTrue("CSV value not detected", result);
+
+ }
+
+ @Test
+ public void isCsvValueStringTest_2() {
+ final String csv1 = RandomStringUtils.randomAlphanumeric(5);
+ final String testValue = " " + csv1 + " ,";
+ final boolean result = KeyValueUtils.isCsvValueString(testValue);
+ Assert.assertFalse("CSV value not detected", result);
+
+ }
+
+ @Test
+ public void isCsvValueStringTest_3() {
+ final String csv1 = RandomStringUtils.randomAlphanumeric(5);
+ final String testValue = " " + csv1;
+ final boolean result = KeyValueUtils.isCsvValueString(testValue);
+ Assert.assertFalse("CSV value not detected", result);
+
+ }
+
+ @Test
+ public void getListOfCsvValuesTest_1() {
+ final String csv1 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv2 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv3 = RandomStringUtils.randomAlphanumeric(5);
+ final String csv4 = RandomStringUtils.randomAlphanumeric(5);
+ final String testValue = " " + csv1 + " ," + csv2 + "," + csv3 + "\n," + csv4 + " ";
+
+ final List<String> result = KeyValueUtils.getListOfCsvValues(testValue);
+
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ Assert.assertEquals("Result size wrong", 4, result.size());
+ Assert.assertEquals("Result 1 wrong", csv1, result.get(0));
+ Assert.assertEquals("Result 2 wrong", csv2, result.get(1));
+ Assert.assertEquals("Result 3 wrong", csv3, result.get(2));
+ Assert.assertEquals("Result 4 wrong", csv4, result.get(3));
+
+ }
+
+ @Test
+ public void convertListToMapTest_1() {
+ final java.util.List<String> propList = new ArrayList<>();
+ final String prefix = RandomStringUtils.randomAlphabetic(4) + ".";
+ final String key1 = RandomStringUtils.randomAlphabetic(5);
+ final String value1 = RandomStringUtils.randomAlphanumeric(10);
+ final String key2 = RandomStringUtils.randomAlphabetic(5);
+ final String value2 = RandomStringUtils.randomAlphanumeric(10);
+ final String key3 = RandomStringUtils.randomAlphabetic(5);
+ final String value3 = RandomStringUtils.randomAlphanumeric(10);
+ final String key4 = RandomStringUtils.randomAlphabetic(5);
+ final String value4 = RandomStringUtils.randomAlphanumeric(10);
+ final String key5 = RandomStringUtils.randomAlphabetic(5);
+ final String value5 = RandomStringUtils.randomAlphanumeric(10);
+ final String key6 = RandomStringUtils.randomAlphabetic(5);
+ final String value6 = "=" + RandomStringUtils.randomAlphanumeric(10);
+
+ propList.add(prefix + key1 + "=" + value1);
+ propList.add(prefix + key2 + "=" + value2);
+ propList.add(prefix + key3 + "=" + value3);
+ propList.add(prefix + key4 + "=" + value4);
+ propList.add(prefix + key5 + "+" + value5);
+ propList.add(prefix + key6 + "=" + value6);
+
+ final Map<String, String> result = KeyValueUtils.convertListToMap(propList);
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertFalse("Result is empty", result.isEmpty());
+ Assert.assertEquals("Result size not match", 5, result.size());
+
+ Assert.assertTrue("Key1 not found", result.containsKey(prefix + key1));
+ Assert.assertEquals("Value1 not found", value1, result.get(prefix + key1));
+ Assert.assertTrue("Key2 not found", result.containsKey(prefix + key2));
+ Assert.assertEquals("Value2 not found", value2, result.get(prefix + key2));
+ Assert.assertTrue("Key3 not found", result.containsKey(prefix + key3));
+ Assert.assertEquals("Value3 not found", value3, result.get(prefix + key3));
+ Assert.assertTrue("Key4 not found", result.containsKey(prefix + key4));
+ Assert.assertEquals("Value4 not found", value4, result.get(prefix + key4));
+
+ }
+
+ @Test
+ public void convertListToMapTest_2() {
+ final java.util.List<String> propList = new ArrayList<>();
+
+ final Map<String, String> result = KeyValueUtils.convertListToMap(propList);
+ Assert.assertNotNull("Result is null", result);
+ Assert.assertTrue("Result is not empty", result.isEmpty());
+
+ }
+
+ private Map<String, String> generateTestMap(final String testPrefix, final int entriesWithPrefix,
+ final int entriesWithoutPrefix) {
+ final Map<String, String> result = new HashMap<>();
+ for (int i = 0; i < entriesWithPrefix; i++) {
+ result.put(testPrefix + KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(5),
+ RandomStringUtils.randomAlphabetic(5));
+ }
+
+ final String key = RandomStringUtils.randomAlphabetic(4) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ + RandomStringUtils.randomAlphabetic(5);
+ for (int i = 0; i < entriesWithoutPrefix; i++) {
+ result.put(key + KeyValueUtils.KEY_DELIMITER + RandomStringUtils.randomAlphabetic(5),
+ RandomStringUtils.randomAlphabetic(5));
+ }
+
+ return result;
+
+ }
+
+}
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/TestConstants.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/TestConstants.java
new file mode 100644
index 00000000..c8e45a9a
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/TestConstants.java
@@ -0,0 +1,7 @@
+package at.gv.egiz.eaaf.core.test;
+
+public class TestConstants {
+
+ public static final String TEST_SPI_LOADER_PATH =
+ "/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider";
+}
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
new file mode 100644
index 00000000..ed2e159b
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EaafKeyStoreFactoryTest.java
@@ -0,0 +1,655 @@
+package at.gv.egiz.eaaf.core.test.credentials;
+
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.Provider;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+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.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.test.dummy.DummyAuthConfigMap;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.annotation.DirtiesContext.MethodMode;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicates;
+import com.google.common.base.Throwables;
+import com.google.common.collect.FluentIterable;
+import io.grpc.StatusRuntimeException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("/spring/test_eaaf_pvp_lazy.beans.xml")
+@DirtiesContext(methodMode = MethodMode.BEFORE_METHOD)
+public class EaafKeyStoreFactoryTest {
+
+ private static final String HSM_FACASE_HOST = "eid.a-sit.at";
+ private static final String HSM_FACASE_PORT = "9050";
+ private static final String HSM_FACASE_SSL_TRUST = "src/test/resources/data/hsm_facade_trust_root.crt";
+ private static final String HSM_FACASE_USERNAME = "authhandler-junit";
+ private static final String HSM_FACASE_PASSWORD = "supersecret123";
+ private static final String PATH_TO_SOFTWARE_KEYSTORE_JKS_WITH_TRUSTED_CERTS =
+ "src/test/resources/data/junit.jks";
+ private static final String PATH_TO_SOFTWARE_KEYSTORE_JKS =
+ "src/test/resources/data/junit_without_trustcerts.jks";
+ private static final String PATH_TO_SOFTWARE_KEYSTORE_PKCS12 =
+ "src/test/resources/data/junit_without_trustcerts.p12";
+ private static final String PATH_TO_HSM_FACADE_TRUST_CERT = "src/test/resources/data/hsm_facade_trust_root.crt";
+ private static final String SOFTWARE_KEYSTORE_PASSWORD = "password";
+
+ private static final String HSM_FACADE_KEY_ALIAS = "authhandler-sign";
+
+ @Autowired
+ private DummyAuthConfigMap mapConfig;
+ @Autowired
+ private ApplicationContext context;
+
+ /**
+ * jUnit test set-up.
+ */
+ @Before
+ public void testSetup() {
+ mapConfig.clearAllConfig();
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void startWithoutConfigHsmFacadeConfig() {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void buildyStoreWithOutConfig() {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ try {
+ keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class, e, "Wong ExceptionType");
+ Assert.assertEquals("wrong errorCode", "internal.keystore.01", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void buildyStoreWithPkcs11() {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.PKCS11);
+ try {
+ keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class, e, "Wong ExceptionType");
+ Assert.assertEquals("wrong errorCode", "internal.keystore.02", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void softwareKeyStoreWithoutConfig() {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.JKS);
+ try {
+ keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class, e, "Wong ExceptionType");
+ Assert.assertEquals("wrong errorCode", "internal.keystore.06", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void softwareKeyStoreWithoutConfigSecond() {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.PKCS12);
+ try {
+ keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class, e, "Wong ExceptionType");
+ Assert.assertEquals("wrong errorCode", "internal.keystore.06", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void softwareKeyStoreWithoutPassword() {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.JKS);
+ keyStoreConfig.setSoftKeyStoreFilePath(PATH_TO_SOFTWARE_KEYSTORE_JKS);
+
+ try {
+ keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class, e, "Wong ExceptionType");
+ Assert.assertEquals("wrong errorCode", "internal.keystore.06", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void softwareKeyStoreWithoutPath() {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.JKS);
+ keyStoreConfig.setSoftKeyStorePassword(SOFTWARE_KEYSTORE_PASSWORD);
+
+
+ try {
+ keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class, e, "Wong ExceptionType");
+ Assert.assertEquals("wrong errorCode", "internal.keystore.06", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void softwareKeyStoreWithoutType() 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.JKS);
+ keyStoreConfig.setSoftKeyStoreFilePath(PATH_TO_SOFTWARE_KEYSTORE_JKS);
+ keyStoreConfig.setSoftKeyStorePassword(SOFTWARE_KEYSTORE_PASSWORD);
+
+ 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
+ public void softwareKeyStoreWithWrongPath() {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.JKS);
+ keyStoreConfig.setSoftKeyStoreFilePath("src/test/resources/notexist.jks");
+ keyStoreConfig.setSoftKeyStorePassword(SOFTWARE_KEYSTORE_PASSWORD);
+
+
+ try {
+ keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class, e, "Wong ExceptionType");
+ Assert.assertEquals("wrong errorCode", "internal.keystore.05", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void softwareKeyStoreWithWrongPassword() {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.JKS);
+ keyStoreConfig.setSoftKeyStoreFilePath(PATH_TO_SOFTWARE_KEYSTORE_JKS);
+ keyStoreConfig.setSoftKeyStorePassword("wrong password");
+
+
+ try {
+ keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafFactoryException.class, e, "Wong ExceptionType");
+ Assert.assertEquals("wrong errorCode", "internal.keystore.06", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void softwareKeyStoreSuccessJks() 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.JKS);
+ keyStoreConfig.setSoftKeyStoreFilePath(PATH_TO_SOFTWARE_KEYSTORE_JKS);
+ keyStoreConfig.setSoftKeyStorePassword(SOFTWARE_KEYSTORE_PASSWORD);
+
+ 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
+ public void softwareKeyStoreAccessOperations() throws EaafException, KeyStoreException {
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertFalse("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.JKS);
+ keyStoreConfig.setSoftKeyStoreFilePath(PATH_TO_SOFTWARE_KEYSTORE_JKS_WITH_TRUSTED_CERTS);
+ keyStoreConfig.setSoftKeyStorePassword(SOFTWARE_KEYSTORE_PASSWORD);
+
+ 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());
+
+ //read trusted certs
+ final List<X509Certificate> trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore(keyStore.getFirst());
+ Assert.assertNotNull("Trusted certs", trustedCerts);
+ Assert.assertEquals("Trusted certs size", 2, trustedCerts.size());
+
+ //read priv. key
+ final Pair<Key, X509Certificate[]> privCred1 = EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), "meta", "password".toCharArray(), true, "jUnit test");
+ Assert.assertNotNull("Credential 1", privCred1);
+ Assert.assertNotNull("Credential 1 priv. key", privCred1.getFirst());
+ Assert.assertNotNull("Credential 1 certificate", privCred1.getSecond());
+
+ //read priv. key
+ final Pair<Key, X509Certificate[]> privCred2 = EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), "sig", "password".toCharArray(), true, "jUnit test");
+ Assert.assertNotNull("Credential 2", privCred2);
+ Assert.assertNotNull("Credential 2 priv. key", privCred2.getFirst());
+ Assert.assertNotNull("Credential 2 certificate", privCred2.getSecond());
+
+
+ //read priv. key
+ final Pair<Key, X509Certificate[]> privCred3 = EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), "notexist", "password".toCharArray(), false, "jUnit test");
+ Assert.assertNull("Credential 3", privCred3);
+
+ //read priv. key
+ final Pair<Key, X509Certificate[]> privCred4 = EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), "meta", "wrong".toCharArray(), false, "jUnit test");
+ Assert.assertNull("Credential 3", privCred4);
+
+ try {
+ EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), "meta", "wrong".toCharArray(), true, "jUnit test");
+ Assert.fail("Wrong password not detected");
+
+ } catch (final EaafKeyAccessException e) {
+ Assert.assertEquals("wrong errorcode", "internal.keystore.09", e.getErrorId());
+ }
+
+ try {
+ EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), "wrong", "password".toCharArray(), true, "jUnit test");
+ Assert.fail("Wrong alias not detected");
+
+ } catch (final EaafKeyAccessException e) {
+ Assert.assertEquals("wrong errorcode", "internal.keystore.09", e.getErrorId());
+ }
+
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void softwareKeyStoreSuccessPkcs12() 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.PKCS12);
+ keyStoreConfig.setSoftKeyStoreFilePath(PATH_TO_SOFTWARE_KEYSTORE_PKCS12);
+ keyStoreConfig.setSoftKeyStorePassword(SOFTWARE_KEYSTORE_PASSWORD);
+
+ 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
+ public void hsmFacadeOnlyHostConfig() {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST,
+ RandomStringUtils.randomNumeric(10));
+ try {
+ context.getBean(EaafKeyStoreFactory.class);
+ Assert.fail("Missing HSM Facade not detected");
+
+ } catch (final BeansException e) {
+ checkMissingConfigException(e);
+
+ }
+ }
+
+ @Test
+ public void hsmFacadeMissingPort() {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME,
+ RandomStringUtils.randomAlphanumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD,
+ RandomStringUtils.randomNumeric(10));
+
+ try {
+ context.getBean(EaafKeyStoreFactory.class);
+ Assert.fail("Missing HSM Facade not detected");
+
+ } catch (final BeansException e) {
+ checkMissingConfigException(e);
+
+ }
+ }
+
+ @Test
+ public void hsmFacadeMissingUsername() {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_PORT,
+ RandomStringUtils.randomNumeric(4));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD,
+ RandomStringUtils.randomNumeric(10));
+ try {
+ context.getBean(EaafKeyStoreFactory.class);
+ Assert.fail("Missing HSM Facade not detected");
+
+ } catch (final BeansException e) {
+ checkMissingConfigException(e);
+
+ }
+ }
+
+ @Test
+ public void hsmFacadeMissingPassword() {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_PORT,
+ RandomStringUtils.randomNumeric(4));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME,
+ RandomStringUtils.randomAlphanumeric(10));
+
+ try {
+ context.getBean(EaafKeyStoreFactory.class);
+ Assert.fail("Missing HSM Facade not detected");
+
+ } catch (final BeansException e) {
+ checkMissingConfigException(e);
+
+ }
+ }
+
+ @Test
+ public void hsmFacadeMissingTrustedCertificate() {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_PORT,
+ RandomStringUtils.randomNumeric(4));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD,
+ RandomStringUtils.randomAlphanumeric(10));
+
+ try {
+ context.getBean(EaafKeyStoreFactory.class);
+ Assert.fail("Missing HSM Facade not detected");
+
+ } catch (final BeansException e) {
+ checkMissingConfigException(e);
+
+ }
+ }
+
+ @Test
+ public void hsmFacadeMissingTrustedCertificateFile() {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_PORT,
+ RandomStringUtils.randomNumeric(4));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD,
+ RandomStringUtils.randomAlphanumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_SSLTRUST,
+ "src/test/resources/data/notexist.crt");
+
+ try {
+ context.getBean(EaafKeyStoreFactory.class);
+ Assert.fail("Missing HSM Facade not detected");
+
+ } catch (final BeansException e) {
+ checkMissingConfigException(e, "internal.keystore.05");
+
+ }
+ }
+
+ @Test
+ public void hsmFacadeMissingWrongTrustedCertificate() {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_PORT,
+ RandomStringUtils.randomNumeric(4));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD,
+ RandomStringUtils.randomAlphanumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_SSLTRUST,
+ "src/test/resources/spring/test_eaaf_pvp_lazy.beans.xml");
+
+ try {
+ context.getBean(EaafKeyStoreFactory.class);
+ Assert.fail("Missing HSM Facade not detected");
+
+ } catch (final BeansException e) {
+ checkMissingConfigException(e, "internal.keystore.05");
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void hsmFacadeInitialized() {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_PORT,
+ RandomStringUtils.randomNumeric(4));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME,
+ RandomStringUtils.randomNumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD,
+ RandomStringUtils.randomAlphanumeric(10));
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_SSLTRUST,
+ PATH_TO_HSM_FACADE_TRUST_CERT);
+
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertTrue("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void hsmFacadeKeyStoreNoKeyStoreName() {
+ configureHsmFacade();
+
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertTrue("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.HSMFACADE);
+
+ try {
+ keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafException e) {
+ org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class, e, "Wong ExceptionType");
+ Assert.assertEquals("wrong errorCode", "internal.keystore.06", e.getErrorId());
+ }
+
+ }
+
+ @Test
+ @DirtiesContext
+ public void hsmFacadeKeyStoreSuccess() throws EaafException {
+ configureHsmFacade();
+
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertTrue("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.HSMFACADE);
+ keyStoreConfig.setKeyStoreName("authhandler");
+
+ keyStoreConfig.validate();
+
+ try {
+ final Pair<KeyStore, Provider> keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.assertNotNull("KeyStore is null", keyStore);
+ Assert.assertNotNull("KeyStore is null", keyStore.getFirst());
+ Assert.assertNotNull("KeyStore is null", keyStore.getSecond());
+
+ } catch (final StatusRuntimeException e) {
+ // because there is no mockup of HSM facade available
+ // Assert.assertTrue("Wrong exception", e.getMessage().contains("io
+ // exception"));
+
+ }
+ }
+
+ @Test
+ @DirtiesContext
+ public void hsmFacadeKeyStoreSuccessASitTestFacade() throws EaafException, KeyStoreException {
+ configureHsmFacade();
+
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertTrue("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration();
+ keyStoreConfig.setKeyStoreType(KeyStoreType.HSMFACADE);
+ keyStoreConfig.setKeyStoreName("authhandler");
+
+ keyStoreConfig.validate();
+
+ final Pair<KeyStore, Provider> keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig);
+ Assert.assertNotNull("KeyStore is null", keyStore);
+ Assert.assertNotNull("KeyStore is null", keyStore.getFirst());
+ Assert.assertNotNull("KeyStore is null", keyStore.getSecond());
+
+ //read trusted certs
+ final List<X509Certificate> trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore(
+ keyStore.getFirst());
+ Assert.assertNotNull("Trusted certs", trustedCerts);
+ Assert.assertEquals("Trusted certs size", 0, trustedCerts.size());
+
+ //read priv. key
+ final Pair<Key, X509Certificate[]> privCred1 = EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), HSM_FACADE_KEY_ALIAS, null, true, "jUnit test");
+ Assert.assertNotNull("Credential 1", privCred1);
+ Assert.assertNotNull("Credential 1 priv. key", privCred1.getFirst());
+ Assert.assertNotNull("Credential 1 certificate", privCred1.getSecond());
+
+ //read priv. key
+ final Pair<Key, X509Certificate[]> privCred2 = EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), HSM_FACADE_KEY_ALIAS, "shouldBeIgnord".toCharArray(), true, "jUnit test");
+ Assert.assertNotNull("Credential 2", privCred2);
+ Assert.assertNotNull("Credential 2 priv. key", privCred2.getFirst());
+ Assert.assertNotNull("Credential 2 certificate", privCred2.getSecond());
+
+ try {
+ EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), "notExist", "wrong".toCharArray(), true, "jUnit test");
+ Assert.fail("Wrong password not detected");
+
+ } catch (final EaafKeyAccessException e) {
+ Assert.assertEquals("wrong errorcode", "internal.keystore.09", e.getErrorId());
+ }
+
+ }
+
+ private void configureHsmFacade() {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST, HSM_FACASE_HOST);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_PORT, HSM_FACASE_PORT);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_SSLTRUST, HSM_FACASE_SSL_TRUST);
+
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME, HSM_FACASE_USERNAME);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD, HSM_FACASE_PASSWORD);
+
+ }
+
+ private void checkMissingConfigException(Exception e) {
+ checkMissingConfigException(e, "internal.keystore.04");
+
+ }
+
+ private void checkMissingConfigException(Exception e, String errorCode) {
+ final Optional<Throwable> eaafException = FluentIterable.from(
+ Throwables.getCausalChain(e)).filter(
+ Predicates.instanceOf(EaafConfigurationException.class)).first();
+ Assert.assertTrue("Wrong exception", eaafException.isPresent());
+ Assert.assertEquals("Wrong errorCode",
+ errorCode, ((EaafException) eaafException.get()).getErrorId());
+
+ }
+
+}
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyStoreConfigurationTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyStoreConfigurationTest.java
new file mode 100644
index 00000000..8cb81107
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyStoreConfigurationTest.java
@@ -0,0 +1,190 @@
+package at.gv.egiz.eaaf.core.test.credentials;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType;
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class KeyStoreConfigurationTest {
+
+ private Map<String, String> config;
+
+ @Before
+ public void testSetup() {
+ config = new HashMap<>();
+
+ }
+
+ @Test
+ public void emptyConfigMap() {
+ try {
+ KeyStoreConfiguration.buildFromConfigurationMap(config, "jUnitTest");
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafConfigurationException e) {
+ Assert.assertEquals("wrong errorCode", "internal.keystore.04", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void emptyKeyStoreType() {
+ try {
+ config.put("keystore.type", "");
+
+ KeyStoreConfiguration.buildFromConfigurationMap(config, "jUnitTest");
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafConfigurationException e) {
+ Assert.assertEquals("wrong errorCode", "internal.keystore.04", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void unknownKeyStoreType() {
+ try {
+ config.put("keystore.type", "test");
+
+ KeyStoreConfiguration.buildFromConfigurationMap(config, "jUnitTest");
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafConfigurationException e) {
+ Assert.assertEquals("wrong errorCode", "internal.keystore.01", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void pkcs11KeyStoreType() throws EaafConfigurationException {
+ config.put("keystore.type", "pkcs11");
+ try {
+ final KeyStoreConfiguration keyStoreConfig = KeyStoreConfiguration.buildFromConfigurationMap(config,
+ "jUnitTest");
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafConfigurationException e) {
+ Assert.assertEquals("wrong errorCode", "internal.keystore.02", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void hsmFacadeKeyStoreTypeMissingName() {
+ try {
+ config.put("keystore.type", "hsmfacade");
+
+ KeyStoreConfiguration.buildFromConfigurationMap(config, "jUnitTest");
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafConfigurationException e) {
+ Assert.assertEquals("wrong errorCode", "internal.keystore.04", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void hsmFacadeKeyStoreTypeSucces() throws EaafConfigurationException {
+ final String keyStoreName = RandomStringUtils.randomAlphabetic(5);
+ config.put("keystore.type", "hsmfacade");
+ config.put("keystore.name", keyStoreName);
+
+ final KeyStoreConfiguration keyStoreConfig = KeyStoreConfiguration.buildFromConfigurationMap(config,
+ "jUnitTest");
+
+ Assert.assertNotNull("KeyStore config object", keyStoreConfig);
+ Assert.assertEquals("Wrong Type", KeyStoreType.HSMFACADE, keyStoreConfig.getKeyStoreType());
+ Assert.assertEquals("Wrong KeyStoreName", keyStoreName, keyStoreConfig.getKeyStoreName());
+
+ }
+
+ @Test
+ public void softwareKeyStoreTypeMissingPath() {
+ try {
+ final String keyStorePass = RandomStringUtils.randomAlphabetic(5);
+ config.put("keystore.type", "software");
+ config.put("keystore.password", keyStorePass);
+ config.put("keystore.type", "jks");
+
+ KeyStoreConfiguration.buildFromConfigurationMap(config, "jUnitTest");
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafConfigurationException e) {
+ Assert.assertEquals("wrong errorCode", "internal.keystore.04", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void softwareKeyStoreTypeMissingPassword() {
+ try {
+ final String keyStorePath = RandomStringUtils.randomAlphabetic(5);
+ config.put("keystore.type", "software");
+ config.put("keystore.software.path", keyStorePath);
+ config.put("keystore.type", "jks");
+
+ KeyStoreConfiguration.buildFromConfigurationMap(config, "jUnitTest");
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafConfigurationException e) {
+ Assert.assertEquals("wrong errorCode", "internal.keystore.04", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void softwareKeyStoreTypeUnknownType() {
+ try {
+ final String keyStorePath = RandomStringUtils.randomAlphabetic(5);
+ final String keyStorePass = RandomStringUtils.randomAlphabetic(5);
+ config.put("keystore.path", keyStorePath);
+ config.put("keystore.password", keyStorePass);
+ config.put("keystore.type", RandomStringUtils.randomAlphabetic(4));
+
+ KeyStoreConfiguration.buildFromConfigurationMap(config, "jUnitTest");
+ Assert.fail("Wrong config not detected");
+
+ } catch (final EaafConfigurationException e) {
+ Assert.assertEquals("wrong errorCode", "internal.keystore.01", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void softwareKeyStoreTypeSuccesJks() throws EaafConfigurationException {
+ final String keyStorePath = RandomStringUtils.randomAlphabetic(5);
+ final String keyStorePass = RandomStringUtils.randomAlphabetic(5);
+ config.put("keystore.type", "jks");
+ config.put("keystore.path", keyStorePath);
+ config.put("keystore.password", keyStorePass);
+
+ final KeyStoreConfiguration keyStoreConfig = KeyStoreConfiguration.buildFromConfigurationMap(config,
+ "jUnitTest");
+
+ Assert.assertNotNull("KeyStore config object", keyStoreConfig);
+ Assert.assertEquals("Wrong Type", KeyStoreType.JKS, keyStoreConfig.getKeyStoreType());
+ Assert.assertEquals("Wrong KeyStoreName", keyStorePath, keyStoreConfig.getSoftKeyStoreFilePath());
+ Assert.assertEquals("Wrong KeyStoreName", keyStorePass, keyStoreConfig.getSoftKeyStorePassword());
+
+ }
+
+ @Test
+ public void softwareKeyStoreTypeSuccesPkcs12() throws EaafConfigurationException {
+ final String keyStorePath = RandomStringUtils.randomAlphabetic(5);
+ final String keyStorePass = RandomStringUtils.randomAlphabetic(5);
+ config.put("keystore.type", "pkcs12");
+ config.put("keystore.path", keyStorePath);
+ config.put("keystore.password", keyStorePass);
+
+ final KeyStoreConfiguration keyStoreConfig = KeyStoreConfiguration.buildFromConfigurationMap(config,
+ "jUnitTest");
+
+ Assert.assertNotNull("KeyStore config object", keyStoreConfig);
+ Assert.assertEquals("Wrong Type", KeyStoreType.PKCS12, keyStoreConfig.getKeyStoreType());
+ Assert.assertEquals("Wrong KeyStoreName", keyStorePath, keyStoreConfig.getSoftKeyStoreFilePath());
+ Assert.assertEquals("Wrong KeyStoreName", keyStorePass, keyStoreConfig.getSoftKeyStorePassword());
+
+ }
+}
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/dummy/DummyAuthConfigMap.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/dummy/DummyAuthConfigMap.java
new file mode 100644
index 00000000..bf1dfd03
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/dummy/DummyAuthConfigMap.java
@@ -0,0 +1,142 @@
+package at.gv.egiz.eaaf.core.test.dummy;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+
+/**
+ * Dummy Application-configuration implementation for jUnit tests.
+ *
+ * @author tlenz
+ *
+ */
+public class DummyAuthConfigMap implements IConfigurationWithSP {
+
+ private Map<String, String> config = new HashMap<>();
+
+ /**
+ * Creates an emptry configuration.
+ *
+ */
+ public DummyAuthConfigMap() {
+
+ }
+
+ /**
+ * Dummy Application-configuration.
+ *
+ * @param configIs Property based configuration
+ * @throws IOException In case of an configuration read error
+ */
+ public DummyAuthConfigMap(final InputStream configIs) throws IOException {
+
+ final Properties props = new Properties();
+ props.load(configIs);
+
+ config = KeyValueUtils.convertPropertiesToMap(props);
+
+ }
+
+ /**
+ * Dummy Application-configuration.
+ *
+ * @param path Path to property based configuration
+ * @throws IOException In case of an configuration read error
+ */
+ public DummyAuthConfigMap(final String path) throws IOException {
+
+ final Properties props = new Properties();
+ props.load(this.getClass().getResourceAsStream(path));
+
+ config = KeyValueUtils.convertPropertiesToMap(props);
+
+ }
+
+ @Override
+ public String getBasicConfiguration(final String key) {
+ return config.get(key);
+
+ }
+
+ @Override
+ public String getBasicConfiguration(final String key, final String defaultValue) {
+ final String value = getBasicConfiguration(key);
+ if (StringUtils.isEmpty(value)) {
+ return defaultValue;
+ } else {
+ return value;
+ }
+
+ }
+
+ @Override
+ public boolean getBasicConfigurationBoolean(final String key) {
+ final String value = getBasicConfiguration(key);
+ if (StringUtils.isEmpty(value)) {
+ return false;
+ } else {
+ return Boolean.valueOf(value);
+ }
+ }
+
+ @Override
+ public boolean getBasicConfigurationBoolean(final String key, final boolean defaultValue) {
+ return Boolean.parseBoolean(getBasicConfiguration(key, String.valueOf(defaultValue)));
+
+ }
+
+ @Override
+ public Map<String, String> getBasicConfigurationWithPrefix(final String prefix) {
+ return KeyValueUtils.getSubSetWithPrefix(config, prefix);
+
+ }
+
+ @Override
+ public ISpConfiguration getServiceProviderConfiguration(final String uniqueID)
+ throws EaafConfigurationException {
+ return null;
+ }
+
+ @Override
+ public <T> T getServiceProviderConfiguration(final String spIdentifier, final Class<T> decorator)
+ throws EaafConfigurationException {
+ return null;
+ }
+
+ @Override
+ public URI getConfigurationRootDirectory() {
+ return new java.io.File(".").toURI();
+
+ }
+
+ @Override
+ public String validateIdpUrl(final URL authReqUrl) throws EaafException {
+ return null;
+ }
+
+ public void putConfigValue(final String key, final String value) {
+ config.put(key, value);
+ }
+
+ public void removeConfigValue(final String key) {
+ config.remove(key);
+
+ }
+
+ public void clearAllConfig() {
+ config.clear();
+ }
+
+}
diff --git a/eaaf_core_utils/src/test/resources/data/hsm_facade_trust_root.crt b/eaaf_core_utils/src/test/resources/data/hsm_facade_trust_root.crt
new file mode 100644
index 00000000..01be3821
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/hsm_facade_trust_root.crt
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBdDCCARqgAwIBAgIEXkz1yjAKBggqhkjOPQQDAjARMQ8wDQYDVQQDDAZlY3Jv
+b3QwHhcNMjAwMjE5MDg0NjAyWhcNMjEwMjE4MDg0NjAyWjARMQ8wDQYDVQQDDAZl
+Y3Jvb3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS8yvpVIWbPj4E7Lr87hwQR
+T9DZf9WY5LMV7gF6NKpnJ5JkEql/s7fqBVbrh8aSNo6gmfmSk4VYGhPJ+DCMzzQj
+o2AwXjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFOXafzYpIOlu6BgNU+Ee
+JWuJobgWMB0GA1UdDgQWBBTl2n82KSDpbugYDVPhHiVriaG4FjALBgNVHQ8EBAMC
+AQYwCgYIKoZIzj0EAwIDSAAwRQIgRt/51PKL/bATuLCdib95Ika+h845Jo0G+Sbn
+bzNwJAcCIQCVD1cxEBuUkKaiaLbTiNVsEjvQb6ti0TFbbQUH66jCGA==
+-----END CERTIFICATE-----
diff --git a/eaaf_core_utils/src/test/resources/data/junit.jks b/eaaf_core_utils/src/test/resources/data/junit.jks
new file mode 100644
index 00000000..59e6ad13
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/junit.jks
Binary files differ
diff --git a/eaaf_core_utils/src/test/resources/data/junit_without_trustcerts.jks b/eaaf_core_utils/src/test/resources/data/junit_without_trustcerts.jks
new file mode 100644
index 00000000..b5262cb8
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/junit_without_trustcerts.jks
Binary files differ
diff --git a/eaaf_core_utils/src/test/resources/data/junit_without_trustcerts.p12 b/eaaf_core_utils/src/test/resources/data/junit_without_trustcerts.p12
new file mode 100644
index 00000000..c3fe2681
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/junit_without_trustcerts.p12
Binary files differ
diff --git a/eaaf_core_utils/src/test/resources/data/test.crt b/eaaf_core_utils/src/test/resources/data/test.crt
new file mode 100644
index 00000000..76c18361
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/data/test.crt
@@ -0,0 +1,3 @@
+-----BEGIN CERTIFICATE-----
+MIIEXDCCA0SgAwIBAgIEY4Qn3zANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCQVQxSDBGBgNVBAoMP0EtVHJ1c3QgR2VzLiBmLiBTaWNoZXJoZWl0c3N5c3RlbWUgaW0gZWxla3RyLiBEYXRlbnZlcmtlaHIgR21iSDEmMCQGA1UECwwdYS1zaWduLVRlc3QtUHJlbWl1bS1Nb2JpbGUtMDUxJjAkBgNVBAMMHWEtc2lnbi1UZXN0LVByZW1pdW0tTW9iaWxlLTA1MB4XDTE5MTIxMzEzNDg0N1oXDTI0MTIxMzEzNDg0N1owYDELMAkGA1UEBhMCQVQxFzAVBgNVBAMMDk1heCBNdXN0ZXJtYW5uMRMwEQYDVQQEDApNdXN0ZXJtYW5uMQwwCgYDVQQqDANNYXgxFTATBgNVBAUTDDgxNjkyMjY1ODM0ODBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAUAVvbow4O/DMA5ZZoPHQXe0rtf86lvH8GLM/Crz1vvRYyQ5D4ESYRFy+s3zHdLqhE4l8I95i9jz2qTvof46mqjggGfMIIBmzCBggYIKwYBBQUHAQEEdjB0MEkGCCsGAQUFBzAChj1odHRwOi8vd3d3LmEtdHJ1c3QuYXQvY2VydHMvYS1zaWduLXRlc3QtcHJlbWl1bS1tb2JpbGUtMDUuY3J0MCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5hLXRydXN0LmF0L29jc3AwEwYDVR0jBAwwCoAITuhoD/7N29AwEQYDVR0OBAoECEyqhgBwLul2MA4GA1UdDwEB/wQEAwIGwDAJBgNVHRMEAjAAMIGGBgNVHSAEfzB9MHsGBiooABEBBDBxMDgGCCsGAQUFBwICMCwaKkRpZXNlcyBaZXJ0aWZpa2F0IGRpZW50IG51ciB6dSBUZXN0endlY2tlbjA1BggrBgEFBQcCARYpaHR0cDovL3d3dy5hLXRydXN0LmF0L2RvY3MvY3AvYS1zaWduLVRFU1QwSAYDVR0fBEEwPzA9oDugOYY3aHR0cDovL2NybC5hLXRydXN0LmF0L2NybC9hLXNpZ24tdGVzdC1wcmVtaXVtLW1vYmlsZS0wNTANBgkqhkiG9w0BAQsFAAOCAQEATD4ZnrEV+xeT7PFI/idqHdElLZ1BVUO9G9qfQQn4oKNCWWHxMo/ZXSlvsOtTjFezCQFkcFO1eJtXNHCyqfr69jorzhZcicscNRMrDlJoB/sJr0l/Ekjlt/dgRaTuZ7NzWE/oTefI3M3xkkLd0ydAMrhrZx+9f82VE3k63I1fmT90kQ8PfDzAMMRmlwbZDA+2TB8iF7SQkOOL6H1j2L9qrhjlG2ekU4cyx6KMkRjLLbr1JVgS07qOzUkeQPR2KTJcWWR+/NQZWDKdOz97eVOulxeI+Y3y96arraGM7lIbV9ZrpkbUn/IxQ9TQTE5X02EipgnZdR7bZrwJ7hJ27vwnfQ==
+-----END CERTIFICATE-----
diff --git a/eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_lazy.beans.xml b/eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_lazy.beans.xml
new file mode 100644
index 00000000..210b88be
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_lazy.beans.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
+ default-lazy-init="true">
+
+ <bean id="dummyAuthConfigMap"
+ class="at.gv.egiz.eaaf.core.test.dummy.DummyAuthConfigMap" />
+
+ <bean id="eaafKeyStoreFactory"
+ class="at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory" />
+
+ <bean id="eaafUtilsMessageSource"
+ class="at.gv.egiz.eaaf.core.impl.logging.EaafUtilsMessageSource" />
+
+</beans> \ No newline at end of file
diff --git a/eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_not_lazy.beans.xml b/eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_not_lazy.beans.xml
new file mode 100644
index 00000000..402e07f9
--- /dev/null
+++ b/eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_not_lazy.beans.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
+ default-lazy-init="true">
+
+ <bean id="dummyAuthConfigMap"
+ class="at.gv.egiz.eaaf.core.test.dummy.DummyAuthConfigMap" />
+
+ <import resource="classpath:/spring/eaaf_utils.beans.xml"/>
+
+</beans> \ No newline at end of file