From 514747e925abddcb320a8433908dbae32dc5049b Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 28 Jun 2019 09:25:09 +0200 Subject: some small updates --- .../gv/egiz/eaaf/core/api/utils/IJsonMapper.java | 32 ++++ .../builder/AbstractAuthenticationDataBuilder.java | 12 +- .../builder/attributes/BPKAttributeBuilder.java | 16 +- .../egiz/eaaf/core/impl/utils/KeyValueUtils.java | 58 +++--- .../core/impl/idp/module/test/TestRequestImpl.java | 11 +- .../gv/egiz/eaaf/core/api/data/EAAFConstants.java | 4 +- .../api/data/ExtendedPVPAttributeDefinitions.java | 12 +- .../core/exceptions/EAAFJsonMapperException.java | 16 ++ .../sl20/AbstractSL20AuthenticationModulImpl.java | 9 +- .../gv/egiz/eaaf/modules/auth/sl20/Constants.java | 9 +- .../gv/egiz/eaaf/modules/auth/sl20/EventCodes.java | 2 + .../tasks/AbstractCreateQualeIDRequestTask.java | 25 +-- .../sl20/tasks/AbstractReceiveQualeIDTask.java | 197 ++++++++++++--------- .../eaaf/modules/auth/sl20/utils/JsonMapper.java | 89 +++++----- .../modules/auth/sl20/utils/JsonSecurityUtils.java | 58 +++--- .../modules/auth/sl20/utils/SL20Constants.java | 27 +-- .../auth/sl20/utils/SL20HttpBindingUtils.java | 35 ++-- .../auth/sl20/utils/SL20JSONBuilderUtils.java | 88 +++++---- 18 files changed, 435 insertions(+), 265 deletions(-) create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java create mode 100644 eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFJsonMapperException.java diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java new file mode 100644 index 00000000..10e6464b --- /dev/null +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/api/utils/IJsonMapper.java @@ -0,0 +1,32 @@ +package at.gv.egiz.eaaf.core.api.utils; + +import java.io.IOException; + +import at.gv.egiz.eaaf.core.exceptions.EAAFJsonMapperException; + +public interface IJsonMapper { + + + /** + * Serialize an object to a JSON string. + * @param value the object to serialize + * @return a JSON string + * @throws JsonProcessingException thrown when an error occurs during serialization + */ + String serialize(Object value) throws EAAFJsonMapperException; + + /** + * Deserialize a JSON string. + * + * @param value the JSON string to deserialize + * @param clazz optional parameter that determines the type of the returned object. If not set, an {@link Object} is returned. + * @return the deserialized JSON string as an object of type {@code clazz} or {@link Object} + * @throws JsonParseException if the JSON string contains invalid content. + * @throws JsonMappingException if the input JSON structure does not match structure expected for result type + * @throws IOException if an I/O problem occurs (e.g. unexpected end-of-input) + */ + Object deserialize(String value, Class clazz) throws EAAFJsonMapperException; + + // Object deserialize(String value, TypeReference clazz) throws EAAFJsonMapperException; + +} \ No newline at end of file diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java index 47b1ecf9..558a9a33 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java @@ -97,7 +97,9 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati Assert.notNull(authData, "AuthData is null"); } - + + } catch ( EAAFAuthenticationException e) { + throw e; } catch (XPathException | DOMException | EAAFException e) { log.warn("Can not build authentication data from auth. process information"); @@ -461,10 +463,8 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati authData.setBPKType(result.getSecond()); } else { - log.warn("Can not build authData, because moaSession include no valid bPK, encrypted bPK or baseID"); - throw new EAAFBuilderException("builder.08", new Object[]{"No valid " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME - + " or " + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME - + " or " + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME}, + log.warn("Can not build authData, because moaSession include no valid bPK, encrypted bPK or sourceID"); + throw new EAAFBuilderException("builder.13", new Object[]{pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()}, "No valid " + PVPAttributeDefinitions.BPK_FRIENDLY_NAME + " or " + PVPAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME + " or " + PVPAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME); @@ -550,7 +550,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati * @return true, if bPK-Type matchs to Service-Provider configuration, otherwise false */ @Deprecated - private boolean matchsReceivedbPKToOnlineApplication(ISPConfiguration oaParam, String bPKType) { + protected boolean matchsReceivedbPKToOnlineApplication(ISPConfiguration oaParam, String bPKType) { return oaParam.getAreaSpecificTargetIdentifier().equals(bPKType); } diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BPKAttributeBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BPKAttributeBuilder.java index 7005c930..714ffc9d 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BPKAttributeBuilder.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/builder/attributes/BPKAttributeBuilder.java @@ -26,9 +26,12 @@ *******************************************************************************/ package at.gv.egiz.eaaf.core.impl.idp.builder.attributes; +import javax.annotation.Nonnull; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.util.Assert; import at.gv.egiz.eaaf.core.api.data.EAAFConstants; import at.gv.egiz.eaaf.core.api.idp.IAttributeGenerator; @@ -44,18 +47,21 @@ public class BPKAttributeBuilder implements IPVPAttributeBuilder { private static final Logger log = LoggerFactory.getLogger(BPKAttributeBuilder.class); public static final String DELIMITER_BPKTYPE_BPK = ":"; + @Override public String getName() { return BPK_NAME; } + @Override public ATT build(ISPConfiguration oaParam, IAuthData authData, IAttributeGenerator g) throws AttributeBuilderException { - String result = getBpkForSP(authData); + final String result = getBpkForSP(authData); log.trace("Authenticate user with bPK/wbPK: " + result); return g.buildStringAttribute(BPK_FRIENDLY_NAME, BPK_NAME, result); } + @Override public ATT buildEmpty(IAttributeGenerator g) { return g.buildEmptyAttribute(BPK_FRIENDLY_NAME, BPK_NAME); } @@ -68,8 +74,8 @@ public class BPKAttributeBuilder implements IPVPAttributeBuilder { * @throws UnavailableAttributeException */ protected String getBpkForSP(IAuthData authData) throws UnavailableAttributeException { - String bpk = attrMaxSize(authData.getBPK()); - String type = removeBpkTypePrefix(authData.getBPKType()); + final String bpk = attrMaxSize(authData.getBPK()); + final String type = removeBpkTypePrefix(authData.getBPKType()); if (StringUtils.isEmpty(bpk)) throw new UnavailableAttributeException(BPK_NAME); @@ -98,7 +104,9 @@ public class BPKAttributeBuilder implements IPVPAttributeBuilder { * @param type * @return */ - protected String removeBpkTypePrefix(String type) { + @Nonnull + protected String removeBpkTypePrefix(@Nonnull String type) { + Assert.isTrue(type != null, "bPKType is 'NULL'"); if (type.startsWith(EAAFConstants.URN_PREFIX_WBPK)) return type.substring((EAAFConstants.URN_PREFIX_WBPK).length()); diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java index f0a082c3..efc47337 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/KeyValueUtils.java @@ -36,6 +36,9 @@ import java.util.Map.Entry; import java.util.Properties; import java.util.Set; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -81,11 +84,11 @@ public class KeyValueUtils { * @return Child key {String} if it exists or null */ public static String getFirstChildAfterPrefix(String key, String prefix) { - String idAfterPrefix = removePrefixFromKey(key, prefix); + final String idAfterPrefix = removePrefixFromKey(key, prefix); if (idAfterPrefix != null) { - int index = idAfterPrefix.indexOf(KEY_DELIMITER); + final int index = idAfterPrefix.indexOf(KEY_DELIMITER); if (index > 0) { - String adding = idAfterPrefix.substring(0, index); + final String adding = idAfterPrefix.substring(0, index); if (!(adding.isEmpty())) { return adding; @@ -108,7 +111,7 @@ public class KeyValueUtils { */ public static String getPrefixFromKey(String key, String suffix) { if (key != null && key.endsWith(suffix)) { - String idPreforeSuffix = key.substring(0, key.length()-suffix.length()); + final String idPreforeSuffix = key.substring(0, key.length()-suffix.length()); if (idPreforeSuffix.endsWith(KEY_DELIMITER)) return idPreforeSuffix.substring(0, idPreforeSuffix.length()-1); else @@ -131,7 +134,7 @@ public class KeyValueUtils { if (key!=null && key.startsWith(prefix)) { String afterPrefix = key.substring(prefix.length()); - int index = afterPrefix.indexOf(KEY_DELIMITER); + final int index = afterPrefix.indexOf(KEY_DELIMITER); if (index == 0) { afterPrefix = afterPrefix.substring(1); @@ -151,11 +154,11 @@ public class KeyValueUtils { * @return {Map} of key/value pairs without prefix in key, but never null */ public static Map removePrefixFromKeys(Map keys, String prefix) { - Map result = new HashMap(); - Iterator> interator = keys.entrySet().iterator(); + final Map result = new HashMap(); + final Iterator> interator = keys.entrySet().iterator(); while(interator.hasNext()) { - Entry el = interator.next(); - String newKey = removePrefixFromKey(el.getKey(), prefix); + final Entry el = interator.next(); + final String newKey = removePrefixFromKey(el.getKey(), prefix); if (StringUtils.isNotEmpty(newKey)) { result.put(newKey, el.getValue()); } @@ -186,10 +189,10 @@ public class KeyValueUtils { * @return {Map} of key/value pairs in which all keys are absolute but never null */ public static Map makeKeysAbsolut(Map input, String prefix, String absolutIdentifier) { - Map result = new HashMap(); - Iterator> interator = input.entrySet().iterator(); + final Map result = new HashMap(); + final Iterator> interator = input.entrySet().iterator(); while(interator.hasNext()) { - Entry el = interator.next(); + final Entry el = interator.next(); if (!el.getKey().startsWith(absolutIdentifier)) { //key is not absolute -> add prefix result.put(prefix @@ -213,7 +216,7 @@ public class KeyValueUtils { */ public static String getParentKey(String key) { if (StringUtils.isNotEmpty(key)) { - int index = key.lastIndexOf(KEY_DELIMITER); + final int index = key.lastIndexOf(KEY_DELIMITER); if (index > 0) { return key.substring(0, index); @@ -232,13 +235,13 @@ public class KeyValueUtils { */ public static int findNextFreeListCounter(String[] input, String listPrefix) { - List counters = new ArrayList(); + final List counters = new ArrayList(); if (input == null || input.length == 0) return 0; else { - for (String key : input) { - String listIndex = getFirstChildAfterPrefix(key, listPrefix); + for (final String key : input) { + final String listIndex = getFirstChildAfterPrefix(key, listPrefix); counters.add(Integer.parseInt(listIndex)); } @@ -259,7 +262,7 @@ public class KeyValueUtils { if (keySet.isEmpty()) return 0; - String[] array = new String[keySet.size()]; + final String[] array = new String[keySet.size()]; keySet.toArray(array); return findNextFreeListCounter(array, listPrefix); } @@ -278,8 +281,8 @@ public class KeyValueUtils { public static String normalizeCSVValueString(String value) { String normalizedCodes = null; if (StringUtils.isNotEmpty(value)) { - String[] codes = value.split(CSV_DELIMITER); - for (String el: codes) { + final String[] codes = value.split(CSV_DELIMITER); + for (final String el: codes) { if (normalizedCodes == null) normalizedCodes = StringUtils.chomp(el.trim()); else @@ -301,7 +304,7 @@ public class KeyValueUtils { */ public static boolean isCSVValueString(String value) { if (StringUtils.isNotEmpty(value)) { - String[] codes = value.split(CSV_DELIMITER); + final String[] codes = value.split(CSV_DELIMITER); if (codes.length >= 2) { if (StringUtils.isNotEmpty(codes[1].trim())) return true; @@ -322,11 +325,12 @@ public class KeyValueUtils { * @param csv CSV encoded input data * @return List of CSV normalized values, but never null */ - public static List getListOfCSVValues(String csv) { - List list = new ArrayList(); + @Nonnull + public static List getListOfCSVValues(@Nullable String csv) { + final List list = new ArrayList(); if (StringUtils.isNotEmpty(csv)) { - String[] values = csv.split(CSV_DELIMITER); - for (String el: values) + final String[] values = csv.split(CSV_DELIMITER); + for (final String el: values) list.add(el.trim()); } @@ -343,10 +347,10 @@ public class KeyValueUtils { * @return Map of Key / Value pairs, but never null */ public static Map convertListToMap(List elements) { - Map map = new HashMap(); - for (String el : elements) { + final Map map = new HashMap(); + for (final String el : elements) { if (el.contains(KEYVVALUEDELIMITER)) { - String[] split = el.split(KEYVVALUEDELIMITER); + final String[] split = el.split(KEYVVALUEDELIMITER); map.put(split[0], split[1]); } else diff --git a/eaaf_core/src/test/java/at/gv/egiz/eaaf/core/impl/idp/module/test/TestRequestImpl.java b/eaaf_core/src/test/java/at/gv/egiz/eaaf/core/impl/idp/module/test/TestRequestImpl.java index 108484f2..25e2d6a1 100644 --- a/eaaf_core/src/test/java/at/gv/egiz/eaaf/core/impl/idp/module/test/TestRequestImpl.java +++ b/eaaf_core/src/test/java/at/gv/egiz/eaaf/core/impl/idp/module/test/TestRequestImpl.java @@ -43,7 +43,8 @@ public class TestRequestImpl implements IRequest { private String processInstanceID = null; private ISPConfiguration spConfig = null; - private Map storage = new HashMap(); + private final Map storage = new HashMap(); + private String transactionId = null; /* (non-Javadoc) * @see at.gv.egovernment.moa.id.moduls.IRequest#requestedModule() @@ -103,8 +104,7 @@ public class TestRequestImpl implements IRequest { */ @Override public String getUniqueTransactionIdentifier() { - // TODO Auto-generated method stub - return null; + return this.transactionId; } /* (non-Javadoc) @@ -298,6 +298,11 @@ public class TestRequestImpl implements IRequest { return null; } + + public void setTransactionId(String transactionId) { + this.transactionId = transactionId; + } + diff --git a/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java b/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java index 0a457825..b29e9843 100644 --- a/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java +++ b/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/api/data/EAAFConstants.java @@ -55,7 +55,9 @@ public class EAAFConstants { public static final String URN_PREFIX_BPK = URN_PREFIX_CDID + "bpk"; public static final String URN_PREFIX_WBPK = URN_PREFIX + ":" + URN_PART_WBPK; public static final String URN_PREFIX_EIDAS = URN_PREFIX + ":" + URN_PART_EIDAS; - + public static final String URN_PREFIX_OW_BPK = URN_PREFIX_CDID + "OW"; + + //Authentication process data_constants public static final String UNIQUESESSIONIDENTIFIER = "eaaf_uniqueSessionIdentifier"; public static final String AUTH_DATA_CREATED = "eaaf_authdata_created"; diff --git a/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/api/data/ExtendedPVPAttributeDefinitions.java b/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/api/data/ExtendedPVPAttributeDefinitions.java index 62242799..d9ab2283 100644 --- a/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/api/data/ExtendedPVPAttributeDefinitions.java +++ b/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/api/data/ExtendedPVPAttributeDefinitions.java @@ -26,23 +26,23 @@ package at.gv.egiz.eaaf.core.api.data; public interface ExtendedPVPAttributeDefinitions extends PVPAttributeDefinitions { - public static final String SP_UNIQUEID_NAME = "http://eid.gv.at/eID/attributes/ServiceProviderUniqueId"; + public static final String SP_UNIQUEID_NAME = "urn:eidgvat:attributes.ServiceProviderUniqueId"; public static final String SP_UNIQUEID_FRIENDLY_NAME = "ServiceProvider-UniqueId"; - public static final String SP_FRIENDLYNAME_NAME = "http://eid.gv.at/eID/attributes/ServiceProviderFriendlyName"; + public static final String SP_FRIENDLYNAME_NAME = "urn:eidgvat:attributes.ServiceProviderFriendlyName"; public static final String SP_FRIENDLYNAME_FRIENDLY_NAME = "ServiceProvider-FriendlyName"; - public static final String SP_COUNTRYCODE_NAME = "http://eid.gv.at/eID/attributes/ServiceProviderCountryCode"; + public static final String SP_COUNTRYCODE_NAME = "urn:eidgvat:attributes.ServiceProviderCountryCode"; public static final String SP_COUNTRYCODE_FRIENDLY_NAME = "ServiceProvider-CountryCode"; - public static final String SP_USESMANDATES_NAME = "http://eid.gv.at/eID/attributes/ServiceProviderMandateProfiles"; + public static final String SP_USESMANDATES_NAME = "urn:eidgvat:attributes.ServiceProviderMandateProfiles"; public static final String SP_USESMANDATES_FRIENDLY_NAME = "ServiceProvider-MandateProfiles"; /* Attributes for E-ID */ - public static final String EID_ENCRYPTED_SOURCEID_NAME = "http://eid.gv.at/eID/attributes/vsz/value"; + public static final String EID_ENCRYPTED_SOURCEID_NAME = "urn:eidgvat:attributes.vsz.value"; public static final String EID_ENCRYPTED_SOURCEID_FRIENDLY_NAME = "vSZ"; - public static final String EID_ENCRYPTED_SOURCEID_TYPE_NAME = "http://eid.gv.at/eID/attributes/vsz/type"; + public static final String EID_ENCRYPTED_SOURCEID_TYPE_NAME = "urn:eidgvat:attributes.vsz.type"; public static final String EID_ENCRYPTED_SOURCEID_TYPE_FRIENDLY_NAME = "vSZ-Type"; diff --git a/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFJsonMapperException.java b/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFJsonMapperException.java new file mode 100644 index 00000000..41431d02 --- /dev/null +++ b/eaaf_core_api/src/main/java/at/gv/egiz/eaaf/core/exceptions/EAAFJsonMapperException.java @@ -0,0 +1,16 @@ +package at.gv.egiz.eaaf.core.exceptions; + +public class EAAFJsonMapperException extends EAAFParserException { + + + private static final long serialVersionUID = 2278865064672630267L; + + public EAAFJsonMapperException(String reason) { + super("parser.03", new Object[] {reason}); + } + + public EAAFJsonMapperException(String reason, Throwable ex) { + super("parser.03", new Object[] {reason}, ex); + } + +} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/AbstractSL20AuthenticationModulImpl.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/AbstractSL20AuthenticationModulImpl.java index f6488626..a5bbf03f 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/AbstractSL20AuthenticationModulImpl.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/AbstractSL20AuthenticationModulImpl.java @@ -70,7 +70,7 @@ public abstract class AbstractSL20AuthenticationModulImpl implements AuthModule log.debug("SL2.0 is enabled for " + spConfig.getUniqueIdentifier()); log.trace(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + ": " + sl20ClientTypeHeader); log.trace(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE + ": " + sl20VDATypeHeader); - return "SL20Authentication"; + return getProcessName(); } else { log.trace("SL2.0 is NOT enabled for " + spConfig.getUniqueIdentifier()); @@ -87,6 +87,13 @@ public abstract class AbstractSL20AuthenticationModulImpl implements AuthModule */ public abstract String getConfigPropertyNameEnableModule(); + /** + * Get the name of this specific SL2.0 process + * + * @return + */ + public abstract String getProcessName(); + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions() */ diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java index 94322084..72781dc7 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java @@ -13,7 +13,8 @@ public class Constants { public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS = CONFIG_PROP_PREFIX + ".security.encryption.alias";; public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD = CONFIG_PROP_PREFIX + ".security.encryption.password"; - public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT = CONFIG_PROP_VDA_ENDPOINT_QUALeID + "default"; + public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT = "default"; + public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT = CONFIG_PROP_VDA_ENDPOINT_QUALeID + CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT; public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_LIST = CONFIG_PROP_VDA_ENDPOINT_QUALeID + "list"; public static final String CONFIG_PROP_SP_LIST = CONFIG_PROP_PREFIX + ".sp.entityIds."; @@ -22,10 +23,12 @@ public class Constants { public static final String CONFIG_PROP_FORCE_EID_ENCRYPTION = CONFIG_PROP_PREFIX + ".security.eID.encryption.required"; public static final String CONFIG_PROP_FORCE_EID_SIGNED_RESULT = CONFIG_PROP_PREFIX + ".security.eID.signed.result.required"; - public static final String CONFIG_PROP_IPC_RETURN_URL = CONFIG_PROP_PREFIX + ".ipc.return.url"; - + public static final String CONFIG_PROP_IPC_RETURN_URL = CONFIG_PROP_PREFIX + ".testing.ipc.return.url"; + public static final String CONFIG_PROP_HTTP_REDIRECT_CODE = CONFIG_PROP_PREFIX + ".testing.redirect.http.code"; + public static final String CONFIG_PROP_HTTP_REDIRECT_CODE_DEFAULT_VALUE = "307"; public static final String CONFIG_PROP_SP_ENABLE_SL20_AUTHENTICATION = "auth.sl20.enabled"; + public static final String CONFIG_PROP_SP_SL20_ENDPOINT_LIST = "auth.sl20.endpoints"; public static final String PENDING_REQ_STORAGE_PREFIX = "SL20_AUTH_"; diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java index 9cc574bd..e19ef5fc 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java @@ -11,4 +11,6 @@ public class EventCodes { public static final int AUTHPROCESS_SL20_SELECTED = 4111; public static final int AUTHPROCESS_SL20_ENDPOINT_URL = 4112; public static final int AUTHPROCESS_SL20_DATAURL_IP = 4113; + + public static final int AUTHPROCESS_SL20_CONSENT_VALID = 4113; } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualeIDRequestTask.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualeIDRequestTask.java index dfcaaf5a..8939e61d 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualeIDRequestTask.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualeIDRequestTask.java @@ -69,6 +69,9 @@ public abstract class AbstractCreateQualeIDRequestTask extends AbstractAuthServl } log.debug("Use {} as VDA end-point", vdaQualeIDUrl) ; + pendingReq.setRawDataToTransaction( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL, + vdaQualeIDUrl); revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_ENDPOINT_URL, vdaQualeIDUrl); //create SL2.0 command for qualified eID @@ -129,7 +132,8 @@ public abstract class AbstractCreateQualeIDRequestTask extends AbstractAuthServl //forward SL2.0 command //TODO: maybe add SL2ClientType Header from execution context - SL20HttpBindingUtils.writeIntoResponse(request, response, sl20Forward, redirectURL); + SL20HttpBindingUtils.writeIntoResponse(request, response, sl20Forward, redirectURL, + Integer.parseInt(authConfig.getBasicConfiguration(Constants.CONFIG_PROP_HTTP_REDIRECT_CODE, Constants.CONFIG_PROP_HTTP_REDIRECT_CODE_DEFAULT_VALUE))); } else if (respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText() .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR)) { @@ -179,11 +183,12 @@ public abstract class AbstractCreateQualeIDRequestTask extends AbstractAuthServl private String extractVDAURLForSpecificOA(ISPConfiguration oaConfig, ExecutionContext executionContext) { - //TODO: fully remove if not required any more - //String spSpecificVDAEndpoints = oaConfig.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_AUTH_SL20_ENDPOINTS); - final String spSpecificVDAEndpoints = null; + //load SP specific config for development and testing purposes + final String spSpecificVDAEndpoints = oaConfig.getConfigurationValue(Constants.CONFIG_PROP_SP_SL20_ENDPOINT_LIST); + //load general configuration final Map endPointMap = authConfig.getBasicConfigurationWithPrefix(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_LIST); + endPointMap.put(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT, authConfig.getBasicConfiguration(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT)); if (StringUtils.isNotEmpty(spSpecificVDAEndpoints)) { endPointMap.putAll(KeyValueUtils.convertListToMap( KeyValueUtils.getListOfCSVValues( @@ -199,15 +204,15 @@ public abstract class AbstractCreateQualeIDRequestTask extends AbstractAuthServl if (StringUtils.isNotEmpty(sl20VDATypeHeader)) { final String vdaURL = endPointMap.get(sl20VDATypeHeader); if (StringUtils.isNotEmpty(vdaURL)) - return vdaURL.trim(); - - else + return vdaURL.trim(); + else log.info("Can NOT find VDA with Id: " + sl20VDATypeHeader + ". Use default VDA"); } - - log.info("NO SP specific VDA endpoint found. Use default VDA"); - return authConfig.getBasicConfiguration(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT); + + + log.info("NO specific VDA endpoint requested or found. Use default VDA"); + return endPointMap.get(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT); } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualeIDTask.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualeIDTask.java index 5abbd543..761c8b24 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualeIDTask.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualeIDTask.java @@ -2,6 +2,7 @@ package at.gv.egiz.eaaf.modules.auth.sl20.tasks; import java.io.IOException; import java.io.StringWriter; +import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -10,6 +11,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.ContentType; import org.jose4j.base64url.Base64Url; import org.slf4j.Logger; @@ -54,7 +56,12 @@ public abstract class AbstractReceiveQualeIDTask extends AbstractAuthServletTask try { log.debug("Receiving SL2.0 response process .... "); - JsonNode sl20ReqObj = null; + JsonNode sl20ReqObj = null; + + //A-Trust does not SET http-header 'SL2ClientType' with value 'native' + //If A-trust sends an error, its maybe FrontChannel on DataURL + boolean aTrustErrorWorkAround = false; + try { //get SL2.0 command or result from HTTP request final Map reqParams = getParameters(request); @@ -88,41 +95,61 @@ public abstract class AbstractReceiveQualeIDTask extends AbstractAuthServletTask } - //validate reqId with inResponseTo - final String sl20ReqId = pendingReq.getRawData(Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, String.class); - final String inRespTo = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_INRESPTO, true); - if (sl20ReqId == null || !sl20ReqId.equals(inRespTo)) { - log.info("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); - throw new SL20SecurityException("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); - } - - - //validate signature - final VerificationResult payLoadContainer = SL20JSONExtractorUtils.extractSL20PayLoad( - sl20ReqObj, joseTools, - authConfig.getBasicConfigurationBoolean(Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)); + //check on errorMessage + final VerificationResult payLoadContainerErrorCheck = SL20JSONExtractorUtils.extractSL20PayLoad(sl20ReqObj, joseTools, false); + if (SL20JSONExtractorUtils.getStringValue( + payLoadContainerErrorCheck.getPayload(), SL20Constants.SL20_COMMAND_CONTAINER_NAME, true) + .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR)) { + log.debug("Find " + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR + " result .... "); + final JsonNode errorResult = SL20JSONExtractorUtils.extractSL20Result(payLoadContainerErrorCheck.getPayload(), joseTools, false); + final String errorCode = SL20JSONExtractorUtils.getStringValue(errorResult, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, true); + final String errorMsg = SL20JSONExtractorUtils.getStringValue(errorResult, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, false); + + log.info("Receiving errorcode: {} with msg: {} from VDA! Stopping auth-process ... "); + aTrustErrorWorkAround = true; + throw new SL20Exception("sl20.08", new Object[] {errorCode, errorMsg}); + + } else { + //Receive no error - To request validation + + //validate reqId with inResponseTo + final String sl20ReqId = pendingReq.getRawData(Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, String.class); + final String inRespTo = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_INRESPTO, true); + if (sl20ReqId == null || !sl20ReqId.equals(inRespTo)) { + log.info("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); + throw new SL20SecurityException("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); + } - if ( (payLoadContainer.isValidSigned() == null || !payLoadContainer.isValidSigned())) { - if (authConfig.getBasicConfigurationBoolean(Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)) { - log.info("SL20 result from VDA was not valid signed"); - throw new SL20SecurityException(new Object[]{"Signature on SL20 result NOT valid."}); - } else { - log.warn("SL20 result from VDA is NOT valid signed, but signatures-verification is DISABLED by configuration!"); - + //validate signature + final VerificationResult payLoadContainer = SL20JSONExtractorUtils.extractSL20PayLoad( + sl20ReqObj, joseTools, + authConfig.getBasicConfigurationBoolean(Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)); + + if ( (payLoadContainer.isValidSigned() == null || !payLoadContainer.isValidSigned())) { + if (authConfig.getBasicConfigurationBoolean(Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)) { + log.info("SL20 result from VDA was not valid signed"); + throw new SL20SecurityException(new Object[]{"Signature on SL20 result NOT valid."}); + + } else { + log.warn("SL20 result from VDA is NOT valid signed, but signatures-verification is DISABLED by configuration!"); + + } } - } + + payLoadContainer.getCertChain(); - payLoadContainer.getCertChain(); - - - //extract payloaf - final JsonNode payLoad = payLoadContainer.getPayload(); - - //handle SL2.0 response payLoad - handleResponsePayLoad(payLoad); - + //extract payloaf + final JsonNode payLoad = payLoadContainer.getPayload(); + + + //handle SL2.0 response payLoad + handleResponsePayLoad(payLoad); + + } } catch (final EAAFAuthenticationException e) { log.warn("SL2.0 processing error:", e); @@ -147,7 +174,7 @@ public abstract class AbstractReceiveQualeIDTask extends AbstractAuthServletTask //write SL2.0 response if (sl20ReqObj != null) - buildResponse(request, response, sl20ReqObj); + buildResponse(request, response, sl20ReqObj, aTrustErrorWorkAround); else buildErrorResponse(request, response, "2000", "General transport Binding error"); @@ -197,59 +224,71 @@ public abstract class AbstractReceiveQualeIDTask extends AbstractAuthServletTask } - private void buildResponse(HttpServletRequest request, HttpServletResponse response, JsonNode sl20ReqObj) throws IOException, SL20Exception { - //create response - final Map reqParameters = new HashMap(); - reqParameters.put(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReq.getPendingRequestId()); - final ObjectNode callReqParams = SL20JSONBuilderUtils.createCallCommandParameters( - new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), getResumeEndPoint(), null), - SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET, - false, - reqParameters); - final ObjectNode callCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_CALL, callReqParams); + private void buildResponse(HttpServletRequest request, HttpServletResponse response, JsonNode sl20ReqObj, boolean aTrustErrorWorkAround) throws IOException, SL20Exception, URISyntaxException { + //create response + final Map reqParameters = new HashMap(); + reqParameters.put(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReq.getPendingRequestId()); + final ObjectNode callReqParams = SL20JSONBuilderUtils.createCallCommandParameters( + new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), getResumeEndPoint(), null), + SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET, + false, + reqParameters); + final ObjectNode callCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_CALL, callReqParams); - //build first redirect command for app - final ObjectNode redirectOneParams = SL20JSONBuilderUtils.createRedirectCommandParameters( - generateICPRedirectURLForDebugging(), - callCommand, null, true); - final ObjectNode redirectOneCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectOneParams); - - //build second redirect command for IDP - final ObjectNode redirectTwoParams = SL20JSONBuilderUtils.createRedirectCommandParameters( - new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), getResumeEndPoint(), pendingReq.getPendingRequestId()), - redirectOneCommand, null, true); - final ObjectNode redirectTwoCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectTwoParams); - - //build generic SL2.0 response container - final String transactionId = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_TRANSACTIONID, false); - final ObjectNode respContainer = SL20JSONBuilderUtils.createGenericRequest( - UUID.randomUUID().toString(), - transactionId, - redirectTwoCommand, - null); + //build first redirect command for app + final ObjectNode redirectOneParams = SL20JSONBuilderUtils.createRedirectCommandParameters( + generateICPRedirectURLForDebugging(), + callCommand, null, true); + final ObjectNode redirectOneCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectOneParams); + + //build second redirect command for IDP + final ObjectNode redirectTwoParams = SL20JSONBuilderUtils.createRedirectCommandParameters( + new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), getResumeEndPoint(), pendingReq.getPendingRequestId()), + redirectOneCommand, null, true); + final ObjectNode redirectTwoCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectTwoParams); + + //build generic SL2.0 response container + final String transactionId = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_TRANSACTIONID, false); + final ObjectNode respContainer = SL20JSONBuilderUtils.createGenericRequest( + UUID.randomUUID().toString(), + transactionId, + redirectTwoCommand, + null); //workaround for A-Trust - if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null && + if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null && request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE).equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE) - || true) { + || !aTrustErrorWorkAround) { log.debug("Client request containts 'native client' header ... "); log.trace("SL20 response to VDA: " + respContainer); - final StringWriter writer = new StringWriter(); - writer.write(respContainer.toString()); - final byte[] content = writer.toString().getBytes("UTF-8"); - response.setStatus(HttpServletResponse.SC_OK); - response.setContentLength(content.length); - response.setContentType(ContentType.APPLICATION_JSON.toString()); - response.getOutputStream().write(content); - - - } else { - log.info("SL2.0 DataURL communication needs http header: '" + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"); - throw new SL20Exception("sl20.06", - new Object[] {"SL2.0 DataURL communication needs http header: '" + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"}); - - } - } + final StringWriter writer = new StringWriter(); + writer.write(respContainer.toString()); + final byte[] content = writer.toString().getBytes("UTF-8"); + response.setStatus(HttpServletResponse.SC_OK); + response.setContentLength(content.length); + response.setContentType(ContentType.APPLICATION_JSON.toString()); + response.getOutputStream().write(content); + + + } else { + log.info("SL2.0 DataURL communication needs http header: '" + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"); + + log.debug("Client request containts is no native client ... "); + final URIBuilder clientRedirectURI = new URIBuilder( + new DataURLBuilder().buildDataURL( + pendingReq.getAuthURL(), getResumeEndPoint(), pendingReq.getPendingRequestId())); + response.setStatus(Integer.parseInt( + authConfig.getBasicConfiguration( + Constants.CONFIG_PROP_HTTP_REDIRECT_CODE, + Constants.CONFIG_PROP_HTTP_REDIRECT_CODE_DEFAULT_VALUE))); + response.setHeader("Location", clientRedirectURI.build().toString()); + + +// throw new SL20Exception("sl20.06", +// new Object[] {"SL2.0 DataURL communication needs http header: '" + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"}); + + } + } /** * Generates a IPC redirect URL that is configured on IDP side diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonMapper.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonMapper.java index 959a696a..043a39bc 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonMapper.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonMapper.java @@ -1,10 +1,5 @@ package at.gv.egiz.eaaf.modules.auth.sl20.utils; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; - import java.io.IOException; import org.slf4j.Logger; @@ -12,17 +7,22 @@ import org.slf4j.LoggerFactory; import org.springframework.lang.NonNull; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.type.TypeFactory; -public class JsonMapper { +import at.gv.egiz.eaaf.core.api.utils.IJsonMapper; +import at.gv.egiz.eaaf.core.exceptions.EAAFJsonMapperException; + +public class JsonMapper implements IJsonMapper { private static final Logger log = LoggerFactory.getLogger(JsonMapper.class); - private ObjectMapper mapper = new ObjectMapper(); + private final ObjectMapper mapper = new ObjectMapper(); /** * The default constructor where the default pretty printer is disabled. @@ -53,10 +53,8 @@ public class JsonMapper { } - /** - * Get the internal mapper implemenation - * - * @return + /* (non-Javadoc) + * @at.gv.egiz.eaaf.core.api.utils.IJsonMapper#getMapper() */ public ObjectMapper getMapper() { return mapper; @@ -64,44 +62,47 @@ public class JsonMapper { } - /** - * Serialize an object to a JSON string. - * @param value the object to serialize - * @return a JSON string - * @throws JsonProcessingException thrown when an error occurs during serialization + /* (non-Javadoc) + * @see at.gv.egiz.eaaf.core.api.utils.IJsonMapper#serialize(java.lang.Object) */ - public String serialize(Object value) throws JsonProcessingException { - return mapper.writeValueAsString(value); + @Override + public String serialize(Object value) throws EAAFJsonMapperException { + try { + return mapper.writeValueAsString(value); + + } catch (final JsonProcessingException e) { + log.warn("JSON mapping FAILED with error: {}", e.getMessage()); + throw new EAAFJsonMapperException(e.getMessage(), e); + + } } - /** - * Deserialize a JSON string. - * - * @param value the JSON string to deserialize - * @param clazz optional parameter that determines the type of the returned object. If not set, an {@link Object} is returned. - * @return the deserialized JSON string as an object of type {@code clazz} or {@link Object} - * @throws JsonParseException if the JSON string contains invalid content. - * @throws JsonMappingException if the input JSON structure does not match structure expected for result type - * @throws IOException if an I/O problem occurs (e.g. unexpected end-of-input) + /* (non-Javadoc) + * @see at.gv.egiz.eaaf.core.api.utils.IJsonMapper#deserialize(java.lang.String, java.lang.Class) */ - public Object deserialize(String value, Class clazz) throws JsonParseException, JsonMappingException, IOException{ - - ObjectMapper mapper = new ObjectMapper(); - if (clazz != null) { - JavaType javaType = TypeFactory.defaultInstance().constructType(clazz); - return mapper.readValue(value, javaType); + @Override + public Object deserialize(String value, Class clazz) throws EAAFJsonMapperException { + try { + if (clazz != null) { + if (clazz.isAssignableFrom(TypeReference.class)) + return mapper.readValue(value, clazz); + + else { + final JavaType javaType = TypeFactory.defaultInstance().constructType(clazz); + return mapper.readValue(value, javaType); + + } - } else - return mapper.readValue(value, Object.class); + } else + return mapper.readValue(value, Object.class); + + } catch (final IOException e) { + log.warn("JSON mapping FAILED with error: {}", e.getMessage()); + throw new EAAFJsonMapperException(e.getMessage(), e); + + } } - - - - public Object deserialize(String value, TypeReference clazz) throws JsonParseException, JsonMappingException, IOException { - return mapper.readValue(value, clazz); - - } - + } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java index 5eda95cc..33873f43 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java @@ -57,7 +57,7 @@ public class JsonSecurityUtils implements IJOSETools{ private Key encPrivKey = null; private X509Certificate[] encCertChain = null; - private List trustedCerts = new ArrayList(); + private final List trustedCerts = new ArrayList(); private static JsonMapper mapper = new JsonMapper(); @@ -66,12 +66,12 @@ public class JsonSecurityUtils implements IJOSETools{ log.info("Initialize SL2.0 authentication security constrains ... "); try { if (getKeyStoreFilePath() != null) { - KeyStore keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), + final KeyStore keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), getKeyStorePassword()); //load signing key signPrivKey = keyStore.getKey(getSigningKeyAlias(), getSigningKeyPassword().toCharArray()); - Certificate[] certChainSigning = keyStore.getCertificateChain(getSigningKeyAlias()); + final Certificate[] certChainSigning = keyStore.getCertificateChain(getSigningKeyAlias()); signCertChain = new X509Certificate[certChainSigning.length]; for (int i=0; i aliases = keyStore.aliases(); + final Enumeration aliases = keyStore.aliases(); while(aliases.hasMoreElements()) { - String el = aliases.nextElement(); + final String el = aliases.nextElement(); log.trace("Process TrustStoreEntry: " + el); if (keyStore.isCertificateEntry(el)) { - Certificate cert = keyStore.getCertificate(el); + final Certificate cert = keyStore.getCertificate(el); if (cert != null && cert instanceof X509Certificate) trustedCerts.add((X509Certificate) cert); else @@ -134,7 +134,7 @@ public class JsonSecurityUtils implements IJOSETools{ } else log.info("NO SL2.0 authentication security configuration. Initialization was skipped"); - } catch ( Exception e) { + } catch ( final Exception e) { log.error("SL2.0 security constrains initialization FAILED.", e); } @@ -145,7 +145,7 @@ public class JsonSecurityUtils implements IJOSETools{ @Override public String createSignature(String payLoad) throws SLCommandoBuildException { try { - JsonWebSignature jws = new JsonWebSignature(); + final JsonWebSignature jws = new JsonWebSignature(); //set payload jws.setPayload(payLoad); @@ -163,7 +163,7 @@ public class JsonSecurityUtils implements IJOSETools{ return jws.getCompactSerialization(); - } catch (JoseException e) { + } catch (final JoseException e) { log.warn("Can NOT sign SL2.0 command.", e); throw new SLCommandoBuildException("Can NOT sign SL2.0 command.", e); @@ -174,7 +174,7 @@ public class JsonSecurityUtils implements IJOSETools{ @Override public VerificationResult validateSignature(String serializedContent) throws SL20Exception { try { - JsonWebSignature jws = new JsonWebSignature(); + final JsonWebSignature jws = new JsonWebSignature(); //set payload jws.setCompactSerialization(serializedContent); @@ -184,12 +184,12 @@ public class JsonSecurityUtils implements IJOSETools{ //load signinc certs Key selectedKey = null; - List x5cCerts = jws.getCertificateChainHeaderValue(); - String x5t256 = jws.getX509CertSha256ThumbprintHeaderValue(); + final List x5cCerts = jws.getCertificateChainHeaderValue(); + final String x5t256 = jws.getX509CertSha256ThumbprintHeaderValue(); if (x5cCerts != null) { log.debug("Found x509 certificate in JOSE header ... "); log.trace("Sorting received X509 certificates ... "); - List sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); + final List sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); if (trustedCerts.contains(sortedX5cCerts.get(0))) { selectedKey = sortedX5cCerts.get(0).getPublicKey(); @@ -199,7 +199,7 @@ public class JsonSecurityUtils implements IJOSETools{ log.debug("JOSE certificate: " + sortedX5cCerts.get(0).toString()); try { log.debug("Cert: " + Base64Utils.encodeToString(sortedX5cCerts.get(0).getEncoded())); - } catch (CertificateEncodingException e) { + } catch (final CertificateEncodingException e) { e.printStackTrace(); } @@ -207,7 +207,7 @@ public class JsonSecurityUtils implements IJOSETools{ } else if (StringUtils.isNotEmpty(x5t256)) { log.debug("Found x5t256 fingerprint in JOSE header .... "); - X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver(trustedCerts); + final X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver(trustedCerts); selectedKey = x509VerificationKeyResolver.resolveKey(jws, Collections.emptyList()); } else { @@ -226,7 +226,7 @@ public class JsonSecurityUtils implements IJOSETools{ jws.setKey(selectedKey); //validate signature - boolean valid = jws.verifySignature(); + final boolean valid = jws.verifySignature(); if (!valid) { log.info("JWS signature invalide. Stopping authentication process ..."); log.debug("Received JWS msg: " + serializedContent); @@ -237,7 +237,7 @@ public class JsonSecurityUtils implements IJOSETools{ //load payLoad log.debug("SL2.0 commando signature validation sucessfull"); - JsonNode sl20Req = mapper.getMapper().readTree(jws.getPayload()); + final JsonNode sl20Req = mapper.getMapper().readTree(jws.getPayload()); return new VerificationResult(sl20Req, null, valid) ; @@ -245,7 +245,7 @@ public class JsonSecurityUtils implements IJOSETools{ log.warn("SL2.0 commando signature validation FAILED", e); throw new SL20SecurityException(new Object[]{e.getMessage()}, e); - } catch (IOException e) { + } catch (final IOException e) { log.warn("Decrypted SL2.0 result can not be parsed.", e); throw new SLCommandoParserException("Decrypted SL2.0 result can not be parsed", e); @@ -257,7 +257,7 @@ public class JsonSecurityUtils implements IJOSETools{ @Override public JsonNode decryptPayload(String compactSerialization) throws SL20Exception { try { - JsonWebEncryption receiverJwe = new JsonWebEncryption(); + final JsonWebEncryption receiverJwe = new JsonWebEncryption(); //set security constrains receiverJwe.setAlgorithmConstraints( @@ -272,12 +272,12 @@ public class JsonSecurityUtils implements IJOSETools{ //validate key from header against key from config - List x5cCerts = receiverJwe.getCertificateChainHeaderValue(); - String x5t256 = receiverJwe.getX509CertSha256ThumbprintHeaderValue(); + final List x5cCerts = receiverJwe.getCertificateChainHeaderValue(); + final String x5t256 = receiverJwe.getX509CertSha256ThumbprintHeaderValue(); if (x5cCerts != null) { log.debug("Found x509 certificate in JOSE header ... "); log.trace("Sorting received X509 certificates ... "); - List sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); + final List sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); if (!sortedX5cCerts.get(0).equals(encCertChain[0])) { log.info("Certificate from JOSE header does NOT match encryption certificate"); @@ -285,7 +285,7 @@ public class JsonSecurityUtils implements IJOSETools{ try { log.debug("Cert: " + Base64Utils.encode(sortedX5cCerts.get(0).getEncoded())); - } catch (CertificateEncodingException e) { + } catch (final CertificateEncodingException e) { e.printStackTrace(); } throw new SL20Exception("sl20.05", new Object[]{"Certificate from JOSE header does NOT match encryption certificate"}); @@ -293,7 +293,7 @@ public class JsonSecurityUtils implements IJOSETools{ } else if (StringUtils.isNotEmpty(x5t256)) { log.debug("Found x5t256 fingerprint in JOSE header .... "); - String certFingerPrint = X509Util.x5tS256(encCertChain[0]); + final String certFingerPrint = X509Util.x5tS256(encCertChain[0]); if (!certFingerPrint.equals(x5t256)) { log.info("X5t256 from JOSE header does NOT match encryption certificate"); log.debug("X5t256 from JOSE header: " + x5t256 + " Encrytption cert: " + certFingerPrint); @@ -314,15 +314,15 @@ public class JsonSecurityUtils implements IJOSETools{ //decrypt payload return mapper.getMapper().readTree(receiverJwe.getPlaintextString()); - } catch (JoseException e) { + } catch (final JoseException e) { log.warn("SL2.0 result decryption FAILED", e); throw new SL20SecurityException(new Object[]{e.getMessage()}, e); - } catch ( JsonParseException e) { + } catch ( final JsonParseException e) { log.warn("Decrypted SL2.0 result is NOT a valid JSON.", e); throw new SLCommandoParserException("Decrypted SL2.0 result is NOT a valid JSON.", e); - } catch (IOException e) { + } catch (final IOException e) { log.warn("Decrypted SL2.0 result can not be parsed.", e); throw new SLCommandoParserException("Decrypted SL2.0 result can not be parsed", e); } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java index 416c16b6..06c36cff 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java @@ -92,7 +92,8 @@ public class SL20Constants { public static final String SL20_COMMAND_IDENTIFIER_REDIRECT = "redirect"; public static final String SL20_COMMAND_IDENTIFIER_CALL = "call"; public static final String SL20_COMMAND_IDENTIFIER_ERROR = "error"; - public static final String SL20_COMMAND_IDENTIFIER_QUALIFIEDEID = "qualifiedeID"; + @Deprecated public static final String SL20_COMMAND_IDENTIFIER_QUALIFIEDEID = "qualifiedeID"; + public static final String SL20_COMMAND_IDENTIFIER_QUALIFIEDEIDCONSENT = "qualifiedEIDConsent"; //public static final String SL20_COMMAND_IDENTIFIER_QUALIFIEDSIG = "qualifiedSig"; public static final String SL20_COMMAND_IDENTIFIER_GETCERTIFICATE = "getCertificate"; @@ -133,19 +134,25 @@ public class SL20Constants { public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE = "errorMessage"; //qualified eID command - public static final String SL20_COMMAND_PARAM_EID_AUTHBLOCKID = "authBlockTemplateID"; + @Deprecated public static final String SL20_COMMAND_PARAM_EID_AUTHBLOCKID = "authBlockTemplateID"; public static final String SL20_COMMAND_PARAM_EID_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; - public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES = "attributes"; - public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_MANDATEREFVALUE = "MANDATE-REFERENCE-VALUE"; - public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPUNIQUEID = "SP-UNIQUEID"; - public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPFRIENDLYNAME = "SP-FRIENDLYNAME"; - public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPCOUNTRYCODE = "SP-COUNTRYCODE"; + @Deprecated public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES = "attributes"; + @Deprecated public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_MANDATEREFVALUE = "MANDATE-REFERENCE-VALUE"; + @Deprecated public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPUNIQUEID = "SP-UNIQUEID"; + @Deprecated public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPFRIENDLYNAME = "SP-FRIENDLYNAME"; + @Deprecated public static final String SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPCOUNTRYCODE = "SP-COUNTRYCODE"; public static final String SL20_COMMAND_PARAM_EID_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE; public static final String SL20_COMMAND_PARAM_EID_JWKCENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK; - public static final String SL20_COMMAND_PARAM_EID_RESULT_IDL = "EID-IDENTITY-LINK"; - public static final String SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK = "EID-AUTH-BLOCK"; + @Deprecated public static final String SL20_COMMAND_PARAM_EID_RESULT_IDL = "EID-IDENTITY-LINK"; + @Deprecated public static final String SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK = "EID-AUTH-BLOCK"; public static final String SL20_COMMAND_PARAM_EID_RESULT_CCSURL = "EID-CCS-URL"; - public static final String SL20_COMMAND_PARAM_EID_RESULT_LOA = "EID-CITIZEN-QAA-LEVEL"; + @Deprecated public static final String SL20_COMMAND_PARAM_EID_RESULT_LOA = "EID-CITIZEN-QAA-LEVEL"; + + public static final String SL20_COMMAND_PARAM_EID_CONSENTTEMPLATEID = "consentTemplateID"; + public static final String SL20_COMMAND_PARAM_EID_CONSENT = "consent"; + public static final String SL20_COMMAND_PARAM_EID_CONSENT_RESULT_MDS = "MDS"; + public static final String SL20_COMMAND_PARAM_EID_CONSENT_RESULT_VSZ = "vSZ"; + public static final String SL20_COMMAND_PARAM_EID_CONSENT_RESULT_SIGNEDCONSENT = "signedConsent"; //qualified Signature comamnd // public static final String SL20_COMMAND_PARAM_QUALSIG_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20HttpBindingUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20HttpBindingUtils.java index e1cca5ef..39f2515d 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20HttpBindingUtils.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20HttpBindingUtils.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.io.StringWriter; import java.net.URISyntaxException; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -18,20 +20,33 @@ import com.fasterxml.jackson.databind.JsonNode; public class SL20HttpBindingUtils { private static final Logger log = LoggerFactory.getLogger(SL20HttpBindingUtils.class); - public static void writeIntoResponse(HttpServletRequest request, HttpServletResponse response, JsonNode sl20Forward, String redirectURL) throws IOException, URISyntaxException { + /** + * Write SL2.0 response into http-response object + * + * @param httpReq Current http request + * @param httpResp Current http response + * @param sl20Forward SL2.0 command that should be written to response + * @param redirectURL SL2.0 redirect URL in case of SL2.0 redirect command and no native client (see SL2.0 specification) + * @param httpCodeRedirect http redirect-code in case of SL2.0 redirect command and no native client (see SL2.0 specification) + * @throws IOException + * @throws URISyntaxException + */ + public static void writeIntoResponse(@Nonnull HttpServletRequest httpReq, @Nonnull HttpServletResponse httpResp, + @Nonnull JsonNode sl20Forward, @Nullable String redirectURL, + @Nonnull int httpCodeRedirect) throws IOException, URISyntaxException { //forward SL2.0 command - response.addIntHeader(SL20Constants.HTTP_HEADER_SL20_RESP, SL20Constants.CURRENT_SL20_VERSION); + httpResp.addIntHeader(SL20Constants.HTTP_HEADER_SL20_RESP, SL20Constants.CURRENT_SL20_VERSION); - if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null && - request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE).equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) { + if (httpReq.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null && + httpReq.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE).equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) { log.debug("Client request containts 'native client' header ... "); final StringWriter writer = new StringWriter(); writer.write(sl20Forward.toString()); final byte[] content = writer.toString().getBytes("UTF-8"); - response.setStatus(HttpServletResponse.SC_OK); - response.setContentLength(content.length); - response.setContentType(ContentType.APPLICATION_JSON.toString()); - response.getOutputStream().write(content); + httpResp.setStatus(HttpServletResponse.SC_OK); + httpResp.setContentLength(content.length); + httpResp.setContentType(ContentType.APPLICATION_JSON.toString()); + httpResp.getOutputStream().write(content); } else { log.debug("Client request containts is no native client ... "); @@ -39,8 +54,8 @@ public class SL20HttpBindingUtils { clientRedirectURI.addParameter( SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, Base64Url.encode(sl20Forward.toString().getBytes())); - response.setStatus(307); - response.setHeader("Location", clientRedirectURI.build().toString()); + httpResp.setStatus(httpCodeRedirect); + httpResp.setHeader("Location", clientRedirectURI.build().toString()); } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONBuilderUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONBuilderUtils.java index 611bb339..84e02887 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONBuilderUtils.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONBuilderUtils.java @@ -27,7 +27,7 @@ public class SL20JSONBuilderUtils { */ public static ObjectNode createCommand(String name, ObjectNode params) throws SLCommandoBuildException { - ObjectNode command = mapper.getMapper().createObjectNode(); + final ObjectNode command = mapper.getMapper().createObjectNode(); addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); addSingleJSONElement(command, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, params, true); return command; @@ -44,7 +44,7 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static String createSignedCommand(String name, ObjectNode params, IJOSETools signer) throws SLCommandoBuildException { - ObjectNode command = mapper.getMapper().createObjectNode(); + final ObjectNode command = mapper.getMapper().createObjectNode(); addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); addSingleJSONElement(command, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, params, true); return signer.createSignature(command.toString()); @@ -63,9 +63,9 @@ public class SL20JSONBuilderUtils { public static String createEncryptedCommandoResult(ObjectNode result, JsonSecurityUtils encrypter) throws SLCommandoBuildException { //TODO: add real implementation //create header and footer - String dummyHeader = createJsonEncryptionHeader(encrypter).toString(); - String payLoad = result.toString(); - String dummyFooter = createJsonSignedFooter(encrypter); + final String dummyHeader = createJsonEncryptionHeader(encrypter).toString(); + final String payLoad = result.toString(); + final String dummyFooter = createJsonSignedFooter(encrypter); return Base64.getUrlEncoder().encodeToString(dummyHeader.getBytes()) + "." + Base64.getUrlEncoder().encodeToString(payLoad.getBytes()) + "." @@ -84,7 +84,7 @@ public class SL20JSONBuilderUtils { * @return */ public static ObjectNode createCommandResponse(String name, ObjectNode result, String encryptedResult) throws SLCommandoBuildException { - ObjectNode command = mapper.getMapper().createObjectNode(); + final ObjectNode command = mapper.getMapper().createObjectNode(); addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); addOnlyOnceOfTwo(command, SL20Constants.SL20_COMMAND_CONTAINER_RESULT, SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT, @@ -103,17 +103,17 @@ public class SL20JSONBuilderUtils { * @return */ public static String createSignedCommandResponse(String name, ObjectNode result, String encryptedResult, JsonSecurityUtils signer) throws SLCommandoBuildException { - ObjectNode command = mapper.getMapper().createObjectNode(); + final ObjectNode command = mapper.getMapper().createObjectNode(); addSingleStringElement(command, SL20Constants.SL20_COMMAND_CONTAINER_NAME, name, true); addOnlyOnceOfTwo(command, SL20Constants.SL20_COMMAND_CONTAINER_RESULT, SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT, result, encryptedResult); - String encodedCommand = command.toString(); + final String encodedCommand = command.toString(); //TODO: add real implementation //create header and footer - String dummyHeader = createJsonSignedHeader(signer).toString(); - String dummyFooter = createJsonSignedFooter(signer); + final String dummyHeader = createJsonSignedHeader(signer).toString(); + final String dummyFooter = createJsonSignedFooter(signer); return Base64.getUrlEncoder().encodeToString(dummyHeader.getBytes()) + "." + Base64.getUrlEncoder().encodeToString(encodedCommand.getBytes()) + "." @@ -132,7 +132,7 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static ObjectNode createRedirectCommandParameters(String url, ObjectNode command, ObjectNode signedCommand, Boolean ipcRedirect) throws SLCommandoBuildException{ - ObjectNode redirectReqParams = mapper.getMapper().createObjectNode(); + final ObjectNode redirectReqParams = mapper.getMapper().createObjectNode(); addOnlyOnceOfTwo(redirectReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND, command, signedCommand); @@ -153,7 +153,7 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static ObjectNode createCallCommandParameters(String url, String method, Boolean includeTransactionId, Map reqParameters) throws SLCommandoBuildException { - ObjectNode callReqParams = mapper.getMapper().createObjectNode(); + final ObjectNode callReqParams = mapper.getMapper().createObjectNode(); addSingleStringElement(callReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_URL, url, true); addSingleStringElement(callReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD, method, true); addSingleBooleanElement(callReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_INCLUDETRANSACTIONID, includeTransactionId, false); @@ -171,13 +171,36 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static ObjectNode createErrorCommandResult(String errorCode, String errorMsg) throws SLCommandoBuildException { - ObjectNode result = mapper.getMapper().createObjectNode(); + final ObjectNode result = mapper.getMapper().createObjectNode(); addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, errorCode, true); addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, errorMsg, true); return result; } + /** + * Create parameters for qualifiedeID command + * + * @param consentTemplateId Identifier of the template that is used for consent visualization + * @param consent Consent that has to be signed by user + * @param dataUrl + * @param additionalReqParameters + * @param x5cEnc + * @return + * @throws CertificateEncodingException + * @throws SLCommandoBuildException + */ + public static ObjectNode createQualifiedeEIDConsent(String consentTemplateId, byte[] consent, String dataUrl, + X509Certificate x5cEnc) throws CertificateEncodingException, SLCommandoBuildException { + final ObjectNode params = mapper.getMapper().createObjectNode(); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_CONSENTTEMPLATEID, consentTemplateId, true); + addSingleByteElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_CONSENT, consent, true); + addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_DATAURL, dataUrl, true); + addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_X5CENC, x5cEnc, false); + return params; + + } + /** * Create parameters for qualifiedeID command @@ -190,9 +213,10 @@ public class SL20JSONBuilderUtils { * @throws CertificateEncodingException * @throws SLCommandoBuildException */ + @Deprecated public static ObjectNode createQualifiedeIDCommandParameters(String authBlockId, String dataUrl, Map additionalReqParameters, X509Certificate x5cEnc) throws CertificateEncodingException, SLCommandoBuildException { - ObjectNode params = mapper.getMapper().createObjectNode(); + final ObjectNode params = mapper.getMapper().createObjectNode(); addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_AUTHBLOCKID, authBlockId, true); addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_DATAURL, dataUrl, true); addArrayOfStringElements(params, SL20Constants.SL20_COMMAND_PARAM_EID_ATTRIBUTES, additionalReqParameters); @@ -212,7 +236,7 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static ObjectNode createQualifiedeIDCommandResult(byte[] idl, byte[] authBlock, String ccsURL, String LoA) throws SLCommandoBuildException { - ObjectNode result = mapper.getMapper().createObjectNode(); + final ObjectNode result = mapper.getMapper().createObjectNode(); addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_IDL, idl, true); addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK, authBlock, true); addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL, ccsURL, true); @@ -240,7 +264,7 @@ public class SL20JSONBuilderUtils { */ public static ObjectNode createBindingKeyCommandParams(String kontoId, String subjectName, int keySize, String keyAlg, Map policies, String dataUrl, X509Certificate x5cVdaTrust, Boolean reqUserPassword, X509Certificate x5cEnc) throws SLCommandoBuildException, CertificateEncodingException { - ObjectNode params = mapper.getMapper().createObjectNode(); + final ObjectNode params = mapper.getMapper().createObjectNode(); addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID, kontoId, true); addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_SN, subjectName, true); addSingleNumberElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_KEYLENGTH, keySize, true); @@ -266,7 +290,7 @@ public class SL20JSONBuilderUtils { * @throws CertificateEncodingException */ public static ObjectNode createBindingKeyCommandResult(String appId, byte[] csr, X509Certificate attCert, byte[] password) throws SLCommandoBuildException, CertificateEncodingException { - ObjectNode result = mapper.getMapper().createObjectNode(); + final ObjectNode result = mapper.getMapper().createObjectNode(); addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_APPID, appId, true); addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_CSR, csr, true); addSingleCertificateElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_KEYATTESTATIONZERTIFICATE, attCert, false); @@ -285,7 +309,7 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static ObjectNode createStoreBindingCertCommandParams(X509Certificate cert, String dataUrl) throws CertificateEncodingException, SLCommandoBuildException { - ObjectNode params = mapper.getMapper().createObjectNode(); + final ObjectNode params = mapper.getMapper().createObjectNode(); addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_CERTIFICATE, cert, true); addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_DATAURL, dataUrl, true); return params; @@ -299,7 +323,7 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static ObjectNode createStoreBindingCertCommandSuccessResult() throws SLCommandoBuildException { - ObjectNode result = mapper.getMapper().createObjectNode(); + final ObjectNode result = mapper.getMapper().createObjectNode(); addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS, SL20Constants.SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS_VALUE, true); return result; @@ -318,7 +342,7 @@ public class SL20JSONBuilderUtils { * @throws CertificateEncodingException */ public static ObjectNode createIdAndPasswordCommandParameters(String keyAlg, String dataUrl, X509Certificate x5cEnc) throws SLCommandoBuildException, CertificateEncodingException { - ObjectNode params = mapper.getMapper().createObjectNode(); + final ObjectNode params = mapper.getMapper().createObjectNode(); addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG, keyAlg, true); addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_DATAURL, dataUrl, true); addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_X5CENC, x5cEnc, false); @@ -335,7 +359,7 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static ObjectNode createIdAndPasswordCommandResult(String kontoId, byte[] password) throws SLCommandoBuildException { - ObjectNode result = mapper.getMapper().createObjectNode(); + final ObjectNode result = mapper.getMapper().createObjectNode(); addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_KONTOID, kontoId, true); addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_USERPASSWORD, password, true); return result; @@ -353,7 +377,7 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static ObjectNode createJwsTokenAuthCommandParams(String nonce, String dataUrl, List displayData, List displayUrl) throws SLCommandoBuildException { - ObjectNode params = mapper.getMapper().createObjectNode(); + final ObjectNode params = mapper.getMapper().createObjectNode(); addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE, nonce, true); addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DATAURL, dataUrl, true); addArrayOfStrings(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYDATA, displayData); @@ -370,7 +394,7 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static ObjectNode createJwsTokenAuthCommandResult(String nonce) throws SLCommandoBuildException { - ObjectNode result = mapper.getMapper().createObjectNode(); + final ObjectNode result = mapper.getMapper().createObjectNode(); addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_RESULT_NONCE, nonce, true); return result; @@ -388,7 +412,7 @@ public class SL20JSONBuilderUtils { * @throws SLCommandoBuildException */ public static ObjectNode createGenericRequest(String reqId, String transactionId, ObjectNode payLoad, String signedPayload) throws SLCommandoBuildException { - ObjectNode req = mapper.getMapper().createObjectNode(); + final ObjectNode req = mapper.getMapper().createObjectNode(); addSingleIntegerElement(req, SL20Constants.SL20_VERSION, SL20Constants.CURRENT_SL20_VERSION, true); addSingleStringElement(req, SL20Constants.SL20_REQID, reqId, true); addSingleStringElement(req, SL20Constants.SL20_TRANSACTIONID, transactionId, false); @@ -411,7 +435,7 @@ public class SL20JSONBuilderUtils { */ public static final ObjectNode createGenericResponse(String respId, String inResponseTo, String transactionId, ObjectNode payLoad, String signedPayload) throws SLCommandoBuildException { - ObjectNode req = mapper.getMapper().createObjectNode(); + final ObjectNode req = mapper.getMapper().createObjectNode(); addSingleIntegerElement(req, SL20Constants.SL20_VERSION, SL20Constants.CURRENT_SL20_VERSION, true); addSingleStringElement(req, SL20Constants.SL20_RESPID, respId, true); addSingleStringElement(req, SL20Constants.SL20_INRESPTO, inResponseTo, true); @@ -454,7 +478,7 @@ public class SL20JSONBuilderUtils { //TODO!!!! private static ObjectNode createJsonSignedHeader(JsonSecurityUtils signer) throws SLCommandoBuildException { - ObjectNode header = mapper.getMapper().createObjectNode(); + final ObjectNode header = mapper.getMapper().createObjectNode(); addSingleStringElement(header, SL20Constants.JSON_ALGORITHM, SL20Constants.JSON_ALGORITHM_SIGNING_RS256, true); addSingleStringElement(header, SL20Constants.JSON_CONTENTTYPE, SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND, true); addArrayOfStrings(header, SL20Constants.JSON_X509_CERTIFICATE, Arrays.asList(Constants.DUMMY_SIGNING_CERT)); @@ -464,7 +488,7 @@ public class SL20JSONBuilderUtils { //TODO!!!! private static ObjectNode createJsonEncryptionHeader(JsonSecurityUtils signer) throws SLCommandoBuildException { - ObjectNode header = mapper.getMapper().createObjectNode(); + final ObjectNode header = mapper.getMapper().createObjectNode(); addSingleStringElement(header, SL20Constants.JSON_ALGORITHM, SL20Constants.JSON_ALGORITHM_ENC_KEY_RSAOAEP, true); addSingleStringElement(header, SL20Constants.JSON_ENCRYPTION_PAYLOAD, SL20Constants.JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256, true); addSingleStringElement(header, SL20Constants.JSON_CONTENTTYPE, SL20Constants.SL20_CONTENTTYPE_ENCRYPTED_RESULT, true); @@ -488,9 +512,9 @@ public class SL20JSONBuilderUtils { private static void addArrayOfStrings(ObjectNode parent, String keyId, List values) throws SLCommandoBuildException { validateParentAndKey(parent, keyId); if (values != null) { - ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode(); + final ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode(); parent.set(keyId, callReqParamsArray ); - for(String el : values) + for(final String el : values) callReqParamsArray.add(el); } @@ -500,11 +524,11 @@ public class SL20JSONBuilderUtils { private static void addArrayOfStringElements(ObjectNode parent, String keyId, Map keyValuePairs) throws SLCommandoBuildException { validateParentAndKey(parent, keyId); if (keyValuePairs != null) { - ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode(); + final ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode(); parent.set(keyId, callReqParamsArray); - for(Entry el : keyValuePairs.entrySet()) { - ObjectNode callReqParams = mapper.getMapper().createObjectNode(); + for(final Entry el : keyValuePairs.entrySet()) { + final ObjectNode callReqParams = mapper.getMapper().createObjectNode(); callReqParams.put(el.getKey(), el.getValue()); callReqParamsArray.add(callReqParams); -- cgit v1.2.3