diff options
Diffstat (limited to 'eaaf_core_utils')
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>"Ableitung f¨r die bereichsspezifische Personenkennzeichnung"</code> + * version <code>1.0.1</code> from + * <code>"reference.e-government.gv.at"</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)); +     +  } +} | 
