summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_auth_sl20/src
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_modules/eaaf_module_auth_sl20/src')
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/AbstractSL20AuthenticationModulImpl.java238
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java123
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java14
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java59
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20EidDataValidationException.java16
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20Exception.java20
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20SecurityException.java24
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20eIDDataValidationException.java16
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoBuildException.java17
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoParserException.java17
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoBuildException.java17
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoParserException.java17
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualEidRequestTask.java250
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualeIDRequestTask.java227
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualEidTask.java344
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualeIDTask.java321
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJOSETools.java87
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java84
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonMapper.java227
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java773
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java499
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20HttpBindingUtils.java90
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONBuilderUtils.java640
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONExtractorUtils.java368
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonBuilderUtils.java731
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java407
26 files changed, 2958 insertions, 2668 deletions
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 7e306f25..4009796f 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
@@ -2,129 +2,145 @@ package at.gv.egiz.eaaf.modules.auth.sl20;
import java.util.Arrays;
import java.util.List;
-
import javax.annotation.PostConstruct;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
-import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.IspConfiguration;
import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.impl.idp.auth.AbstractAuthenticationManager;
import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
/**
+ * AuthModule to select a Securtiy-Layer 2.0 based authentication process.
+ *
* @author tlenz
*
*/
-public abstract class AbstractSL20AuthenticationModulImpl implements AuthModule {
- private static final Logger log = LoggerFactory.getLogger(AbstractSL20AuthenticationModulImpl.class);
-
- private int priority = 3;
- public static final List<String> VDA_TYPE_IDS = Arrays.asList("1", "2", "3", "4");
-
- @Autowired(required=true) protected IConfiguration authConfig;
- @Autowired(required=true) private AbstractAuthenticationManager authManager;
-
- @Override
- public int getPriority() {
- return priority;
- }
-
- /**
- * Sets the priority of this module. Default value is {@code 0}.
- * @param priority The priority.
- */
- public void setPriority(int priority) {
- this.priority = priority;
- }
-
- @PostConstruct
- protected void initalSL20Authentication() {
- //parameter to whiteList
- authManager.addHeaderNameToWhiteList(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE);
- authManager.addHeaderNameToWhiteList(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE);
-
- }
-
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process.api.ExecutionContext)
- */
- @Override
- public String selectProcess(ExecutionContext context, IRequest pendingReq) {
- final ISPConfiguration spConfig = pendingReq.getServiceProviderConfiguration();
-
- if (spConfig == null) {
- log.error("Suspect state. NO SP CONFIGURATION IN CONTEXT!");
- throw new RuntimeException("Suspect state. NO SP CONFIGURATION IN CONTEXT!");
-
- }
-
- final String sl20ClientTypeHeader = (String) context.get(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE.toLowerCase());
- final String sl20VDATypeHeader = (String) context.get(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE.toLowerCase());
-
- if (authConfig.getBasicConfigurationBoolean(getGeneralConfigPropertyNameEnableModule(), getGeneralConfigPropertyNameEnableModuleDefault())) {
- if (spConfig != null &&
- StringUtils.isNotEmpty(spConfig.getConfigurationValue(getSPConfigPropertyNameEnableModule())) &&
- Boolean.valueOf(spConfig.getConfigurationValue(getSPConfigPropertyNameEnableModule()))) {
- 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 getProcessName();
-
- } else {
- log.trace("SL2.0 is NOT enabled for " + spConfig.getUniqueIdentifier());
- return null;
-
- }
-
- } else {
- log.trace("SL2.0 is NOT enabled with property: {}", getGeneralConfigPropertyNameEnableModule());
- return null;
-
- }
-
- }
-
- /**
- * Get the general configuration-key that holds the enabled key for this authentication module
- *
- * @return
- */
- public abstract String getGeneralConfigPropertyNameEnableModule();
-
- /**
- * Get the default value of the general configuration-key that holds the enabled key for this authentication module
- *
- * @return
- */
- public abstract boolean getGeneralConfigPropertyNameEnableModuleDefault();
-
- /**
- * Get the SP specific configuration-key that holds the enabled key for this authentication module
- *
- * @return configuration key for SP configuration
- */
- public abstract String getSPConfigPropertyNameEnableModule();
-
- /**
- * 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()
- */
- @Override
- public abstract String[] getProcessDefinitions();
+public abstract class AbstractSL20AuthenticationModulImpl implements AuthModule {
+ private static final Logger log =
+ LoggerFactory.getLogger(AbstractSL20AuthenticationModulImpl.class);
+
+ private int priority = 3;
+ public static final List<String> VDA_TYPE_IDS = Arrays.asList("1", "2", "3", "4");
+
+ @Autowired(required = true)
+ protected IConfiguration authConfig;
+ @Autowired(required = true)
+ private AbstractAuthenticationManager authManager;
+
+ @Override
+ public int getPriority() {
+ return priority;
+ }
+
+ /**
+ * Sets the priority of this module. Default value is {@code 0}.
+ *
+ * @param priority The priority.
+ */
+ public void setPriority(final int priority) {
+ this.priority = priority;
+ }
+
+ @PostConstruct
+ protected void initalSL20Authentication() {
+ // parameter to whiteList
+ authManager.addHeaderNameToWhiteList(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE);
+ authManager.addHeaderNameToWhiteList(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE);
+
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process
+ * .api.ExecutionContext)
+ */
+ @Override
+ public String selectProcess(final ExecutionContext context, final IRequest pendingReq) {
+ final IspConfiguration spConfig = pendingReq.getServiceProviderConfiguration();
+
+ if (spConfig == null) {
+ log.error("Suspect state. NO SP CONFIGURATION IN CONTEXT!");
+ throw new RuntimeException("Suspect state. NO SP CONFIGURATION IN CONTEXT!");
+
+ }
+
+ final String sl20ClientTypeHeader =
+ (String) context.get(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE.toLowerCase());
+ final String sl20VdaTypeHeader =
+ (String) context.get(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE.toLowerCase());
+
+ if (authConfig.getBasicConfigurationBoolean(getGeneralConfigPropertyNameEnableModule(),
+ getGeneralConfigPropertyNameEnableModuleDefault())) {
+ if (spConfig != null
+ && StringUtils
+ .isNotEmpty(spConfig.getConfigurationValue(getSpConfigPropertyNameEnableModule()))
+ && Boolean
+ .valueOf(spConfig.getConfigurationValue(getSpConfigPropertyNameEnableModule()))) {
+ 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 getProcessName();
+
+ } else {
+ log.trace("SL2.0 is NOT enabled for " + spConfig.getUniqueIdentifier());
+ return null;
+
+ }
+
+ } else {
+ log.trace("SL2.0 is NOT enabled with property: {}",
+ getGeneralConfigPropertyNameEnableModule());
+ return null;
+
+ }
+
+ }
+
+ /**
+ * Get the general configuration-key that holds the enabled key for this authentication module.
+ *
+ * @return
+ */
+ public abstract String getGeneralConfigPropertyNameEnableModule();
+
+ /**
+ * Get the default value of the general configuration-key that holds the enabled key for this
+ * authentication module.
+ *
+ * @return
+ */
+ public abstract boolean getGeneralConfigPropertyNameEnableModuleDefault();
+
+ /**
+ * Get the SP specific configuration-key that holds the enabled key for this authentication module.
+ *
+ * @return configuration key for SP configuration
+ */
+ public abstract String getSpConfigPropertyNameEnableModule();
+
+ /**
+ * 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()
+ */
+ @Override
+ public abstract String[] 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 a1490d2b..a8460911 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
@@ -1,58 +1,75 @@
package at.gv.egiz.eaaf.modules.auth.sl20;
public class Constants {
-
- public static final String CONFIG_PROP_PREFIX = "modules.sl20";
- public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID = CONFIG_PROP_PREFIX + ".vda.urls.qualeID.";
-
- public static final String CONFIG_PROP_VDA_AUTHBLOCK_TRANSFORMATION_ID = CONFIG_PROP_PREFIX + ".vda.authblock.transformation.id";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_PATH = CONFIG_PROP_PREFIX + ".security.keystore.path";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD = CONFIG_PROP_PREFIX + ".security.keystore.password";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS = CONFIG_PROP_PREFIX + ".security.sign.alias";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD = CONFIG_PROP_PREFIX + ".security.sign.password";
- 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_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.";
-
- public static final String CONFIG_PROP_DISABLE_EID_VALIDATION = CONFIG_PROP_PREFIX + ".security.eID.validation.disable";
- public static final String CONFIG_PROP_ENABLE_EID_ENCRYPTION = CONFIG_PROP_PREFIX + ".security.eID.encryption.enabled";
- 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 + ".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 = "303";
-
- 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_";
-
- /**
- * Only dummy data for development!!!!!!
- */
- public static final String DUMMY_SIGNING_CERT =
- "MIIC9zCCAd8CBFretWcwDQYJKoZIhvcNAQEOBQAwQDELMAkGA1UEBhMCQVQxDTAL\n" +
- "BgNVBAoMBEVHSVoxIjAgBgNVBAMMGW93biBkdW1teSBtZXRhZGF0YSBzaWduZXIw\n" +
- "HhcNMTgwNDI0MDQ0MTExWhcNMjEwMTE3MDQ0MTExWjBAMQswCQYDVQQGEwJBVDEN\n" +
- "MAsGA1UECgwERUdJWjEiMCAGA1UEAwwZb3duIGR1bW15IG1ldGFkYXRhIHNpZ25l\n" +
- "cjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJvN3l1pjzlnmoW5trHH\n" +
- "Rb1s60QtGNp2v1nfMg1R6h7SzygtmO869v5bqrVBBVGmujslr7W8cZ2DLmJoQx1N\n" +
- "WwhccjXTHpNPw0B70qHGch2uRNkqkizSOlwth0Ll2DJtzxTolbajYdg+xppXScUq\n" +
- "WNlNZndauPSnB2CESgNkaUou4x4YVSDInugAtLvdLx8rf2YcuidI6UIXxeSZr3VO\n" +
- "Z12YtddzcJ+lwh7OX8B0UvLsdYjKjefjEudyuNBmVwLv4K2LsFhSqgE1CAzk3oCb\n" +
- "V2A84klaWVPiXoBiOucyouvX781WVp1aCBp0QA8gpJH7/2wRsdPQ90tjMzM7dcgY\n" +
- "LDkCAwEAATANBgkqhkiG9w0BAQ4FAAOCAQEAQuYRQcCNLDYU1ItliYz9f28+KDyU\n" +
- "8WjF3NDZrlJbGSKQ4n7wkBfxdK3zprmpHadWDB+aZaPt/+voE2FduzPiLUDlpazN\n" +
- "60JJ5/YHZ3q9MZvdoNg6rjkpioWatoj/smUkT6oUWL/gp8tH12fOd2oJygBqXMve\n" +
- "3y3qVCghnjRaMYuXcScTZcjH9yebkTLygirtw34oGVb7t+HwbtcN65fUIBly6Rcl\n" +
- "8NV3pwOKhXFKDAqXUpvhebL4+tWOqPdqfIfGaE6rELfTf3icGY3CQCzDz5Gp0Ptc\n" +
- "TfQqm64xnhtAruXNJXWg2ptg+GuQgWnJUgQ8wLNMxw9XdeEwlQo5dL6xmg==";
-
- public static final String DUMMY_SIGNING_CERT_FINGERPRINT = "IwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJvN3l1pjzlnmoW";
+
+ public static final String CONFIG_PROP_PREFIX = "modules.sl20";
+ public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID =
+ CONFIG_PROP_PREFIX + ".vda.urls.qualeID.";
+
+ public static final String CONFIG_PROP_VDA_AUTHBLOCK_TRANSFORMATION_ID =
+ CONFIG_PROP_PREFIX + ".vda.authblock.transformation.id";
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_PATH =
+ CONFIG_PROP_PREFIX + ".security.keystore.path";
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD =
+ CONFIG_PROP_PREFIX + ".security.keystore.password";
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS =
+ CONFIG_PROP_PREFIX + ".security.sign.alias";
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD =
+ CONFIG_PROP_PREFIX + ".security.sign.password";
+ 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_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.";
+
+ public static final String CONFIG_PROP_DISABLE_EID_VALIDATION =
+ CONFIG_PROP_PREFIX + ".security.eID.validation.disable";
+ public static final String CONFIG_PROP_ENABLE_EID_ENCRYPTION =
+ CONFIG_PROP_PREFIX + ".security.eID.encryption.enabled";
+ 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 + ".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 = "303";
+
+ 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_";
+
+ /**
+ * Only dummy data for development!!!!!!.
+ */
+ public static final String DUMMY_SIGNING_CERT =
+ "MIIC9zCCAd8CBFretWcwDQYJKoZIhvcNAQEOBQAwQDELMAkGA1UEBhMCQVQxDTAL\n"
+ + "BgNVBAoMBEVHSVoxIjAgBgNVBAMMGW93biBkdW1teSBtZXRhZGF0YSBzaWduZXIw\n"
+ + "HhcNMTgwNDI0MDQ0MTExWhcNMjEwMTE3MDQ0MTExWjBAMQswCQYDVQQGEwJBVDEN\n"
+ + "MAsGA1UECgwERUdJWjEiMCAGA1UEAwwZb3duIGR1bW15IG1ldGFkYXRhIHNpZ25l\n"
+ + "cjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJvN3l1pjzlnmoW5trHH\n"
+ + "Rb1s60QtGNp2v1nfMg1R6h7SzygtmO869v5bqrVBBVGmujslr7W8cZ2DLmJoQx1N\n"
+ + "WwhccjXTHpNPw0B70qHGch2uRNkqkizSOlwth0Ll2DJtzxTolbajYdg+xppXScUq\n"
+ + "WNlNZndauPSnB2CESgNkaUou4x4YVSDInugAtLvdLx8rf2YcuidI6UIXxeSZr3VO\n"
+ + "Z12YtddzcJ+lwh7OX8B0UvLsdYjKjefjEudyuNBmVwLv4K2LsFhSqgE1CAzk3oCb\n"
+ + "V2A84klaWVPiXoBiOucyouvX781WVp1aCBp0QA8gpJH7/2wRsdPQ90tjMzM7dcgY\n"
+ + "LDkCAwEAATANBgkqhkiG9w0BAQ4FAAOCAQEAQuYRQcCNLDYU1ItliYz9f28+KDyU\n"
+ + "8WjF3NDZrlJbGSKQ4n7wkBfxdK3zprmpHadWDB+aZaPt/+voE2FduzPiLUDlpazN\n"
+ + "60JJ5/YHZ3q9MZvdoNg6rjkpioWatoj/smUkT6oUWL/gp8tH12fOd2oJygBqXMve\n"
+ + "3y3qVCghnjRaMYuXcScTZcjH9yebkTLygirtw34oGVb7t+HwbtcN65fUIBly6Rcl\n"
+ + "8NV3pwOKhXFKDAqXUpvhebL4+tWOqPdqfIfGaE6rELfTf3icGY3CQCzDz5Gp0Ptc\n"
+ + "TfQqm64xnhtAruXNJXWg2ptg+GuQgWnJUgQ8wLNMxw9XdeEwlQo5dL6xmg==";
+
+ public static final String DUMMY_SIGNING_CERT_FINGERPRINT =
+ "IwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJvN3l1pjzlnmoW";
}
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 e19ef5fc..af155206 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
@@ -1,16 +1,16 @@
package at.gv.egiz.eaaf.modules.auth.sl20;
/**
- * Set of event codes uses in Auth-Handler implementation
- *
+ * Set of event codes uses in Auth-Handler implementation.
+ *
* @author tlenz
*
*/
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;
+ 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/data/VerificationResult.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java
index 0c625a9b..7ca4ea87 100644
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java
@@ -7,33 +7,34 @@ import com.fasterxml.jackson.databind.JsonNode;
public class VerificationResult {
- private Boolean validSigned = null;
- private List<X509Certificate> certs = null;
- private JsonNode payload = null;
-
- public VerificationResult(JsonNode payload) {
- this.payload = payload;
-
- }
-
- public VerificationResult(JsonNode string, List<X509Certificate> certs, boolean wasValidSigned) {
- this.payload = string;
- this.certs = certs;
- this.validSigned = wasValidSigned;
-
- }
-
- public Boolean isValidSigned() {
- return validSigned;
- }
- public List<X509Certificate> getCertChain() {
- return certs;
- }
- public JsonNode getPayload() {
- return payload;
- }
-
-
-
-
+ private Boolean validSigned = null;
+ private List<X509Certificate> certs = null;
+ private JsonNode payload = null;
+
+ public VerificationResult(final JsonNode payload) {
+ this.payload = payload;
+
+ }
+
+ public VerificationResult(final JsonNode string, final List<X509Certificate> certs, final boolean wasValidSigned) {
+ this.payload = string;
+ this.certs = certs;
+ this.validSigned = wasValidSigned;
+
+ }
+
+ public Boolean isValidSigned() {
+ return validSigned;
+ }
+
+ public List<X509Certificate> getCertChain() {
+ return certs;
+ }
+
+ public JsonNode getPayload() {
+ return payload;
+ }
+
+
+
}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20EidDataValidationException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20EidDataValidationException.java
new file mode 100644
index 00000000..a14fbe9e
--- /dev/null
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20EidDataValidationException.java
@@ -0,0 +1,16 @@
+package at.gv.egiz.eaaf.modules.auth.sl20.exceptions;
+
+public class SL20EidDataValidationException extends SL20Exception {
+ private static final long serialVersionUID = 1L;
+
+ public SL20EidDataValidationException(final Object[] parameters) {
+ super("sl20.07", parameters);
+
+ }
+
+ public SL20EidDataValidationException(final Object[] parameters, final Throwable e) {
+ super("sl20.07", parameters, e);
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20Exception.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20Exception.java
index b23b5ca3..12921ad6 100644
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20Exception.java
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20Exception.java
@@ -1,19 +1,19 @@
package at.gv.egiz.eaaf.modules.auth.sl20.exceptions;
-import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
-public class SL20Exception extends EAAFAuthenticationException {
+public class SL20Exception extends EaafAuthenticationException {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
- public SL20Exception(String messageId, Object[] parameters) {
- super(messageId, parameters);
+ public SL20Exception(final String messageId, final Object[] parameters) {
+ super(messageId, parameters);
- }
-
- public SL20Exception(String messageId, Object[] parameters, Throwable wrapped) {
- super(messageId, parameters, wrapped);
+ }
- }
+ public SL20Exception(final String messageId, final Object[] parameters, final Throwable wrapped) {
+ super(messageId, parameters, wrapped);
+
+ }
}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20SecurityException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20SecurityException.java
index eaf55ba3..c751f2c2 100644
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20SecurityException.java
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20SecurityException.java
@@ -2,19 +2,19 @@ package at.gv.egiz.eaaf.modules.auth.sl20.exceptions;
public class SL20SecurityException extends SL20Exception {
- private static final long serialVersionUID = 3281385988027147449L;
+ private static final long serialVersionUID = 3281385988027147449L;
- public SL20SecurityException(Object[] parameters) {
- super("sl20.05", parameters);
- }
-
- public SL20SecurityException(String parameter) {
- super("sl20.05", new Object[] {parameter});
- }
-
- public SL20SecurityException(Object[] parameters, Throwable wrapped) {
- super("sl20.05", parameters, wrapped);
+ public SL20SecurityException(final Object[] parameters) {
+ super("sl20.05", parameters);
+ }
- }
+ public SL20SecurityException(final String parameter) {
+ super("sl20.05", new Object[] {parameter});
+ }
+
+ public SL20SecurityException(final Object[] parameters, final Throwable wrapped) {
+ super("sl20.05", parameters, wrapped);
+
+ }
}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20eIDDataValidationException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20eIDDataValidationException.java
deleted file mode 100644
index 24df735a..00000000
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20eIDDataValidationException.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package at.gv.egiz.eaaf.modules.auth.sl20.exceptions;
-
-public class SL20eIDDataValidationException extends SL20Exception {
- private static final long serialVersionUID = 1L;
-
- public SL20eIDDataValidationException(Object[] parameters) {
- super("sl20.07", parameters);
-
- }
-
- public SL20eIDDataValidationException(Object[] parameters, Throwable e) {
- super("sl20.07", parameters, e);
-
- }
-
-}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoBuildException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoBuildException.java
deleted file mode 100644
index 1f521ebc..00000000
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoBuildException.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package at.gv.egiz.eaaf.modules.auth.sl20.exceptions;
-
-public class SLCommandoBuildException extends SL20Exception {
-
- private static final long serialVersionUID = 1L;
-
-
- public SLCommandoBuildException(String msg) {
- super("sl20.01", new Object[]{msg});
-
- }
-
- public SLCommandoBuildException(String msg, Throwable e) {
- super("sl20.01", new Object[]{msg}, e);
-
- }
-}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoParserException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoParserException.java
deleted file mode 100644
index 60993e69..00000000
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SLCommandoParserException.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package at.gv.egiz.eaaf.modules.auth.sl20.exceptions;
-
-public class SLCommandoParserException extends SL20Exception {
-
- private static final long serialVersionUID = 1L;
-
-
- public SLCommandoParserException(String msg) {
- super("sl20.02", new Object[]{msg});
-
- }
-
- public SLCommandoParserException(String msg, Throwable e) {
- super("sl20.02", new Object[]{msg}, e);
-
- }
-}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoBuildException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoBuildException.java
new file mode 100644
index 00000000..bed1cdb0
--- /dev/null
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoBuildException.java
@@ -0,0 +1,17 @@
+package at.gv.egiz.eaaf.modules.auth.sl20.exceptions;
+
+public class SlCommandoBuildException extends SL20Exception {
+
+ private static final long serialVersionUID = 1L;
+
+
+ public SlCommandoBuildException(final String msg) {
+ super("sl20.01", new Object[] {msg});
+
+ }
+
+ public SlCommandoBuildException(final String msg, final Throwable e) {
+ super("sl20.01", new Object[] {msg}, e);
+
+ }
+}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoParserException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoParserException.java
new file mode 100644
index 00000000..dab42631
--- /dev/null
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SlCommandoParserException.java
@@ -0,0 +1,17 @@
+package at.gv.egiz.eaaf.modules.auth.sl20.exceptions;
+
+public class SlCommandoParserException extends SL20Exception {
+
+ private static final long serialVersionUID = 1L;
+
+
+ public SlCommandoParserException(final String msg) {
+ super("sl20.02", new Object[] {msg});
+
+ }
+
+ public SlCommandoParserException(final String msg, final Throwable e) {
+ super("sl20.02", new Object[] {msg}, e);
+
+ }
+}
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
new file mode 100644
index 00000000..251b516f
--- /dev/null
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualEidRequestTask.java
@@ -0,0 +1,250 @@
+package at.gv.egiz.eaaf.modules.auth.sl20.tasks;
+
+import java.security.cert.CertificateEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
+import at.gv.egiz.eaaf.core.api.idp.IspConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
+import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils;
+import at.gv.egiz.eaaf.modules.auth.sl20.Constants;
+import at.gv.egiz.eaaf.modules.auth.sl20.EventCodes;
+import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException;
+import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants;
+import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20HttpBindingUtils;
+import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JsonExtractorUtils;
+import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JsonBuilderUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.message.BasicNameValuePair;
+import org.jose4j.base64url.Base64Url;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public abstract class AbstractCreateQualEidRequestTask extends AbstractAuthServletTask {
+ private static final Logger log = LoggerFactory.getLogger(AbstractCreateQualEidRequestTask.class);
+
+ @Autowired(required = true)
+ private IHttpClientFactory httpClientFactory;
+ @Autowired(required = true)
+ protected IConfigurationWithSP authConfigWithSp;
+
+ @Override
+ public void execute(final ExecutionContext executionContext, final HttpServletRequest request,
+ final HttpServletResponse response) throws TaskExecutionException {
+
+ log.debug("Starting SL2.0 authentication process .... ");
+
+ revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_SELECTED, "sl20auth");
+
+ try {
+ // get service-provider configuration
+ final IspConfiguration oaConfig = pendingReq.getServiceProviderConfiguration();
+
+ if (oaConfig == null) {
+ log.warn("No SP configuration in pendingReq!");
+ throw new RuntimeException("Suspect state. NO SP CONFIGURATION IN PendingRequest!");
+
+ }
+
+ // get basic configuration parameters
+ final String vdaQualEidDUrl = extractVdaUrlForSpecificOa(oaConfig, executionContext);
+ if (StringUtils.isEmpty(vdaQualEidDUrl)) {
+ log.error("NO VDA URL for qualified eID ("
+ + Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT + ")");
+ throw new SL20Exception("sl20.03", new Object[] {"NO VDA URL for qualified eID"});
+
+ }
+
+ log.debug("Use {} as VDA end-point", vdaQualEidDUrl);
+ pendingReq.setRawDataToTransaction(
+ Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL,
+ vdaQualEidDUrl);
+ revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_ENDPOINT_URL, vdaQualEidDUrl);
+
+ // create SL2.0 command for qualified eID
+ final String signedQualEidCommand = buildSignedQualifiedEidCommand();
+
+ // build request container
+ final String qualEidReqId = Random.nextProcessReferenceValue();
+ final ObjectNode sl20Req =
+ SL20JsonBuilderUtils.createGenericRequest(qualEidReqId, null, null, signedQualEidCommand);
+
+ // build http POST request
+ final HttpPost httpReq = new HttpPost(new URIBuilder(vdaQualEidDUrl).build());
+ final List<NameValuePair> parameters = new ArrayList<>();
+ parameters.add(new BasicNameValuePair(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM,
+ Base64Url.encode(sl20Req.toString().getBytes())));
+ httpReq.setEntity(new UrlEncodedFormEntity(parameters));
+
+ // build http GET request
+ // URIBuilder sl20ReqUri = new URIBuilder(vdaQualeIDUrl);
+ // sl20ReqUri.addParameter(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM,
+ // Base64Url.encode(sl20Req.toString().getBytes()));
+ // HttpGet httpReq = new HttpGet(sl20ReqUri.build());
+
+ // set native client header
+ httpReq.addHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE,
+ SL20Constants.HTTP_HEADER_VALUE_NATIVE);
+
+ log.trace("Request VDA via SL20 with: " + Base64Url.encode(sl20Req.toString().getBytes()));
+
+ // request VDA
+ final HttpResponse httpResp = httpClientFactory.getHttpClient(false).execute(httpReq);
+
+ // parse response
+ log.info("Receive response from VDA ... ");
+ final JsonNode sl20Resp = SL20JsonExtractorUtils.getSL20ContainerFromResponse(httpResp);
+ final VerificationResult respPayloadContainer =
+ SL20JsonExtractorUtils.extractSL20PayLoad(sl20Resp, null, false);
+
+ if (respPayloadContainer.isValidSigned() == null) {
+ log.debug("Receive unsigned payLoad from VDA");
+
+ }
+
+ final JsonNode respPayload = respPayloadContainer.getPayload();
+ if (respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText()
+ .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT)) {
+ log.debug("Find 'redirect' command in VDA response ... ");
+ final JsonNode params = SL20JsonExtractorUtils.getJsonObjectValue(respPayload,
+ SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, true);
+ final String redirectUrl = SL20JsonExtractorUtils.getStringValue(params,
+ SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL, true);
+ final JsonNode command = SL20JsonExtractorUtils.getJsonObjectValue(params,
+ SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND, false);
+ final String signedCommand = SL20JsonExtractorUtils.getStringValue(params,
+ SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND, false);
+
+ // create forward SL2.0 command
+ final ObjectNode sl20Forward = sl20Resp.deepCopy();
+ SL20JsonBuilderUtils.addOnlyOnceOfTwo(sl20Forward, SL20Constants.SL20_PAYLOAD,
+ SL20Constants.SL20_SIGNEDPAYLOAD, command.deepCopy(), signedCommand);
+
+ // store pending request
+ pendingReq.setRawDataToTransaction(
+ Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, qualEidReqId);
+ requestStoreage.storePendingRequest(pendingReq);
+
+ // forward SL2.0 command
+ // TODO: maybe add SL2ClientType Header from execution context
+ 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)) {
+ JsonNode result = SL20JsonExtractorUtils.getJsonObjectValue(respPayload,
+ SL20Constants.SL20_COMMAND_CONTAINER_RESULT, false);
+ if (result == null) {
+ result = SL20JsonExtractorUtils.getJsonObjectValue(respPayload,
+ SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, false);
+ }
+
+ final String errorCode = SL20JsonExtractorUtils.getStringValue(result,
+ SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, true);
+ final String errorMsg = SL20JsonExtractorUtils.getStringValue(result,
+ SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, true);
+
+ log.info("Receive SL2.0 error. Code:" + errorCode + " Msg:" + errorMsg);
+ throw new SL20Exception("sl20.08", new Object[] {errorCode, errorMsg});
+
+ } else {
+ // TODO: update to add error handling
+ log.warn("Received an unrecognized command: "
+ + respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText());
+ throw new SlCommandoParserException(
+ "Received an unrecognized command: "
+ + respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).toString());
+ }
+
+
+ } catch (final EaafAuthenticationException e) {
+ throw new TaskExecutionException(pendingReq,
+ "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e);
+
+ } catch (final Exception e) {
+ log.warn("SL2.0 Authentication FAILED with a generic error.", e);
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ } finally {
+ TransactionIdUtils.removeTransactionId();
+ TransactionIdUtils.removeSessionId();
+
+ }
+
+ }
+
+ /**
+ * Create a implementation specific qualified eID SL2.0 command
+ *
+ * @param oaConfig
+ *
+ * @return signed JWT token as serialized {@link String}
+ * @throws CertificateEncodingException In case of certificate parsing error
+ * @throws SL20Exception In case of a SL2.0 error
+ */
+ protected abstract String buildSignedQualifiedEidCommand()
+ throws CertificateEncodingException, SL20Exception;
+
+
+ private String extractVdaUrlForSpecificOa(final IspConfiguration oaConfig,
+ final ExecutionContext executionContext) {
+
+ // 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<String, String> endPointMap = authConfigWithSp
+ .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(KeyValueUtils.normalizeCsvValueString(spSpecificVdaEndpoints))));
+ log.debug("Find OA specific SL2.0 endpoints. Updating endPoint list ... ");
+
+ }
+
+ log.trace("Find #" + endPointMap.size() + " SL2.0 endpoints ... ");
+
+ // selection based on request Header
+ final String sl20VdaTypeHeader =
+ (String) executionContext.get(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE.toLowerCase());
+ if (StringUtils.isNotEmpty(sl20VdaTypeHeader)) {
+ final String vdaUrl = endPointMap.get(sl20VdaTypeHeader);
+ if (StringUtils.isNotEmpty(vdaUrl)) {
+ return vdaUrl.trim();
+ } else {
+ log.info("Can NOT find VDA with Id: " + sl20VdaTypeHeader + ". Use default VDA");
+ }
+
+ }
+
+
+ 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/AbstractCreateQualeIDRequestTask.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualeIDRequestTask.java
deleted file mode 100644
index 85302d83..00000000
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractCreateQualeIDRequestTask.java
+++ /dev/null
@@ -1,227 +0,0 @@
-package at.gv.egiz.eaaf.modules.auth.sl20.tasks;
-
-import java.security.cert.CertificateEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.message.BasicNameValuePair;
-import org.jose4j.base64url.Base64Url;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
-import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
-import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
-import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
-import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
-import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
-import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
-import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
-import at.gv.egiz.eaaf.core.impl.utils.Random;
-import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
-import at.gv.egiz.eaaf.modules.auth.sl20.Constants;
-import at.gv.egiz.eaaf.modules.auth.sl20.EventCodes;
-import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoBuildException;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoParserException;
-import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants;
-import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20HttpBindingUtils;
-import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JSONBuilderUtils;
-import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JSONExtractorUtils;
-
-public abstract class AbstractCreateQualeIDRequestTask extends AbstractAuthServletTask {
- private static final Logger log = LoggerFactory.getLogger(AbstractCreateQualeIDRequestTask.class);
-
- @Autowired(required=true) private IHttpClientFactory httpClientFactory;
- @Autowired(required=true) protected IConfigurationWithSP authConfigWithSp;
-
- @Override
- public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
- throws TaskExecutionException {
-
- log.debug("Starting SL2.0 authentication process .... ");
-
- revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_SELECTED, "sl20auth");
-
- try {
- //get service-provider configuration
- final ISPConfiguration oaConfig = pendingReq.getServiceProviderConfiguration();
-
- if (oaConfig == null) {
- log.warn("No SP configuration in pendingReq!");
- throw new RuntimeException("Suspect state. NO SP CONFIGURATION IN PendingRequest!");
-
- }
-
- //get basic configuration parameters
- final String vdaQualeIDUrl = extractVDAURLForSpecificOA(oaConfig, executionContext);
- if (StringUtils.isEmpty(vdaQualeIDUrl)) {
- log.error("NO VDA URL for qualified eID (" + Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT + ")");
- throw new SL20Exception("sl20.03", new Object[]{"NO VDA URL for qualified eID"});
-
- }
-
- 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
- final String signedQualeIDCommand = buildSignedQualifiedEIDCommand();
-
- //build request container
- final String qualeIDReqId = Random.nextProcessReferenceValue();
- final ObjectNode sl20Req = SL20JSONBuilderUtils.createGenericRequest(qualeIDReqId, null, null, signedQualeIDCommand);
-
- //build http POST request
- final HttpPost httpReq = new HttpPost(new URIBuilder(vdaQualeIDUrl).build());
- final List<NameValuePair> parameters = new ArrayList<NameValuePair>();;
- parameters.add(new BasicNameValuePair(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, Base64Url.encode(sl20Req.toString().getBytes())));
- httpReq.setEntity(new UrlEncodedFormEntity(parameters ));
-
- //build http GET request
-// URIBuilder sl20ReqUri = new URIBuilder(vdaQualeIDUrl);
-// sl20ReqUri.addParameter(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, Base64Url.encode(sl20Req.toString().getBytes()));
-// HttpGet httpReq = new HttpGet(sl20ReqUri.build());
-
- //set native client header
- httpReq.addHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE, SL20Constants.HTTP_HEADER_VALUE_NATIVE);
-
- log.trace("Request VDA via SL20 with: " + Base64Url.encode(sl20Req.toString().getBytes()));
-
- //request VDA
- final HttpResponse httpResp = httpClientFactory.getHttpClient(false).execute(httpReq);
-
- //parse response
- log.info("Receive response from VDA ... ");
- final JsonNode sl20Resp = SL20JSONExtractorUtils.getSL20ContainerFromResponse(httpResp);
- final VerificationResult respPayloadContainer = SL20JSONExtractorUtils.extractSL20PayLoad(sl20Resp, null, false);
-
- if (respPayloadContainer.isValidSigned() == null) {
- log.debug("Receive unsigned payLoad from VDA");
-
- }
-
- final JsonNode respPayload = respPayloadContainer.getPayload();
- if (respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText()
- .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT)) {
- log.debug("Find 'redirect' command in VDA response ... ");
- final JsonNode params = SL20JSONExtractorUtils.getJSONObjectValue(respPayload, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, true);
- final String redirectURL = SL20JSONExtractorUtils.getStringValue(params, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL, true);
- final JsonNode command = SL20JSONExtractorUtils.getJSONObjectValue(params, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND, false);
- final String signedCommand = SL20JSONExtractorUtils.getStringValue(params, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND, false);
-
- //create forward SL2.0 command
- final ObjectNode sl20Forward = sl20Resp.deepCopy();
- SL20JSONBuilderUtils.addOnlyOnceOfTwo(sl20Forward,
- SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD,
- command.deepCopy(), signedCommand);
-
- //store pending request
- pendingReq.setRawDataToTransaction(Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID,
- qualeIDReqId);
- requestStoreage.storePendingRequest(pendingReq);
-
- //forward SL2.0 command
- //TODO: maybe add SL2ClientType Header from execution context
- 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)) {
- JsonNode result = SL20JSONExtractorUtils.getJSONObjectValue(respPayload, SL20Constants.SL20_COMMAND_CONTAINER_RESULT, false);
- if (result == null)
- result = SL20JSONExtractorUtils.getJSONObjectValue(respPayload, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, false);
-
- final String errorCode = SL20JSONExtractorUtils.getStringValue(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, true);
- final String errorMsg = SL20JSONExtractorUtils.getStringValue(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, true);
-
- log.info("Receive SL2.0 error. Code:" + errorCode + " Msg:" + errorMsg);
- throw new SL20Exception("sl20.08", new Object[]{errorCode, errorMsg});
-
- } else {
- //TODO: update to add error handling
- log.warn("Received an unrecognized command: " + respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).asText());
- throw new SLCommandoParserException("Received an unrecognized command: \" + respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).getAsString()");
- }
-
-
- } catch (final EAAFAuthenticationException e) {
- throw new TaskExecutionException(pendingReq, "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e);
-
- } catch (final Exception e) {
- log.warn("SL2.0 Authentication FAILED with a generic error.", e);
- throw new TaskExecutionException(pendingReq, e.getMessage(), e);
-
- } finally {
- TransactionIDUtils.removeTransactionId();
- TransactionIDUtils.removeSessionId();
-
- }
-
- }
-
- /**
- * Create a implementation specific qualified eID SL2.0 command
- * @param oaConfig
- *
- * @return signed JWT token as serialized {@link String}
- * @throws CertificateEncodingException
- * @throws SLCommandoBuildException
- * @throws SL20Exception
- */
- protected abstract String buildSignedQualifiedEIDCommand() throws CertificateEncodingException, SL20Exception;
-
-
- private String extractVDAURLForSpecificOA(ISPConfiguration oaConfig, ExecutionContext executionContext) {
-
- //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<String, String> endPointMap = authConfigWithSp.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(
- KeyValueUtils.normalizeCSVValueString(spSpecificVDAEndpoints))));
- log.debug("Find OA specific SL2.0 endpoints. Updating endPoint list ... ");
-
- }
-
- log.trace("Find #" + endPointMap.size() + " SL2.0 endpoints ... ");
-
- //selection based on request Header
- final String sl20VDATypeHeader = (String) executionContext.get(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE.toLowerCase());
- if (StringUtils.isNotEmpty(sl20VDATypeHeader)) {
- final String vdaURL = endPointMap.get(sl20VDATypeHeader);
- if (StringUtils.isNotEmpty(vdaURL))
- return vdaURL.trim();
- else
- log.info("Can NOT find VDA with Id: " + sl20VDATypeHeader + ". Use default VDA");
-
- }
-
-
- 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
new file mode 100644
index 00000000..39cfce05
--- /dev/null
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualEidTask.java
@@ -0,0 +1,344 @@
+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;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
+import at.gv.egiz.eaaf.core.impl.utils.DataUrlBuilder;
+import at.gv.egiz.eaaf.core.impl.utils.StreamUtils;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils;
+import at.gv.egiz.eaaf.modules.auth.sl20.Constants;
+import at.gv.egiz.eaaf.modules.auth.sl20.EventCodes;
+import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException;
+import at.gv.egiz.eaaf.modules.auth.sl20.utils.IJoseTools;
+import at.gv.egiz.eaaf.modules.auth.sl20.utils.JsonMapper;
+import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants;
+import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JsonBuilderUtils;
+import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JsonExtractorUtils;
+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;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+
+public abstract class AbstractReceiveQualEidTask extends AbstractAuthServletTask {
+ private static final Logger log = LoggerFactory.getLogger(AbstractReceiveQualEidTask.class);
+
+ private static final String PATTERN_PENDING_REQ_ID = "#PENDINGREQID#";
+
+ @Autowired(required = true)
+ private IJoseTools joseTools;
+
+ @Override
+ public void execute(final ExecutionContext executionContext, final HttpServletRequest request,
+ final HttpServletResponse response) throws TaskExecutionException {
+ String sl20Result = null;
+
+ try {
+ log.debug("Receiving SL2.0 response process .... ");
+ 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<String, String> reqParams = getParameters(request);
+ sl20Result = reqParams.get(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM);
+
+ if (StringUtils.isEmpty(sl20Result)) {
+ // Workaround for SIC Handy-Signature, because it sends result in InputStream
+ final String isReqInput = StreamUtils.readStream(request.getInputStream(), "UTF-8");
+ if (StringUtils.isNotEmpty(isReqInput)) {
+ log.info("Use SIC Handy-Signature work-around!");
+ sl20Result = isReqInput.substring("slcommand=".length());
+
+ } else {
+ log.info("NO SL2.0 commando or result FOUND.");
+ throw new SL20Exception("sl20.04", null);
+ }
+
+ }
+
+ log.trace("Received SL2.0 result: " + sl20Result);
+ revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_DATAURL_IP,
+ request.getRemoteAddr());
+
+ // parse SL2.0 command/result into JSON
+ try {
+ sl20ReqObj =
+ new JsonMapper().getMapper().readTree(Base64Url.decodeToUtf8String(sl20Result));
+
+ } catch (final JsonParseException e) {
+ log.warn("SL2.0 command or result is NOT valid JSON.", e);
+ log.debug("SL2.0 msg: " + sl20Result);
+ throw new SL20Exception("sl20.02",
+ new Object[] {"SL2.0 command or result is NOT valid JSON."}, e);
+
+ }
+
+ // 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 ... ",
+ errorCode, errorMsg);
+ // 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);
+ }
+
+
+ // 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();
+
+
+ // 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);
+ if (sl20Result != null) {
+ log.debug("Received SL2.0 result: " + sl20Result);
+ }
+ pendingReq.setRawDataToTransaction(
+ Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR,
+ new TaskExecutionException(pendingReq,
+ "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e));
+
+ } catch (final Exception e) {
+ log.warn("ERROR:", e);
+ log.warn("SL2.0 Authentication FAILED with a generic error.", e);
+ if (sl20Result != null) {
+ log.debug("Received SL2.0 result: " + sl20Result);
+ }
+ pendingReq.setRawDataToTransaction(
+ Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR,
+ new TaskExecutionException(pendingReq, e.getMessage(), e));
+
+ } finally {
+ // store pending request
+ requestStoreage.storePendingRequest(pendingReq);
+
+ // write SL2.0 response
+ if (sl20ReqObj != null) {
+ // buildResponse(request, response, sl20ReqObj, aTrustErrorWorkAround);
+ buildResponse(request, response, sl20ReqObj);
+ } else {
+ buildErrorResponse(request, response, "2000", "General transport Binding error");
+ }
+
+ }
+
+ } catch (final Exception e) {
+ // write internal server errror 500 according to SL2.0 specification, chapter https transport
+ // binding
+ log.warn("Can NOT build SL2.0 response. Reason: " + e.getMessage(), e);
+ if (sl20Result != null) {
+ log.debug("Received SL2.0 result: " + sl20Result);
+ }
+ try {
+ response.sendError(500, "Internal Server Error.");
+
+ } catch (final IOException e1) {
+ log.error("Can NOT send error message. SOMETHING IS REALY WRONG!", e);
+
+ }
+
+ } finally {
+ TransactionIdUtils.removeTransactionId();
+ TransactionIdUtils.removeSessionId();
+
+ }
+ }
+
+ protected abstract void handleResponsePayLoad(JsonNode payLoad)
+ throws SlCommandoParserException, SL20Exception, EaafStorageException;
+
+ protected abstract String getResumeEndPoint();
+
+ private void buildErrorResponse(final HttpServletRequest request,
+ final HttpServletResponse response, final String errorCode, final String errorMsg)
+ throws Exception {
+ final ObjectNode error = SL20JsonBuilderUtils.createErrorCommandResult(errorCode, errorMsg);
+ final ObjectNode errorCommand = SL20JsonBuilderUtils
+ .createCommandResponse(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR, error, null);
+
+
+ final ObjectNode respContainer = SL20JsonBuilderUtils
+ .createGenericResponse(UUID.randomUUID().toString(), null, null, errorCommand, null);
+
+ 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);
+
+ }
+
+ private void buildResponse(final HttpServletRequest request, final HttpServletResponse response,
+ final JsonNode sl20ReqObj) throws IOException, SL20Exception, URISyntaxException {
+ // create response
+ final Map<String, String> 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(
+ generateIpcRedirectUrlForDebugging(), 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, false);
+ 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);
+
+ if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null
+ && request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE)
+ .equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) {
+ 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 + "'");
+
+ 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.
+ *
+ * @return IPC ReturnURL, or null if no URL is configured
+ */
+ private String generateIpcRedirectUrlForDebugging() {
+
+
+ String ipcRedirectUrlConfig =
+ authConfig.getBasicConfiguration(Constants.CONFIG_PROP_IPC_RETURN_URL);
+ if (StringUtils.isNotEmpty(ipcRedirectUrlConfig)) {
+ if (ipcRedirectUrlConfig.contains(PATTERN_PENDING_REQ_ID)) {
+ log.trace("Find 'pendingReqId' pattern in IPC redirect URL. Update url ... ");
+ ipcRedirectUrlConfig = ipcRedirectUrlConfig.replaceAll("#PENDINGREQID#",
+ EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID + "="
+ + pendingReq.getPendingRequestId());
+
+ }
+
+ return ipcRedirectUrlConfig;
+ }
+
+ return null;
+
+ }
+
+
+}
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
deleted file mode 100644
index b4039cf9..00000000
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualeIDTask.java
+++ /dev/null
@@ -1,321 +0,0 @@
-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;
-
-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;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
-import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
-import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
-import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
-import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
-import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
-import at.gv.egiz.eaaf.core.impl.utils.DataURLBuilder;
-import at.gv.egiz.eaaf.core.impl.utils.StreamUtils;
-import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
-import at.gv.egiz.eaaf.modules.auth.sl20.Constants;
-import at.gv.egiz.eaaf.modules.auth.sl20.EventCodes;
-import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoParserException;
-import at.gv.egiz.eaaf.modules.auth.sl20.utils.IJOSETools;
-import at.gv.egiz.eaaf.modules.auth.sl20.utils.JsonMapper;
-import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants;
-import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JSONBuilderUtils;
-import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JSONExtractorUtils;
-
-
-public abstract class AbstractReceiveQualeIDTask extends AbstractAuthServletTask {
- private static final Logger log = LoggerFactory.getLogger(AbstractReceiveQualeIDTask.class);
-
- @Autowired(required=true) private IJOSETools joseTools;
-
- @Override
- public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
- throws TaskExecutionException {
- String sl20Result = null;
-
- try {
- log.debug("Receiving SL2.0 response process .... ");
- 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<String, String> reqParams = getParameters(request);
- sl20Result = reqParams.get(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM);
-
- if (StringUtils.isEmpty(sl20Result)) {
- //Workaround for SIC Handy-Signature, because it sends result in InputStream
- final String isReqInput = StreamUtils.readStream(request.getInputStream(), "UTF-8");
- if (StringUtils.isNotEmpty(isReqInput)) {
- log.info("Use SIC Handy-Signature work-around!");
- sl20Result = isReqInput.substring("slcommand=".length());
-
- } else {
- log.info("NO SL2.0 commando or result FOUND.");
- throw new SL20Exception("sl20.04", null);
- }
-
- }
-
- log.trace("Received SL2.0 result: " + sl20Result);
- revisionsLogger.logEvent(pendingReq, EventCodes.AUTHPROCESS_SL20_DATAURL_IP, request.getRemoteAddr());
-
- //parse SL2.0 command/result into JSON
- try {
- sl20ReqObj = new JsonMapper().getMapper().readTree(Base64Url.decodeToUtf8String(sl20Result));
-
- } catch (final JsonParseException e) {
- log.warn("SL2.0 command or result is NOT valid JSON.", e);
- log.debug("SL2.0 msg: " + sl20Result);
- throw new SL20Exception("sl20.02", new Object[]{"SL2.0 command or result is NOT valid JSON."}, e);
-
- }
-
- //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 ... ", errorCode, errorMsg);
- //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);
- }
-
-
- //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();
-
-
- //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);
- if (sl20Result != null)
- log.debug("Received SL2.0 result: " + sl20Result);
- pendingReq.setRawDataToTransaction(
- Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR,
- new TaskExecutionException(pendingReq, "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e));
-
- } catch (final Exception e) {
- log.warn("ERROR:", e);
- log.warn("SL2.0 Authentication FAILED with a generic error.", e);
- if (sl20Result != null)
- log.debug("Received SL2.0 result: " + sl20Result);
- pendingReq.setRawDataToTransaction(
- Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR,
- new TaskExecutionException(pendingReq, e.getMessage(), e));
-
- } finally {
- //store pending request
- requestStoreage.storePendingRequest(pendingReq);
-
- //write SL2.0 response
- if (sl20ReqObj != null)
- //buildResponse(request, response, sl20ReqObj, aTrustErrorWorkAround);
- buildResponse(request, response, sl20ReqObj);
- else
- buildErrorResponse(request, response, "2000", "General transport Binding error");
-
- }
-
- } catch (final Exception e) {
- //write internal server errror 500 according to SL2.0 specification, chapter https transport binding
- log.warn("Can NOT build SL2.0 response. Reason: " + e.getMessage(), e);
- if (sl20Result != null)
- log.debug("Received SL2.0 result: " + sl20Result);
- try {
- response.sendError(500, "Internal Server Error.");
-
- } catch (final IOException e1) {
- log.error("Can NOT send error message. SOMETHING IS REALY WRONG!", e);
-
- }
-
- } finally {
- TransactionIDUtils.removeTransactionId();
- TransactionIDUtils.removeSessionId();
-
- }
- }
-
- protected abstract void handleResponsePayLoad(JsonNode payLoad) throws SLCommandoParserException, SL20Exception, EAAFStorageException;
-
- protected abstract String getResumeEndPoint();
-
- private void buildErrorResponse(HttpServletRequest request, HttpServletResponse response, String errorCode, String errorMsg) throws Exception {
- final ObjectNode error = SL20JSONBuilderUtils.createErrorCommandResult(errorCode, errorMsg);
- final ObjectNode errorCommand = SL20JSONBuilderUtils.createCommandResponse(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR, error, null);
-
-
- final ObjectNode respContainer = SL20JSONBuilderUtils.createGenericResponse(
- UUID.randomUUID().toString(),
- null,
- null,
- errorCommand ,
- null);
-
- 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);
-
- }
-
- private void buildResponse(HttpServletRequest request, HttpServletResponse response, JsonNode sl20ReqObj) throws IOException, SL20Exception, URISyntaxException {
- //create response
- final Map<String, String> reqParameters = new HashMap<String, String>();
- 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, false);
- 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);
-
- if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null &&
- request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE).equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) {
- 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 + "'");
-
- 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
- *
- * @return IPC ReturnURL, or null if no URL is configured
- */
- private String generateICPRedirectURLForDebugging() {
- final String PATTERN_PENDING_REQ_ID = "#PENDINGREQID#";
-
- String ipcRedirectURLConfig = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_IPC_RETURN_URL);
- if (StringUtils.isNotEmpty(ipcRedirectURLConfig)) {
- if (ipcRedirectURLConfig.contains(PATTERN_PENDING_REQ_ID)) {
- log.trace("Find 'pendingReqId' pattern in IPC redirect URL. Update url ... ");
- ipcRedirectURLConfig = ipcRedirectURLConfig.replaceAll(
- "#PENDINGREQID#",
- EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID + "=" + pendingReq.getPendingRequestId());
-
- }
-
- return ipcRedirectURLConfig;
- }
-
- return null;
-
- }
-
-
-}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJOSETools.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJOSETools.java
deleted file mode 100644
index b124ada7..00000000
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJOSETools.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package at.gv.egiz.eaaf.modules.auth.sl20.utils;
-
-import java.io.IOException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.cert.X509Certificate;
-import java.util.List;
-
-import javax.annotation.Nonnull;
-
-import org.jose4j.jwa.AlgorithmConstraints;
-import org.jose4j.lang.JoseException;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoBuildException;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoParserException;
-
-public interface IJOSETools {
-
- /**
- * Create a JWS signature
- *
- * @param payLoad Payload to sign
- * @throws SLCommandoBuildException
- */
- public String createSignature(String payLoad) throws SLCommandoBuildException;
-
- /**
- * Validates a signed SL2.0 message
- *
- * @param serializedContent
- * @return
- * @throws SLCommandoParserException
- * @throws SL20Exception
- */
- @Nonnull
- public VerificationResult validateSignature(@Nonnull String serializedContent) throws SL20Exception;
-
- /**
- * Validate a JWS signature
- *
- * @param serializedContent JWS in serialized form
- * @param trustedCerts trusted X509 certificates
- * @param constraints signature verification constraints
- * @return Signature-verification result
- * @throws JoseException
- * @throws IOException
- */
- @Nonnull
- public VerificationResult validateSignature(@Nonnull String serializedContent, @Nonnull List<X509Certificate> trustedCerts,
- @Nonnull AlgorithmConstraints constraints) throws JoseException, IOException;
-
- /**
- * Validate a JWS signature
- *
- * @param serializedContent JWS in serialized form
- * @param trustStore with trusted X509 certificates
- * @param algconstraints signature verification constraints
- * @return Signature-verification result
- * @throws JoseException
- * @throws IOException
- * @throws KeyStoreException
- */
- @Nonnull
- public VerificationResult validateSignature(@Nonnull String serializedContent, @Nonnull KeyStore trustStore,
- @Nonnull AlgorithmConstraints algconstraints) throws JoseException, IOException, KeyStoreException;
-
- /**
- * Get the encryption certificate for SL2.0 End-to-End encryption
- *
- * @return
- */
- public X509Certificate getEncryptionCertificate();
-
- /**
- * Decrypt a serialized JWE token
- *
- * @param compactSerialization Serialized JWE token
- * @return decrypted payload
- * @throws SL20Exception
- */
- public JsonNode decryptPayload(String compactSerialization) throws SL20Exception;
-
-}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java
new file mode 100644
index 00000000..caa2e8d8
--- /dev/null
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java
@@ -0,0 +1,84 @@
+package at.gv.egiz.eaaf.modules.auth.sl20.utils;
+
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import javax.annotation.Nonnull;
+import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException;
+import org.jose4j.jwa.AlgorithmConstraints;
+import org.jose4j.lang.JoseException;
+import com.fasterxml.jackson.databind.JsonNode;
+
+public interface IJoseTools {
+
+ /**
+ * Create a JWS signature.
+ *
+ * @param payLoad Payload to sign
+ * @throws SlCommandoBuildException In case of a signature creation error
+ */
+ public String createSignature(String payLoad) throws SlCommandoBuildException;
+
+ /**
+ * Validates a signed SL2.0 message.
+ *
+ * @param serializedContent Serialized JWS signature
+ * @return Verification-result DAO
+ * @throws SL20Exception In case of a signature validation error
+ */
+ @Nonnull
+ public VerificationResult validateSignature(@Nonnull String serializedContent)
+ throws SL20Exception;
+
+ /**
+ * Validate a JWS signature.
+ *
+ * @param serializedContent JWS in serialized form
+ * @param trustedCerts trusted X509 certificates
+ * @param constraints signature verification constraints
+ * @return Signature-verification result
+ * @throws JoseException In case of a signature verification error
+ * @throws IOException In case of a general IO error
+ */
+ @Nonnull
+ public VerificationResult validateSignature(@Nonnull String serializedContent,
+ @Nonnull List<X509Certificate> trustedCerts, @Nonnull AlgorithmConstraints constraints)
+ throws JoseException, IOException;
+
+ /**
+ * Validate a JWS signature.
+ *
+ * @param serializedContent JWS in serialized form
+ * @param trustStore with trusted X509 certificates
+ * @param algconstraints signature verification constraints
+ * @return Signature-verification result
+ * @throws JoseException In case of a signature verification error
+ * @throws IOException In case of a general IO error
+ * @throws KeyStoreException In case of TrustStore error
+ */
+ @Nonnull
+ public VerificationResult validateSignature(@Nonnull String serializedContent,
+ @Nonnull KeyStore trustStore, @Nonnull AlgorithmConstraints algconstraints)
+ throws JoseException, IOException, KeyStoreException;
+
+ /**
+ * Get the encryption certificate for SL2.0 End-to-End encryption.
+ *
+ * @return
+ */
+ public X509Certificate getEncryptionCertificate();
+
+ /**
+ * Decrypt a serialized JWE token.
+ *
+ * @param compactSerialization Serialized JWE token
+ * @return decrypted payload
+ * @throws SL20Exception In case of a decryption error
+ */
+ public JsonNode decryptPayload(String compactSerialization) throws SL20Exception;
+
+}
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 b33649e1..f38203d2 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
@@ -18,114 +18,125 @@ import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.TypeFactory;
import at.gv.egiz.eaaf.core.api.utils.IJsonMapper;
-import at.gv.egiz.eaaf.core.exceptions.EAAFJsonMapperException;
+import at.gv.egiz.eaaf.core.exceptions.EaafJsonMapperException;
public class JsonMapper implements IJsonMapper {
- private static final Logger log = LoggerFactory.getLogger(JsonMapper.class);
-
- private final ObjectMapper mapper = new ObjectMapper();
-
- /**
- * The default constructor where the default pretty printer is disabled.
- */
- public JsonMapper() {
- this(false);
-
- }
-
- /**
- * The constructor.
- * @param prettyPrint enables or disables the default pretty printer
- */
- public JsonMapper(@NonNull boolean prettyPrint) {
- log.trace("Initializing JSON object-mapper ... ");
- mapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true);
- mapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true);
- mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES , true);
- mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
- mapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY);
- mapper.setVisibility(PropertyAccessor.IS_GETTER, Visibility.PUBLIC_ONLY);
- if (prettyPrint) {
- mapper.enable(SerializationFeature.INDENT_OUTPUT);
- }
-
- log.debug("JSON object-mapper initialized");
-
- }
-
-
- /* (non-Javadoc)
- * @at.gv.egiz.eaaf.core.api.utils.IJsonMapper#getMapper()
- */
- public ObjectMapper getMapper() {
- return mapper;
-
- }
-
-
- /* (non-Javadoc)
- * @see at.gv.egiz.eaaf.core.api.utils.IJsonMapper#serialize(java.lang.Object)
- */
- @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);
-
- }
-
- }
-
- /* (non-Javadoc)
- * @see at.gv.egiz.eaaf.core.api.utils.IJsonMapper#deserialize(java.lang.String, java.lang.Class)
- */
- @Override
- public <T> Object deserialize(String value, Class<T> 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);
-
- } catch (final IOException e) {
- log.warn("JSON mapping FAILED with error: {}", e.getMessage());
- throw new EAAFJsonMapperException(e.getMessage(), e);
-
- }
-
- }
-
- @Override
- public <T> Object deserialize(InputStream is, Class<T> clazz) throws EAAFJsonMapperException {
- try {
- if (clazz != null) {
- if (clazz.isAssignableFrom(TypeReference.class))
- return mapper.readValue(is, clazz);
- else {
- final JavaType javaType = TypeFactory.defaultInstance().constructType(clazz);
- return mapper.readValue(is, javaType);
-
- }
-
- } else
- return mapper.readValue(is, Object.class);
-
- } catch (final IOException e) {
- log.warn("JSON mapping FAILED with error: {}", e.getMessage());
- throw new EAAFJsonMapperException(e.getMessage(), e);
-
- }
-
- }
-
+ private static final Logger log = LoggerFactory.getLogger(JsonMapper.class);
+
+ private final ObjectMapper mapper = new ObjectMapper();
+
+ /**
+ * The default constructor where the default pretty printer is disabled.
+ */
+ public JsonMapper() {
+ this(false);
+
+ }
+
+ /**
+ * The constructor.
+ *
+ * @param prettyPrint enables or disables the default pretty printer
+ */
+ public JsonMapper(@NonNull final boolean prettyPrint) {
+ log.trace("Initializing JSON object-mapper ... ");
+ mapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true);
+ mapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true);
+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
+ mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
+ mapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY);
+ mapper.setVisibility(PropertyAccessor.IS_GETTER, Visibility.PUBLIC_ONLY);
+ if (prettyPrint) {
+ mapper.enable(SerializationFeature.INDENT_OUTPUT);
+ }
+
+ log.debug("JSON object-mapper initialized");
+
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @at.gv.egiz.eaaf.core.api.utils.IJsonMapper#getMapper()
+ */
+ public ObjectMapper getMapper() {
+ return mapper;
+
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egiz.eaaf.core.api.utils.IJsonMapper#serialize(java.lang.Object)
+ */
+ @Override
+ public String serialize(final 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);
+
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egiz.eaaf.core.api.utils.IJsonMapper#deserialize(java.lang.String, java.lang.Class)
+ */
+ @Override
+ public <T> Object deserialize(final String value, final Class<T> 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);
+ }
+
+ } catch (final IOException e) {
+ log.warn("JSON mapping FAILED with error: {}", e.getMessage());
+ throw new EaafJsonMapperException(e.getMessage(), e);
+
+ }
+
+ }
+
+ @Override
+ public <T> Object deserialize(final InputStream is, final Class<T> clazz)
+ throws EaafJsonMapperException {
+ try {
+ if (clazz != null) {
+ if (clazz.isAssignableFrom(TypeReference.class)) {
+ return mapper.readValue(is, clazz);
+ } else {
+ final JavaType javaType = TypeFactory.defaultInstance().constructType(clazz);
+ return mapper.readValue(is, javaType);
+
+ }
+
+ } else {
+ return mapper.readValue(is, Object.class);
+ }
+
+ } catch (final IOException e) {
+ log.warn("JSON mapping FAILED with error: {}", e.getMessage());
+ throw new EaafJsonMapperException(e.getMessage(), e);
+
+ }
+
+ }
+
}
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 c07c6081..28106377 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
@@ -38,7 +38,7 @@ import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonNode;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
-import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils;
import at.gv.egiz.eaaf.core.impl.utils.X509Utils;
@@ -46,375 +46,408 @@ import at.gv.egiz.eaaf.modules.auth.sl20.Constants;
import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoBuildException;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoParserException;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException;
@Service
-public class JsonSecurityUtils implements IJOSETools{
- private static final Logger log = LoggerFactory.getLogger(JsonSecurityUtils.class);
-
- @Autowired(required=true) IConfiguration authConfig;
- private Key signPrivKey = null;
- private X509Certificate[] signCertChain = null;
-
- private Key encPrivKey = null;
- private X509Certificate[] encCertChain = null;
-
- private List<X509Certificate> trustedCerts = new ArrayList<X509Certificate>();
-
- private static JsonMapper mapper = new JsonMapper();
-
- @PostConstruct
- protected void initalize() {
- log.info("Initialize SL2.0 authentication security constrains ... ");
- try {
- if (getKeyStoreFilePath() != null) {
- final KeyStore keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(),
- getKeyStorePassword());
-
- //load signing key
- signPrivKey = keyStore.getKey(getSigningKeyAlias(), getSigningKeyPassword().toCharArray());
- final Certificate[] certChainSigning = keyStore.getCertificateChain(getSigningKeyAlias());
- signCertChain = new X509Certificate[certChainSigning.length];
- for (int i=0; i<certChainSigning.length; i++) {
- if (certChainSigning[i] instanceof X509Certificate) {
- signCertChain[i] = (X509Certificate)certChainSigning[i];
- } else
- log.warn("NO X509 certificate for signing: " + certChainSigning[i].getType());
-
- }
-
- //load encryption key
- try {
- encPrivKey = keyStore.getKey(getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray());
- if (encPrivKey != null) {
- final Certificate[] certChainEncryption = keyStore.getCertificateChain(getEncryptionKeyAlias());
- encCertChain = new X509Certificate[certChainEncryption.length];
- for (int i=0; i<certChainEncryption.length; i++) {
- if (certChainEncryption[i] instanceof X509Certificate) {
- encCertChain[i] = (X509Certificate)certChainEncryption[i];
- } else
- log.warn("NO X509 certificate for encryption: " + certChainEncryption[i].getType());
- }
- } else
- log.info("No encryption key for SL2.0 found. End-to-End encryption is not used.");
-
- } catch (final Exception e) {
- log.warn("No encryption key for SL2.0 found. End-to-End encryption is not used. Reason: " + e.getMessage(), e);
-
- }
-
- //load trusted certificates
- trustedCerts = readCertsFromKeyStore(keyStore);
-
- //some short validation
- if (signPrivKey == null || !(signPrivKey instanceof PrivateKey)) {
- log.info("Can NOT open privateKey for SL2.0 signing. KeyStore=" + getKeyStoreFilePath());
- throw new SL20Exception("sl20.03", new Object[]{"Can NOT open private key for signing"});
-
- }
-
- if (signCertChain == null || signCertChain.length == 0) {
- log.info("NO certificate for SL2.0 signing. KeyStore=" + getKeyStoreFilePath());
- throw new SL20Exception("sl20.03", new Object[]{"NO certificate for SL2.0 signing"});
-
- }
-
- log.info("SL2.0 authentication security constrains initialized.");
-
- } else
- log.info("NO SL2.0 authentication security configuration. Initialization was skipped");
-
- } catch ( final Exception e) {
- log.error("SL2.0 security constrains initialization FAILED.", e);
-
- }
-
- }
-
- @Override
- public String createSignature(String payLoad) throws SLCommandoBuildException {
- try {
- final JsonWebSignature jws = new JsonWebSignature();
-
- //set payload
- jws.setPayload(payLoad);
-
- //set basic header
- jws.setContentTypeHeaderValue(SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND);
-
- //set signing information
- jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
- jws.setKey(signPrivKey);
-
- //TODO:
- jws.setCertificateChainHeaderValue(signCertChain);
- jws.setX509CertSha256ThumbprintHeaderValue(signCertChain[0]);
-
- return jws.getCompactSerialization();
-
- } catch (final JoseException e) {
- log.warn("Can NOT sign SL2.0 command.", e);
- throw new SLCommandoBuildException("Can NOT sign SL2.0 command.", e);
-
- }
-
- }
-
- @Override
- public VerificationResult validateSignature(String serializedContent, KeyStore trustStore,
- AlgorithmConstraints algconstraints) throws JoseException, IOException, KeyStoreException {
- final List<X509Certificate> trustedCertificates = readCertsFromKeyStore(trustStore);
- return validateSignature(serializedContent, trustedCertificates , algconstraints);
-
- }
-
- @Override
- @NonNull
- public VerificationResult validateSignature(@Nonnull String serializedContent, @Nonnull List<X509Certificate> trustedCerts, @Nonnull AlgorithmConstraints constraints) throws JoseException, IOException {
- final JsonWebSignature jws = new JsonWebSignature();
- //set payload
- jws.setCompactSerialization(serializedContent);
-
- //set security constrains
- jws.setAlgorithmConstraints(constraints);
-
- //load signinc certs
- Key selectedKey = null;
- final List<X509Certificate> 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 ... ");
- final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
-
- if (trustedCerts.contains(sortedX5cCerts.get(0))) {
- selectedKey = sortedX5cCerts.get(0).getPublicKey();
-
- } else {
- log.info("Can NOT find JOSE certificate in truststore.");
- try {
- log.debug("Cert: " + Base64Utils.encodeToString(sortedX5cCerts.get(0).getEncoded()));
-
- } catch (final CertificateEncodingException e) {
- e.printStackTrace();
-
- }
-
- }
-
- } else if (StringUtils.isNotEmpty(x5t256)) {
- log.debug("Found x5t256 fingerprint in JOSE header .... ");
- final X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver(trustedCerts);
- selectedKey = x509VerificationKeyResolver.resolveKey(jws, Collections.<JsonWebStructure>emptyList());
-
- } else {
- throw new JoseException("JWS contains NO signature certificate or NO certificate fingerprint");
-
- }
-
- if (selectedKey == null) {
- throw new JoseException("Can NOT select verification key for JWS. Signature verification FAILED");
-
- }
-
- //set verification key
- jws.setKey(selectedKey);
-
- //load payLoad
- return new VerificationResult(mapper.getMapper().readTree(jws.getPayload()), null, jws.verifySignature()) ;
-
-
- }
-
- @Override
- @Nonnull
- public VerificationResult validateSignature(@Nonnull String serializedContent) throws SL20Exception {
- try {
- final AlgorithmConstraints algConstraints = new AlgorithmConstraints(ConstraintType.WHITELIST,
- SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()]));
-
- final VerificationResult result = validateSignature(serializedContent, trustedCerts, algConstraints);
-
- if (!result.isValidSigned()) {
- log.info("JWS signature invalide. Stopping authentication process ...");
- log.debug("Received JWS msg: " + serializedContent);
- throw new SL20SecurityException("JWS signature invalide.");
-
- }
-
- log.debug("SL2.0 commando signature validation sucessfull");
- return result;
-
- } catch (JoseException | JsonParseException e) {
- log.warn("SL2.0 commando signature validation FAILED", e);
- throw new SL20SecurityException(new Object[]{e.getMessage()}, 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);
-
- }
-
- }
-
-
- @Override
- public JsonNode decryptPayload(String compactSerialization) throws SL20Exception {
- try {
- final JsonWebEncryption receiverJwe = new JsonWebEncryption();
-
- //set security constrains
- receiverJwe.setAlgorithmConstraints(
- new AlgorithmConstraints(ConstraintType.WHITELIST,
- SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION.size()])));
- receiverJwe.setContentEncryptionAlgorithmConstraints(
- new AlgorithmConstraints(ConstraintType.WHITELIST,
- SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION.size()])));
-
- //set payload
- receiverJwe.setCompactSerialization(compactSerialization);
-
-
- //validate key from header against key from config
- final List<X509Certificate> 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 ... ");
- final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
-
- if (!sortedX5cCerts.get(0).equals(encCertChain[0])) {
- log.info("Certificate from JOSE header does NOT match encryption certificate");
- log.debug("JOSE certificate: " + sortedX5cCerts.get(0).toString());
-
- try {
- log.debug("Cert: " + Base64Utils.encode(sortedX5cCerts.get(0).getEncoded()));
- } catch (final CertificateEncodingException e) {
- e.printStackTrace();
- }
- throw new SL20Exception("sl20.05", new Object[]{"Certificate from JOSE header does NOT match encryption certificate"});
- }
-
- } else if (StringUtils.isNotEmpty(x5t256)) {
- log.debug("Found x5t256 fingerprint in JOSE header .... ");
- 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);
- throw new SL20Exception("sl20.05", new Object[]{"X5t256 from JOSE header does NOT match encryption certificate"});
-
- }
-
- } else {
- log.info("Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint");
- throw new SLCommandoParserException("Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint");
-
- }
-
- //set key
- receiverJwe.setKey(encPrivKey);
-
-
- //decrypt payload
- return mapper.getMapper().readTree(receiverJwe.getPlaintextString());
-
- } catch (final JoseException e) {
- log.warn("SL2.0 result decryption FAILED", e);
- throw new SL20SecurityException(new Object[]{e.getMessage()}, 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 (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);
- }
-
- }
-
-
-
- @Override
- public X509Certificate getEncryptionCertificate() {
- //TODO: maybe update after SL2.0 update on encryption certificate parts
- if (encCertChain !=null && encCertChain.length > 0)
- return encCertChain[0];
- else
- return null;
- }
-
- private String getKeyStoreFilePath() throws EAAFConfigurationException, MalformedURLException {
- return FileUtils.makeAbsoluteURL(
- authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PATH),
- authConfig.getConfigurationRootDirectory());
- }
-
- private String getKeyStorePassword() {
- String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD);
- if (value != null)
- value = value.trim();
-
- return value;
-
- }
-
- private String getSigningKeyAlias() {
- String value = authConfig.getBasicConfiguration(
- Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS).trim();
- if (value != null)
- value = value.trim();
-
- return value;
- }
-
- private String getSigningKeyPassword() {
- String value = authConfig.getBasicConfiguration(
- Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD).trim();
- if (value != null)
- value = value.trim();
-
- return value;
- }
-
- private String getEncryptionKeyAlias() {
- String value = authConfig.getBasicConfiguration(
- Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS).trim();
- if (value != null)
- value = value.trim();
-
- return value;
- }
-
- private String getEncryptionKeyPassword() {
- String value = authConfig.getBasicConfiguration(
- Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD).trim();
- if (value != null)
- value = value.trim();
-
- return value;
- }
-
- @Nonnull
- private List<X509Certificate> readCertsFromKeyStore(@Nonnull KeyStore keyStore) throws KeyStoreException {
- final List<X509Certificate> result = new ArrayList<>();
-
- final Enumeration<String> aliases = keyStore.aliases();
- while(aliases.hasMoreElements()) {
- final String el = aliases.nextElement();
- log.trace("Process TrustStoreEntry: " + el);
- if (keyStore.isCertificateEntry(el)) {
- final Certificate cert = keyStore.getCertificate(el);
- if (cert != null && cert instanceof X509Certificate)
- result.add((X509Certificate) cert);
- else
- log.info("Can not process entry: " + el + ". Reason: " + cert.toString());
-
- }
- }
-
- return Collections.unmodifiableList(result);
- }
-
+public class JsonSecurityUtils implements IJoseTools {
+ private static final Logger log = LoggerFactory.getLogger(JsonSecurityUtils.class);
+
+ @Autowired(required = true)
+ IConfiguration authConfig;
+ private Key signPrivKey = null;
+ private X509Certificate[] signCertChain = null;
+
+ private Key encPrivKey = null;
+ private X509Certificate[] encCertChain = null;
+
+ private List<X509Certificate> trustedCerts = new ArrayList<>();
+
+ private static JsonMapper mapper = new JsonMapper();
+
+ @PostConstruct
+ protected void initalize() {
+ log.info("Initialize SL2.0 authentication security constrains ... ");
+ try {
+ if (getKeyStoreFilePath() != null) {
+ final KeyStore keyStore =
+ KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), getKeyStorePassword());
+
+ // load signing key
+ signPrivKey = keyStore.getKey(getSigningKeyAlias(), getSigningKeyPassword().toCharArray());
+ final Certificate[] certChainSigning = keyStore.getCertificateChain(getSigningKeyAlias());
+ signCertChain = new X509Certificate[certChainSigning.length];
+ for (int i = 0; i < certChainSigning.length; i++) {
+ if (certChainSigning[i] instanceof X509Certificate) {
+ signCertChain[i] = (X509Certificate) certChainSigning[i];
+ } else {
+ log.warn("NO X509 certificate for signing: " + certChainSigning[i].getType());
+ }
+
+ }
+
+ // load encryption key
+ try {
+ encPrivKey =
+ keyStore.getKey(getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray());
+ if (encPrivKey != null) {
+ final Certificate[] certChainEncryption =
+ keyStore.getCertificateChain(getEncryptionKeyAlias());
+ encCertChain = new X509Certificate[certChainEncryption.length];
+ for (int i = 0; i < certChainEncryption.length; i++) {
+ if (certChainEncryption[i] instanceof X509Certificate) {
+ encCertChain[i] = (X509Certificate) certChainEncryption[i];
+ } else {
+ log.warn("NO X509 certificate for encryption: " + certChainEncryption[i].getType());
+ }
+ }
+ } else {
+ log.info("No encryption key for SL2.0 found. End-to-End encryption is not used.");
+ }
+
+ } catch (final Exception e) {
+ log.warn("No encryption key for SL2.0 found. End-to-End encryption is not used. Reason: "
+ + e.getMessage(), e);
+
+ }
+
+ // load trusted certificates
+ trustedCerts = readCertsFromKeyStore(keyStore);
+
+ // some short validation
+ if (signPrivKey == null || !(signPrivKey instanceof PrivateKey)) {
+ log.info("Can NOT open privateKey for SL2.0 signing. KeyStore=" + getKeyStoreFilePath());
+ throw new SL20Exception("sl20.03", new Object[] {"Can NOT open private key for signing"});
+
+ }
+
+ if (signCertChain == null || signCertChain.length == 0) {
+ log.info("NO certificate for SL2.0 signing. KeyStore=" + getKeyStoreFilePath());
+ throw new SL20Exception("sl20.03", new Object[] {"NO certificate for SL2.0 signing"});
+
+ }
+
+ log.info("SL2.0 authentication security constrains initialized.");
+
+ } else {
+ log.info("NO SL2.0 authentication security configuration. Initialization was skipped");
+ }
+
+ } catch (final Exception e) {
+ log.error("SL2.0 security constrains initialization FAILED.", e);
+
+ }
+
+ }
+
+ @Override
+ public String createSignature(final String payLoad) throws SlCommandoBuildException {
+ try {
+ final JsonWebSignature jws = new JsonWebSignature();
+
+ // set payload
+ jws.setPayload(payLoad);
+
+ // set basic header
+ jws.setContentTypeHeaderValue(SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND);
+
+ // set signing information
+ jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
+ jws.setKey(signPrivKey);
+
+ // TODO:
+ jws.setCertificateChainHeaderValue(signCertChain);
+ jws.setX509CertSha256ThumbprintHeaderValue(signCertChain[0]);
+
+ return jws.getCompactSerialization();
+
+ } catch (final JoseException e) {
+ log.warn("Can NOT sign SL2.0 command.", e);
+ throw new SlCommandoBuildException("Can NOT sign SL2.0 command.", e);
+
+ }
+
+ }
+
+ @Override
+ public VerificationResult validateSignature(final String serializedContent,
+ final KeyStore trustStore, final AlgorithmConstraints algconstraints)
+ throws JoseException, IOException, KeyStoreException {
+ final List<X509Certificate> trustedCertificates = readCertsFromKeyStore(trustStore);
+ return validateSignature(serializedContent, trustedCertificates, algconstraints);
+
+ }
+
+ @Override
+ @NonNull
+ public VerificationResult validateSignature(@Nonnull final String serializedContent,
+ @Nonnull final List<X509Certificate> trustedCerts,
+ @Nonnull final AlgorithmConstraints constraints) throws JoseException, IOException {
+ final JsonWebSignature jws = new JsonWebSignature();
+ // set payload
+ jws.setCompactSerialization(serializedContent);
+
+ // set security constrains
+ jws.setAlgorithmConstraints(constraints);
+
+ // load signinc certs
+ Key selectedKey = null;
+ final List<X509Certificate> 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 ... ");
+ final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
+
+ if (trustedCerts.contains(sortedX5cCerts.get(0))) {
+ selectedKey = sortedX5cCerts.get(0).getPublicKey();
+
+ } else {
+ log.info("Can NOT find JOSE certificate in truststore.");
+ try {
+ log.debug("Cert: " + Base64Utils.encodeToString(sortedX5cCerts.get(0).getEncoded()));
+
+ } catch (final CertificateEncodingException e) {
+ e.printStackTrace();
+
+ }
+
+ }
+
+ } else if (StringUtils.isNotEmpty(x5t256)) {
+ log.debug("Found x5t256 fingerprint in JOSE header .... ");
+ final X509VerificationKeyResolver x509VerificationKeyResolver =
+ new X509VerificationKeyResolver(trustedCerts);
+ selectedKey =
+ x509VerificationKeyResolver.resolveKey(jws, Collections.<JsonWebStructure>emptyList());
+
+ } else {
+ throw new JoseException(
+ "JWS contains NO signature certificate or NO certificate fingerprint");
+
+ }
+
+ if (selectedKey == null) {
+ throw new JoseException(
+ "Can NOT select verification key for JWS. Signature verification FAILED");
+
+ }
+
+ // set verification key
+ jws.setKey(selectedKey);
+
+ // load payLoad
+ return new VerificationResult(mapper.getMapper().readTree(jws.getPayload()), null,
+ jws.verifySignature());
+
+
+ }
+
+ @Override
+ @Nonnull
+ public VerificationResult validateSignature(@Nonnull final String serializedContent)
+ throws SL20Exception {
+ try {
+ final AlgorithmConstraints algConstraints = new AlgorithmConstraints(ConstraintType.WHITELIST,
+ SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING
+ .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()]));
+
+ final VerificationResult result =
+ validateSignature(serializedContent, trustedCerts, algConstraints);
+
+ if (!result.isValidSigned()) {
+ log.info("JWS signature invalide. Stopping authentication process ...");
+ log.debug("Received JWS msg: " + serializedContent);
+ throw new SL20SecurityException("JWS signature invalide.");
+
+ }
+
+ log.debug("SL2.0 commando signature validation sucessfull");
+ return result;
+
+ } catch (JoseException | JsonParseException e) {
+ log.warn("SL2.0 commando signature validation FAILED", e);
+ throw new SL20SecurityException(new Object[] {e.getMessage()}, 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);
+
+ }
+
+ }
+
+
+ @Override
+ public JsonNode decryptPayload(final String compactSerialization) throws SL20Exception {
+ try {
+ final JsonWebEncryption receiverJwe = new JsonWebEncryption();
+
+ // set security constrains
+ receiverJwe.setAlgorithmConstraints(new AlgorithmConstraints(ConstraintType.WHITELIST,
+ SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION
+ .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION.size()])));
+ receiverJwe.setContentEncryptionAlgorithmConstraints(new AlgorithmConstraints(
+ ConstraintType.WHITELIST, SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION
+ .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION.size()])));
+
+ // set payload
+ receiverJwe.setCompactSerialization(compactSerialization);
+
+
+ // validate key from header against key from config
+ final List<X509Certificate> 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 ... ");
+ final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
+
+ if (!sortedX5cCerts.get(0).equals(encCertChain[0])) {
+ log.info("Certificate from JOSE header does NOT match encryption certificate");
+ log.debug("JOSE certificate: " + sortedX5cCerts.get(0).toString());
+
+ try {
+ log.debug("Cert: " + Base64Utils.encode(sortedX5cCerts.get(0).getEncoded()));
+ } catch (final CertificateEncodingException e) {
+ e.printStackTrace();
+ }
+ throw new SL20Exception("sl20.05",
+ new Object[] {"Certificate from JOSE header does NOT match encryption certificate"});
+ }
+
+ } else if (StringUtils.isNotEmpty(x5t256)) {
+ log.debug("Found x5t256 fingerprint in JOSE header .... ");
+ 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);
+ throw new SL20Exception("sl20.05",
+ new Object[] {"X5t256 from JOSE header does NOT match encryption certificate"});
+
+ }
+
+ } else {
+ log.info(
+ "Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint");
+ throw new SlCommandoParserException(
+ "Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint");
+
+ }
+
+ // set key
+ receiverJwe.setKey(encPrivKey);
+
+
+ // decrypt payload
+ return mapper.getMapper().readTree(receiverJwe.getPlaintextString());
+
+ } catch (final JoseException e) {
+ log.warn("SL2.0 result decryption FAILED", e);
+ throw new SL20SecurityException(new Object[] {e.getMessage()}, 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 (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);
+ }
+
+ }
+
+
+
+ @Override
+ public X509Certificate getEncryptionCertificate() {
+ // TODO: maybe update after SL2.0 update on encryption certificate parts
+ if (encCertChain != null && encCertChain.length > 0) {
+ return encCertChain[0];
+ } else {
+ return null;
+ }
+ }
+
+ private String getKeyStoreFilePath() throws EaafConfigurationException, MalformedURLException {
+ return FileUtils.makeAbsoluteUrl(
+ authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PATH),
+ authConfig.getConfigurationRootDirectory());
+ }
+
+ private String getKeyStorePassword() {
+ String value =
+ authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD);
+ if (value != null) {
+ value = value.trim();
+ }
+
+ return value;
+
+ }
+
+ private String getSigningKeyAlias() {
+ String value = authConfig
+ .getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS).trim();
+ if (value != null) {
+ value = value.trim();
+ }
+
+ return value;
+ }
+
+ private String getSigningKeyPassword() {
+ String value = authConfig
+ .getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD).trim();
+ if (value != null) {
+ value = value.trim();
+ }
+
+ return value;
+ }
+
+ private String getEncryptionKeyAlias() {
+ String value = authConfig
+ .getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS).trim();
+ if (value != null) {
+ value = value.trim();
+ }
+
+ return value;
+ }
+
+ private String getEncryptionKeyPassword() {
+ String value = authConfig
+ .getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD)
+ .trim();
+ if (value != null) {
+ value = value.trim();
+ }
+
+ return value;
+ }
+
+ @Nonnull
+ private List<X509Certificate> readCertsFromKeyStore(@Nonnull final KeyStore keyStore)
+ throws KeyStoreException {
+ final List<X509Certificate> result = new ArrayList<>();
+
+ final Enumeration<String> aliases = keyStore.aliases();
+ while (aliases.hasMoreElements()) {
+ final String el = aliases.nextElement();
+ log.trace("Process TrustStoreEntry: " + el);
+ if (keyStore.isCertificateEntry(el)) {
+ final Certificate cert = keyStore.getCertificate(el);
+ if (cert != null && cert instanceof X509Certificate) {
+ result.add((X509Certificate) cert);
+ } else {
+ log.info("Can not process entry: " + el + ". Reason: " + cert.toString());
+ }
+
+ }
+ }
+
+ return Collections.unmodifiableList(result);
+ }
+
}
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 06c36cff..5a8be243 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
@@ -8,234 +8,273 @@ import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers;
import org.jose4j.jws.AlgorithmIdentifiers;
public class SL20Constants {
- public static final int CURRENT_SL20_VERSION = 10;
-
- //http binding parameters
- public static final String PARAM_SL20_REQ_COMMAND_PARAM = "slcommand";
- public static final String PARAM_SL20_REQ_COMMAND_PARAM_OLD = "sl2command";
-
- public static final String PARAM_SL20_REQ_ICP_RETURN_URL_PARAM = "slIPCReturnUrl";
- public static final String PARAM_SL20_REQ_TRANSACTIONID = "slTransactionID";
-
- public static final String HTTP_HEADER_SL20_CLIENT_TYPE = "SL2ClientType";
- public static final String HTTP_HEADER_SL20_VDA_TYPE = "X-MOA-VDA";
- public static final String HTTP_HEADER_VALUE_NATIVE = "nativeApp";
-
- public static final String HTTP_HEADER_SL20_RESP = "X-SL20Operation";
-
-
- //*******************************************************************************************
- //JSON signing and encryption headers
- public static final String JSON_ALGORITHM = "alg";
- public static final String JSON_CONTENTTYPE = "cty";
- public static final String JSON_X509_CERTIFICATE = "x5c";
- public static final String JSON_X509_FINGERPRINT = "x5t#S256";
- public static final String JSON_ENCRYPTION_PAYLOAD = "enc";
-
- public static final String JSON_ALGORITHM_SIGNING_RS256 = AlgorithmIdentifiers.RSA_USING_SHA256;
- public static final String JSON_ALGORITHM_SIGNING_RS512 = AlgorithmIdentifiers.RSA_USING_SHA512;
- public static final String JSON_ALGORITHM_SIGNING_ES256 = AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256;
- public static final String JSON_ALGORITHM_SIGNING_ES512 = AlgorithmIdentifiers.ECDSA_USING_P521_CURVE_AND_SHA512;
- public static final String JSON_ALGORITHM_SIGNING_PS256 = AlgorithmIdentifiers.RSA_PSS_USING_SHA256;
- public static final String JSON_ALGORITHM_SIGNING_PS512 = AlgorithmIdentifiers.RSA_PSS_USING_SHA512;
-
- public static final List<String> SL20_ALGORITHM_WHITELIST_SIGNING = Arrays.asList(
- JSON_ALGORITHM_SIGNING_RS256,
- JSON_ALGORITHM_SIGNING_RS512,
- JSON_ALGORITHM_SIGNING_ES256,
- JSON_ALGORITHM_SIGNING_ES512,
- JSON_ALGORITHM_SIGNING_PS256,
- JSON_ALGORITHM_SIGNING_PS512
- );
-
- public static final String JSON_ALGORITHM_ENC_KEY_RSAOAEP = KeyManagementAlgorithmIdentifiers.RSA_OAEP;
- public static final String JSON_ALGORITHM_ENC_KEY_RSAOAEP256 = KeyManagementAlgorithmIdentifiers.RSA_OAEP_256;
-
- public static final List<String> SL20_ALGORITHM_WHITELIST_KEYENCRYPTION = Arrays.asList(
- JSON_ALGORITHM_ENC_KEY_RSAOAEP,
- JSON_ALGORITHM_ENC_KEY_RSAOAEP256
- );
-
- public static final String JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256 = ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256;
- public static final String JSON_ALGORITHM_ENC_PAYLOAD_A256CBCHS512 = ContentEncryptionAlgorithmIdentifiers.AES_256_CBC_HMAC_SHA_512;
- public static final String JSON_ALGORITHM_ENC_PAYLOAD_A128GCM = ContentEncryptionAlgorithmIdentifiers.AES_128_GCM;
- public static final String JSON_ALGORITHM_ENC_PAYLOAD_A256GCM = ContentEncryptionAlgorithmIdentifiers.AES_256_GCM;
-
- public static final List<String> SL20_ALGORITHM_WHITELIST_ENCRYPTION = Arrays.asList(
- JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256,
- JSON_ALGORITHM_ENC_PAYLOAD_A256CBCHS512,
- JSON_ALGORITHM_ENC_PAYLOAD_A128GCM,
- JSON_ALGORITHM_ENC_PAYLOAD_A256GCM
- );
-
-
- //*********************************************************************************************
- //Object identifier for generic transport container
- public static final String SL20_CONTENTTYPE_SIGNED_COMMAND ="application/sl2.0;command";
- public static final String SL20_CONTENTTYPE_ENCRYPTED_RESULT ="application/sl2.0;result";
-
- public static final String SL20_VERSION = "v";
- public static final String SL20_REQID = "reqID";
- public static final String SL20_RESPID = "respID";
- public static final String SL20_INRESPTO = "inResponseTo";
- public static final String SL20_TRANSACTIONID = "transactionID";
- public static final String SL20_PAYLOAD = "payload";
- public static final String SL20_SIGNEDPAYLOAD = "signedPayload";
-
- //Generic Object identifier for commands
- public static final String SL20_COMMAND_CONTAINER_NAME = "name";
- public static final String SL20_COMMAND_CONTAINER_PARAMS = "params";
- public static final String SL20_COMMAND_CONTAINER_RESULT = "result";
- public static final String SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT = "encryptedResult";
-
- //COMMAND Object identifier
- 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";
- @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";
- public static final String SL20_COMMAND_IDENTIFIER_CREATE_SIG_CADES = "createCAdES";
-
-
- public static final String SL20_COMMAND_IDENTIFIER_BINDING_CREATE_KEY = "createBindingKey";
- public static final String SL20_COMMAND_IDENTIFIER_BINDING_STORE_CERT = "storeBindingCert";
-
- public static final String SL20_COMMAND_IDENTIFIER_AUTH_IDANDPASSWORD = "idAndPassword";
- public static final String SL20_COMMAND_IDENTIFIER_AUTH_JWSTOKENFACTOR = "jwsTokenAuth";
- public static final String SL20_COMMAND_IDENTIFIER_AUTH_QRCODEFACTOR = "qrCodeFactor";
-
- //*****COMMAND parameter identifier******
- //general Identifier
- public static final String SL20_COMMAND_PARAM_GENERAL_REQPARAMETER_VALUE = "value";
- public static final String SL20_COMMAND_PARAM_GENERAL_REQPARAMETER_KEY = "key";
- public static final String SL20_COMMAND_PARAM_GENERAL_DATAURL = "dataUrl";
- public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE = "x5cEnc";
- public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK = "jwkEnc";
-
- //Redirect command
- public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL = "url";
- public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND = "command";
- public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND = "signedCommand";
- public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_IPCREDIRECT = "IPCRedirect";
-
- //Call command
- public static final String SL20_COMMAND_PARAM_GENERAL_CALL_URL = SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL;
- public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD = "method";
- public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET = "get";
- public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_POST = "post";
- public static final String SL20_COMMAND_PARAM_GENERAL_CALL_INCLUDETRANSACTIONID = "includeTransactionID";
- public static final String SL20_COMMAND_PARAM_GENERAL_CALL_REQPARAMETER = "reqParams";
-
- //error command
- public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE = "errorCode";
- public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE = "errorMessage";
-
- //qualified eID command
- @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;
- @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;
- @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";
- @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;
-// public static final String SL20_COMMAND_PARAM_QUALSIG_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE;
-
-
- //getCertificate
- public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_KEYID = "keyId";
- public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL;
- public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE;
- public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_JWKCENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK;
- public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_RESULT_CERTIFICATE = "x5c";
-
- //createCAdES Signture
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_KEYID = "keyId";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CONTENT = "content";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_MIMETYPE = "mimeType";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_PADES_COMBATIBILTY = "padesComatibility";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_EXCLUDEBYTERANGE = "excludedByteRange";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL = "cadesLevel";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL;
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE;
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_JWKCENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK;
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_RESULT_SIGNATURE = "signature";
-
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_BASIC = "cAdES";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_T = "cAdES-T";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_C = "cAdES-C";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_X = "cAdES-X";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_XL = "cAdES-X-L";
- public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_A = "cAdES-A";
-
-
-
- //create binding key command
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID = "kontoID";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_SN = "SN";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYLENGTH = "keyLength";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG = "keyAlg";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES = "policies";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL;
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_X5CVDATRUST = "x5cVdaTrust";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_REQUESTUSERPASSWORD = "reqUserPassword";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE;
-
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG_RSA = "RSA";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG_SECPR256R1 = "secp256r1";
-
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_LIFETIME = "lifeTime";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_USESECUREELEMENT = "useSecureElement";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_KEYTIMEOUT = "keyTimeout";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_NEEDUSERAUTH = "needUserAuth";
-
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_APPID = "appID";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_CSR = "csr";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_KEYATTESTATIONZERTIFICATE = "attCert";
- public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD = "encodedPass";
-
-
- //store binding certificate command
- public static final String SL20_COMMAND_PARAM_BINDING_STORE_CERTIFICATE = "x5c";
- public static final String SL20_COMMAND_PARAM_BINDING_STORE_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL;
- public static final String SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS = "success";
- public static final String SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS_VALUE = "OK";
-
- // Username and password authentication
- public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG = "keyAlg";
- public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG_VALUE_PLAIN = "plain";
- public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG_VALUE_PBKDF2 = "PBKDF2";
- public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL;
- public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_X5CENC = SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE;
- public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_KONTOID = SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID;
- public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_USERPASSWORD = SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD;
-
- //JWS Token authentication
- public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE = "nonce";
- public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYDATA = "displayData";
- public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYURL = "displayUrl";
- public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL;
- public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_RESULT_NONCE = SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE;
-
- //QR-Code authentication
- public static final String SL20_COMMAND_PARAM_AUTH_QRCODE_QRCODE = "qrCode";
- public static final String SL20_COMMAND_PARAM_AUTH_QRCODE_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL;
-
+ public static final int CURRENT_SL20_VERSION = 10;
+
+ // http binding parameters
+ public static final String PARAM_SL20_REQ_COMMAND_PARAM = "slcommand";
+ public static final String PARAM_SL20_REQ_COMMAND_PARAM_OLD = "sl2command";
+
+ public static final String PARAM_SL20_REQ_ICP_RETURN_URL_PARAM = "slIPCReturnUrl";
+ public static final String PARAM_SL20_REQ_TRANSACTIONID = "slTransactionID";
+
+ public static final String HTTP_HEADER_SL20_CLIENT_TYPE = "SL2ClientType";
+ public static final String HTTP_HEADER_SL20_VDA_TYPE = "X-MOA-VDA";
+ public static final String HTTP_HEADER_VALUE_NATIVE = "nativeApp";
+
+ public static final String HTTP_HEADER_SL20_RESP = "X-SL20Operation";
+
+
+ // *******************************************************************************************
+ // JSON signing and encryption headers
+ public static final String JSON_ALGORITHM = "alg";
+ public static final String JSON_CONTENTTYPE = "cty";
+ public static final String JSON_X509_CERTIFICATE = "x5c";
+ public static final String JSON_X509_FINGERPRINT = "x5t#S256";
+ public static final String JSON_ENCRYPTION_PAYLOAD = "enc";
+
+ public static final String JSON_ALGORITHM_SIGNING_RS256 = AlgorithmIdentifiers.RSA_USING_SHA256;
+ public static final String JSON_ALGORITHM_SIGNING_RS512 = AlgorithmIdentifiers.RSA_USING_SHA512;
+ public static final String JSON_ALGORITHM_SIGNING_ES256 =
+ AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256;
+ public static final String JSON_ALGORITHM_SIGNING_ES512 =
+ AlgorithmIdentifiers.ECDSA_USING_P521_CURVE_AND_SHA512;
+ public static final String JSON_ALGORITHM_SIGNING_PS256 =
+ AlgorithmIdentifiers.RSA_PSS_USING_SHA256;
+ public static final String JSON_ALGORITHM_SIGNING_PS512 =
+ AlgorithmIdentifiers.RSA_PSS_USING_SHA512;
+
+ public static final List<String> SL20_ALGORITHM_WHITELIST_SIGNING = Arrays.asList(
+ JSON_ALGORITHM_SIGNING_RS256, JSON_ALGORITHM_SIGNING_RS512, JSON_ALGORITHM_SIGNING_ES256,
+ JSON_ALGORITHM_SIGNING_ES512, JSON_ALGORITHM_SIGNING_PS256, JSON_ALGORITHM_SIGNING_PS512);
+
+ public static final String JSON_ALGORITHM_ENC_KEY_RSAOAEP =
+ KeyManagementAlgorithmIdentifiers.RSA_OAEP;
+ public static final String JSON_ALGORITHM_ENC_KEY_RSAOAEP256 =
+ KeyManagementAlgorithmIdentifiers.RSA_OAEP_256;
+
+ public static final List<String> SL20_ALGORITHM_WHITELIST_KEYENCRYPTION =
+ Arrays.asList(JSON_ALGORITHM_ENC_KEY_RSAOAEP, JSON_ALGORITHM_ENC_KEY_RSAOAEP256);
+
+ public static final String JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256 =
+ ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256;
+ public static final String JSON_ALGORITHM_ENC_PAYLOAD_A256CBCHS512 =
+ ContentEncryptionAlgorithmIdentifiers.AES_256_CBC_HMAC_SHA_512;
+ public static final String JSON_ALGORITHM_ENC_PAYLOAD_A128GCM =
+ ContentEncryptionAlgorithmIdentifiers.AES_128_GCM;
+ public static final String JSON_ALGORITHM_ENC_PAYLOAD_A256GCM =
+ ContentEncryptionAlgorithmIdentifiers.AES_256_GCM;
+
+ public static final List<String> SL20_ALGORITHM_WHITELIST_ENCRYPTION = Arrays.asList(
+ JSON_ALGORITHM_ENC_PAYLOAD_A128CBCHS256, JSON_ALGORITHM_ENC_PAYLOAD_A256CBCHS512,
+ JSON_ALGORITHM_ENC_PAYLOAD_A128GCM, JSON_ALGORITHM_ENC_PAYLOAD_A256GCM);
+
+
+ // *********************************************************************************************
+ // Object identifier for generic transport container
+ public static final String SL20_CONTENTTYPE_SIGNED_COMMAND = "application/sl2.0;command";
+ public static final String SL20_CONTENTTYPE_ENCRYPTED_RESULT = "application/sl2.0;result";
+
+ public static final String SL20_VERSION = "v";
+ public static final String SL20_REQID = "reqID";
+ public static final String SL20_RESPID = "respID";
+ public static final String SL20_INRESPTO = "inResponseTo";
+ public static final String SL20_TRANSACTIONID = "transactionID";
+ public static final String SL20_PAYLOAD = "payload";
+ public static final String SL20_SIGNEDPAYLOAD = "signedPayload";
+
+ // Generic Object identifier for commands
+ public static final String SL20_COMMAND_CONTAINER_NAME = "name";
+ public static final String SL20_COMMAND_CONTAINER_PARAMS = "params";
+ public static final String SL20_COMMAND_CONTAINER_RESULT = "result";
+ public static final String SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT = "encryptedResult";
+
+ // COMMAND Object identifier
+ 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";
+ @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";
+ public static final String SL20_COMMAND_IDENTIFIER_CREATE_SIG_CADES = "createCAdES";
+
+
+ public static final String SL20_COMMAND_IDENTIFIER_BINDING_CREATE_KEY = "createBindingKey";
+ public static final String SL20_COMMAND_IDENTIFIER_BINDING_STORE_CERT = "storeBindingCert";
+
+ public static final String SL20_COMMAND_IDENTIFIER_AUTH_IDANDPASSWORD = "idAndPassword";
+ public static final String SL20_COMMAND_IDENTIFIER_AUTH_JWSTOKENFACTOR = "jwsTokenAuth";
+ public static final String SL20_COMMAND_IDENTIFIER_AUTH_QRCODEFACTOR = "qrCodeFactor";
+
+ // *****COMMAND parameter identifier******
+ // general Identifier
+ public static final String SL20_COMMAND_PARAM_GENERAL_REQPARAMETER_VALUE = "value";
+ public static final String SL20_COMMAND_PARAM_GENERAL_REQPARAMETER_KEY = "key";
+ public static final String SL20_COMMAND_PARAM_GENERAL_DATAURL = "dataUrl";
+ public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE = "x5cEnc";
+ public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK = "jwkEnc";
+
+ // Redirect command
+ public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL = "url";
+ public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND = "command";
+ public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND = "signedCommand";
+ public static final String SL20_COMMAND_PARAM_GENERAL_REDIRECT_IPCREDIRECT = "IPCRedirect";
+
+ // Call command
+ public static final String SL20_COMMAND_PARAM_GENERAL_CALL_URL =
+ SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL;
+ public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD = "method";
+ public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET = "get";
+ public static final String SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_POST = "post";
+ public static final String SL20_COMMAND_PARAM_GENERAL_CALL_INCLUDETRANSACTIONID =
+ "includeTransactionID";
+ public static final String SL20_COMMAND_PARAM_GENERAL_CALL_REQPARAMETER = "reqParams";
+
+ // error command
+ public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE = "errorCode";
+ public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE = "errorMessage";
+
+ // qualified eID command
+ @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;
+ @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;
+ @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";
+ @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;
+ // public static final String SL20_COMMAND_PARAM_QUALSIG_X5CENC =
+ // SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE;
+
+
+ // getCertificate
+ public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_KEYID = "keyId";
+ public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_DATAURL =
+ SL20_COMMAND_PARAM_GENERAL_DATAURL;
+ public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_X5CENC =
+ SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE;
+ public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_JWKCENC =
+ SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK;
+ public static final String SL20_COMMAND_PARAM_GETCERTIFICATE_RESULT_CERTIFICATE = "x5c";
+
+ // createCAdES Signture
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_KEYID = "keyId";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CONTENT = "content";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_MIMETYPE = "mimeType";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_PADES_COMBATIBILTY =
+ "padesComatibility";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_EXCLUDEBYTERANGE =
+ "excludedByteRange";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL = "cadesLevel";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_DATAURL =
+ SL20_COMMAND_PARAM_GENERAL_DATAURL;
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_X5CENC =
+ SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE;
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_JWKCENC =
+ SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONJWK;
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_RESULT_SIGNATURE = "signature";
+
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_BASIC = "cAdES";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_T = "cAdES-T";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_C = "cAdES-C";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_X = "cAdES-X";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_XL = "cAdES-X-L";
+ public static final String SL20_COMMAND_PARAM_CREATE_SIG_CADES_CADESLEVEL_A = "cAdES-A";
+
+
+
+ // create binding key command
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID = "kontoID";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_SN = "SN";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYLENGTH = "keyLength";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG = "keyAlg";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES = "policies";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_DATAURL =
+ SL20_COMMAND_PARAM_GENERAL_DATAURL;
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_X5CVDATRUST = "x5cVdaTrust";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_REQUESTUSERPASSWORD =
+ "reqUserPassword";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_X5CENC =
+ SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE;
+
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG_RSA = "RSA";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG_SECPR256R1 = "secp256r1";
+
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_LIFETIME = "lifeTime";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_USESECUREELEMENT =
+ "useSecureElement";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_KEYTIMEOUT = "keyTimeout";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES_NEEDUSERAUTH =
+ "needUserAuth";
+
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_APPID = "appID";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_CSR = "csr";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_KEYATTESTATIONZERTIFICATE =
+ "attCert";
+ public static final String SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD = "encodedPass";
+
+
+ // store binding certificate command
+ public static final String SL20_COMMAND_PARAM_BINDING_STORE_CERTIFICATE = "x5c";
+ public static final String SL20_COMMAND_PARAM_BINDING_STORE_DATAURL =
+ SL20_COMMAND_PARAM_GENERAL_DATAURL;
+ public static final String SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS = "success";
+ public static final String SL20_COMMAND_PARAM_BINDING_STORE_RESULT_SUCESS_VALUE = "OK";
+
+ // Username and password authentication
+ public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG = "keyAlg";
+ public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG_VALUE_PLAIN = "plain";
+ public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_KEYALG_VALUE_PBKDF2 = "PBKDF2";
+ public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_DATAURL =
+ SL20_COMMAND_PARAM_GENERAL_DATAURL;
+ public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_X5CENC =
+ SL20_COMMAND_PARAM_GENERAL_RESPONSEENCRYPTIONCERTIFICATE;
+ public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_KONTOID =
+ SL20_COMMAND_PARAM_BINDING_CREATE_KONTOID;
+ public static final String SL20_COMMAND_PARAM_AUTH_IDANDPASSWORD_RESULT_USERPASSWORD =
+ SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD;
+
+ // JWS Token authentication
+ public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE = "nonce";
+ public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYDATA = "displayData";
+ public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYURL = "displayUrl";
+ public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DATAURL =
+ SL20_COMMAND_PARAM_GENERAL_DATAURL;
+ public static final String SL20_COMMAND_PARAM_AUTH_JWSTOKEN_RESULT_NONCE =
+ SL20_COMMAND_PARAM_AUTH_JWSTOKEN_NONCE;
+
+ // QR-Code authentication
+ public static final String SL20_COMMAND_PARAM_AUTH_QRCODE_QRCODE = "qrCode";
+ public static final String SL20_COMMAND_PARAM_AUTH_QRCODE_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 4d8cabb7..be306b69 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
@@ -3,61 +3,61 @@ package at.gv.egiz.eaaf.modules.auth.sl20.utils;
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;
-
import org.apache.http.client.utils.URIBuilder;
import org.jose4j.base64url.Base64Url;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
-
import com.fasterxml.jackson.databind.JsonNode;
public class SL20HttpBindingUtils {
- private static final Logger log = LoggerFactory.getLogger(SL20HttpBindingUtils.class);
-
- /**
- * 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
- httpResp.addIntHeader(SL20Constants.HTTP_HEADER_SL20_RESP, SL20Constants.CURRENT_SL20_VERSION);
-
- 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");
- httpResp.setStatus(HttpServletResponse.SC_OK);
- httpResp.setContentLength(content.length);
- httpResp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
- httpResp.getOutputStream().write(content);
-
- } else {
- log.debug("Client request containts is no native client ... ");
- final URIBuilder clientRedirectURI = new URIBuilder(redirectURL);
- clientRedirectURI.addParameter(
- SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM,
- Base64Url.encode(sl20Forward.toString().getBytes()));
- httpResp.setStatus(httpCodeRedirect);
- httpResp.setHeader("Location", clientRedirectURI.build().toString());
-
- }
-
- }
+ private static final Logger log = LoggerFactory.getLogger(SL20HttpBindingUtils.class);
+
+ /**
+ * 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 In case of an IO error
+ * @throws URISyntaxException In case of a wrong URL
+ */
+ public static void writeIntoResponse(@Nonnull final HttpServletRequest httpReq,
+ @Nonnull final HttpServletResponse httpResp, @Nonnull final JsonNode sl20Forward,
+ @Nullable final String redirectUrl, @Nonnull final int httpCodeRedirect)
+ throws IOException, URISyntaxException {
+ // forward SL2.0 command
+ httpResp.addIntHeader(SL20Constants.HTTP_HEADER_SL20_RESP, SL20Constants.CURRENT_SL20_VERSION);
+
+ 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");
+ httpResp.setStatus(HttpServletResponse.SC_OK);
+ httpResp.setContentLength(content.length);
+ httpResp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
+ httpResp.getOutputStream().write(content);
+
+ } else {
+ log.debug("Client request containts is no native client ... ");
+ final URIBuilder clientRedirectUri = new URIBuilder(redirectUrl);
+ clientRedirectUri.addParameter(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM,
+ Base64Url.encode(sl20Forward.toString().getBytes()));
+ 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
deleted file mode 100644
index ba069ac7..00000000
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONBuilderUtils.java
+++ /dev/null
@@ -1,640 +0,0 @@
-package at.gv.egiz.eaaf.modules.auth.sl20.utils;
-
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import at.gv.egiz.eaaf.modules.auth.sl20.Constants;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoBuildException;
-
-public class SL20JSONBuilderUtils {
-
- private static JsonMapper mapper = new JsonMapper();
-
- /**
- * Create command request
- * @param name
- * @param params
- * @throws SLCommandoBuildException
- * @return
- */
- public static ObjectNode createCommand(String name, ObjectNode params) throws SLCommandoBuildException {
-
- 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;
-
- }
-
- /**
- * Create signed command request
- *
- * @param name
- * @param params
- * @param signer
- * @return
- * @throws SLCommandoBuildException
- */
- public static String createSignedCommand(String name, ObjectNode params, IJOSETools signer) throws SLCommandoBuildException {
- 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());
-
- }
-
-
- /**
- * Create encrypted command result
- *
- * @param result
- * @param encrypter
- * @return
- * @throws SLCommandoBuildException
- */
- public static String createEncryptedCommandoResult(ObjectNode result, JsonSecurityUtils encrypter) throws SLCommandoBuildException {
- //TODO: add real implementation
- //create header and footer
- 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()) + "."
- + Base64.getUrlEncoder().encodeToString(dummyFooter.getBytes());
-
- }
-
-
- /**
- * Create command result
- *
- * @param name
- * @param result
- * @param encryptedResult
- * @throws SLCommandoBuildException
- * @return
- */
- public static ObjectNode createCommandResponse(String name, ObjectNode result, String encryptedResult) throws SLCommandoBuildException {
- 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);
- return command;
-
- }
-
- /**
- * Create command result
- *
- * @param name
- * @param result
- * @param encryptedResult
- * @throws SLCommandoBuildException
- * @return
- */
- public static String createSignedCommandResponse(String name, ObjectNode result, String encryptedResult, JsonSecurityUtils signer) throws SLCommandoBuildException {
- 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);
- final String encodedCommand = command.toString();
-
- //TODO: add real implementation
- //create header and footer
- final String dummyHeader = createJsonSignedHeader(signer).toString();
- final String dummyFooter = createJsonSignedFooter(signer);
-
- return Base64.getUrlEncoder().encodeToString(dummyHeader.getBytes()) + "."
- + Base64.getUrlEncoder().encodeToString(encodedCommand.getBytes()) + "."
- + Base64.getUrlEncoder().encodeToString(dummyFooter.getBytes());
-
- }
-
- /**
- * Create parameters for Redirect command
- *
- * @param url
- * @param command
- * @param signedCommand
- * @param ipcRedirect
- * @return
- * @throws SLCommandoBuildException
- */
- public static ObjectNode createRedirectCommandParameters(String url, ObjectNode command, ObjectNode signedCommand, Boolean ipcRedirect) throws SLCommandoBuildException{
- final ObjectNode redirectReqParams = mapper.getMapper().createObjectNode();
- addOnlyOnceOfTwo(redirectReqParams,
- SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND,
- command, signedCommand);
- addSingleStringElement(redirectReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL, url, false);
- addSingleBooleanElement(redirectReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_IPCREDIRECT, ipcRedirect, false);
- return redirectReqParams;
-
- }
-
- /**
- * Create parameters for Call command
- *
- * @param url
- * @param method
- * @param includeTransactionId
- * @param reqParameters
- * @return
- * @throws SLCommandoBuildException
- */
- public static ObjectNode createCallCommandParameters(String url, String method, Boolean includeTransactionId, Map<String, String> reqParameters) throws SLCommandoBuildException {
- 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);
- addArrayOfStringElements(callReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_REQPARAMETER, reqParameters);
- return callReqParams;
-
- }
-
- /**
- * Create result for Error command
- *
- * @param errorCode
- * @param errorMsg
- * @return
- * @throws SLCommandoBuildException
- */
- public static ObjectNode createErrorCommandResult(String errorCode, String errorMsg) throws SLCommandoBuildException {
- 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
- *
- * @param authBlockId
- * @param dataUrl
- * @param additionalReqParameters
- * @param x5cEnc
- * @return
- * @throws CertificateEncodingException
- * @throws SLCommandoBuildException
- */
- @Deprecated
- public static ObjectNode createQualifiedeIDCommandParameters(String authBlockId, String dataUrl,
- Map<String, String> additionalReqParameters, X509Certificate x5cEnc) throws CertificateEncodingException, SLCommandoBuildException {
- 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);
- addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_X5CENC, x5cEnc, false);
- return params;
-
- }
-
- /**
- * Create result for qualifiedeID command
- *
- * @param idl
- * @param authBlock
- * @param ccsURL
- * @param LoA
- * @return
- * @throws SLCommandoBuildException
- */
- public static ObjectNode createQualifiedeIDCommandResult(byte[] idl, byte[] authBlock, String ccsURL, String LoA) throws SLCommandoBuildException {
- 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);
- addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_LOA, LoA, true);
- return result;
-
- }
-
-
- /**
- * Create Binding-Key command parameters
- *
- * @param kontoId
- * @param subjectName
- * @param keySize
- * @param keyAlg
- * @param policies
- * @param dataUrl
- * @param x5cVdaTrust
- * @param reqUserPassword
- * @param x5cEnc
- * @return
- * @throws SLCommandoBuildException
- * @throws CertificateEncodingException
- */
- public static ObjectNode createBindingKeyCommandParams(String kontoId, String subjectName, int keySize, String keyAlg,
- Map<String, String> policies, String dataUrl, X509Certificate x5cVdaTrust, Boolean reqUserPassword, X509Certificate x5cEnc) throws SLCommandoBuildException, CertificateEncodingException {
- 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);
- addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG, keyAlg, true);
- addArrayOfStringElements(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES, policies);
- addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_DATAURL, dataUrl, true);
- addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_X5CVDATRUST, x5cVdaTrust, false);
- addSingleBooleanElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_REQUESTUSERPASSWORD, reqUserPassword, false);
- addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_X5CENC, x5cEnc, false);
- return params;
-
- }
-
- /**
- * Create Binding-Key command result
- *
- * @param appId
- * @param csr
- * @param attCert
- * @param password
- * @return
- * @throws SLCommandoBuildException
- * @throws CertificateEncodingException
- */
- public static ObjectNode createBindingKeyCommandResult(String appId, byte[] csr, X509Certificate attCert, byte[] password) throws SLCommandoBuildException, CertificateEncodingException {
- 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);
- addSingleByteElement(result, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD, password, false);
- return result;
-
- }
-
- /**
- * Create Store Binding-Certificate command parameters
- *
- * @param cert
- * @param dataUrl
- * @return
- * @throws CertificateEncodingException
- * @throws SLCommandoBuildException
- */
- public static ObjectNode createStoreBindingCertCommandParams(X509Certificate cert, String dataUrl) throws CertificateEncodingException, SLCommandoBuildException {
- 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;
-
- }
-
- /**
- * Create Store Binding-Certificate command result
- *
- * @return
- * @throws SLCommandoBuildException
- */
- public static ObjectNode createStoreBindingCertCommandSuccessResult() throws SLCommandoBuildException {
- 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;
-
- }
-
-
- /**
- * Create idAndPassword command parameters
- *
- * @param keyAlg
- * @param dataUrl
- * @param x5cEnc
- * @return
- * @throws SLCommandoBuildException
- * @throws CertificateEncodingException
- */
- public static ObjectNode createIdAndPasswordCommandParameters(String keyAlg, String dataUrl, X509Certificate x5cEnc) throws SLCommandoBuildException, CertificateEncodingException {
- 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);
- return params;
-
- }
-
- /**
- * Create idAndPassword command result
- *
- * @param kontoId
- * @param password
- * @return
- * @throws SLCommandoBuildException
- */
- public static ObjectNode createIdAndPasswordCommandResult(String kontoId, byte[] password) throws SLCommandoBuildException {
- 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;
-
- }
-
- /**
- * Create JWS Token Authentication command
- *
- * @param nonce
- * @param dataUrl
- * @param displayData
- * @param displayUrl
- * @return
- * @throws SLCommandoBuildException
- */
- public static ObjectNode createJwsTokenAuthCommandParams(String nonce, String dataUrl, List<String> displayData, List<String> displayUrl) throws SLCommandoBuildException {
- 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);
- addArrayOfStrings(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYURL, displayUrl);
- return params;
-
- }
-
- /**
- * Create JWS Token Authentication command result
- *
- * @param nonce
- * @return
- * @throws SLCommandoBuildException
- */
- public static ObjectNode createJwsTokenAuthCommandResult(String nonce) throws SLCommandoBuildException {
- final ObjectNode result = mapper.getMapper().createObjectNode();
- addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_RESULT_NONCE, nonce, true);
- return result;
-
- }
-
-
- /**
- * Create Generic Request Container
- *
- * @param reqId
- * @param transactionId
- * @param payLoad
- * @param signedPayload
- * @return
- * @throws SLCommandoBuildException
- */
- public static ObjectNode createGenericRequest(String reqId, String transactionId, ObjectNode payLoad, String signedPayload) throws SLCommandoBuildException {
- 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);
- addOnlyOnceOfTwo(req, SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD,
- payLoad, signedPayload);
- return req;
-
- }
-
- /**
- * Create Generic Response Container
- *
- * @param respId
- * @param inResponseTo
- * @param transactionId
- * @param payLoad
- * @param signedPayload
- * @return
- * @throws SLCommandoBuildException
- */
- public static final ObjectNode createGenericResponse(String respId, String inResponseTo, String transactionId,
- ObjectNode payLoad, String signedPayload) throws SLCommandoBuildException {
- 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, false);
- addSingleStringElement(req, SL20Constants.SL20_TRANSACTIONID, transactionId, false);
- addOnlyOnceOfTwo(req, SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD,
- payLoad, signedPayload);
- return req;
-
- }
-
- /**
- * Add one element of two possible elements <br>
- * This method adds either the first element or the second element to parent JSON, but never both.
- *
- * @param parent Parent JSON element
- * @param firstKeyId first element Id
- * @param secondKeyId second element Id
- * @param first first element
- * @param second second element
- * @throws SLCommandoBuildException
- */
- public static void addOnlyOnceOfTwo(ObjectNode parent, String firstKeyId, String secondKeyId, ObjectNode first, String second) throws SLCommandoBuildException {
- if (first == null && (second == null || second.isEmpty()))
- throw new SLCommandoBuildException(firstKeyId + " and " + secondKeyId + " is NULL");
-
- else if (first != null && second != null)
- throw new SLCommandoBuildException(firstKeyId + " and " + secondKeyId + " can not SET TWICE");
-
- else if (first != null)
- parent.set(firstKeyId, first);
-
- else if (second != null && !second.isEmpty())
- parent.put(secondKeyId, second);
-
- else
- throw new SLCommandoBuildException("Internal build error");
- }
-
-
-
- //TODO!!!!
- private static ObjectNode createJsonSignedHeader(JsonSecurityUtils signer) throws SLCommandoBuildException {
- 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));
-
- return header;
- }
-
- //TODO!!!!
- private static ObjectNode createJsonEncryptionHeader(JsonSecurityUtils signer) throws SLCommandoBuildException {
- 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);
- addSingleStringElement(header, SL20Constants.JSON_X509_FINGERPRINT, Constants.DUMMY_SIGNING_CERT_FINGERPRINT, true);
-
- return header;
- }
-
- //TODO!!!!
- private static String createJsonSignedFooter(JsonSecurityUtils signer) {
- return "cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZmh7\n" +
- " AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjbKBYNX4\n" +
- " BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHlb1L07Qe7K\n" +
- " 0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZESc6BfI7noOPqv\n" +
- " hJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrB\n" +
- " p0igcN_IoypGlUPQGe77Rw";
- }
-
-
-
- private static void addArrayOfStrings(ObjectNode parent, String keyId, List<String> values) throws SLCommandoBuildException {
- validateParentAndKey(parent, keyId);
- if (values != null) {
- final ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode();
- parent.set(keyId, callReqParamsArray );
- for(final String el : values)
- callReqParamsArray.add(el);
-
- }
- }
-
-
- private static void addArrayOfStringElements(ObjectNode parent, String keyId, Map<String, String> keyValuePairs) throws SLCommandoBuildException {
- validateParentAndKey(parent, keyId);
- if (keyValuePairs != null) {
- final ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode();
- parent.set(keyId, callReqParamsArray);
-
- for(final Entry<String, String> el : keyValuePairs.entrySet()) {
- final ObjectNode callReqParams = mapper.getMapper().createObjectNode();
- callReqParams.put(el.getKey(), el.getValue());
- callReqParamsArray.add(callReqParams);
-
- }
- }
- }
-
- private static void addSingleCertificateElement(ObjectNode parent, String keyId, X509Certificate cert, boolean isRequired) throws CertificateEncodingException, SLCommandoBuildException {
- if (cert != null)
- addSingleByteElement(parent, keyId, cert.getEncoded(), isRequired);
-
- else if (isRequired)
- throw new SLCommandoBuildException(keyId + " is marked as REQUIRED");
-
- }
-
-
-
- private static void addSingleByteElement(ObjectNode parent, String keyId, byte[] value, boolean isRequired) throws SLCommandoBuildException {
- validateParentAndKey(parent, keyId);
-
- if (isRequired && value == null)
- throw new SLCommandoBuildException(keyId + " has NULL value");
-
- else if (value != null)
- parent.put(keyId, Base64.getEncoder().encodeToString(value));
-
- }
-
- private static void addSingleBooleanElement(ObjectNode parent, String keyId, Boolean value, boolean isRequired) throws SLCommandoBuildException {
- validateParentAndKey(parent, keyId);
-
- if (isRequired && value == null)
- throw new SLCommandoBuildException(keyId + " has a NULL value");
-
- else if (value != null)
- parent.put(keyId, value);
-
- }
-
- private static void addSingleNumberElement(ObjectNode parent, String keyId, Integer value, boolean isRequired) throws SLCommandoBuildException {
- validateParentAndKey(parent, keyId);
-
- if (isRequired && value == null)
- throw new SLCommandoBuildException(keyId + " has a NULL value");
-
- else if (value != null)
- parent.put(keyId, value);;
-
- }
-
- private static void addSingleStringElement(ObjectNode parent, String keyId, String value, boolean isRequired) throws SLCommandoBuildException {
- validateParentAndKey(parent, keyId);
-
- if (isRequired && (value == null || value.isEmpty()))
- throw new SLCommandoBuildException(keyId + " has an empty value");
-
- else if (value != null && !value.isEmpty())
- parent.put(keyId, value);
-
- }
-
- private static void addSingleIntegerElement(ObjectNode parent, String keyId, Integer value, boolean isRequired) throws SLCommandoBuildException {
- validateParentAndKey(parent, keyId);
-
- if (isRequired && value == null)
- throw new SLCommandoBuildException(keyId + " has an empty value");
-
- else if (value != null)
- parent.put(keyId, value);
-
- }
-
- private static void addSingleJSONElement(ObjectNode parent, String keyId, ObjectNode element, boolean isRequired) throws SLCommandoBuildException {
- validateParentAndKey(parent, keyId);
-
- if (isRequired && element == null)
- throw new SLCommandoBuildException("No commando name included");
-
- else if (element != null)
- parent.set(keyId, element);
-
- }
-
- private static void addOnlyOnceOfTwo(ObjectNode parent, String firstKeyId, String secondKeyId, ObjectNode first, ObjectNode second) throws SLCommandoBuildException {
- if (first == null && second == null)
- throw new SLCommandoBuildException(firstKeyId + " and " + secondKeyId + " is NULL");
-
- else if (first != null && second != null)
- throw new SLCommandoBuildException(firstKeyId + " and " + secondKeyId + " can not SET TWICE");
-
- else if (first != null)
- parent.set(firstKeyId, first);
-
- else if (second != null)
- parent.set(secondKeyId, second);
-
- else
- throw new SLCommandoBuildException("Internal build error");
- }
-
- private static void validateParentAndKey(ObjectNode parent, String keyId) throws SLCommandoBuildException {
- if (parent == null)
- throw new SLCommandoBuildException("NO parent JSON element");
-
- if (keyId == null || keyId.isEmpty())
- throw new SLCommandoBuildException("NO JSON element identifier");
- }
-}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONExtractorUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONExtractorUtils.java
deleted file mode 100644
index 314dde17..00000000
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JSONExtractorUtils.java
+++ /dev/null
@@ -1,368 +0,0 @@
-package at.gv.egiz.eaaf.modules.auth.sl20.utils;
-
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.util.EntityUtils;
-import org.jose4j.base64url.Base64Url;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SLCommandoParserException;
-
-public class SL20JSONExtractorUtils {
- private static final Logger log = LoggerFactory.getLogger(SL20JSONExtractorUtils.class);
- private static JsonMapper mapper = new JsonMapper();
-
-
- /**
- * Extract String value from JSON
- *
- * @param input
- * @param keyID
- * @param isRequired
- * @return
- * @throws SLCommandoParserException
- */
- public static String getStringValue(JsonNode input, String keyID, boolean isRequired) throws SLCommandoParserException {
- try {
- final JsonNode internal = getAndCheck(input, keyID, isRequired);
-
- if (internal != null)
- return internal.asText();
- else
- return null;
-
- } catch (final SLCommandoParserException e) {
- throw e;
-
- } catch (final Exception e) {
- throw new SLCommandoParserException("Can not extract String value with keyId: " + keyID, e);
-
- }
- }
-
- /**
- * Extract Boolean value from JSON
- *
- * @param input
- * @param keyID
- * @param isRequired
- * @return
- * @throws SLCommandoParserException
- */
- public static boolean getBooleanValue(ObjectNode input, String keyID, boolean isRequired, boolean defaultValue) throws SLCommandoParserException {
- try {
- final JsonNode internal = getAndCheck(input, keyID, isRequired);
-
- if (internal != null)
- return internal.asBoolean();
- else
- return defaultValue;
-
- } catch (final SLCommandoParserException e) {
- throw e;
-
- } catch (final Exception e) {
- throw new SLCommandoParserException("Can not extract Boolean value with keyId: " + keyID, e);
-
- }
- }
-
- /**
- * Extract JSONObject value from JSON
- *
- * @param input
- * @param keyID
- * @param isRequired
- * @return
- * @throws SLCommandoParserException
- */
- public static JsonNode getJSONObjectValue(JsonNode input, String keyID, boolean isRequired) throws SLCommandoParserException {
- try {
- final JsonNode internal = getAndCheck(input, keyID, isRequired);
-
- if (internal != null)
- return internal;
- else
- return null;
-
- } catch (final SLCommandoParserException e) {
- throw e;
-
- } catch (final Exception e) {
- throw new SLCommandoParserException("Can not extract Boolean value with keyId: " + keyID, e);
-
- }
- }
-
- /**
- * Extract a List of String elements from a JSON element
- *
- * @param input
- * @return
- * @throws SLCommandoParserException
- */
- public static List<String> getListOfStringElements(JsonNode input) throws SLCommandoParserException {
- final List<String> result = new ArrayList<String>();
- if (input != null) {
- if (input.isArray()) {
- final Iterator<JsonNode> arrayIterator = input.iterator();
- while(arrayIterator.hasNext()) {
- final JsonNode next = arrayIterator.next();
- if (next.isTextual())
- result.add(next.asText());
- }
-
- } else if (input.isTextual()) {
- result.add(input.asText());
-
- } else {
- log.warn("JSON Element IS NOT a JSON array or a JSON Primitive");
- throw new SLCommandoParserException("JSON Element IS NOT a JSON array or a JSON Primitive");
-
- }
- }
-
- return result;
- }
-
- /**
- * Extract Map of Key/Value pairs from a JSON Element
- *
- * @param input parent JSON object
- * @param keyID KeyId of the child that should be parsed
- * @param isRequired
- * @return
- * @throws SLCommandoParserException
- */
- public static Map<String, String> getMapOfStringElements(JsonNode input, String keyID, boolean isRequired) throws SLCommandoParserException {
- final JsonNode internal = getAndCheck(input, keyID, isRequired);
- return getMapOfStringElements(internal);
-
- }
-
- /**
- * Extract Map of Key/Value pairs from a JSON Element
- *
- * @param input
- * @return
- * @throws SLCommandoParserException
- */
- public static Map<String, String> getMapOfStringElements(JsonNode input) throws SLCommandoParserException {
- final Map<String, String> result = new HashMap<String, String>();
-
- if (input != null) {
- if (input.isArray()) {
- final Iterator<JsonNode> arrayIterator = input.iterator();
- while(arrayIterator.hasNext()) {
- final JsonNode next = arrayIterator.next();
- final Iterator<Entry<String, JsonNode>> entry = next.fields();
- entitySetToMap(result, entry);
-
- }
-
- } else if (input.isObject()) {
- final Iterator<Entry<String, JsonNode>> objectKeys = input.fields();
- entitySetToMap(result, objectKeys);
-
- } else
- throw new SLCommandoParserException("JSON Element IS NOT a JSON array or a JSON object");
-
- }
-
- return result;
- }
-
- private static void entitySetToMap(Map<String, String> result, Iterator<Entry<String, JsonNode>> entry) {
- while (entry.hasNext()) {
- final Entry<String, JsonNode> el = entry.next();
- if (result.containsKey(el.getKey()))
- log.info("Attr. Map already contains Element with Key: " + el.getKey() + ". Overwrite element ... ");
-
- result.put(el.getKey(), el.getValue().asText());
-
- }
-
- }
-
-
- public static JsonNode extractSL20Result(JsonNode command, IJOSETools decrypter, boolean mustBeEncrypted) throws SL20Exception {
- final JsonNode result = command.get(SL20Constants.SL20_COMMAND_CONTAINER_RESULT);
- final JsonNode encryptedResult = command.get(SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT);
-
- if (result == null && encryptedResult == null)
- throw new SLCommandoParserException("NO result OR encryptedResult FOUND.");
-
- else if (encryptedResult == null && mustBeEncrypted)
- throw new SLCommandoParserException("result MUST be encrypted.");
-
- else if (encryptedResult != null && encryptedResult.isTextual()) {
- try {
- return decrypter.decryptPayload(encryptedResult.asText());
-
- } catch (final Exception e) {
- log.info("Can NOT decrypt SL20 result. Reason:" + e.getMessage());
- if (!mustBeEncrypted) {
- log.warn("Decrypted results are disabled by configuration. Parse result in plain if it is possible");
-
- //dummy code
- try {
- final String[] signedPayload = encryptedResult.toString().split("\\.");
- final JsonNode payLoad = mapper.getMapper().readTree(new String(Base64.getUrlDecoder().decode(signedPayload[1])));
- return payLoad;
-
- } catch (final Exception e1) {
- log.debug("DummyCode FAILED, Reason: " + e1.getMessage() + " Ignore it ...");
- throw new SL20Exception(e.getMessage(), null, e);
-
- }
-
- } else
- throw e;
-
- }
-
- } else if (result != null) {
- return result;
-
- } else
- throw new SLCommandoParserException("Internal build error");
-
-
- }
-
- /**
- * Extract payLoad from generic transport container
- *
- * @param container
- * @param joseTools
- * @return
- * @throws SLCommandoParserException
- */
- public static VerificationResult extractSL20PayLoad(JsonNode container, IJOSETools joseTools, boolean mustBeSigned) throws SL20Exception {
-
- final JsonNode sl20Payload = container.get(SL20Constants.SL20_PAYLOAD);
- final JsonNode sl20SignedPayload = container.get(SL20Constants.SL20_SIGNEDPAYLOAD);
-
- if (mustBeSigned && joseTools == null)
- throw new SLCommandoParserException("'joseTools' MUST be set if 'mustBeSigned' is 'true'");
-
- if (sl20Payload == null && sl20SignedPayload == null)
- throw new SLCommandoParserException("NO payLoad OR signedPayload FOUND.");
-
- else if (sl20SignedPayload == null && mustBeSigned)
- throw new SLCommandoParserException("payLoad MUST be signed.");
-
- else if (joseTools != null && sl20SignedPayload != null && sl20SignedPayload.isTextual()) {
- return joseTools.validateSignature(sl20SignedPayload.asText());
-
- } else if (sl20Payload != null)
- return new VerificationResult(sl20Payload);
-
- else
- throw new SLCommandoParserException("Internal build error");
-
-
- }
-
-
- /**
- * Extract generic transport container from httpResponse
- *
- * @param httpResp
- * @return
- * @throws SLCommandoParserException
- */
- public static JsonNode getSL20ContainerFromResponse(HttpResponse httpResp) throws SLCommandoParserException {
- try {
- JsonNode sl20Resp = null;
- if (httpResp.getStatusLine().getStatusCode() == 303 || httpResp.getStatusLine().getStatusCode() == 307) {
- final Header[] locationHeader = httpResp.getHeaders("Location");
- if (locationHeader == null)
- throw new SLCommandoParserException("Find Redirect statuscode but not Location header");
-
- final String sl20RespString = new URIBuilder(locationHeader[0].getValue()).getQueryParams().get(0).getValue();
- sl20Resp = mapper.getMapper().readTree(Base64Url.decode(sl20RespString));
-
- } else if (httpResp.getStatusLine().getStatusCode() == 200) {
- if (httpResp.getEntity().getContentType() == null)
- throw new SLCommandoParserException("SL20 response contains NO ContentType");
-
- if (!httpResp.getEntity().getContentType().getValue().startsWith("application/json"))
- throw new SLCommandoParserException("SL20 response with a wrong ContentType: " + httpResp.getEntity().getContentType().getValue());
- sl20Resp = parseSL20ResultFromResponse(httpResp.getEntity());
-
- } else if ( (httpResp.getStatusLine().getStatusCode() == 500) ||
- (httpResp.getStatusLine().getStatusCode() == 401) ||
- (httpResp.getStatusLine().getStatusCode() == 400) ) {
- log.info("SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode()
- + ". Search for error message");
-
- try {
- sl20Resp = parseSL20ResultFromResponse(httpResp.getEntity());
-
- } catch (final Exception e) {
- log.warn("SL20 response contains no valid JSON", e);
- throw new SLCommandoParserException("SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode()
- + " AND NO valid JSON errormsg", e);
-
- }
-
-
-
- } else
- throw new SLCommandoParserException("SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode());
-
- log.info("Find JSON object in http response");
- return sl20Resp;
-
- } catch (final Exception e) {
- throw new SLCommandoParserException("SL20 response parsing FAILED! Reason: " + e.getMessage(), e);
-
- }
- }
-
- private static JsonNode parseSL20ResultFromResponse(HttpEntity resp) throws Exception {
- if (resp != null && resp.getContent() != null) {
- final String rawSL20Resp = EntityUtils.toString(resp);
- final JsonNode sl20Resp = mapper.getMapper().readTree(rawSL20Resp);
-
- //TODO: check sl20Resp type like && sl20Resp.isJsonObject()
- if (sl20Resp != null) {
- return sl20Resp;
-
- } else
- throw new SLCommandoParserException("SL2.0 can NOT parse to a JSON object");
-
-
- } else
- throw new SLCommandoParserException("Can NOT find content in http response");
-
- }
-
-
- private static JsonNode getAndCheck(JsonNode input, String keyID, boolean isRequired) throws SLCommandoParserException {
- final JsonNode internal = input.get(keyID);
-
- if (internal == null && isRequired)
- throw new SLCommandoParserException("REQUIRED Element with keyId: " + keyID + " does not exist");
-
- return internal;
-
- }
-}
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
new file mode 100644
index 00000000..f505f28d
--- /dev/null
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonBuilderUtils.java
@@ -0,0 +1,731 @@
+package at.gv.egiz.eaaf.modules.auth.sl20.utils;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import at.gv.egiz.eaaf.modules.auth.sl20.Constants;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class SL20JsonBuilderUtils {
+
+ private static JsonMapper mapper = new JsonMapper();
+
+ /**
+ * Create command request.
+ *
+ * @param name Commando name
+ * @param params Commando parameters
+ * @return JSON Object
+ * @throws SlCommandoBuildException In case of a build error
+ */
+ public static ObjectNode createCommand(final String name, final ObjectNode params)
+ throws SlCommandoBuildException {
+
+ 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;
+
+ }
+
+ /**
+ * Create signed command request.
+ *
+ * @param name Commando name
+ * @param params commando parameter
+ * @param signer JWS signer implementation
+ * @return Serialized JWS
+ * @throws SlCommandoBuildException In case of a build error
+ */
+ public static String createSignedCommand(final String name, final ObjectNode params,
+ final IJoseTools signer) throws SlCommandoBuildException {
+ 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());
+
+ }
+
+
+ /**
+ * Create encrypted command result.
+ *
+ * @param result JSON to encrypt
+ * @param encrypter JWE encrypter implementation
+ * @return Serialized JWE
+ * @throws SlCommandoBuildException In case of a processing error
+ */
+ public static String createEncryptedCommandoResult(final ObjectNode result,
+ final JsonSecurityUtils encrypter) throws SlCommandoBuildException {
+ // TODO: add real implementation
+ // create header and footer
+ 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()) + "."
+ + Base64.getUrlEncoder().encodeToString(dummyFooter.getBytes());
+
+ }
+
+
+ /**
+ * Create command result.
+ *
+ * @param name Commando name
+ * @param result commande result
+ * @param encryptedResult encrypted commando result
+ * @return Result json
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static ObjectNode createCommandResponse(final String name, final ObjectNode result,
+ final String encryptedResult) throws SlCommandoBuildException {
+ 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);
+ return command;
+
+ }
+
+ /**
+ * Create signed command result.
+ *
+ * @param name commando name
+ * @param result commando result
+ * @param encryptedResult encrypted commando result
+ * @return JWS in serialized form
+ * @throws SlCommandoBuildException in case of an error
+
+ */
+ public static String createSignedCommandResponse(final String name, final ObjectNode result,
+ final String encryptedResult, final JsonSecurityUtils signer)
+ throws SlCommandoBuildException {
+ 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);
+ final String encodedCommand = command.toString();
+
+ // TODO: add real implementation
+ // create header and footer
+ final String dummyHeader = createJsonSignedHeader(signer).toString();
+ final String dummyFooter = createJsonSignedFooter(signer);
+
+ return Base64.getUrlEncoder().encodeToString(dummyHeader.getBytes()) + "."
+ + Base64.getUrlEncoder().encodeToString(encodedCommand.getBytes()) + "."
+ + Base64.getUrlEncoder().encodeToString(dummyFooter.getBytes());
+
+ }
+
+ /**
+ * Create parameters for Redirect command.
+ *
+ * @param url redirect URL
+ * @param command embedded command
+ * @param signedCommand Signed embedded command
+ * @param ipcRedirect IPC redirect flag
+ * @return result JSON
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static ObjectNode createRedirectCommandParameters(final String url,
+ final ObjectNode command, final ObjectNode signedCommand, final Boolean ipcRedirect)
+ throws SlCommandoBuildException {
+ final ObjectNode redirectReqParams = mapper.getMapper().createObjectNode();
+ addOnlyOnceOfTwo(redirectReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND,
+ SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND, command, signedCommand);
+ addSingleStringElement(redirectReqParams, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL,
+ url, false);
+ addSingleBooleanElement(redirectReqParams,
+ SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_IPCREDIRECT, ipcRedirect, false);
+ return redirectReqParams;
+
+ }
+
+ /**
+ * Create parameters for Call command.
+ *
+ * @param url http URL for Call command
+ * @param method http method used by call commando result
+ * @param includeTransactionId TransactionId
+ * @param reqParameters Request parameters on CALL command
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static ObjectNode createCallCommandParameters(final String url, final String method,
+ final Boolean includeTransactionId, final Map<String, String> reqParameters)
+ throws SlCommandoBuildException {
+ 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);
+ addArrayOfStringElements(callReqParams,
+ SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_REQPARAMETER, reqParameters);
+ return callReqParams;
+
+ }
+
+ /**
+ * Create result for Error command.
+ *
+ * @param errorCode Error-Code
+ * @param errorMsg Error-message
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static ObjectNode createErrorCommandResult(final String errorCode, final String errorMsg)
+ throws SlCommandoBuildException {
+ 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 DataURL for result
+ * @param x5cEnc Response encryption certificate
+ * @return JSON
+ * @throws CertificateEncodingException In case of a encryption certificate encoding problem
+ * @throws SlCommandoBuildException In case of a generel error
+ */
+ public static ObjectNode createQualifiedeEidConsent(final String consentTemplateId,
+ final byte[] consent, final String dataUrl, final 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.
+ *
+ * @param authBlockId AuthBlock transformation Id
+ * @param dataUrl DataURL for result
+ * @param additionalReqParameters additional parameters
+ * @param x5cEnc Response encryption certificate
+ * @return JSON
+ * @throws CertificateEncodingException In case of a encryption certificate encoding problem
+ * @throws SlCommandoBuildException In case of a generel error
+ */
+ @Deprecated
+ public static ObjectNode createQualifiedEidCommandParameters(final String authBlockId,
+ final String dataUrl, final Map<String, String> additionalReqParameters,
+ final X509Certificate x5cEnc) throws CertificateEncodingException, SlCommandoBuildException {
+ 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);
+ addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_EID_X5CENC, x5cEnc, false);
+ return params;
+
+ }
+
+ /**
+ * Create result for qualifiedeID command.
+ *
+ * @param idl IdentityLink
+ * @param authBlock AuthBlock
+ * @param ccsUrl VDA URL
+ * @param loa LoA
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static ObjectNode createQualifiedEidCommandResult(final byte[] idl, final byte[] authBlock,
+ final String ccsUrl, final String loa) throws SlCommandoBuildException {
+ 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);
+ addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_LOA, loa, true);
+ return result;
+
+ }
+
+
+ /**
+ * Create Binding-Key command parameters.
+ *
+ * @param kontoId KontoId
+ * @param subjectName SubjectName
+ * @param keySize KeySize
+ * @param keyAlg Key-algorithm
+ * @param policies Key policy
+ * @param dataUrl DataURL
+ * @param x5cVdaTrust trusted certificate from VDA
+ * @param reqUserPassword User passwort initialize request
+ * @param x5cEnc Result encryption certificate
+ * @return JSON
+ * @throws SlCommandoBuildException in case of an errr
+ * @throws CertificateEncodingException In case of a certificate error
+ */
+ public static ObjectNode createBindingKeyCommandParams(final String kontoId,
+ final String subjectName, final int keySize, final String keyAlg,
+ final Map<String, String> policies, final String dataUrl, final X509Certificate x5cVdaTrust,
+ final Boolean reqUserPassword, final X509Certificate x5cEnc)
+ throws SlCommandoBuildException, CertificateEncodingException {
+ 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);
+ addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_KEYALG, keyAlg,
+ true);
+ addArrayOfStringElements(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_POLICIES,
+ policies);
+ addSingleStringElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_DATAURL, dataUrl,
+ true);
+ addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_X5CVDATRUST,
+ x5cVdaTrust, false);
+ addSingleBooleanElement(params,
+ SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_REQUESTUSERPASSWORD, reqUserPassword,
+ false);
+ addSingleCertificateElement(params, SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_X5CENC,
+ x5cEnc, false);
+ return params;
+
+ }
+
+ /**
+ * Create Binding-Key command result.
+ *
+ * @param appId AppId
+ * @param csr CSR
+ * @param attCert Key-Attestation certificate
+ * @param password user's password
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ * @throws CertificateEncodingException In case of a certificate processing error
+ */
+ public static ObjectNode createBindingKeyCommandResult(final String appId, final byte[] csr,
+ final X509Certificate attCert, final byte[] password)
+ throws SlCommandoBuildException, CertificateEncodingException {
+ 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);
+ addSingleByteElement(result,
+ SL20Constants.SL20_COMMAND_PARAM_BINDING_CREATE_RESULT_USERPASSWORD, password, false);
+ return result;
+
+ }
+
+ /**
+ * Create Store Binding-Certificate command parameters.
+ *
+ * @param cert Certificate
+ * @param dataUrl DATA URL
+ * @return JSON
+ * @throws CertificateEncodingException In case of a certificate processing error
+ * @throws SlCommandoBuildException In case of a error
+ */
+ public static ObjectNode createStoreBindingCertCommandParams(final X509Certificate cert,
+ final String dataUrl) throws CertificateEncodingException, SlCommandoBuildException {
+ 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;
+
+ }
+
+ /**
+ * Create Store Binding-Certificate command result.
+ *
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static ObjectNode createStoreBindingCertCommandSuccessResult()
+ throws SlCommandoBuildException {
+ 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;
+
+ }
+
+
+ /**
+ * Create idAndPassword command parameters.
+ *
+ * @param keyAlg key algorithm
+ * @param dataUrl DATA Url
+ * @param x5cEnc result encryption certificate
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ * @throws CertificateEncodingException In case of a certificate processing error
+ */
+ public static ObjectNode createIdAndPasswordCommandParameters(final String keyAlg,
+ final String dataUrl, final X509Certificate x5cEnc)
+ throws SlCommandoBuildException, CertificateEncodingException {
+ 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);
+ return params;
+
+ }
+
+ /**
+ * Create idAndPassword command result.
+ *
+ * @param kontoId User's Id
+ * @param password User's password
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static ObjectNode createIdAndPasswordCommandResult(final String kontoId,
+ final byte[] password) throws SlCommandoBuildException {
+ 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;
+
+ }
+
+ /**
+ * Create JWS Token Authentication command.
+ *
+ * @param nonce nonce that should be signed
+ * @param dataUrl Data URL
+ * @param displayData Data that should be displayed
+ * @param displayUrl URL to data that should be displayed
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static ObjectNode createJwsTokenAuthCommandParams(final String nonce, final String dataUrl,
+ final List<String> displayData, final List<String> displayUrl)
+ throws SlCommandoBuildException {
+ 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);
+ addArrayOfStrings(params, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_DISPLAYURL,
+ displayUrl);
+ return params;
+
+ }
+
+ /**
+ * Create JWS Token Authentication command result.
+ *
+ * @param nonce Serialzed JWS that contains the signed nonce
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static ObjectNode createJwsTokenAuthCommandResult(final String nonce)
+ throws SlCommandoBuildException {
+ final ObjectNode result = mapper.getMapper().createObjectNode();
+ addSingleStringElement(result, SL20Constants.SL20_COMMAND_PARAM_AUTH_JWSTOKEN_RESULT_NONCE,
+ nonce, true);
+ return result;
+
+ }
+
+
+ /**
+ * Create Generic Request Container.
+ *
+ * @param reqId RequestId
+ * @param transactionId TransactionId
+ * @param payLoad unsigned payload
+ * @param signedPayload Signed payload
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static ObjectNode createGenericRequest(final String reqId, final String transactionId,
+ final ObjectNode payLoad, final String signedPayload) throws SlCommandoBuildException {
+ 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);
+ addOnlyOnceOfTwo(req, SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD, payLoad,
+ signedPayload);
+ return req;
+
+ }
+
+ /**
+ * Create Generic Response Container.
+ *
+ * @param respId Response Id
+ * @param inResponseTo RequestId to this response
+ * @param transactionId transactionId
+ * @param payLoad Unsigned payload
+ * @param signedPayload Signed payload
+ * @return JSON
+ * @throws SlCommandoBuildException In case of an error
+ */
+ public static final ObjectNode createGenericResponse(final String respId,
+ final String inResponseTo, final String transactionId, final ObjectNode payLoad,
+ final String signedPayload) throws SlCommandoBuildException {
+ 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, false);
+ addSingleStringElement(req, SL20Constants.SL20_TRANSACTIONID, transactionId, false);
+ addOnlyOnceOfTwo(req, SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD, payLoad,
+ signedPayload);
+ return req;
+
+ }
+
+ private static void addOnlyOnceOfTwo(final ObjectNode parent, final String firstKeyId,
+ final String secondKeyId, final ObjectNode first, final ObjectNode second)
+ throws SlCommandoBuildException {
+ if (first == null && second == null) {
+ throw new SlCommandoBuildException(firstKeyId + " and " + secondKeyId + " is NULL");
+ } else if (first != null && second != null) {
+ throw new SlCommandoBuildException(firstKeyId + " and " + secondKeyId + " can not SET TWICE");
+ } else if (first != null) {
+ parent.set(firstKeyId, first);
+ } else if (second != null) {
+ parent.set(secondKeyId, second);
+ } else {
+ throw new SlCommandoBuildException("Internal build error");
+ }
+ }
+
+ /**
+ * Add one element of two possible elements <br>
+ * This method adds either the first element or the second element to parent JSON, but never both.
+ *
+ * @param parent Parent JSON element
+ * @param firstKeyId first element Id
+ * @param secondKeyId second element Id
+ * @param first first element
+ * @param second second element
+ * @throws SlCommandoBuildException In case of an error.
+ */
+ public static void addOnlyOnceOfTwo(final ObjectNode parent, final String firstKeyId,
+ final String secondKeyId, final ObjectNode first, final String second)
+ throws SlCommandoBuildException {
+ if (first == null && (second == null || second.isEmpty())) {
+ throw new SlCommandoBuildException(firstKeyId + " and " + secondKeyId + " is NULL");
+ } else if (first != null && second != null) {
+ throw new SlCommandoBuildException(firstKeyId + " and " + secondKeyId + " can not SET TWICE");
+ } else if (first != null) {
+ parent.set(firstKeyId, first);
+ } else if (second != null && !second.isEmpty()) {
+ parent.put(secondKeyId, second);
+ } else {
+ throw new SlCommandoBuildException("Internal build error");
+ }
+ }
+
+
+
+ // TODO!!!!
+ private static ObjectNode createJsonSignedHeader(final JsonSecurityUtils signer)
+ throws SlCommandoBuildException {
+ 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));
+
+ return header;
+ }
+
+ // TODO!!!!
+ private static ObjectNode createJsonEncryptionHeader(final JsonSecurityUtils signer)
+ throws SlCommandoBuildException {
+ 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);
+ addSingleStringElement(header, SL20Constants.JSON_X509_FINGERPRINT,
+ Constants.DUMMY_SIGNING_CERT_FINGERPRINT, true);
+
+ return header;
+ }
+
+ // TODO!!!!
+ private static String createJsonSignedFooter(final JsonSecurityUtils signer) {
+ return "cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZmh7\n"
+ + " AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjbKBYNX4\n"
+ + " BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHlb1L07Qe7K\n"
+ + " 0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZESc6BfI7noOPqv\n"
+ + " hJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrB\n"
+ + " p0igcN_IoypGlUPQGe77Rw";
+ }
+
+
+
+ private static void addArrayOfStrings(final ObjectNode parent, final String keyId,
+ final List<String> values) throws SlCommandoBuildException {
+ validateParentAndKey(parent, keyId);
+ if (values != null) {
+ final ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode();
+ parent.set(keyId, callReqParamsArray);
+ for (final String el : values) {
+ callReqParamsArray.add(el);
+ }
+
+ }
+ }
+
+
+ private static void addArrayOfStringElements(final ObjectNode parent, final String keyId,
+ final Map<String, String> keyValuePairs) throws SlCommandoBuildException {
+ validateParentAndKey(parent, keyId);
+ if (keyValuePairs != null) {
+ final ArrayNode callReqParamsArray = mapper.getMapper().createArrayNode();
+ parent.set(keyId, callReqParamsArray);
+
+ for (final Entry<String, String> el : keyValuePairs.entrySet()) {
+ final ObjectNode callReqParams = mapper.getMapper().createObjectNode();
+ callReqParams.put(el.getKey(), el.getValue());
+ callReqParamsArray.add(callReqParams);
+
+ }
+ }
+ }
+
+ private static void addSingleCertificateElement(final ObjectNode parent, final String keyId,
+ final X509Certificate cert, final boolean isRequired)
+ throws CertificateEncodingException, SlCommandoBuildException {
+ if (cert != null) {
+ addSingleByteElement(parent, keyId, cert.getEncoded(), isRequired);
+ } else if (isRequired) {
+ throw new SlCommandoBuildException(keyId + " is marked as REQUIRED");
+ }
+
+ }
+
+
+
+ private static void addSingleByteElement(final ObjectNode parent, final String keyId,
+ final byte[] value, final boolean isRequired) throws SlCommandoBuildException {
+ validateParentAndKey(parent, keyId);
+
+ if (isRequired && value == null) {
+ throw new SlCommandoBuildException(keyId + " has NULL value");
+ } else if (value != null) {
+ parent.put(keyId, Base64.getEncoder().encodeToString(value));
+ }
+
+ }
+
+ private static void addSingleBooleanElement(final ObjectNode parent, final String keyId,
+ final Boolean value, final boolean isRequired) throws SlCommandoBuildException {
+ validateParentAndKey(parent, keyId);
+
+ if (isRequired && value == null) {
+ throw new SlCommandoBuildException(keyId + " has a NULL value");
+ } else if (value != null) {
+ parent.put(keyId, value);
+ }
+
+ }
+
+ private static void addSingleNumberElement(final ObjectNode parent, final String keyId,
+ final Integer value, final boolean isRequired) throws SlCommandoBuildException {
+ validateParentAndKey(parent, keyId);
+
+ if (isRequired && value == null) {
+ throw new SlCommandoBuildException(keyId + " has a NULL value");
+ } else if (value != null) {
+ parent.put(keyId, value);
+ }
+
+ }
+
+ private static void addSingleStringElement(final ObjectNode parent, final String keyId,
+ final String value, final boolean isRequired) throws SlCommandoBuildException {
+ validateParentAndKey(parent, keyId);
+
+ if (isRequired && (value == null || value.isEmpty())) {
+ throw new SlCommandoBuildException(keyId + " has an empty value");
+ } else if (value != null && !value.isEmpty()) {
+ parent.put(keyId, value);
+ }
+
+ }
+
+ private static void addSingleIntegerElement(final ObjectNode parent, final String keyId,
+ final Integer value, final boolean isRequired) throws SlCommandoBuildException {
+ validateParentAndKey(parent, keyId);
+
+ if (isRequired && value == null) {
+ throw new SlCommandoBuildException(keyId + " has an empty value");
+ } else if (value != null) {
+ parent.put(keyId, value);
+ }
+
+ }
+
+ private static void addSingleJsonElement(final ObjectNode parent, final String keyId,
+ final ObjectNode element, final boolean isRequired) throws SlCommandoBuildException {
+ validateParentAndKey(parent, keyId);
+
+ if (isRequired && element == null) {
+ throw new SlCommandoBuildException("No commando name included");
+ } else if (element != null) {
+ parent.set(keyId, element);
+ }
+
+ }
+
+
+
+ private static void validateParentAndKey(final ObjectNode parent, final String keyId)
+ throws SlCommandoBuildException {
+ if (parent == null) {
+ throw new SlCommandoBuildException("NO parent JSON element");
+ }
+
+ if (keyId == null || keyId.isEmpty()) {
+ throw new SlCommandoBuildException("NO JSON element identifier");
+ }
+ }
+}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java
new file mode 100644
index 00000000..f4b5a724
--- /dev/null
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java
@@ -0,0 +1,407 @@
+package at.gv.egiz.eaaf.modules.auth.sl20.utils;
+
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.util.EntityUtils;
+import org.jose4j.base64url.Base64Url;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class SL20JsonExtractorUtils {
+ private static final Logger log = LoggerFactory.getLogger(SL20JsonExtractorUtils.class);
+ private static JsonMapper mapper = new JsonMapper();
+
+
+ /**
+ * Extract String value from JSON.
+ *
+ * @param input JSON
+ * @param keyID Element identifier
+ * @param isRequired true, if the element must not null
+ * @return Value of this element
+ * @throws SlCommandoParserException In case an error
+ */
+ public static String getStringValue(final JsonNode input, final String keyID,
+ final boolean isRequired) throws SlCommandoParserException {
+ try {
+ final JsonNode internal = getAndCheck(input, keyID, isRequired);
+
+ if (internal != null) {
+ return internal.asText();
+ } else {
+ return null;
+ }
+
+ } catch (final SlCommandoParserException e) {
+ throw e;
+
+ } catch (final Exception e) {
+ throw new SlCommandoParserException("Can not extract String value with keyId: " + keyID, e);
+
+ }
+ }
+
+ /**
+ * Extract Boolean value from JSON.
+ *
+ * @param input JSON
+ * @param keyID Element identifier
+ * @param isRequired true, if the element must not null
+ * @return Boolean
+ * @throws SlCommandoParserException In case of an error
+ */
+ public static boolean getBooleanValue(final ObjectNode input, final String keyID,
+ final boolean isRequired, final boolean defaultValue) throws SlCommandoParserException {
+ try {
+ final JsonNode internal = getAndCheck(input, keyID, isRequired);
+
+ if (internal != null) {
+ return internal.asBoolean();
+ } else {
+ return defaultValue;
+ }
+
+ } catch (final SlCommandoParserException e) {
+ throw e;
+
+ } catch (final Exception e) {
+ throw new SlCommandoParserException("Can not extract Boolean value with keyId: " + keyID, e);
+
+ }
+ }
+
+ /**
+ * Extract JSONObject value from JSON.
+ *
+ * @param input JSON
+ * @param keyID Element identifier
+ * @param isRequired true, if the element must not null
+ * @return JSON node
+ * @throws SlCommandoParserException In case of an error
+ */
+ public static JsonNode getJsonObjectValue(final JsonNode input, final String keyID,
+ final boolean isRequired) throws SlCommandoParserException {
+ try {
+ final JsonNode internal = getAndCheck(input, keyID, isRequired);
+
+ if (internal != null) {
+ return internal;
+ } else {
+ return null;
+ }
+
+ } catch (final SlCommandoParserException e) {
+ throw e;
+
+ } catch (final Exception e) {
+ throw new SlCommandoParserException("Can not extract Boolean value with keyId: " + keyID, e);
+
+ }
+ }
+
+ /**
+ * Extract a List of String elements from a JSON element.
+ *
+ * @param input JSON
+ * @return List of Elements in this node
+ * @throws SlCommandoParserException In case of an error
+ */
+ public static List<String> getListOfStringElements(final JsonNode input)
+ throws SlCommandoParserException {
+ final List<String> result = new ArrayList<>();
+ if (input != null) {
+ if (input.isArray()) {
+ final Iterator<JsonNode> arrayIterator = input.iterator();
+ while (arrayIterator.hasNext()) {
+ final JsonNode next = arrayIterator.next();
+ if (next.isTextual()) {
+ result.add(next.asText());
+ }
+ }
+
+ } else if (input.isTextual()) {
+ result.add(input.asText());
+
+ } else {
+ log.warn("JSON Element IS NOT a JSON array or a JSON Primitive");
+ throw new SlCommandoParserException("JSON Element IS NOT a JSON array or a JSON Primitive");
+
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Extract Map of Key/Value pairs from a JSON Element.
+ *
+ * @param input parent JSON object
+ * @param keyID KeyId of the child that should be parsed
+ * @param isRequired true, if the element must not null
+ * @return Map of element pairs
+ * @throws SlCommandoParserException In case of an error
+ */
+ public static Map<String, String> getMapOfStringElements(final JsonNode input, final String keyID,
+ final boolean isRequired) throws SlCommandoParserException {
+ final JsonNode internal = getAndCheck(input, keyID, isRequired);
+ return getMapOfStringElements(internal);
+
+ }
+
+ /**
+ * Extract Map of Key/Value pairs from a JSON Element.
+ *
+ * @param input JSON
+ * @return Map of element pairs
+ * @throws SlCommandoParserException in case of an error
+ */
+ public static Map<String, String> getMapOfStringElements(final JsonNode input)
+ throws SlCommandoParserException {
+ final Map<String, String> result = new HashMap<>();
+
+ if (input != null) {
+ if (input.isArray()) {
+ final Iterator<JsonNode> arrayIterator = input.iterator();
+ while (arrayIterator.hasNext()) {
+ final JsonNode next = arrayIterator.next();
+ final Iterator<Entry<String, JsonNode>> entry = next.fields();
+ entitySetToMap(result, entry);
+
+ }
+
+ } else if (input.isObject()) {
+ final Iterator<Entry<String, JsonNode>> objectKeys = input.fields();
+ entitySetToMap(result, objectKeys);
+
+ } else {
+ throw new SlCommandoParserException("JSON Element IS NOT a JSON array or a JSON object");
+ }
+
+ }
+
+ return result;
+ }
+
+ private static void entitySetToMap(final Map<String, String> result,
+ final Iterator<Entry<String, JsonNode>> entry) {
+ while (entry.hasNext()) {
+ final Entry<String, JsonNode> el = entry.next();
+ if (result.containsKey(el.getKey())) {
+ log.info("Attr. Map already contains Element with Key: " + el.getKey()
+ + ". Overwrite element ... ");
+ }
+
+ result.put(el.getKey(), el.getValue().asText());
+
+ }
+
+ }
+
+
+ /**
+ * Extract Security-Layer 2.0 result from response object.
+ *
+ * @param command SL2.0 command
+ * @param decrypter JWS decrypter implementation
+ * @param mustBeEncrypted if <code>true</code>, the result must be encrypted
+ * @return decrypted JSON
+ * @throws SL20Exception In case of an error
+ */
+ public static JsonNode extractSL20Result(final JsonNode command, final IJoseTools decrypter,
+ final boolean mustBeEncrypted) throws SL20Exception {
+ final JsonNode result = command.get(SL20Constants.SL20_COMMAND_CONTAINER_RESULT);
+ final JsonNode encryptedResult =
+ command.get(SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT);
+
+ if (result == null && encryptedResult == null) {
+ throw new SlCommandoParserException("NO result OR encryptedResult FOUND.");
+ } else if (encryptedResult == null && mustBeEncrypted) {
+ throw new SlCommandoParserException("result MUST be encrypted.");
+ } else if (encryptedResult != null && encryptedResult.isTextual()) {
+ try {
+ return decrypter.decryptPayload(encryptedResult.asText());
+
+ } catch (final Exception e) {
+ log.info("Can NOT decrypt SL20 result. Reason:" + e.getMessage());
+ if (!mustBeEncrypted) {
+ log.warn(
+ "Decrypted results are disabled by configuration. Parse result in plain if it is possible");
+
+ // dummy code
+ try {
+ final String[] signedPayload = encryptedResult.toString().split("\\.");
+ final JsonNode payLoad = mapper.getMapper()
+ .readTree(new String(Base64.getUrlDecoder().decode(signedPayload[1])));
+ return payLoad;
+
+ } catch (final Exception e1) {
+ log.debug("DummyCode FAILED, Reason: " + e1.getMessage() + " Ignore it ...");
+ throw new SL20Exception(e.getMessage(), null, e);
+
+ }
+
+ } else {
+ throw e;
+ }
+
+ }
+
+ } else if (result != null) {
+ return result;
+
+ } else {
+ throw new SlCommandoParserException("Internal build error");
+ }
+
+
+ }
+
+ /**
+ * Extract payLoad from generic transport container.
+ *
+ * @param container JSON
+ * @param joseTools JWS implementation
+ * @return Signature verification result that contains the payLoad
+ * @throws SlCommandoParserException In case of an error
+ */
+ public static VerificationResult extractSL20PayLoad(final JsonNode container,
+ final IJoseTools joseTools, final boolean mustBeSigned) throws SL20Exception {
+
+ final JsonNode sl20Payload = container.get(SL20Constants.SL20_PAYLOAD);
+ final JsonNode sl20SignedPayload = container.get(SL20Constants.SL20_SIGNEDPAYLOAD);
+
+ if (mustBeSigned && joseTools == null) {
+ throw new SlCommandoParserException("'joseTools' MUST be set if 'mustBeSigned' is 'true'");
+ }
+
+ if (sl20Payload == null && sl20SignedPayload == null) {
+ throw new SlCommandoParserException("NO payLoad OR signedPayload FOUND.");
+ } else if (sl20SignedPayload == null && mustBeSigned) {
+ throw new SlCommandoParserException("payLoad MUST be signed.");
+ } else if (joseTools != null && sl20SignedPayload != null && sl20SignedPayload.isTextual()) {
+ return joseTools.validateSignature(sl20SignedPayload.asText());
+
+ } else if (sl20Payload != null) {
+ return new VerificationResult(sl20Payload);
+ } else {
+ throw new SlCommandoParserException("Internal build error");
+ }
+
+
+ }
+
+
+ /**
+ * Extract generic transport container from httpResponse.
+ *
+ * @param httpResp Http response object
+ * @return JSON with SL2.0 response
+ * @throws SlCommandoParserException In case of an error
+ */
+ public static JsonNode getSL20ContainerFromResponse(final HttpResponse httpResp)
+ throws SlCommandoParserException {
+ try {
+ JsonNode sl20Resp = null;
+ if (httpResp.getStatusLine().getStatusCode() == 303
+ || httpResp.getStatusLine().getStatusCode() == 307) {
+ final Header[] locationHeader = httpResp.getHeaders("Location");
+ if (locationHeader == null) {
+ throw new SlCommandoParserException("Find Redirect statuscode but not Location header");
+ }
+
+ final String sl20RespString =
+ new URIBuilder(locationHeader[0].getValue()).getQueryParams().get(0).getValue();
+ sl20Resp = mapper.getMapper().readTree(Base64Url.decode(sl20RespString));
+
+ } else if (httpResp.getStatusLine().getStatusCode() == 200) {
+ if (httpResp.getEntity().getContentType() == null) {
+ throw new SlCommandoParserException("SL20 response contains NO ContentType");
+ }
+
+ if (!httpResp.getEntity().getContentType().getValue().startsWith("application/json")) {
+ throw new SlCommandoParserException("SL20 response with a wrong ContentType: "
+ + httpResp.getEntity().getContentType().getValue());
+ }
+ sl20Resp = parseSL20ResultFromResponse(httpResp.getEntity());
+
+ } else if ((httpResp.getStatusLine().getStatusCode() == 500)
+ || (httpResp.getStatusLine().getStatusCode() == 401)
+ || (httpResp.getStatusLine().getStatusCode() == 400)) {
+ log.info("SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode()
+ + ". Search for error message");
+
+ try {
+ sl20Resp = parseSL20ResultFromResponse(httpResp.getEntity());
+
+ } catch (final Exception e) {
+ log.warn("SL20 response contains no valid JSON", e);
+ throw new SlCommandoParserException("SL20 response with http-code: "
+ + httpResp.getStatusLine().getStatusCode() + " AND NO valid JSON errormsg", e);
+
+ }
+
+
+
+ } else {
+ throw new SlCommandoParserException(
+ "SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode());
+ }
+
+ log.info("Find JSON object in http response");
+ return sl20Resp;
+
+ } catch (final Exception e) {
+ throw new SlCommandoParserException("SL20 response parsing FAILED! Reason: " + e.getMessage(),
+ e);
+
+ }
+ }
+
+ private static JsonNode parseSL20ResultFromResponse(final HttpEntity resp) throws Exception {
+ if (resp != null && resp.getContent() != null) {
+ final String rawSL20Resp = EntityUtils.toString(resp);
+ final JsonNode sl20Resp = mapper.getMapper().readTree(rawSL20Resp);
+
+ // TODO: check sl20Resp type like && sl20Resp.isJsonObject()
+ if (sl20Resp != null) {
+ return sl20Resp;
+
+ } else {
+ throw new SlCommandoParserException("SL2.0 can NOT parse to a JSON object");
+ }
+
+
+ } else {
+ throw new SlCommandoParserException("Can NOT find content in http response");
+ }
+
+ }
+
+
+ private static JsonNode getAndCheck(final JsonNode input, final String keyID,
+ final boolean isRequired) throws SlCommandoParserException {
+ final JsonNode internal = input.get(keyID);
+
+ if (internal == null && isRequired) {
+ throw new SlCommandoParserException(
+ "REQUIRED Element with keyId: " + keyID + " does not exist");
+ }
+
+ return internal;
+
+ }
+}