From fc360a112b7e4714edde1ad9bd44f6397b4e7449 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Tue, 31 Mar 2020 17:36:53 +0200 Subject: switch internal wbPK target-identifier for FN, ZVR, and ERSB to XFN, XZVR, and XERSB --- .../core/impl/idp/auth/builder/BpkBuilder.java | 159 ++++++++++++++------- 1 file changed, 108 insertions(+), 51 deletions(-) (limited to 'eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java') diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java index a613bd56..bb8355ad 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java @@ -25,20 +25,22 @@ import java.security.PrivateKey; import java.security.PublicKey; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Map.Entry; +import javax.annotation.Nullable; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; 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 @@ -47,9 +49,9 @@ import at.gv.egiz.eaaf.core.impl.data.Pair; * "reference.e-government.gv.at". * */ +@Slf4j public class BpkBuilder { - private static final Logger log = LoggerFactory.getLogger(BpkBuilder.class); - + /** * Calculates an area specific unique person-identifier from a baseID. * @@ -100,12 +102,17 @@ public class BpkBuilder { if (baseIdType.equals(EaafConstants.URN_PREFIX_BASEID)) { log.trace("Find baseID. Starting unique identifier caluclation for this target"); - if (targetIdentifier.startsWith(EaafConstants.URN_PREFIX_CDID) - || targetIdentifier.startsWith(EaafConstants.URN_PREFIX_WBPK)) { - log.trace("Calculate bPK, wbPK, or STORK identifier for target: " + targetIdentifier); + 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); + return Pair.newInstance(calculatebPKwbPK( + baseID + "+" + normalizeBpkTargetIdentifierToCalculationFormat(targetIdentifier)), + normalizeBpkTargetIdentifierToCommonFormat(targetIdentifier)); + } else if (targetIdentifier.startsWith(EaafConstants.URN_PREFIX_EIDAS)) { log.trace("Calculate eIDAS identifier for target: " + targetIdentifier); final String[] splittedTarget = targetIdentifier.split("\\+"); @@ -144,51 +151,7 @@ public class BpkBuilder { } } - /** - * 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 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); - } /** * Create an encrypted bPK. @@ -264,6 +227,100 @@ public class BpkBuilder { } } + /** + * Normalize wbPK target identifier for FN, ZVR, and ERSB to XFN, XZVR, and XERSB. + * + *

If the target is not of this types the target will be returned as it is

+ * @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 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 calculation format like, FN, ZVR, and ERSB. + * + *

If the target is not of this types the target will be returned as it is

+ * + * @param targetIdentifier bPK input target + * @return FN, ZVR, ERSB, or targetIdentfier if no normalization is required + */ + @Nullable + public static String normalizeBpkTargetIdentifierToCalculationFormat(@Nullable String targetIdentifier) { + if (targetIdentifier != null && targetIdentifier.startsWith(EaafConstants.URN_PREFIX_WBPK)) { + for (Entry 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; + } + + /** + * 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 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"); -- cgit v1.2.3 From bada55e1a4ee92bc05d55950836942ed6c3e97f6 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Wed, 1 Apr 2020 09:05:40 +0200 Subject: fix wrong format in case of encrypted wbPKs --- .../core/impl/idp/auth/builder/BpkBuilder.java | 57 ++++++++++++++-------- 1 file changed, 37 insertions(+), 20 deletions(-) (limited to 'eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java') diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java index bb8355ad..fed4af32 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/BpkBuilder.java @@ -52,6 +52,8 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class BpkBuilder { + 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. * @@ -157,7 +159,7 @@ public class BpkBuilder { * Create an encrypted bPK. * * @param bpk unencrypted bPK - * @param target bPK target + * @param target bPK target in full form * @param publicKey Public-Key used for encryption * @return encrypted bPK * @throws EaafBuilderException In case of an error @@ -165,12 +167,17 @@ public class BpkBuilder { 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_CDID)) { - target = target.substring(EaafConstants.URN_PREFIX_CDID.length()); + + if (!target.startsWith(EaafConstants.URN_PREFIX_WITH_COLON)) { + throw new EaafBuilderException("builder.32", + null, ERROR_MSG_WRONG_TARGET_FORMAT); + } + + target = normalizeBpkTargetIdentifierToCalculationFormat(target); final String input = - "V1::urn:publicid:gv.at:cdid+" + target + "::" + bpk + "::" + sdf.format(new Date()); + "V1::" + target + "::" + bpk + "::" + sdf.format(new Date()); // System.out.println(input); byte[] result; try { @@ -190,17 +197,23 @@ public class BpkBuilder { * Decrypt an encrypted bPK. * * @param encryptedBpk encrypted bPK - * @param target bPK target + * @param target bPK target in full form * @param privateKey private-key for decryption - * @return bPK + * @return bPK Pair consists of (unique person identifier for this target, + * targetArea) but never null * @throws EaafBuilderException In case of an error */ - public static String decryptBpk(final String encryptedBpk, String target, + public static Pair 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 { - // byte[] encryptedBytes = Base64Utils.decode(encryptedBpk, false, - // "ISO-8859-1"); final byte[] encryptedBytes = Base64Utils.decode(encryptedBpk.getBytes("ISO-8859-1")); final byte[] decryptedBytes = decrypt(encryptedBytes, privateKey); decryptedString = new String(decryptedBytes, "ISO-8859-1"); @@ -210,20 +223,24 @@ public class BpkBuilder { } - String tmp = decryptedString.substring(decryptedString.indexOf('+') + 1); - final String sector = tmp.substring(0, tmp.indexOf("::")); - tmp = tmp.substring(tmp.indexOf("::") + 2); - final String bPK = tmp.substring(0, tmp.indexOf("::")); - - if (target.startsWith(EaafConstants.URN_PREFIX_CDID + "+")) { - target = target.substring((EaafConstants.URN_PREFIX_CDID + "+").length()); + 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(sector)) { - return bPK; + if (target.equals(normalizeBpkTargetIdentifierToCommonFormat(sector))) { + return Pair.newInstance(bPK, target); + } else { - log.error("Decrypted bPK does not match to request bPK target."); - return null; + throw new EaafBuilderException("builder.30", new Object[] {sector, target}, + "Decrypted bPK-target does not match"); + } } -- cgit v1.2.3