summaryrefslogtreecommitdiff
path: root/eaaf_core_utils
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_core_utils')
-rw-r--r--eaaf_core_utils/checks/spotbugs-exclude.xml7
-rw-r--r--eaaf_core_utils/pom.xml2
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/builder/BpkBuilder.java446
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java44
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/X509Utils.java15
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/impl/utils/test/KeyValueUtilsTest.java3
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/builder/BpkBuilderTest.java489
7 files changed, 976 insertions, 30 deletions
diff --git a/eaaf_core_utils/checks/spotbugs-exclude.xml b/eaaf_core_utils/checks/spotbugs-exclude.xml
index b42f34c2..c1271f91 100644
--- a/eaaf_core_utils/checks/spotbugs-exclude.xml
+++ b/eaaf_core_utils/checks/spotbugs-exclude.xml
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<Match>
+ <!-- bPK requires SHA1 from specification -->
+ <Class name="at.gv.egiz.eaaf.core.impl.builder.BpkBuilder" />
+ <OR>
+ <Bug pattern="WEAK_MESSAGE_DIGEST_SHA1" />
+ </OR>
+ </Match>
+ <Match>
<Class name="at.gv.egiz.eaaf.core.impl.utils.EaafSerializationUtils" />
<OR>
<Bug pattern="OBJECT_DESERIALIZATION" />
diff --git a/eaaf_core_utils/pom.xml b/eaaf_core_utils/pom.xml
index 7e155680..4e3bbeee 100644
--- a/eaaf_core_utils/pom.xml
+++ b/eaaf_core_utils/pom.xml
@@ -7,7 +7,7 @@
<parent>
<groupId>at.gv.egiz</groupId>
<artifactId>eaaf</artifactId>
- <version>1.1.12-SNAPSHOT</version>
+ <version>1.1.13-SNAPSHOT</version>
</parent>
<groupId>at.gv.egiz.eaaf</groupId>
<artifactId>eaaf_core_utils</artifactId>
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/builder/BpkBuilder.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/builder/BpkBuilder.java
new file mode 100644
index 00000000..903aa300
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/builder/BpkBuilder.java
@@ -0,0 +1,446 @@
+/*
+ * 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.builder;
+
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map.Entry;
+
+import javax.annotation.Nonnull;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.lang.Nullable;
+import org.springframework.util.Assert;
+import org.springframework.util.Base64Utils;
+
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import lombok.extern.slf4j.Slf4j;
+
+
+/**
+ * Builder for the bPK, as defined in
+ * <code>&quot;Ableitung f&uml;r die bereichsspezifische Personenkennzeichnung&quot;</code>
+ * version <code>1.0.1</code> from
+ * <code>&quot;reference.e-government.gv.at&quot;</code>.
+ *
+ */
+@Slf4j
+public class BpkBuilder {
+
+ private static final String ERROR_CODE_33 = "builder.33";
+
+ private static final String ERROR_MSG_WRONG_TARGET_FORMAT = "bPK-target format must be full URI";
+
+
+ /**
+ * Calculates an area specific unique person-identifier from a baseID.
+ *
+ * @param baseID baseId from user but never null
+ * @param targetIdentifier target identifier for area specific identifier
+ * calculation but never null
+ * @return Pair consists of (unique person identifier for this target,
+ * targetArea) but never null
+ * @throws EaafBuilderException if some input data are not valid
+ */
+ public static Pair<String, String> generateAreaSpecificPersonIdentifier(final String baseID,
+ final String targetIdentifier) throws EaafBuilderException {
+ return generateAreaSpecificPersonIdentifier(baseID, EaafConstants.URN_PREFIX_BASEID,
+ targetIdentifier);
+
+ }
+
+ /**
+ * Calculates an area specific unique person-identifier from an unique
+ * identifier with a specific type.
+ *
+ * @param baseID baseId from user but never null
+ * @param baseIdType Type of the baseID but never null
+ * @param targetIdentifier target identifier for area specific identifier
+ * calculation but never null
+ * @return Pair consists of (unique person identifier for this target,
+ * targetArea) but never null
+ * @throws EaafBuilderException if some input data are not valid
+ */
+ public static Pair<String, String> generateAreaSpecificPersonIdentifier(final String baseID,
+ final String baseIdType, final String targetIdentifier) throws EaafBuilderException {
+ if (StringUtils.isEmpty(baseID)) {
+ throw new EaafBuilderException(ERROR_CODE_33, new Object[] { "baseID is empty or null" },
+ "BaseId is empty or null");
+ }
+
+ if (StringUtils.isEmpty(baseIdType)) {
+ throw new EaafBuilderException(ERROR_CODE_33,
+ new Object[] { "the type of baseID is empty or null" }, "Type of baseId is empty or null");
+ }
+
+ if (StringUtils.isEmpty(targetIdentifier)) {
+ throw new EaafBuilderException(ERROR_CODE_33,
+ new Object[] { "SP specific target identifier is empty or null" },
+ "SP specific target identifier is empty or null");
+ }
+
+ if (baseIdType.startsWith(EaafConstants.URN_PREFIX_BASEID)) {
+ log.trace("Find baseID. Starting unique identifier caluclation for this target");
+
+ if (targetIdentifier.startsWith(EaafConstants.URN_PREFIX_CDID)) {
+ log.trace("Calculate bPK identifier for target: " + targetIdentifier);
+ return Pair.newInstance(calculatebPKwbPK(baseID + "+" + targetIdentifier),
+ targetIdentifier);
+
+ } else if (targetIdentifier.startsWith(EaafConstants.URN_PREFIX_WBPK)) {
+ log.trace("Calculate wbPK identifier for target: " + targetIdentifier);
+ String commonBpkTarget = normalizeBpkTargetIdentifierToCommonFormat(targetIdentifier);
+ return Pair.newInstance(calculatebPKwbPK(
+ baseID + "+" + normalizeBpkTargetIdentifierToBpkCalculationFormat(commonBpkTarget)),
+ commonBpkTarget);
+
+ } else if (targetIdentifier.startsWith(EaafConstants.URN_PREFIX_EIDAS)) {
+ log.trace("Calculate eIDAS identifier for target: " + targetIdentifier);
+ final String[] splittedTarget = targetIdentifier.split("\\+");
+ final String cititzenCountryCode = splittedTarget[1];
+ final String eidasOutboundCountry = splittedTarget[2];
+
+ if (cititzenCountryCode.equalsIgnoreCase(eidasOutboundCountry)) {
+ log.warn("Suspect configuration FOUND!!! CitizenCountry equals DestinationCountry");
+
+ }
+ return buildEidasIdentifer(baseID, baseIdType, cititzenCountryCode, eidasOutboundCountry);
+
+ } else {
+ throw new EaafBuilderException(ERROR_CODE_33,
+ new Object[] { "Target identifier: " + targetIdentifier + " is NOT allowed or unknown" },
+ "Target identifier: " + targetIdentifier + " is NOT allowed or unknown");
+ }
+
+ } else {
+ log.trace("BaseID is not of type " + EaafConstants.URN_PREFIX_BASEID
+ + ". Check type against requested target ...");
+ if (baseIdType.equals(targetIdentifier)) {
+ log.debug("Unique identifier is already area specific. Is nothing todo");
+ return Pair.newInstance(baseID, targetIdentifier);
+
+ } else {
+ log.warn("Get unique identifier for target: " + baseIdType + " but target: "
+ + targetIdentifier + " is required!");
+ throw new EaafBuilderException(ERROR_CODE_33,
+ new Object[] { "Get unique identifier for target: " + baseIdType + " but target: "
+ + targetIdentifier + " is required" },
+ "Get unique identifier for target: " + baseIdType + " but target: " + targetIdentifier
+ + " is required");
+
+ }
+ }
+ }
+
+
+
+ /**
+ * Create an encrypted bPK.
+ *
+ * @param bpk unencrypted bPK
+ * @param target bPK target in full form
+ * @param publicKey Public-Key used for encryption
+ * @return encrypted bPK
+ * @throws EaafBuilderException In case of an error
+ */
+ public static String encryptBpk(final String bpk, String target, final PublicKey publicKey)
+ throws EaafBuilderException {
+ final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+
+ if (!target.startsWith(EaafConstants.URN_PREFIX_WITH_COLON)) {
+ throw new EaafBuilderException("builder.32",
+ null, ERROR_MSG_WRONG_TARGET_FORMAT);
+
+ }
+
+ target = normalizeBpkTargetIdentifierToBpkCalculationFormat(
+ normalizeBpkTargetIdentifierToCommonFormat(target));
+
+ final String input =
+ "V1::" + target + "::" + bpk + "::" + sdf.format(new Date());
+ // System.out.println(input);
+ byte[] result;
+ try {
+ final byte[] inputBytes = input.getBytes("ISO-8859-1");
+ result = encrypt(inputBytes, publicKey);
+ return new String(Base64Utils.encode(result), "ISO-8859-1").replaceAll("\r\n", "");
+ // return new String(Base64Utils.encode(result,
+ // "ISO-8859-1")).replaceAll("\r\n", "");
+
+ } catch (final Exception e) {
+ throw new EaafBuilderException("bPK encryption FAILED", null, e.getMessage(), e);
+
+ }
+ }
+
+ /**
+ * Decrypt an encrypted bPK.
+ *
+ * @param encryptedBpk encrypted bPK
+ * @param target bPK target in full form
+ * @param privateKey private-key for decryption
+ * @return bPK Pair consists of (unique person identifier for this target,
+ * targetArea) but never null
+ * @throws EaafBuilderException In case of an error
+ */
+ public static Pair<String, String> decryptBpk(final String encryptedBpk, String target,
+ final PrivateKey privateKey) throws EaafBuilderException {
+ String decryptedString;
+
+ if (!target.startsWith(EaafConstants.URN_PREFIX_WITH_COLON)) {
+ throw new EaafBuilderException("builder.32",
+ null, ERROR_MSG_WRONG_TARGET_FORMAT);
+
+ }
+
+ try {
+ final byte[] encryptedBytes = Base64Utils.decode(encryptedBpk.getBytes("ISO-8859-1"));
+ final byte[] decryptedBytes = decrypt(encryptedBytes, privateKey);
+ decryptedString = new String(decryptedBytes, "ISO-8859-1");
+
+ } catch (final Exception e) {
+ throw new EaafBuilderException("bPK decryption FAILED", null, e.getMessage(), e);
+
+ }
+
+ String[] parts = decryptedString.split("::");
+ if (parts.length != 4) {
+ log.trace("Encrypted bPK has value: {}", decryptedString);
+ throw new EaafBuilderException("builder.31", new Object[] {parts.length},
+ "encBpk has a suspect format");
+
+ }
+
+ final String sector = parts[1];
+ final String bPK = parts[2];
+
+ if (target.equals(normalizeBpkTargetIdentifierToCommonFormat(sector))) {
+ return Pair.newInstance(bPK, target);
+
+ } else {
+ throw new EaafBuilderException("builder.30", new Object[] {sector, target},
+ "Decrypted bPK-target does not match");
+
+ }
+ }
+
+ /**
+ * Normalize wbPK target identifier for FN, ZVR, and ERSB to XFN, XZVR, and XERSB.
+ *
+ * <p>If the target is not of this types the target will be returned as it is</p>
+ * @param targetIdentifier bPK input target
+ * @return XFN, XZVR, XERSB, or targetIdentfier if no normalization is required
+ */
+ @Nullable
+ public static String normalizeBpkTargetIdentifierToCommonFormat(@Nullable String targetIdentifier) {
+ if (targetIdentifier != null
+ && !targetIdentifier.startsWith(EaafConstants.URN_PREFIX_WBPK_TARGET_WITH_X)) {
+ for (Entry<String, String> mapper : EaafConstants.URN_WBPK_TARGET_X_TO_NONE_MAPPER.entrySet()) {
+ if (targetIdentifier.startsWith(mapper.getValue())) {
+ String wbpkTarget = mapper.getKey() + targetIdentifier.substring(mapper.getValue().length());
+ log.trace("Normalize wbPK target: {} to {}", targetIdentifier, wbpkTarget);
+ return wbpkTarget;
+
+ }
+ }
+ }
+
+ return targetIdentifier;
+ }
+
+ /**
+ * Normalize wbPK target identifier for XFN, XZVR, and XERSB to bPK non-X format like, FN, ZVR, and ERSB.
+ *
+ * <p>If the target is not of this types the target will be returned as it is</p>
+ *
+ * @param targetIdentifier bPK input target
+ * @return FN, ZVR, ERSB, or targetIdentfier if no normalization is required
+ */
+ @Nullable
+ public static String normalizeBpkTargetIdentifierToNonXFormat(@Nullable String targetIdentifier) {
+ if (targetIdentifier != null && targetIdentifier.startsWith(EaafConstants.URN_PREFIX_WBPK)) {
+ for (Entry<String, String> mapper : EaafConstants.URN_WBPK_TARGET_X_TO_NONE_MAPPER.entrySet()) {
+ if (targetIdentifier.startsWith(mapper.getKey())) {
+ String wbpkTarget = mapper.getValue() + targetIdentifier.substring(mapper.getKey().length());
+ log.trace("Find new wbPK target: {}. Replace it by: {}", targetIdentifier, wbpkTarget);
+ return wbpkTarget;
+
+ }
+ }
+ }
+
+ return targetIdentifier;
+ }
+
+ /**
+ * Normalize wbPK target identifier for XFN, XZVR, and XERSB to bPK calculation format like, FN, VR, and ERJ.
+ *
+ * <p>If the target is not of this types the target will be returned as it is</p>
+ *
+ * @param targetIdentifier bPK input target
+ * @return FN, VR, ERJ, or targetIdentfier if no normalization is required
+ */
+ @Nullable
+ public static String normalizeBpkTargetIdentifierToBpkCalculationFormat(@Nullable String targetIdentifier) {
+ if (targetIdentifier != null && targetIdentifier.startsWith(EaafConstants.URN_PREFIX_WBPK)) {
+ for (Entry<String, String> mapper : EaafConstants.URN_WBPK_TARGET_X_TO_CALC_TARGET_MAPPER.entrySet()) {
+ if (targetIdentifier.startsWith(mapper.getKey())) {
+ String wbpkTarget = mapper.getValue() + targetIdentifier.substring(mapper.getKey().length());
+ log.trace("Find new wbPK target: {}. Replace it by: {}", targetIdentifier, wbpkTarget);
+ return wbpkTarget;
+
+ }
+ }
+ }
+
+ return targetIdentifier;
+ }
+
+ /**
+ * Remove prefixes from bPK target identifier and get only the SP specific part.
+ *
+ * @param type full qualified bPK target with 'urn:publicid:gv.at:' prefix
+ * @return SP specific part, or full type if reduction is not supported
+ */
+ @Nonnull
+ public static String removeBpkTypePrefix(@Nonnull final String type) {
+ Assert.isTrue(type != null, "bPKType is 'NULL'");
+ if (type.startsWith(EaafConstants.URN_PREFIX_WBPK)) {
+ return type.substring(EaafConstants.URN_PREFIX_WBPK.length());
+
+ } else if (type.startsWith(EaafConstants.URN_PREFIX_CDID)) {
+ return type.substring(EaafConstants.URN_PREFIX_CDID.length());
+
+ } else if (type.startsWith(EaafConstants.URN_PREFIX_EIDAS)) {
+ return type.substring(EaafConstants.URN_PREFIX_EIDAS.length());
+
+ } else {
+ return type;
+
+ }
+ }
+
+ /**
+ * Builds the eIDAS from the given parameters.
+ *
+ * @param baseId baseID of the citizen
+ * @param baseIdType Type of the baseID
+ * @param sourceCountry CountryCode of that country, which build the eIDAs
+ * ID
+ * @param destinationCountry CountryCode of that country, which receives the
+ * eIDAs ID
+ *
+ * @return Pair eIDAs/bPKType in a BASE64 encoding
+ * @throws EaafBuilderException if some input data are not valid
+ */
+ private static Pair<String, String> buildEidasIdentifer(final String baseId,
+ final String baseIdType, final String sourceCountry, final String destinationCountry)
+ throws EaafBuilderException {
+ String bpk = null;
+ String bpkType = null;
+
+ // check if we have been called by public sector application
+ if (baseIdType.startsWith(EaafConstants.URN_PREFIX_BASEID)) {
+ bpkType = EaafConstants.URN_PREFIX_EIDAS + sourceCountry + "+" + destinationCountry;
+ log.debug("Building eIDAS identification from: [identValue]+" + bpkType);
+ bpk = calculatebPKwbPK(baseId + "+" + bpkType);
+
+ } else { // if not, sector identification value is already calculated by BKU
+ log.debug("eIDAS eIdentifier already provided by BKU");
+ bpk = baseId;
+ }
+
+ if (StringUtils.isEmpty(bpk) || StringUtils.isEmpty(sourceCountry)
+ || StringUtils.isEmpty(destinationCountry)) {
+ throw new EaafBuilderException("builder.00",
+ new Object[] { "eIDAS-ID",
+ "Unvollständige Parameterangaben: identificationValue=" + bpk + ", Zielland="
+ + destinationCountry + ", Ursprungsland=" + sourceCountry },
+ "eIDAS-ID: Unvollständige Parameterangaben: identificationValue=" + bpk + ", Zielland="
+ + destinationCountry + ", Ursprungsland=" + sourceCountry);
+ }
+
+ log.trace("eIDAS pseudonym generation finished. ");
+ final String eIdentifier = sourceCountry + "/" + destinationCountry + "/" + bpk;
+
+ return Pair.newInstance(eIdentifier, bpkType);
+ }
+
+ private static String calculatebPKwbPK(final String basisbegriff) throws EaafBuilderException {
+ try {
+ final MessageDigest md = MessageDigest.getInstance("SHA-1");
+ final byte[] hash = md.digest(basisbegriff.getBytes("ISO-8859-1"));
+ final String hashBase64 =
+ new String(Base64Utils.encode(hash), "ISO-8859-1").replaceAll("\r\n", ""); // Base64Utils.encode(hash);
+ return hashBase64;
+
+ } catch (final Exception ex) {
+ throw new EaafBuilderException(ERROR_CODE_33, new Object[] {ex.toString() },
+ ex.getMessage(), ex);
+
+ }
+
+ }
+
+ private static byte[] encrypt(final byte[] inputBytes, final PublicKey publicKey)
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
+ IllegalBlockSizeException, BadPaddingException {
+ byte[] result;
+ Cipher cipher = null;
+ try {
+ cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); // try with bouncycastle
+
+ } catch (final NoSuchAlgorithmException e) {
+ cipher = Cipher.getInstance("RSA/ECB/OAEP"); // try with iaik provider
+ }
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+ result = cipher.doFinal(inputBytes);
+
+ return result;
+ }
+
+ private static byte[] decrypt(final byte[] encryptedBytes, final PrivateKey privateKey)
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
+ IllegalBlockSizeException, BadPaddingException {
+ byte[] result;
+ Cipher cipher = null;
+ try {
+ cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); // try with bouncycastle
+
+ } catch (final NoSuchAlgorithmException e) {
+ cipher = Cipher.getInstance("RSA/ECB/OAEP"); // try with iaik provider
+
+ }
+ cipher.init(Cipher.DECRYPT_MODE, privateKey);
+ result = cipher.doFinal(encryptedBytes);
+ return result;
+
+ }
+}
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 0c5eeb40..b0a91e74 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
@@ -28,13 +28,12 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Utils to operate on Key/Value based configurations.
@@ -43,8 +42,7 @@ import org.slf4j.LoggerFactory;
*
*/
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 = "=";
@@ -154,18 +152,14 @@ public class KeyValueUtils {
* 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;
+ final String prefix) {
+ return keys.entrySet().stream()
+ .filter(el -> StringUtils.isNotEmpty(removePrefixFromKey(el.getKey(), prefix)))
+ .collect(Collectors.toMap(
+ el -> removePrefixFromKey(el.getKey(), prefix),
+ el -> el.getValue()));
+
+
}
/**
@@ -351,19 +345,13 @@ public class KeyValueUtils {
* @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 elements.stream()
+ .filter(el -> el.contains(KEYVVALUEDELIMITER))
+ .map(el -> el.split(KEYVVALUEDELIMITER))
+ .collect(Collectors.toMap(
+ el -> el[0],
+ el -> el[1]));
- return map;
}
/**
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 72c183bf..e2fc4d1b 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
@@ -5,12 +5,26 @@ import java.util.List;
import javax.security.auth.x500.X500Principal;
+import org.springframework.util.CollectionUtils;
+
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 certChain The first element must be the correct one.
+ * @return sorted Certificate Chain
+ */
+ public static List<X509Certificate> sortCertificates(X509Certificate[] certChain) {
+ return sortCertificates(CollectionUtils.arrayToList(certChain));
+
+ }
+
+ /**
+ * 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
*/
@@ -48,4 +62,5 @@ public class X509Utils {
return certs;
}
+
}
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
index 58788392..ca90f05b 100644
--- 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
@@ -153,7 +153,8 @@ public class KeyValueUtilsTest {
+ RandomStringUtils.randomAlphabetic(6) + KeyValueUtils.KEY_DELIMITER
+ RandomStringUtils.randomAlphabetic(5);
final Map<String, String> testMap = generateTestMap(testPrefix, 5, 5);
-
+ testMap.put(testPrefix, RandomStringUtils.randomAlphabetic(10));
+
final Map<String, String> result = KeyValueUtils.removePrefixFromKeys(testMap, testPrefix);
Assert.assertNotNull("Result is null", result);
Assert.assertFalse("Result is empty", result.isEmpty());
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/builder/BpkBuilderTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/builder/BpkBuilderTest.java
new file mode 100644
index 00000000..ccd452c5
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/builder/BpkBuilderTest.java
@@ -0,0 +1,489 @@
+package at.gv.egiz.eaaf.core.test.builder;
+
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+
+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.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException;
+import at.gv.egiz.eaaf.core.impl.builder.BpkBuilder;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class BpkBuilderTest {
+
+ private static final String BASEID = "RUxHQVRlc3RQQjBYWFjFkHpnw7xyX1hYWFTDvHpla8OnaQ==";
+
+ private KeyPair keyPair;
+
+
+ /**
+ * jUnit test initializer.
+ * @throws NoSuchProviderException In case of an error
+ * @throws NoSuchAlgorithmException In case of an error
+ */
+ @Before
+ public void initialize() throws NoSuchAlgorithmException, NoSuchProviderException {
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
+ keyPair = keyGen.generateKeyPair();
+
+ }
+
+ @Test
+ public void encBpkWrongTarget() throws InvalidKeyException {
+ String bpk = RandomStringUtils.randomAlphanumeric(25);
+ String target = RandomStringUtils.randomAlphanumeric(25);
+
+ try {
+ BpkBuilder.encryptBpk(bpk, target, keyPair.getPublic());
+ Assert.fail("Wrong parameters not detected");
+
+ } catch (EaafBuilderException e) {
+ Assert.assertEquals("Wrong errorMsg", "builder.32", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ public void decBpkWrongTarget() throws InvalidKeyException {
+ String bpk = RandomStringUtils.randomAlphanumeric(25);
+ String target = RandomStringUtils.randomAlphanumeric(25);
+
+ try {
+ BpkBuilder.decryptBpk(bpk, target, keyPair.getPrivate());
+ Assert.fail("Wrong parameters not detected");
+
+ } catch (EaafBuilderException e) {
+ Assert.assertEquals("Wrong errorMsg", "builder.32", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ public void decBpkWrongTargetInEncBpk() throws InvalidKeyException, EaafBuilderException {
+ String bpk = RandomStringUtils.randomAlphanumeric(25);
+ String target = EaafConstants.URN_PREFIX_CDID + "AA";
+
+ String encBpk = BpkBuilder.encryptBpk(bpk, target, keyPair.getPublic());
+ try {
+ BpkBuilder.decryptBpk(encBpk,
+ EaafConstants.URN_PREFIX_CDID + "BB", keyPair.getPrivate());
+ Assert.fail("Wrong parameters not detected");
+
+ } catch (EaafBuilderException e) {
+ Assert.assertEquals("Wrong errorMsg", "builder.30", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ public void encBpkSuccess() throws EaafBuilderException, InvalidKeyException {
+ String bpk = RandomStringUtils.randomAlphanumeric(25);
+ String target = EaafConstants.URN_PREFIX_CDID + "AA";
+
+ String encBpk = BpkBuilder.encryptBpk(bpk, target, keyPair.getPublic());
+
+ Assert.assertNotNull("encBpk", encBpk);
+
+ Pair<String, String> decBpk = BpkBuilder.decryptBpk(encBpk, target, keyPair.getPrivate());
+
+ Assert.assertEquals("wrong bBK", bpk, decBpk.getFirst());
+ Assert.assertEquals("wrong bBK-Target", target, decBpk.getSecond());
+
+ }
+
+ @Test
+ public void encWbpkSuccess() throws EaafBuilderException, InvalidKeyException {
+ String bpk = RandomStringUtils.randomAlphanumeric(25);
+ String target = EaafConstants.URN_PREFIX_WBPK + "XFN+123456i";
+
+ String encBpk = BpkBuilder.encryptBpk(bpk, target, keyPair.getPublic());
+
+ Assert.assertNotNull("encBpk", encBpk);
+
+ Pair<String, String> decBpk = BpkBuilder.decryptBpk(encBpk, target, keyPair.getPrivate());
+
+ Assert.assertEquals("wrong bBK", bpk, decBpk.getFirst());
+ Assert.assertEquals("wrong bBK-Target", target, decBpk.getSecond());
+
+ }
+
+ @Test
+ public void encWbpkSuccessSecond() throws EaafBuilderException, InvalidKeyException {
+ String bpk = RandomStringUtils.randomAlphanumeric(25);
+ String target = EaafConstants.URN_PREFIX_WBPK + "FN+123456i";
+
+ String encBpk = BpkBuilder.encryptBpk(bpk, target, keyPair.getPublic());
+
+ Assert.assertNotNull("encBpk", encBpk);
+
+ Pair<String, String> decBpk = BpkBuilder.decryptBpk(encBpk,
+ EaafConstants.URN_PREFIX_WBPK + "XFN+123456i", keyPair.getPrivate());
+
+ Assert.assertEquals("wrong bBK", bpk, decBpk.getFirst());
+ Assert.assertEquals("wrong bBK-Target",
+ EaafConstants.URN_PREFIX_WBPK + "XFN+123456i", decBpk.getSecond());
+
+ }
+
+
+ @Test
+ public void noBaseId() {
+ try {
+ BpkBuilder.generateAreaSpecificPersonIdentifier(null, EaafConstants.URN_PREFIX_CDID + "AA");
+
+ } catch (EaafBuilderException e) {
+ Assert.assertEquals("Wrong errorCode", "builder.33", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void noTarget() {
+ try {
+ BpkBuilder.generateAreaSpecificPersonIdentifier(BASEID, null);
+
+ } catch (EaafBuilderException e) {
+ Assert.assertEquals("Wrong errorCode", "builder.33", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void noBaseIdType() {
+ try {
+ BpkBuilder.generateAreaSpecificPersonIdentifier(BASEID,
+ null, EaafConstants.URN_PREFIX_CDID + "AA");
+
+ } catch (EaafBuilderException e) {
+ Assert.assertEquals("Wrong errorCode", "builder.33", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void wrongBaseIdType() {
+ try {
+ BpkBuilder.generateAreaSpecificPersonIdentifier(BASEID,
+ EaafConstants.URN_PREFIX_CDID + "BB", EaafConstants.URN_PREFIX_CDID + "AA");
+
+ } catch (EaafBuilderException e) {
+ Assert.assertEquals("Wrong errorCode", "builder.33", e.getErrorId());
+ }
+ }
+
+ @Test
+ public void baseIdTypeEqualsTarget() throws EaafBuilderException {
+ Pair<String, String> result1 = BpkBuilder.generateAreaSpecificPersonIdentifier(BASEID,
+ EaafConstants.URN_PREFIX_CDID + "AA", EaafConstants.URN_PREFIX_CDID + "AA");
+
+ Assert.assertEquals("first bPK", BASEID,
+ result1.getFirst());
+ Assert.assertEquals("first bPK", "urn:publicid:gv.at:cdid+AA",
+ result1.getSecond());
+
+ }
+
+ @Test
+ public void buildBpk() throws EaafBuilderException {
+
+ Pair<String, String> result1 = BpkBuilder.generateAreaSpecificPersonIdentifier(
+ BASEID, EaafConstants.URN_PREFIX_CDID + "AA");
+ Pair<String, String> result2 = BpkBuilder.generateAreaSpecificPersonIdentifier(
+ BASEID, EaafConstants.URN_PREFIX_CDID + "BB");
+
+ Assert.assertEquals("first bPK", "b1Ip610zZq/Or/uCqgb51lnAdZM=",
+ result1.getFirst());
+ Assert.assertEquals("first bPK", "urn:publicid:gv.at:cdid+AA",
+ result1.getSecond());
+
+ Assert.assertEquals("second bPK", "uYst6hjKJvyp7s/ezD8zsnkcj9k=",
+ result2.getFirst());
+ Assert.assertEquals("second bPK", "urn:publicid:gv.at:cdid+BB",
+ result2.getSecond());
+
+ }
+
+ @Test
+ public void buildWbpkFn() throws EaafBuilderException {
+
+ Pair<String, String> result1 = BpkBuilder.generateAreaSpecificPersonIdentifier(
+ BASEID, EaafConstants.URN_PREFIX_WBPK + "FN+123456i");
+
+ Assert.assertEquals("wbPK", "k65HRxpVcoZ2OPZHo3j2LEn/JQE=",
+ result1.getFirst());
+ Assert.assertEquals("wbPK", "urn:publicid:gv.at:wbpk+XFN+123456i",
+ result1.getSecond());
+
+ }
+
+ @Test
+ public void buildWbpkZvr() throws EaafBuilderException {
+
+ Pair<String, String> result1 = BpkBuilder.generateAreaSpecificPersonIdentifier(
+ BASEID, EaafConstants.URN_PREFIX_WBPK + "ZVR+123456");
+
+ Assert.assertEquals("wbPK", "1WvaBLiTxcc3kVzfB71Zh2sCtvA=",
+ result1.getFirst());
+ Assert.assertEquals("wbPK", "urn:publicid:gv.at:wbpk+XZVR+123456",
+ result1.getSecond());
+
+ }
+
+ @Test
+ public void buildWbpkErsb() throws EaafBuilderException {
+
+ Pair<String, String> result1 = BpkBuilder.generateAreaSpecificPersonIdentifier(
+ BASEID, EaafConstants.URN_PREFIX_WBPK + "ERSB+123456");
+
+ Assert.assertEquals("wbPK", "xtAWGAiblvhYJiCpUB3dwdRFPpg=",
+ result1.getFirst());
+ Assert.assertEquals("wbPK", "urn:publicid:gv.at:wbpk+XERSB+123456",
+ result1.getSecond());
+
+ }
+
+ @Test
+ public void buildWbpkXFn() throws EaafBuilderException {
+
+ Pair<String, String> result1 = BpkBuilder.generateAreaSpecificPersonIdentifier(
+ BASEID, EaafConstants.URN_PREFIX_WBPK + "XFN+123456i");
+
+ Assert.assertEquals("wbPK", "k65HRxpVcoZ2OPZHo3j2LEn/JQE=",
+ result1.getFirst());
+ Assert.assertEquals("wbPK", "urn:publicid:gv.at:wbpk+XFN+123456i",
+ result1.getSecond());
+
+ }
+
+ @Test
+ public void buildWbpkXZvr() throws EaafBuilderException {
+
+ Pair<String, String> result1 = BpkBuilder.generateAreaSpecificPersonIdentifier(
+ BASEID, EaafConstants.URN_PREFIX_WBPK + "XZVR+123456");
+
+ Assert.assertEquals("wbPK", "1WvaBLiTxcc3kVzfB71Zh2sCtvA=",
+ result1.getFirst());
+ Assert.assertEquals("wbPK", "urn:publicid:gv.at:wbpk+XZVR+123456",
+ result1.getSecond());
+
+ }
+
+ @Test
+ public void buildWbpkXErsb() throws EaafBuilderException {
+
+ Pair<String, String> result1 = BpkBuilder.generateAreaSpecificPersonIdentifier(
+ BASEID, EaafConstants.URN_PREFIX_WBPK + "XERSB+123456");
+
+ Assert.assertEquals("wbPK", "xtAWGAiblvhYJiCpUB3dwdRFPpg=",
+ result1.getFirst());
+ Assert.assertEquals("wbPK", "urn:publicid:gv.at:wbpk+XERSB+123456",
+ result1.getSecond());
+
+ }
+
+ @Test
+ public void buildWbpkOthers() throws EaafBuilderException {
+
+ Pair<String, String> result1 = BpkBuilder.generateAreaSpecificPersonIdentifier(
+ BASEID, EaafConstants.URN_PREFIX_WBPK + "XABC+123456");
+
+ Assert.assertEquals("wbPK", "wv96/xKUyi6YoYGv7IcIlFTsJIk=",
+ result1.getFirst());
+ Assert.assertEquals("wbPK", "urn:publicid:gv.at:wbpk+XABC+123456",
+ result1.getSecond());
+
+ }
+
+ @Test
+ public void buildEidasId() throws EaafBuilderException {
+
+ Pair<String, String> result1 = BpkBuilder.generateAreaSpecificPersonIdentifier(
+ BASEID, EaafConstants.URN_PREFIX_EIDAS + "AT+ES");
+
+ Assert.assertEquals("eidas", "AT/ES/7AuLZNKsiRr97yvLsQ16SZ6r0q0=",
+ result1.getFirst());
+ Assert.assertEquals("wbPK", "urn:publicid:gv.at:eidasid+AT+ES",
+ result1.getSecond());
+
+ }
+
+ @Test
+ public void normalizeNullTarget() {
+ Assert.assertNull("Wrong normalized target",
+ BpkBuilder.normalizeBpkTargetIdentifierToCommonFormat(null));
+
+ }
+
+ @Test
+ public void normalizeBpkTarget() {
+ String target = EaafConstants.URN_PREFIX_CDID + RandomStringUtils.randomAlphabetic(2);
+ Assert.assertEquals("Wrong normalized target",
+ target,
+ BpkBuilder.normalizeBpkTargetIdentifierToCommonFormat(target));
+
+ }
+
+ @Test
+ public void normalizeWbpkTargetWithX() {
+ String target = EaafConstants.URN_PREFIX_WBPK_TARGET_WITH_X + RandomStringUtils.randomAlphabetic(2);
+ Assert.assertEquals("Wrong normalized target",
+ target,
+ BpkBuilder.normalizeBpkTargetIdentifierToCommonFormat(target));
+
+ }
+
+ @Test
+ public void normalizeWbpkTargetWithOutXNoMapping() {
+ String target = EaafConstants.URN_PREFIX_WBPK + RandomStringUtils.randomAlphabetic(2);
+ Assert.assertEquals("Wrong normalized target",
+ target,
+ BpkBuilder.normalizeBpkTargetIdentifierToCommonFormat(target));
+
+ }
+
+ @Test
+ public void normalizeWbpkTargetWithOutXMappingFn() {
+ Assert.assertEquals("Wrong normalized target",
+ EaafConstants.URN_PREFIX_WBPK + "XFN+123456i",
+ BpkBuilder.normalizeBpkTargetIdentifierToCommonFormat(EaafConstants.URN_PREFIX_WBPK + "FN+123456i"));
+
+ }
+
+ @Test
+ public void normalizeWbpkTargetWithOutXMappingZvr() {
+ Assert.assertEquals("Wrong normalized target",
+ EaafConstants.URN_PREFIX_WBPK + "XZVR+1122334455",
+ BpkBuilder.normalizeBpkTargetIdentifierToCommonFormat(EaafConstants.URN_PREFIX_WBPK + "ZVR+1122334455"));
+
+ }
+
+ @Test
+ public void normalizeWbpkTargetWithOutXMappingErsb() {
+ Assert.assertEquals("Wrong normalized target",
+ EaafConstants.URN_PREFIX_WBPK + "XERSB+998877665544",
+ BpkBuilder.normalizeBpkTargetIdentifierToCommonFormat(EaafConstants.URN_PREFIX_WBPK + "ERSB+998877665544"));
+
+ }
+
+ @Test
+ public void normalizeEidasTarget() {
+ String target = EaafConstants.URN_PREFIX_EIDAS + RandomStringUtils.randomAlphabetic(2)
+ + "+" + RandomStringUtils.randomAlphabetic(2);
+ Assert.assertEquals("Wrong normalized target",
+ target,
+ BpkBuilder.normalizeBpkTargetIdentifierToCommonFormat(target));
+
+ }
+
+ @Test
+ public void calcNormalizeNullTarget() {
+ Assert.assertNull("Wrong normalized target",
+ BpkBuilder.normalizeBpkTargetIdentifierToNonXFormat(null));
+
+ }
+
+ @Test
+ public void calcNormalizeBpkTarget() {
+ String target = EaafConstants.URN_PREFIX_CDID + RandomStringUtils.randomAlphabetic(2);
+ Assert.assertEquals("Wrong normalized target",
+ target,
+ BpkBuilder.normalizeBpkTargetIdentifierToNonXFormat(target));
+
+ }
+
+ @Test
+ public void calcNormalizeWbpkTargetWithoutX() {
+
+ Assert.assertEquals("Wrong normalized target",
+ EaafConstants.URN_PREFIX_WBPK + "FN+123456i",
+ BpkBuilder.normalizeBpkTargetIdentifierToNonXFormat(EaafConstants.URN_PREFIX_WBPK + "FN+123456i"));
+
+ }
+
+ @Test
+ public void calcNormalizeWbpkTargetWithOutXNoMapping() {
+ String target = EaafConstants.URN_PREFIX_WBPK + RandomStringUtils.randomAlphabetic(2);
+ Assert.assertEquals("Wrong normalized target",
+ target,
+ BpkBuilder.normalizeBpkTargetIdentifierToNonXFormat(target));
+
+ }
+
+ @Test
+ public void calcNormalizeWbpkTargetWithXMappingFn() {
+ Assert.assertEquals("Wrong normalized target",
+ EaafConstants.URN_PREFIX_WBPK + "FN+123456i",
+ BpkBuilder.normalizeBpkTargetIdentifierToNonXFormat(EaafConstants.URN_PREFIX_WBPK + "XFN+123456i"));
+
+ }
+
+ @Test
+ public void calcNormalizeWbpkTargetWithXMappingZvr() {
+ Assert.assertEquals("Wrong normalized target",
+ EaafConstants.URN_PREFIX_WBPK + "ZVR+1122334455",
+ BpkBuilder.normalizeBpkTargetIdentifierToNonXFormat(EaafConstants.URN_PREFIX_WBPK + "XZVR+1122334455"));
+
+ }
+
+ @Test
+ public void calcNormalizeWbpkTargetWithXMappingErsb() {
+ Assert.assertEquals("Wrong normalized target",
+ EaafConstants.URN_PREFIX_WBPK + "ERSB+998877665544",
+ BpkBuilder.normalizeBpkTargetIdentifierToNonXFormat(
+ EaafConstants.URN_PREFIX_WBPK + "XERSB+998877665544"));
+
+ }
+
+ @Test
+ public void calcNormalizeEidasTarget() {
+ String target = EaafConstants.URN_PREFIX_EIDAS + RandomStringUtils.randomAlphabetic(2)
+ + "+" + RandomStringUtils.randomAlphabetic(2);
+ Assert.assertEquals("Wrong normalized target",
+ target,
+ BpkBuilder.normalizeBpkTargetIdentifierToNonXFormat(target));
+
+ }
+
+ @Test
+ public void removeBpkPrefix() {
+ String spTarget = RandomStringUtils.randomAlphabetic(2);
+ Assert.assertEquals("Wrong SP target without prefix",
+ spTarget,
+ BpkBuilder.removeBpkTypePrefix(EaafConstants.URN_PREFIX_CDID + spTarget));
+
+ }
+
+ @Test
+ public void removeWpbkPrefix() {
+ String spTarget = RandomStringUtils.randomAlphabetic(10);
+ Assert.assertEquals("Wrong SP target without prefix",
+ spTarget,
+ BpkBuilder.removeBpkTypePrefix(EaafConstants.URN_PREFIX_WBPK + spTarget));
+
+ }
+
+ @Test
+ public void removeEidasPbkPrefix() {
+ String spTarget = RandomStringUtils.randomAlphabetic(2) + "+" + RandomStringUtils.randomAlphabetic(2);
+ Assert.assertEquals("Wrong SP target without prefix",
+ spTarget,
+ BpkBuilder.removeBpkTypePrefix(EaafConstants.URN_PREFIX_EIDAS + spTarget));
+
+ }
+
+ @Test
+ public void removeUnknownPbkPrefix() {
+ String spTarget = RandomStringUtils.randomAlphabetic(10);
+ Assert.assertEquals("Wrong SP target without prefix",
+ EaafConstants.URN_PREFIX_BASEID + spTarget,
+ BpkBuilder.removeBpkTypePrefix(EaafConstants.URN_PREFIX_BASEID + spTarget));
+
+ }
+}