From 7bf7c3c03fd3a1efeaf3f8e3dd75922e2f5f9921 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Mar 2022 19:06:10 +0100
Subject: refactor(core): move all project libs into sub-project 'modules'
---
.../checks/spotbugs-exclude.xml | 44 +
modules/authmodule-eIDAS-v2/pom.xml | 295 +++++++
.../specific/modules/auth/eidas/v2/Constants.java | 192 +++++
.../eidas/v2/EidasAuthenticationModulImpl.java | 87 ++
.../EidasAuthenticationSpringResourceProvider.java | 52 ++
.../modules/auth/eidas/v2/EidasSignalServlet.java | 161 ++++
.../modules/auth/eidas/v2/dao/ErnbEidData.java | 115 +++
.../v2/exception/EidPostProcessingException.java | 40 +
.../v2/exception/EidasAttributeException.java | 34 +
.../exception/EidasSAuthenticationException.java | 41 +
.../v2/exception/EidasValidationException.java | 34 +
.../eidas/v2/exception/SqliteServiceException.java | 40 +
.../v2/exception/SzrCommunicationException.java | 38 +
.../eidas/v2/handler/AbstractEidProcessor.java | 425 ++++++++++
.../auth/eidas/v2/handler/DeEidProcessor.java | 113 +++
.../auth/eidas/v2/handler/GenericEidProcessor.java | 61 ++
.../eidas/v2/handler/INationalEidProcessor.java | 81 ++
.../auth/eidas/v2/handler/LuEidProcessor.java | 61 ++
.../auth/eidas/v2/handler/NlEidProcessor.java | 54 ++
.../eidas/v2/service/AuthBlockSigningService.java | 211 +++++
.../v2/service/CcSpecificEidProcessingService.java | 135 +++
.../eidas/v2/service/EidasAttributeRegistry.java | 180 ++++
.../auth/eidas/v2/service/EidasDataStore.java | 363 ++++++++
.../service/ICcSpecificEidProcessingService.java | 61 ++
.../modules/auth/eidas/v2/szr/SzrClient.java | 522 ++++++++++++
.../modules/auth/eidas/v2/szr/SzrService.java | 164 ++++
.../eidas/v2/tasks/CreateIdentityLinkTask.java | 503 +++++++++++
.../eidas/v2/tasks/GenerateAuthnRequestTask.java | 255 ++++++
.../eidas/v2/tasks/ReceiveAuthnResponseTask.java | 130 +++
.../auth/eidas/v2/utils/EidasResponseUtils.java | 179 ++++
.../modules/auth/eidas/v2/utils/JoseUtils.java | 305 +++++++
.../auth/eidas/v2/utils/LoggingHandler.java | 72 ++
.../eidas/v2/validator/EidasResponseValidator.java | 175 ++++
...iz.components.spring.api.SpringResourceProvider | 1 +
.../resources/eIDAS.Authentication.process.xml | 29 +
.../main/resources/eIDAS/additional-attributes.xml | 42 +
.../src/main/resources/eIDAS/eidas-attributes.xml | 379 +++++++++
.../src/main/resources/eidas_v2_auth.beans.xml | 100 +++
.../resources/xmldata/fakeIdL_IdL_template.xml | 122 +++
.../src/main/resources/szr_client/SZR-1.1.WSDL | 939 +++++++++++++++++++++
.../src/main/resources/szr_client/SZR-1.WSDL | 901 ++++++++++++++++++++
.../src/main/resources/szr_client/SZR_v4.0.wsdl | 441 ++++++++++
.../src/main/resources/szr_client/pvp1.xsd | 133 +++
.../src/main/resources/szr_client/pvp19.xsd | 133 +++
.../src/main/resources/szr_client/szr.xsd | 388 +++++++++
.../src/main/resources/szr_client/szr_ecdsa.xsd | 30 +
.../main/resources/szr_client/szr_persondata.xsd | 54 ++
.../src/main/resources/szr_client/szr_pvp_sec.xsd | 10 +
.../main/resources/szr_client/szr_v4.0-schemas.xml | 54 ++
.../main/resources/szr_client/szr_v4.0-wsdl.xml | 10 +
.../src/main/resources/szr_client/szr_v4.0.xsd | 443 ++++++++++
.../src/main/resources/szr_client/szr_xmldsig.xsd | 31 +
.../resources/templates/eidas_node_forward.html | 36 +
.../test/EidasAuthSpringResourceProviderTest.java | 56 ++
.../v2/test/EidasAuthenticationModulImplTest.java | 121 +++
.../auth/eidas/v2/test/EidasDataStoreTest.java | 118 +++
.../auth/eidas/v2/test/EidasSignalServletTest.java | 244 ++++++
.../modules/auth/eidas/v2/test/SzrClientTest.java | 439 ++++++++++
.../eidas/v2/test/SzrClientTestProduction.java | 236 ++++++
.../dummy/DummySpecificCommunicationService.java | 66 ++
.../tasks/CreateIdentityLinkTaskEidNewTest.java | 491 +++++++++++
.../v2/test/tasks/CreateIdentityLinkTaskTest.java | 464 ++++++++++
.../test/tasks/GenerateAuthnRequestTaskTest.java | 637 ++++++++++++++
.../test/tasks/ReceiveEidasResponseTaskTest.java | 223 +++++
.../auth/eidas/v2/test/utils/JoseUtilsTest.java | 139 +++
.../EidasAttributePostProcessingTest.java | 460 ++++++++++
.../EidasRequestPreProcessingFirstTest.java | 193 +++++
.../EidasRequestPreProcessingSecondTest.java | 157 ++++
.../validation/EidasResponseValidatorTest.java | 333 ++++++++
.../SpringTest-context_basic_mapConfig.xml | 20 +
.../SpringTest-context_basic_realConfig.xml | 25 +
.../resources/SpringTest-context_basic_test.xml | 73 ++
.../resources/SpringTest-context_tasks_test.xml | 67 ++
.../resources/config/additional-attributes.xml | 39 +
.../src/test/resources/config/eidas-attributes.xml | 376 +++++++++
.../resources/config/junit_config_1.properties | 117 +++
.../resources/config/junit_config_2.properties | 114 +++
.../resources/config/junit_config_3.properties | 118 +++
.../resources/config/junit_config_4.properties | 114 +++
.../config/junit_config_de_attributes.properties | 116 +++
.../src/test/resources/data/junit.jks | Bin 0 -> 5738 bytes
.../test/resources/data/szr/signed_eidasBind.jws | 1 +
.../data/szr/szr_resp_error_travelerdocexists.xml | 6 +
.../test/resources/data/szr/szr_resp_valid_1.xml | 50 ++
.../test/resources/data/szr/szr_resp_valid_2.xml | 50 ++
.../src/test/resources/keystore/teststore.jks | Bin 0 -> 2028 bytes
86 files changed, 15162 insertions(+)
create mode 100644 modules/authmodule-eIDAS-v2/checks/spotbugs-exclude.xml
create mode 100644 modules/authmodule-eIDAS-v2/pom.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasAuthenticationModulImpl.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasAuthenticationSpringResourceProvider.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasSignalServlet.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/ErnbEidData.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidPostProcessingException.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasAttributeException.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasSAuthenticationException.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasValidationException.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/SqliteServiceException.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/SzrCommunicationException.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeEidProcessor.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/GenericEidProcessor.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/INationalEidProcessor.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/LuEidProcessor.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/NlEidProcessor.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/AuthBlockSigningService.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/CcSpecificEidProcessingService.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasAttributeRegistry.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasDataStore.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/ICcSpecificEidProcessingService.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/szr/SzrClient.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/szr/SzrService.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateAuthnRequestTask.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAuthnResponseTask.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/JoseUtils.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/LoggingHandler.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/validator/EidasResponseValidator.java
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/eIDAS/additional-attributes.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/eIDAS/eidas-attributes.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/resources/xmldata/fakeIdL_IdL_template.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/SZR-1.1.WSDL
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/SZR-1.WSDL
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/SZR_v4.0.wsdl
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/pvp1.xsd
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/pvp19.xsd
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/szr.xsd
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/szr_ecdsa.xsd
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/szr_persondata.xsd
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/szr_pvp_sec.xsd
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/szr_v4.0-schemas.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/szr_v4.0-wsdl.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/szr_v4.0.xsd
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/szr_client/szr_xmldsig.xsd
create mode 100644 modules/authmodule-eIDAS-v2/src/main/resources/templates/eidas_node_forward.html
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/EidasAuthSpringResourceProviderTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/EidasAuthenticationModulImplTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/EidasDataStoreTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/EidasSignalServletTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/SzrClientTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/SzrClientTestProduction.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/dummy/DummySpecificCommunicationService.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateAuthnRequestTaskTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveEidasResponseTaskTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/utils/JoseUtilsTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingFirstTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasRequestPreProcessingSecondTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasResponseValidatorTest.java
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_mapConfig.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_realConfig.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_basic_test.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/SpringTest-context_tasks_test.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/config/additional-attributes.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/config/eidas-attributes.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_2.properties
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_3.properties
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_4.properties
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_de_attributes.properties
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/data/junit.jks
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/data/szr/signed_eidasBind.jws
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/data/szr/szr_resp_error_travelerdocexists.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/data/szr/szr_resp_valid_1.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/data/szr/szr_resp_valid_2.xml
create mode 100644 modules/authmodule-eIDAS-v2/src/test/resources/keystore/teststore.jks
(limited to 'modules/authmodule-eIDAS-v2')
diff --git a/modules/authmodule-eIDAS-v2/checks/spotbugs-exclude.xml b/modules/authmodule-eIDAS-v2/checks/spotbugs-exclude.xml
new file mode 100644
index 00000000..d961b4d6
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/checks/spotbugs-exclude.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/authmodule-eIDAS-v2/pom.xml b/modules/authmodule-eIDAS-v2/pom.xml
new file mode 100644
index 00000000..f16edb2d
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/pom.xml
@@ -0,0 +1,295 @@
+
+
+ 4.0.0
+
+ at.asitplus.eidas.ms_specific
+ modules
+ 1.2.4-SNAPSHOT
+
+ at.asitplus.eidas.ms_specific.modules
+ authmodule-eIDAS-v2
+ eIDAS v2 authentication module
+ eIDAS module based on eIDAS node reference implementation v2.x
+
+
+
+ default
+
+ true
+
+
+
+ egiz-commons
+ https://apps.egiz.gv.at/maven/
+
+ true
+
+
+
+ eIDASNode-local
+ local
+ file:${basedir}/../../repository
+
+
+
+
+
+
+
+ at.gv.egiz.components
+ egiz-spring-api
+
+
+ at.asitplus.eidas.ms_specific
+ core_common_lib
+
+
+ at.gv.egiz.eaaf
+ eaaf-core
+
+
+
+
+ eu.eidas
+ eidas-commons
+
+
+ log4j
+ log4j
+
+
+ log4j-over-slf4j
+ org.slf4j
+
+
+
+
+
+ eu.eidas
+ eidas-light-commons
+
+
+
+ eu.eidas
+ eidas-specific-communication-definition
+
+
+
+ eu.eidas
+ eidas-jcache-ignite-specific-communication
+
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+ com.google.guava
+ guava
+
+
+ joda-time
+ joda-time
+
+
+ org.apache.commons
+ commons-text
+
+
+ org.springframework
+ spring-webmvc
+
+
+ org.apache.cxf
+ cxf-core
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxws
+
+
+ org.apache.cxf
+ cxf-rt-transports-http
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+
+ org.bitbucket.b_c
+ jose4j
+
+
+
+ javax.servlet
+ javax.servlet-api
+ provided
+
+
+
+
+ junit
+ junit
+ test
+
+
+ org.springframework
+ spring-test
+ test
+
+
+
+ at.asitplus.eidas.ms_specific
+ core_common_lib
+ test
+ test-jar
+
+
+
+ at.gv.egiz.eaaf
+ eaaf_core_utils
+ test
+ test-jar
+
+
+ at.gv.egiz.eaaf
+ eaaf-core
+ test
+ test-jar
+
+
+
+ com.github.skjolber
+ mockito-soap-cxf
+ test
+
+
+
+ org.powermock
+ powermock-module-junit4
+ test
+
+
+ org.powermock
+ powermock-api-mockito2
+ test
+
+
+
+
+
+
+
+ src/main/resources
+
+
+ target/generated-sources/cxf
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.8
+
+
+
+ org.apache.cxf
+ cxf-codegen-plugin
+
+
+ xerces
+ xercesImpl
+ 2.8.1
+
+
+ com.sun.xml.bind
+ jaxb-impl
+ 2.2.5
+
+
+ com.sun.xml.bind
+ jaxb-xjc
+ 2.2.5
+
+
+
+
+ generate-sources
+ generate-sources
+
+ ${project.build.directory}/generated/cxf
+
+
+ ${basedir}/src/main/resources/szr_client/SZR_v4.0.wsdl
+
+ -verbose
+
+
+
+
+
+ wsdl2java
+
+
+
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ ${spotbugs-maven-plugin.version}
+
+ checks/spotbugs-exclude.xml
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+
+
+ post-unit-check
+ test
+
+ check
+ report
+
+
+ true
+
+ **/at/gv/e_government/reference/namespace/persondata/_20020228/*
+ **/org/w3/_2000/_09/*
+ **/org/w3/_2001/_04/*
+ **/szrservices/*
+ **/generated/cxf/*
+
+
+
+
+
+
+
+
+ maven-surefire-plugin
+
+ 1
+
+
+
+ org.apache.maven.surefire
+ surefire-junit47
+ ${surefire.version}
+
+
+
+
+
+
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java
new file mode 100644
index 00000000..a554bf57
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2;
+
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+
+public class Constants {
+
+ public static final String DATA_REQUESTERID = "req_requesterId";
+ public static final String DATA_PROVIDERNAME = "req_providerName";
+ public static final String DATA_REQUESTED_LOA_LIST = "req_requestedLoA";
+ public static final String DATA_REQUESTED_LOA_COMPERISON = "req_requestedLoAComperision";
+ public static final String DATA_FULL_EIDAS_RESPONSE = "resp_fulleIDASResponse";
+
+ // templates for post-binding forwarding
+ public static final String TEMPLATE_POST_FORWARD_NAME = "eidas_node_forward.html";
+ public static final String TEMPLATE_POST_FORWARD_ENDPOINT = "endPoint";
+ public static final String TEMPLATE_POST_FORWARD_TOKEN_NAME = "tokenName";
+ public static final String TEMPLATE_POST_FORWARD_TOKEN_VALUE = "tokenValue";
+
+ // configuration properties
+ public static final String CONIG_PROPS_EIDAS_PREFIX = "auth.eIDAS";
+ public static final String CONIG_PROPS_EIDAS_IS_TEST_IDENTITY = CONIG_PROPS_EIDAS_PREFIX
+ + ".eid.testidentity.default";
+ public static final String CONIG_PROPS_EIDAS_NODE = CONIG_PROPS_EIDAS_PREFIX + ".node_v2";
+ public static final String CONIG_PROPS_EIDAS_NODE_COUNTRYCODE = CONIG_PROPS_EIDAS_NODE + ".countrycode";
+ public static final String CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS = CONIG_PROPS_EIDAS_NODE
+ + ".publicSectorTargets";
+ public static final String CONIG_PROPS_EIDAS_NODE_ENTITYID = CONIG_PROPS_EIDAS_NODE + ".entityId";
+ public static final String CONIG_PROPS_EIDAS_CONNECTOR_NODE_FORWARD_URL = CONIG_PROPS_EIDAS_NODE
+ + ".forward.endpoint";
+
+ public static final String CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD = CONIG_PROPS_EIDAS_NODE
+ + ".forward.method";
+ public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_DEFAULT_ONLYNATURAL =
+ CONIG_PROPS_EIDAS_NODE + ".attributes.requested.onlynatural";
+ public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_CC_SPECIFIC_ONLYNATURAL =
+ CONIG_PROPS_EIDAS_NODE + ".attributes.requested.{0}.onlynatural";
+ public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_REPRESENTATION =
+ CONIG_PROPS_EIDAS_NODE + ".attributes.requested.representation";
+
+ public static final String CONIG_PROPS_EIDAS_NODE_REQUESTERID_USE_HASHED_VERSION =
+ CONIG_PROPS_EIDAS_NODE + ".requesterId.useHashedForm";
+ public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_USE_STATIC_REQUESTERID_FOR_LUX =
+ CONIG_PROPS_EIDAS_NODE + ".requesterId.lu.useStaticRequesterForAll";
+
+ public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME =
+ CONIG_PROPS_EIDAS_NODE + ".workarounds.addAlwaysProviderName";
+ public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_USEREQUESTIDASTRANSACTIONIDENTIFIER =
+ CONIG_PROPS_EIDAS_NODE + ".workarounds.useRequestIdAsTransactionIdentifier";
+
+ public static final String CONFIG_PROP_EIDAS_NODE_NAMEIDFORMAT =
+ CONIG_PROPS_EIDAS_NODE + ".requested.nameIdFormat";
+
+ public static final String CONIG_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP = CONIG_PROPS_EIDAS_NODE
+ + ".staticProviderNameForPublicSPs";
+ public static final String DEFAULT_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP = "Austria";
+
+ public static final String FORWARD_METHOD_POST = "POST";
+ public static final String FORWARD_METHOD_GET = "GET";
+
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT = CONIG_PROPS_EIDAS_PREFIX + ".szrclient";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_USETESTSERVICE = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".useTestService";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_TRACEMESSAGES = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".debug.logfullmessages";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_USEDUMMY = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".debug.useDummySolution";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SET_MDS_TO_EIDASBIND = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".eidasbind.mds.inject";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_CONNECTION = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".timeout.connection";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_RESPONSE = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".timeout.response";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_PROD = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".endpoint.prod";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_TEST = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".endpoint.test";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PATH = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".ssl.keyStore.path";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PASSWORD = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".ssl.keyStore.password";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PATH = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".ssl.trustStore.path";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PASSWORD = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".ssl.trustStore.password";
+
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_EDOCUMENTTYPE = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".params.documenttype";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_VKZ = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".params.vkz";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_ISSUING_DATE = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".params.issuingdate";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_ISSUING_AUTHORITY =
+ CONIG_PROPS_EIDAS_SZRCLIENT + ".params.issuingauthority";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_KEYS_USEDUMMY = CONIG_PROPS_EIDAS_SZRCLIENT
+ + ".params.usedummykeys";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_USESRZFORBPKGENERATION =
+ CONIG_PROPS_EIDAS_SZRCLIENT + ".params.useSZRForbPKCalculation";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_SETPLACEOFBIRTHIFAVAILABLE =
+ CONIG_PROPS_EIDAS_SZRCLIENT + ".params.setPlaceOfBirthIfAvailable";
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_SETBIRTHNAMEIFAVAILABLE =
+ CONIG_PROPS_EIDAS_SZRCLIENT + ".params.setBirthNameIfAvailable";
+
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_WORKAROUND_REVISIONLOGDATASTORE_ACTIVE =
+ CONIG_PROPS_EIDAS_SZRCLIENT + ".revisionlog.eidmapping.active";
+
+ public static final String DEFAULT_MS_NODE_COUNTRY_CODE = "AT";
+
+ @Deprecated
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_WORKAROUND_SQLLITEDATASTORE_URL =
+ CONIG_PROPS_EIDAS_SZRCLIENT + ".workarounds.datastore.sqlite.url";
+ @Deprecated
+ public static final String CONIG_PROPS_EIDAS_SZRCLIENT_WORKAROUND_SQLLITEDATASTORE_ACTIVE =
+ CONIG_PROPS_EIDAS_SZRCLIENT + ".workarounds.datastore.sqlite.active";
+
+ // http endpoint descriptions
+ public static final String eIDAS_HTTP_ENDPOINT_SP_POST = "/eidas/light/sp/post";
+ public static final String eIDAS_HTTP_ENDPOINT_SP_REDIRECT = "/eidas/light/sp/redirect";
+ public static final String eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST = "/eidas/light/ColleagueRequest";
+ public static final String eIDAS_HTTP_ENDPOINT_METADATA = "/eidas/light/metadata";
+
+ // eIDAS request parameters
+ public static final String eIDAS_REQ_NAMEID_FORMAT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent";
+
+ // eIDAS attribute names
+ public static final String eIDAS_ATTR_PERSONALIDENTIFIER = "PersonIdentifier";
+ public static final String eIDAS_ATTR_DATEOFBIRTH = "DateOfBirth";
+ public static final String eIDAS_ATTR_CURRENTGIVENNAME = "FirstName";
+ public static final String eIDAS_ATTR_CURRENTFAMILYNAME = "FamilyName";
+ public static final String eIDAS_ATTR_PLACEOFBIRTH = "PlaceOfBirth";
+ public static final String eIDAS_ATTR_BIRTHNAME = "BirthName";
+ public static final String eIDAS_ATTR_CURRENTADDRESS = "CurrentAddress";
+
+ public static final String eIDAS_ATTR_LEGALPERSONIDENTIFIER = "LegalPersonIdentifier";
+ public static final String eIDAS_ATTR_LEGALNAME = "LegalName";
+
+ public static final String eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER = "RepresentativePersonIdentifier";
+ public static final String eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH = "RepresentativeDateOfBirth";
+ public static final String eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME = "RepresentativeFirstName";
+ public static final String eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME = "RepresentativeFamilyName";
+
+
+ public static final String eIDAS_REQ_PARAM_SECTOR_PUBLIC = "public";
+ public static final String eIDAS_REQ_PARAM_SECTOR_PRIVATE = "private";
+
+ public static final String POLICY_DEFAULT_ALLOWED_TARGETS =
+ EaafConstants.URN_PREFIX_CDID.replaceAll("\\.", "\\\\.").replaceAll("\\+", "\\\\+") + ".*";
+
+ // SAML2 Constants
+ public static final String SUCCESS_URI = "urn:oasis:names:tc:SAML:2.0:status:Success";
+ public static final String ERROR_URI = "urn:oasis:names:tc:SAML:2.0:status:Responder";
+
+ public static final String HTTP_CLIENT_DEFAULT_TIMEOUT_CONNECTION = "30"; // seconds
+ public static final String HTTP_CLIENT_DEFAULT_TIMEOUT_RESPONSE = "60"; // seconds
+
+ public static final String SZR_SCHEMA_LOCATIONS =
+ "urn:SZRServices" + " " + "/szr_client/szr.xsd";
+
+ // Default values for SZR communication
+ public static final String SZR_CONSTANTS_DEFAULT_DOCUMENT_TYPE = "ELEKTR_DOKUMENT";
+
+ // TODO remove!!!
+ public static final String SZR_CONSTANTS_DEFAULT_ISSUING_DATE = "2014-01-01";
+ public static final String SZR_CONSTANTS_DEFAULT_ISSUING_AUTHORITY = "ms-specific eIDAS-Node for AT";
+ public static final String SZR_CONSTANTS_DEFAULT_PUBKEY_EXPONENT = "AQAB";
+ public static final String SZR_CONSTANTS_DEFAULT_PUBKEY_MODULUS =
+ "AJZyj/+sdCMDRq9RkvbFcgSTVn/OfS8EUE81ddwP8MNuJ1kd1SWBUJPaQX2JLJHrL54mkOhrkhH2M/zcuOTu8nW9TOEg"
+ + "XGjrRB/0HpiYKpV+VDJViyyc/GacNLxN4Anw4pima6gHYaJIw9hQkL/nuO2hyh8PGJd7rxeFXJmbLy+X";
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasAuthenticationModulImpl.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasAuthenticationModulImpl.java
new file mode 100644
index 00000000..85f0873e
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasAuthenticationModulImpl.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+
+/**
+ * eIDAS authentication-process selector.
+ *
+ * @author tlenz
+ *
+ */
+public class EidasAuthenticationModulImpl implements AuthModule {
+
+ private int priority = 1;
+
+ @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;
+ }
+
+ /*
+ * (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) {
+ Serializable flagObj = context.get(MsEidasNodeConstants.REQ_PARAM_SELECTED_COUNTRY);
+ if (flagObj != null && flagObj instanceof String
+ && StringUtils.isNotBlank((String) context.get(MsEidasNodeConstants.REQ_PARAM_SELECTED_COUNTRY))) {
+ return "eIDASAuthentication_v2";
+ } else {
+ return null;
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions()
+ */
+ @Override
+ public String[] getProcessDefinitions() {
+ return new String[] { "classpath:eIDAS.Authentication.process.xml" };
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasAuthenticationSpringResourceProvider.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasAuthenticationSpringResourceProvider.java
new file mode 100644
index 00000000..535e4f97
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasAuthenticationSpringResourceProvider.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.components.spring.api.SpringResourceProvider;
+
+public class EidasAuthenticationSpringResourceProvider implements SpringResourceProvider {
+
+ @Override
+ public String getName() {
+ return "Auth. module for eIDAS Ref. Impl. v2.x";
+ }
+
+ @Override
+ public String[] getPackagesToScan() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Resource[] getResourcesToLoad() {
+ final ClassPathResource eidasAuthConfig = new ClassPathResource("/eidas_v2_auth.beans.xml",
+ EidasAuthenticationSpringResourceProvider.class);
+
+ return new Resource[] { eidasAuthConfig };
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasSignalServlet.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasSignalServlet.java
new file mode 100644
index 00000000..d3cac80c
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/EidasSignalServlet.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import com.google.common.collect.ImmutableSortedSet;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractProcessEngineSignalController;
+import eu.eidas.auth.commons.EidasParameterKeys;
+import eu.eidas.auth.commons.light.ILightResponse;
+import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames;
+import eu.eidas.specificcommunication.exception.SpecificCommunicationException;
+import eu.eidas.specificcommunication.protocol.SpecificCommunicationService;
+
+/**
+ * Controler implementation for eIDAS Node communication.
+ *
+ * @author tlenz
+ *
+ */
+@Controller
+public class EidasSignalServlet extends AbstractProcessEngineSignalController {
+
+ private static final Logger log = LoggerFactory.getLogger(EidasSignalServlet.class);
+ @Autowired
+ private ApplicationContext context;
+ @Autowired
+ private EidasAttributeRegistry attrRegistry;
+
+ /**
+ * eIDAS Node communication end-point implementation.
+ *
+ */
+ public EidasSignalServlet() {
+ super();
+ log.debug("Registering servlet {} with mappings '{}' and '{}'.",
+ getClass().getName(), Constants.eIDAS_HTTP_ENDPOINT_SP_POST,
+ Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT);
+
+ }
+
+ @RequestMapping(value = {
+ Constants.eIDAS_HTTP_ENDPOINT_SP_POST,
+ Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT
+ },
+ method = { RequestMethod.POST, RequestMethod.GET })
+ public void restoreEidasAuthProcess(HttpServletRequest req, HttpServletResponse resp) throws IOException,
+ EaafException {
+ signalProcessManagement(req, resp);
+ }
+
+ /**
+ * Protocol specific implementation to get the pending-requestID from http
+ * request object.
+ *
+ * @param request The http Servlet-Request object
+ * @return The Pending-request id
+ *
+ */
+ @Override
+ public String getPendingRequestId(HttpServletRequest request) {
+ // String sessionId = super.getPendingRequestId(request);
+
+ try {
+ // get token from Request
+ final String tokenBase64 = request.getParameter(EidasParameterKeys.TOKEN.toString());
+ if (StringUtils.isEmpty(tokenBase64)) {
+ log.warn("NO eIDAS message token found.");
+ throw new EidasSAuthenticationException("eidas.04", null);
+
+ }
+ log.trace("Receive eIDAS-node token: " + tokenBase64 + " Starting transaction-restore process ... ");
+
+ final SpecificCommunicationService specificConnectorCommunicationService =
+ (SpecificCommunicationService) context.getBean(
+ SpecificCommunicationDefinitionBeanNames.SPECIFIC_CONNECTOR_COMMUNICATION_SERVICE.toString());
+ final ILightResponse eidasResponse = specificConnectorCommunicationService.getAndRemoveResponse(
+ tokenBase64,
+ ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes()));
+
+ String pendingReqId = null;
+ if (StringUtils.isEmpty(eidasResponse.getRelayState())) {
+ log.debug("eIDAS Node returns no RelayState. ");
+
+ if (authConfig.getBasicConfigurationBoolean(
+ Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_USEREQUESTIDASTRANSACTIONIDENTIFIER,
+ false)) {
+ log.trace("Use lightRequestId to recover session ... ");
+ pendingReqId = transactionStorage.get(eidasResponse.getInResponseToId(), String.class);
+ if (StringUtils.isNotEmpty(pendingReqId)) {
+ log.debug("Restoring session with lightRequestId ... ");
+ transactionStorage.remove(eidasResponse.getInResponseToId());
+
+ }
+ }
+
+ } else {
+ log.debug("Find transaction identifier in SAML2 'RelayState': " + eidasResponse.getRelayState());
+ pendingReqId = eidasResponse.getRelayState();
+
+ }
+
+ if (StringUtils.isNotEmpty(pendingReqId)) {
+ request.setAttribute(Constants.DATA_FULL_EIDAS_RESPONSE, eidasResponse);
+ return pendingReqId;
+
+ }
+
+ log.info("NO transaction identifier found! Stopping process ....");
+ log.trace("FullResponse: " + eidasResponse.toString());
+
+ } catch (final SpecificCommunicationException e) {
+ log.warn("Can NOT load eIDAS Response from cache.", e);
+ log.debug("eIDAS response token was: " + request.getParameter(EidasParameterKeys.TOKEN.toString()));
+
+ } catch (final Exception e) {
+ log.warn("Unable to retrieve moa session id.", e);
+
+ }
+
+ return null;
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/ErnbEidData.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/ErnbEidData.java
new file mode 100644
index 00000000..6c7eeb6b
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/ErnbEidData.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao;
+
+import java.text.SimpleDateFormat;
+
+import org.joda.time.DateTime;
+
+import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType;
+
+public class ErnbEidData {
+
+ private String citizenCountryCode = null;
+
+ // MDS
+ private String pseudonym = null;
+ private String givenName = null;
+ private String familyName = null;
+ private DateTime dateOfBirth = null;
+
+ // additional attributes
+ private String placeOfBirth = null;
+ private String birthName = null;
+ private PostalAddressType address = null;
+
+ public String getCitizenCountryCode() {
+ return citizenCountryCode;
+ }
+
+ public void setCitizenCountryCode(String citizenCountryCode) {
+ this.citizenCountryCode = citizenCountryCode;
+ }
+
+ public String getPseudonym() {
+ return pseudonym;
+ }
+
+ public void setPseudonym(String pseudonym) {
+ this.pseudonym = pseudonym;
+ }
+
+ public String getGivenName() {
+ return givenName;
+ }
+
+ public void setGivenName(String givenName) {
+ this.givenName = givenName;
+ }
+
+ public String getFamilyName() {
+ return familyName;
+ }
+
+ public void setFamilyName(String familyName) {
+ this.familyName = familyName;
+ }
+
+ public DateTime getDateOfBirth() {
+ return dateOfBirth;
+ }
+
+ public void setDateOfBirth(DateTime dateOfBirth) {
+ this.dateOfBirth = dateOfBirth;
+ }
+
+ public String getPlaceOfBirth() {
+ return placeOfBirth;
+ }
+
+ public void setPlaceOfBirth(String placeOfBirth) {
+ this.placeOfBirth = placeOfBirth;
+ }
+
+ public String getBirthName() {
+ return birthName;
+ }
+
+ public void setBirthName(String birthName) {
+ this.birthName = birthName;
+ }
+
+ public PostalAddressType getAddress() {
+ return address;
+ }
+
+ public void setAddress(PostalAddressType address) {
+ this.address = address;
+ }
+
+ public String getFormatedDateOfBirth() {
+ return new SimpleDateFormat("yyyy-MM-dd").format(dateOfBirth.toDate());
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidPostProcessingException.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidPostProcessingException.java
new file mode 100644
index 00000000..f4c0be67
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidPostProcessingException.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.exception;
+
+public class EidPostProcessingException extends EidasSAuthenticationException {
+
+ private static final long serialVersionUID = 6780652273831172456L;
+
+ public EidPostProcessingException(String internalMsgId, Object[] params) {
+ super(internalMsgId, params);
+
+ }
+
+ public EidPostProcessingException(String internalMsgId, Object[] params, Throwable e) {
+ super(internalMsgId, params, e);
+
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasAttributeException.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasAttributeException.java
new file mode 100644
index 00000000..49736d58
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasAttributeException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.exception;
+
+public class EidasAttributeException extends EidasSAuthenticationException {
+ private static final long serialVersionUID = 1L;
+
+ public EidasAttributeException(String attrbuteName) {
+ super("eidas.00", new Object[] { attrbuteName });
+
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasSAuthenticationException.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasSAuthenticationException.java
new file mode 100644
index 00000000..8ff218e3
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasSAuthenticationException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.exception;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
+
+public class EidasSAuthenticationException extends EaafAuthenticationException {
+
+
+ private static final long serialVersionUID = 1L;
+
+ public EidasSAuthenticationException(String internalMsgId, Object[] params) {
+ super(internalMsgId, params);
+ }
+
+ public EidasSAuthenticationException(String internalMsgId, Object[] params, Throwable e) {
+ super(internalMsgId, params, e);
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasValidationException.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasValidationException.java
new file mode 100644
index 00000000..2988dd6f
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/EidasValidationException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.exception;
+
+public class EidasValidationException extends EidasSAuthenticationException {
+
+ private static final long serialVersionUID = 1L;
+
+ public EidasValidationException(String internalMsgId, Object[] params) {
+ super(internalMsgId, params);
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/SqliteServiceException.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/SqliteServiceException.java
new file mode 100644
index 00000000..d48abec9
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/SqliteServiceException.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.exception;
+
+public class SqliteServiceException extends EidasSAuthenticationException {
+
+ private static final long serialVersionUID = 2278259367925102676L;
+
+ public SqliteServiceException(String internalMsgId, Object[] params, Throwable e) {
+ super(internalMsgId, params, e);
+
+ }
+
+ public SqliteServiceException(String internalMsgId, Object[] params) {
+ super(internalMsgId, params);
+
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/SzrCommunicationException.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/SzrCommunicationException.java
new file mode 100644
index 00000000..c736cadb
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/SzrCommunicationException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.exception;
+
+public class SzrCommunicationException extends EidasSAuthenticationException {
+
+ private static final long serialVersionUID = 1L;
+
+ public SzrCommunicationException(String internalMsgId, Object[] params) {
+ super(internalMsgId, params);
+ }
+
+ public SzrCommunicationException(String internalMsgId, Object[] params, Throwable e) {
+ super(internalMsgId, params, e);
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java
new file mode 100644
index 00000000..4a3218e9
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java
@@ -0,0 +1,425 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.lang.NonNull;
+
+import com.google.common.collect.ImmutableSortedSet;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils;
+import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.impl.data.Triple;
+import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.light.impl.LightRequest.Builder;
+import eu.eidas.auth.commons.protocol.eidas.SpType;
+import eu.eidas.auth.commons.protocol.eidas.impl.PostalAddress;
+
+public abstract class AbstractEidProcessor implements INationalEidProcessor {
+ private static final Logger log = LoggerFactory.getLogger(AbstractEidProcessor.class);
+
+ @Autowired
+ protected EidasAttributeRegistry attrRegistry;
+ @Autowired
+ protected IConfigurationWithSP basicConfig;
+
+ @Override
+ public final void preProcess(IRequest pendingReq, Builder authnRequestBuilder) {
+
+ buildLevelOfAssurance(pendingReq.getServiceProviderConfiguration(), authnRequestBuilder);
+ buildProviderNameAndRequesterIdAttribute(pendingReq, authnRequestBuilder);
+ buildRequestedAttributes(authnRequestBuilder);
+
+ }
+
+
+ @Override
+ public final ErnbEidData postProcess(Map eidasAttrMap) throws EidPostProcessingException,
+ EidasAttributeException {
+ final ErnbEidData result = new ErnbEidData();
+
+ final Object eIdentifierObj = eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ final Triple eIdentifier =
+ EidasResponseUtils.parseEidasPersonalIdentifier((String) eIdentifierObj);
+ result.setCitizenCountryCode(eIdentifier.getFirst());
+
+ // MDS attributes
+ result.setPseudonym(processPseudonym(eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)));
+ result.setFamilyName(processFamilyName(eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTFAMILYNAME)));
+ result.setGivenName(processGivenName(eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTGIVENNAME)));
+ result.setDateOfBirth(processDateOfBirth(eidasAttrMap.get(Constants.eIDAS_ATTR_DATEOFBIRTH)));
+
+ // additional attributes
+ result.setPlaceOfBirth(processPlaceOfBirth(eidasAttrMap.get(Constants.eIDAS_ATTR_PLACEOFBIRTH)));
+ result.setBirthName(processBirthName(eidasAttrMap.get(Constants.eIDAS_ATTR_BIRTHNAME)));
+ result.setAddress(processAddress(eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTADDRESS)));
+
+ return result;
+
+ }
+
+
+ /**
+ * Get a Map of country-specific requested attributes.
+ *
+ * @return
+ */
+ @NonNull
+ protected abstract Map getCountrySpecificRequestedAttributes();
+
+ /**
+ * Post-Process the eIDAS CurrentAddress attribute.
+ *
+ * @param currentAddressObj eIDAS current address information
+ * @return current address or null if no attribute is available
+ * @throws EidPostProcessingException if post-processing fails
+ * @throws EidasAttributeException if eIDAS attribute is of a wrong type
+ */
+ protected PostalAddressType processAddress(Object currentAddressObj) throws EidPostProcessingException,
+ EidasAttributeException {
+
+ if (currentAddressObj != null) {
+ if (currentAddressObj instanceof PostalAddress) {
+ final PostalAddressType result = new PostalAddressType();
+ result.setPostalCode(((PostalAddress) currentAddressObj).getPostCode());
+ result.setMunicipality(((PostalAddress) currentAddressObj).getPostName());
+
+ // TODO: add more mappings
+
+ return result;
+
+ } else {
+ log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_CURRENTADDRESS + " is of WRONG type");
+ throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTADDRESS);
+
+ }
+
+ } else {
+ log.debug("NO '" + Constants.eIDAS_ATTR_CURRENTADDRESS + "' attribute. Post-Processing skipped ... ");
+ }
+
+ return null;
+
+ }
+
+ /**
+ * Post-Process the eIDAS BirthName attribute.
+ *
+ * @param birthNameObj eIDAS birthname information
+ * @return birthName or null if no attribute is available
+ * @throws EidPostProcessingException if post-processing fails
+ * @throws EidasAttributeException if eIDAS attribute is of a wrong type
+ */
+ protected String processBirthName(Object birthNameObj) throws EidPostProcessingException,
+ EidasAttributeException {
+ if (birthNameObj != null) {
+ if (birthNameObj instanceof String) {
+ return (String) birthNameObj;
+
+ } else {
+ log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_BIRTHNAME + " is of WRONG type");
+ throw new EidasAttributeException(Constants.eIDAS_ATTR_BIRTHNAME);
+
+ }
+
+ } else {
+ log.debug("NO '" + Constants.eIDAS_ATTR_BIRTHNAME + "' attribute. Post-Processing skipped ... ");
+ }
+
+ return null;
+
+ }
+
+ /**
+ * Post-Process the eIDAS PlaceOfBirth attribute.
+ *
+ * @param placeOfBirthObj eIDAS Place-of-Birth information
+ * @return place of Birth or null if no attribute is available
+ * @throws EidPostProcessingException if post-processing fails
+ * @throws EidasAttributeException if eIDAS attribute is of a wrong type
+ */
+ protected String processPlaceOfBirth(Object placeOfBirthObj) throws EidPostProcessingException,
+ EidasAttributeException {
+ if (placeOfBirthObj != null) {
+ if (placeOfBirthObj instanceof String) {
+ return (String) placeOfBirthObj;
+
+ } else {
+ log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_PLACEOFBIRTH + " is of WRONG type");
+ throw new EidasAttributeException(Constants.eIDAS_ATTR_PLACEOFBIRTH);
+
+ }
+
+ } else {
+ log.debug("NO '" + Constants.eIDAS_ATTR_PLACEOFBIRTH + "' attribute. Post-Processing skipped ... ");
+ }
+
+ return null;
+
+ }
+
+ /**
+ * Post-Process the eIDAS DateOfBirth attribute.
+ *
+ * @param dateOfBirthObj eIDAS date-of-birth attribute information
+ * @return formated user's date-of-birth
+ * @throws EidasAttributeException if NO attribute is available
+ * @throws EidPostProcessingException if post-processing fails
+ */
+ protected DateTime processDateOfBirth(Object dateOfBirthObj) throws EidPostProcessingException,
+ EidasAttributeException {
+ if (dateOfBirthObj == null || !(dateOfBirthObj instanceof DateTime)) {
+ throw new EidasAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH);
+ }
+
+ return (DateTime) dateOfBirthObj;
+
+ }
+
+ /**
+ * Post-Process the eIDAS GivenName attribute.
+ *
+ * @param givenNameObj eIDAS givenName attribute information
+ * @return formated user's givenname
+ * @throws EidasAttributeException if NO attribute is available
+ * @throws EidPostProcessingException if post-processing fails
+ */
+ protected String processGivenName(Object givenNameObj) throws EidPostProcessingException,
+ EidasAttributeException {
+ if (givenNameObj == null || !(givenNameObj instanceof String)) {
+ throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME);
+ }
+
+ return (String) givenNameObj;
+
+ }
+
+ /**
+ * Post-Process the eIDAS FamilyName attribute.
+ *
+ * @param familyNameObj eIDAS familyName attribute information
+ * @return formated user's familyname
+ * @throws EidasAttributeException if NO attribute is available
+ * @throws EidPostProcessingException if post-processing fails
+ */
+ protected String processFamilyName(Object familyNameObj) throws EidPostProcessingException,
+ EidasAttributeException {
+ if (familyNameObj == null || !(familyNameObj instanceof String)) {
+ throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME);
+ }
+
+ return (String) familyNameObj;
+
+ }
+
+ /**
+ * Post-Process the eIDAS pseudonym to ERnB unique identifier.
+ *
+ * @param personalIdObj eIDAS PersonalIdentifierAttribute
+ * @return Unique personal identifier without country-code information
+ * @throws EidasAttributeException if NO attribute is available
+ * @throws EidPostProcessingException if post-processing fails
+ */
+ protected String processPseudonym(Object personalIdObj) throws EidPostProcessingException,
+ EidasAttributeException {
+ if (personalIdObj == null || !(personalIdObj instanceof String)) {
+ throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ }
+
+ final Triple eIdentifier =
+ EidasResponseUtils.parseEidasPersonalIdentifier((String) personalIdObj);
+
+ return eIdentifier.getThird();
+
+ }
+
+ /**
+ * Set ProviderName and RequestId into eIDAS AuthnRequest.
+ *
+ * @param pendingReq Current pendingRequest
+ * @param authnRequestBuilder AuthnRequest builder
+ */
+ protected void buildProviderNameAndRequesterIdAttribute(IRequest pendingReq, Builder authnRequestBuilder) {
+ final ISpConfiguration spConfig = pendingReq.getServiceProviderConfiguration();
+
+ // set correct SPType for requested target sector
+ final String publicSectorTargetSelector = basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS,
+ Constants.POLICY_DEFAULT_ALLOWED_TARGETS);
+ final Pattern p = Pattern.compile(publicSectorTargetSelector);
+ final Matcher m = p.matcher(spConfig.getAreaSpecificTargetIdentifier());
+ if (m.matches()) {
+ log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PublicSector'");
+ authnRequestBuilder.spType(SpType.PUBLIC.getValue());
+
+ final String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class);
+ if (basicConfig.getBasicConfigurationBoolean(
+ Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME,
+ false)) {
+ //TODO: only for eIDAS ref. node 2.0 and 2.1 because it need 'Providername' for
+ if (StringUtils.isNotEmpty(providerName)) {
+ log.debug("Set 'providername' to: {}", providerName);
+ authnRequestBuilder.providerName(providerName);
+
+ } else {
+ authnRequestBuilder.providerName(basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP,
+ Constants.DEFAULT_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP));
+
+ }
+ }
+
+ } else {
+ log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PrivateSector'");
+ authnRequestBuilder.spType(SpType.PRIVATE.getValue());
+
+ // TODO: switch to RequesterId in further version
+ // set provider name for private sector applications
+ final String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class);
+ if (StringUtils.isNotEmpty(providerName)) {
+ authnRequestBuilder.providerName(providerName);
+
+ }
+
+ authnRequestBuilder.requesterId(
+ generateRequesterId(pendingReq.getRawData(Constants.DATA_REQUESTERID, String.class)));
+
+ }
+ }
+
+ /**
+ * Build LoA based on Service-Provider configuration.
+ *
+ * @param spConfig Current SP configuration
+ * @param authnRequestBuilder AuthnRequest builder
+ */
+ protected void buildLevelOfAssurance(ISpConfiguration spConfig, Builder authnRequestBuilder) {
+ // TODO: set matching mode if eIDAS ref. impl. support this method
+
+ // TODO: update if eIDAS ref. impl. supports exact matching for non-notified LoA
+ // schemes
+ String loa = EaafConstants.EIDAS_LOA_HIGH;
+ if (spConfig.getRequiredLoA() != null) {
+ if (spConfig.getRequiredLoA().isEmpty()) {
+ log.info("No eIDAS LoA requested. Use LoA HIGH as default");
+ } else {
+ if (spConfig.getRequiredLoA().size() > 1) {
+ log.info(
+ "Currently only ONE requested LoA is supported for service provider. Use first one ... ");
+ }
+
+ loa = spConfig.getRequiredLoA().get(0);
+
+ }
+ }
+
+ log.debug("Request eIdAS node with LoA: " + loa);
+ authnRequestBuilder.levelsOfAssuranceValues(Arrays.asList(loa));
+
+ }
+
+ private String generateRequesterId(String requesterId) {
+ if (requesterId != null && basicConfig.getBasicConfigurationBoolean(
+ Constants.CONIG_PROPS_EIDAS_NODE_REQUESTERID_USE_HASHED_VERSION, true)) {
+ try {
+ log.trace("Building hashed 'requesterId' for private SP ... ");
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ String encodedRequesterId = Base64.getEncoder().encodeToString(
+ digest.digest(requesterId.getBytes(StandardCharsets.UTF_8)));
+ log.debug("Set 'requesterId' for: {} to: {}", requesterId, encodedRequesterId);
+ return encodedRequesterId;
+
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Can NOT generate hashed 'requesterId' from: {}. Use it as it is", requesterId, e);
+
+ }
+
+ }
+
+ return requesterId;
+
+ }
+
+
+ private void buildRequestedAttributes(Builder authnRequestBuilder) {
+ // build and add requested attribute set
+ final Map ccSpecificReqAttr = getCountrySpecificRequestedAttributes();
+ log.debug("Get #{} country-specific requested attributes", ccSpecificReqAttr.size());
+
+ final Map mdsReqAttr = attrRegistry.getDefaultAttributeSetFromConfiguration();
+ log.trace("Get #{} default requested attributes", mdsReqAttr.size());
+
+ // put it together
+ ccSpecificReqAttr.putAll(mdsReqAttr);
+
+ // convert it to eIDAS attributes
+ final ImmutableAttributeMap reqAttrMap = translateToEidasAttributes(ccSpecificReqAttr);
+ authnRequestBuilder.requestedAttributes(reqAttrMap);
+
+ }
+
+ private ImmutableAttributeMap translateToEidasAttributes(final Map requiredAttributes) {
+ final ImmutableAttributeMap.Builder builder = ImmutableAttributeMap.builder();
+ for (final Map.Entry attribute : requiredAttributes.entrySet()) {
+ final String name = attribute.getKey();
+ final ImmutableSortedSet> byFriendlyName = attrRegistry
+ .getCoreAttributeRegistry().getByFriendlyName(name);
+ if (!byFriendlyName.isEmpty()) {
+ final AttributeDefinition> attributeDefinition = byFriendlyName.first();
+ builder.put(AttributeDefinition.builder(attributeDefinition).required(attribute.getValue()).build());
+
+ } else {
+ log.warn("Can NOT request UNKNOWN attribute: " + attribute.getKey() + " Ignore it!");
+ }
+
+ }
+
+ return builder.build();
+
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeEidProcessor.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeEidProcessor.java
new file mode 100644
index 00000000..6dc08181
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/DeEidProcessor.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Base64;
+import java.util.Map;
+
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils;
+import at.gv.egiz.eaaf.core.impl.data.Triple;
+
+
+public class DeEidProcessor extends AbstractEidProcessor {
+ private static final Logger log = LoggerFactory.getLogger(DeEidProcessor.class);
+ private static final String canHandleCC = "DE";
+
+ private int priority = 1;
+
+ @Override
+ public int getPriority() {
+ return priority;
+ }
+
+ @Override
+ public boolean canHandle(String countryCode) {
+ return countryCode != null && countryCode.equalsIgnoreCase(canHandleCC);
+
+ }
+
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+ @Override
+ public String getName() {
+ return "DE-PostProcessor";
+
+ }
+
+ @Override
+ protected String processPseudonym(Object uniqeIdentifierObj) throws EidPostProcessingException,
+ EidasAttributeException {
+ if (uniqeIdentifierObj == null || !(uniqeIdentifierObj instanceof String)) {
+ throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ }
+
+ final Triple eIdentifier =
+ EidasResponseUtils.parseEidasPersonalIdentifier((String) uniqeIdentifierObj);
+
+ log.trace(getName() + " starts processing of attribute: " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ final String result = convertDeIdentifier(eIdentifier.getThird());
+ log.debug(getName() + " finished processing of attribute: " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+
+ return result;
+
+ }
+
+ private String convertDeIdentifier(String hexEncodedDeIdentifier) throws EidPostProcessingException {
+ if (hexEncodedDeIdentifier.length() != 64) {
+ throw new EidPostProcessingException("ernb.03", new Object[] {
+ "Input has wrong length, expected 64 chars" });
+ }
+
+ byte[] data;
+ try {
+ data = Hex.decodeHex(hexEncodedDeIdentifier);
+ final byte[] encoded = Base64.getEncoder().encode(data);
+ return new String(encoded, "UTF-8");
+
+ } catch (final DecoderException | UnsupportedEncodingException e) {
+ throw new EidPostProcessingException("ernb.03", null, e);
+
+ }
+
+
+ }
+
+ @Override
+ protected Map getCountrySpecificRequestedAttributes() {
+ return attrRegistry.getAttributeSetFromConfiguration(canHandleCC);
+
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/GenericEidProcessor.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/GenericEidProcessor.java
new file mode 100644
index 00000000..69949435
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/GenericEidProcessor.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class GenericEidProcessor extends AbstractEidProcessor {
+
+ private int priority = 0;
+
+ @Override
+ public int getPriority() {
+ return priority;
+
+ }
+
+ @Override
+ public boolean canHandle(String countryCode) {
+ return true;
+
+ }
+
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+ @Override
+ public String getName() {
+ return "Default-PostProcessor";
+
+ }
+
+ @Override
+ protected Map getCountrySpecificRequestedAttributes() {
+ return new HashMap<>();
+
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/INationalEidProcessor.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/INationalEidProcessor.java
new file mode 100644
index 00000000..577efbcd
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/INationalEidProcessor.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler;
+
+import java.util.Map;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import eu.eidas.auth.commons.light.ILightRequest;
+import eu.eidas.auth.commons.light.impl.LightRequest.Builder;
+
+public interface INationalEidProcessor {
+
+ /**
+ * Get a friendlyName of this post-processor implementation.
+ *
+ * @return
+ */
+ String getName();
+
+ /**
+ * Get the priority of this eID Post-Processor
+ * If more than one Post-Processor implementations can handle the eID data, the
+ * post-processor with the highest priority are selected. The Default-Processor
+ * has priority '0'
+ *
+ * @return Priority of this handler
+ */
+ int getPriority();
+
+ /**
+ * Check if this postProcessor is sensitive for a specific country.
+ *
+ * @param countryCode of the eID data that should be processed
+ * @return true if this implementation can handle the country, otherwise false
+ *
+ */
+ boolean canHandle(String countryCode);
+
+ /**
+ * Post-Process eIDAS eID data into national format.
+ *
+ * @param eidasAttrMap Map of eIDAS attributes in format friendlyName and
+ * attribute
+ * @throws EidPostProcessingException In case of a post-processing error
+ * @throws EidasAttributeException In case of an invalid eIDAS attribute
+ */
+ ErnbEidData postProcess(Map eidasAttrMap) throws EidPostProcessingException,
+ EidasAttributeException;
+
+ /**
+ * Pre-Process eIDAS Request to national requirements.
+ *
+ * @param pendingReq current pending request
+ * @param authnRequestBuilder eIDAS {@link ILightRequest} builder
+ */
+ void preProcess(IRequest pendingReq, Builder authnRequestBuilder);
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/LuEidProcessor.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/LuEidProcessor.java
new file mode 100644
index 00000000..8402457f
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/LuEidProcessor.java
@@ -0,0 +1,61 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import eu.eidas.auth.commons.light.impl.LightRequest.Builder;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class LuEidProcessor extends AbstractEidProcessor {
+
+
+
+ private static final String canHandleCC = "LU";
+
+ @Getter
+ @Setter
+ private int priority = 1;
+
+ @Override
+ public String getName() {
+ return "LU-PostProcessor";
+
+ }
+
+ @Override
+ public boolean canHandle(String countryCode) {
+ return countryCode != null && countryCode.equalsIgnoreCase(canHandleCC);
+
+ }
+
+ @Override
+ protected void buildProviderNameAndRequesterIdAttribute(IRequest pendingReq, Builder authnRequestBuilder) {
+ super.buildProviderNameAndRequesterIdAttribute(pendingReq, authnRequestBuilder);
+ if (basicConfig.getBasicConfigurationBoolean(
+ Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_USE_STATIC_REQUESTERID_FOR_LUX, true)) {
+ String staticName = basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP,
+ Constants.DEFAULT_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP);
+ authnRequestBuilder.providerName(staticName);
+ authnRequestBuilder.requesterId(staticName);
+ log.debug("Use static name: {} as 'providerName' and 'RequesterId' for all 'LU' requests ", staticName);
+
+ } else {
+ log.info("Static 'providerName' and 'RequesterId' for country: LU is deactivated");
+
+ }
+
+ }
+
+ @Override
+ protected Map getCountrySpecificRequestedAttributes() {
+ return new HashMap<>();
+
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/NlEidProcessor.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/NlEidProcessor.java
new file mode 100644
index 00000000..2dd22927
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/NlEidProcessor.java
@@ -0,0 +1,54 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import eu.eidas.auth.commons.light.impl.LightRequest.Builder;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class NlEidProcessor extends AbstractEidProcessor {
+
+
+
+ private static final String canHandleCC = "NL";
+
+ @Getter
+ @Setter
+ private int priority = 1;
+
+ @Override
+ public String getName() {
+ return "NL-PostProcessor";
+
+ }
+
+ @Override
+ public boolean canHandle(String countryCode) {
+ return countryCode != null && countryCode.equalsIgnoreCase(canHandleCC);
+
+ }
+
+ protected void buildLevelOfAssurance(ISpConfiguration spConfig, Builder authnRequestBuilder) {
+ super.buildLevelOfAssurance(spConfig, authnRequestBuilder);
+
+ //check requested level
+ if (authnRequestBuilder.build().getLevelOfAssurance().equals(EaafConstants.EIDAS_LOA_LOW)) {
+ log.debug("Upgrade LoA to {}, because NL needs it as minimum.", EaafConstants.EIDAS_LOA_SUBSTANTIAL);
+ authnRequestBuilder.levelsOfAssuranceValues(Arrays.asList(EaafConstants.EIDAS_LOA_SUBSTANTIAL));
+
+ }
+ }
+
+ @Override
+ protected Map getCountrySpecificRequestedAttributes() {
+ return new HashMap<>();
+
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/AuthBlockSigningService.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/AuthBlockSigningService.java
new file mode 100644
index 00000000..098e76ce
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/AuthBlockSigningService.java
@@ -0,0 +1,211 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.service;
+
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.Provider;
+import java.security.cert.X509Certificate;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.temporal.ChronoUnit;
+import java.util.Base64;
+import java.util.UUID;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.lang3.StringUtils;
+import org.jose4j.lang.JoseException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+
+import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.JoseUtils;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exception.EaafKeyAccessException;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory;
+import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreUtils;
+import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Service to build and sign AuthBlock's for E-ID system.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+@Service("authBlockSigningService")
+public class AuthBlockSigningService {
+
+ private static final String KEYSTORE_FRIENDLYNAME = "AuthBlock_Signing";
+
+ private static ObjectMapper mapper = new ObjectMapper();
+
+ @Autowired
+ IConfiguration basicConfig;
+
+ @Autowired
+ EaafKeyStoreFactory keyStoreFactory;
+
+
+ private Pair keyStore;
+
+ /**
+ * Build and sign an AuthBlock for E-ID system.
+ *
+ * @param pendingReq data that should be added into AuthBlock
+ * @return serialized JWS
+ * @throws JsonProcessingException In case of a AuthBlock generation error
+ * @throws JoseException In case of a JWS signing error
+ * @throws EaafException In case of a KeyStore or Key error
+ */
+ public String buildSignedAuthBlock(IRequest pendingReq)
+ throws JsonProcessingException, EaafException, JoseException {
+
+ //TODO: set Challenge to SAML2 requestId to create link between authentication request and authBlock
+
+ // build AuthBlock
+ EidasAuchBlock authBlock = new EidasAuchBlock();
+ authBlock.setChallenge(UUID.randomUUID().toString());
+ authBlock.setTimestamp(LocalDateTime.now(ZoneOffset.UTC).truncatedTo(ChronoUnit.SECONDS));
+ authBlock.setUniqueId(pendingReq.getRawData(MsEidasNodeConstants.DATA_REQUESTERID, String.class));
+ authBlock.setPiiTransactionId(pendingReq.getUniquePiiTransactionIdentifier());
+
+ //set Binding PublicKey if available
+ Object bindingPubKey = pendingReq.getRawData(MsEidasNodeConstants.EID_BINDING_PUBLIC_KEY_NAME);
+ if (bindingPubKey instanceof String) {
+ authBlock.setBindingPublicKey((String) bindingPubKey);
+
+ }
+
+ String jwsPayload = mapper.writeValueAsString(authBlock);
+ log.debug("Building and sign authBlock with data: {}", jwsPayload);
+
+ //sign JWS
+ return JoseUtils
+ .createSignature(keyStore, getKeyAlias(), getKeyPassword(), jwsPayload, false,
+ KEYSTORE_FRIENDLYNAME);
+ }
+
+
+ /**
+ * Get the Base64 encoded PublicKey that is used to sign the AuthBlock.
+ *
+ * @return Base64 encoded PublicKey
+ * @throws EaafKeyAccessException In case of an unknown or invalid key
+ */
+ public String getBase64EncodedPublicKey() throws EaafKeyAccessException {
+ Pair keyPair = EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), getKeyAlias(), getKeyPassword(), true, KEYSTORE_FRIENDLYNAME);
+ return Base64.getEncoder().encodeToString(keyPair.getSecond()[0].getPublicKey().getEncoded());
+
+ }
+
+ @PostConstruct
+ private void initialize() throws KeyStoreException, EaafException {
+ log.debug("Initializing AuthBlock signing service ... ");
+ // read Connector wide config data TODO connector wide!
+ String keyStoreName = basicConfig
+ .getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_AUTHBLOCK_KEYSTORE_NAME);
+ String keyStorePw = basicConfig
+ .getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_AUTHBLOCK_KEYSTORE_PASSWORD);
+ String keyStorePath = basicConfig
+ .getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_AUTHBLOCK_KEYSTORE_PATH);
+ String keyStoreType = basicConfig
+ .getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_AUTHBLOCK_KEYSTORE_TYPE);
+
+
+ //build new KeyStore configuration
+ KeyStoreConfiguration keyStoreConfiguration = new KeyStoreConfiguration();
+ keyStoreConfiguration.setFriendlyName(KEYSTORE_FRIENDLYNAME);
+
+ keyStoreConfiguration.setSoftKeyStoreFilePath(keyStorePath);
+ keyStoreConfiguration.setSoftKeyStorePassword(keyStorePw);
+ keyStoreConfiguration.setKeyStoreType(KeyStoreConfiguration.KeyStoreType.fromString(keyStoreType));
+ keyStoreConfiguration.setKeyStoreName(keyStoreName);
+
+ //validate KeyStore configuration
+ keyStoreConfiguration.validate();
+
+ //validate key alias
+ if (StringUtils.isEmpty(getKeyAlias())) {
+ throw new EaafConfigurationException("config.08",
+ new Object[] {MsEidasNodeConstants.PROP_CONFIG_AUTHBLOCK_KEY_ALIAS});
+
+ }
+
+ //build new KeyStore based on configuration
+ keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfiguration);
+
+ //check if Key is accessible
+ EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), getKeyAlias(), getKeyPassword(), true, KEYSTORE_FRIENDLYNAME);
+
+ log.info("AuthBlock signing-service successful initialized");
+
+ }
+
+ private char[] getKeyPassword() {
+ final String value = basicConfig.getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_AUTHBLOCK_KEY_PASSWORD);
+ if (value != null) {
+ return value.trim().toCharArray();
+ }
+
+ return null;
+
+ }
+
+
+ private String getKeyAlias() {
+ return basicConfig
+ .getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_AUTHBLOCK_KEY_ALIAS);
+
+ }
+
+ /**
+ * Technical AuthBlock for eIDAS Authentication.
+ *
+ * @author tlenz
+ *
+ */
+ @Data
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ private static class EidasAuchBlock {
+
+ @JsonProperty("challenge")
+ private String challenge;
+
+ @JsonProperty("timestamp")
+ @JsonSerialize(using = LocalDateTimeSerializer.class)
+ @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+ @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC")
+ private LocalDateTime timestamp;
+
+ @JsonProperty("appId")
+ private String uniqueId;
+
+ @JsonProperty("piiTransactionId")
+ private String piiTransactionId;
+
+ @JsonProperty("bindingPublicKey")
+ private String bindingPublicKey;
+
+ }
+
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/CcSpecificEidProcessingService.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/CcSpecificEidProcessingService.java
new file mode 100644
index 00000000..230d6052
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/CcSpecificEidProcessingService.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.service;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+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 org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Service;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.INationalEidProcessor;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.impl.data.Triple;
+import eu.eidas.auth.commons.light.impl.LightRequest.Builder;
+
+@Service
+public class CcSpecificEidProcessingService implements ICcSpecificEidProcessingService {
+ private static final Logger log = LoggerFactory.getLogger(CcSpecificEidProcessingService.class);
+
+ @Autowired
+ private ApplicationContext context;
+
+ private final List handlers = new ArrayList<>();
+
+ @PostConstruct
+ private void initialize() {
+ log.debug("Initialize eID PostProcessing-Service ... ");
+ final Map postProcessors = context.getBeansOfType(
+ INationalEidProcessor.class);
+ final Iterator> iterator = postProcessors.entrySet().iterator();
+ while (iterator.hasNext()) {
+ final Entry el = iterator.next();
+ log.debug("Find eID-PostProcessor with name: " + el.getKey());
+ handlers.add(el.getValue());
+
+ }
+
+ log.trace("Sorting eID-PostProcessors on priority ... ");
+ Collections.sort(handlers, (thisAuthModule, otherAuthModule) -> {
+ final int thisOrder = thisAuthModule.getPriority();
+ final int otherOrder = otherAuthModule.getPriority();
+ return thisOrder < otherOrder ? 1 : thisOrder == otherOrder ? 0 : -1;
+ });
+
+ log.info("# " + handlers.size() + " eID PostProcessing services are registrated");
+
+ }
+
+ @Override
+ public void preProcess(String selectedCitizenCountry, IRequest pendingReq, Builder authnRequestBuilder)
+ throws EidPostProcessingException {
+ if (StringUtils.isEmpty(selectedCitizenCountry)) {
+ log.info("No CountryCode for eID Pre-Processor. Default Pre-Processor will be used");
+ }
+
+ for (final INationalEidProcessor el : handlers) {
+ if (el.canHandle(selectedCitizenCountry)) {
+ log.debug("Pre-Process eIDAS request for " + selectedCitizenCountry + " by using: " + el.getName());
+ el.preProcess(pendingReq, authnRequestBuilder);
+ return;
+
+ }
+ }
+
+ log.error("NO eID PostProcessor FOUND. Looks like a depentency problem!");
+ throw new EidPostProcessingException("internal.00", null);
+
+ }
+
+ @Override
+ public ErnbEidData postProcess(Map eidasAttrMap) throws EidPostProcessingException,
+ EidasAttributeException {
+ // extract citizen country from eIDAS unique identifier
+ final Object eIdentifierObj = eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ if (eIdentifierObj == null || !(eIdentifierObj instanceof String)) {
+ throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ }
+
+ final Triple eIdentifier =
+ EidasResponseUtils.parseEidasPersonalIdentifier((String) eIdentifierObj);
+ final String citizenCountry = eIdentifier.getFirst();
+
+ if (StringUtils.isEmpty(citizenCountry)) {
+ log.info("No CountryCode for eID PostProcessor. Default-PostProcessor will be used");
+ }
+
+ for (final INationalEidProcessor el : handlers) {
+ if (el.canHandle(citizenCountry)) {
+ log.debug("Post-Process eIDAS eID from " + citizenCountry + " by using: " + el.getName());
+ return el.postProcess(eidasAttrMap);
+
+ }
+ }
+
+ log.error("NO eID PostProcessor FOUND. Looks like a depentency problem!");
+ throw new EidPostProcessingException("internal.00", null);
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasAttributeRegistry.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasAttributeRegistry.java
new file mode 100644
index 00000000..e73491ab
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasAttributeRegistry.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.service;
+
+import java.io.File;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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 org.springframework.lang.NonNull;
+import org.springframework.stereotype.Service;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import eu.eidas.auth.commons.attribute.AttributeRegistries;
+import eu.eidas.auth.commons.attribute.AttributeRegistry;
+
+@Service("attributeRegistry")
+public class EidasAttributeRegistry {
+ private static final Logger log = LoggerFactory.getLogger(EidasAttributeRegistry.class);
+ @Autowired
+ private IConfigurationWithSP basicConfig;
+
+ private AttributeRegistry coreAttributeRegistry;
+
+ private String eidasAttributesFile;
+ private String additionalAttributesFile;
+
+ @PostConstruct
+ private void initialize() throws RuntimeException {
+ try {
+ if (eidasAttributesFile.isEmpty()) {
+ log.error("Basic eIDAS addribute definition NOT defined");
+ throw new EaafConfigurationException("config.30",
+ new Object[] { "eidas-attributes.xml" });
+
+ }
+
+ boolean additionalAttrAvailabe = false;
+ if (!additionalAttributesFile.isEmpty()) {
+ final File file = new File(additionalAttributesFile);
+ if (file.exists()) {
+ additionalAttrAvailabe = true;
+ }
+
+ }
+
+ if (!additionalAttrAvailabe) {
+ log.info("Start eIDAS ref. impl. Core without additional eIDAS attribute definitions ... ");
+ coreAttributeRegistry = AttributeRegistries.fromFiles(eidasAttributesFile, null);
+
+ } else {
+ // load attribute definitions
+ log.info("Start eIDAS ref. impl. Core with additional eIDAS attribute definitions ... ");
+ coreAttributeRegistry = AttributeRegistries.fromFiles(eidasAttributesFile, null,
+ additionalAttributesFile);
+
+ }
+
+ } catch (final Throwable e) {
+ log.error("Can NOT initialize eIDAS attribute definition.", e);
+ throw new RuntimeException("Can NOT initialize eIDAS attribute definition.", e);
+
+ }
+ }
+
+ public AttributeRegistry getCoreAttributeRegistry() {
+ return coreAttributeRegistry;
+ }
+
+ /**
+ * Get Map of attributes that are requested by default.
+ *
+ * @return Map of AttributeIdentifier, isRequired flag
+ */
+ @NonNull
+ public Map getDefaultAttributeSetFromConfiguration() {
+ /*
+ * TODO: select set for representation if mandates should be used. It's an open
+ * task in respect to requested eIDAS attributes and isRequired flag, because
+ * there can be a decision problem in case of natural or legal person
+ * representation! From an Austrian use-case point of view, an Austrian service
+ * provider can support mandates for natural and legal persons at the same time.
+ * However, we CAN NOT request attributes for natural AND legal persons on the
+ * same time, because it's not possible to represent both simultaneously.
+ */
+ final Map configAttributes =
+ basicConfig.getBasicConfigurationWithPrefix(
+ Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_DEFAULT_ONLYNATURAL);
+ return processAttributeInfosFromConfig(configAttributes);
+
+ }
+
+ /**
+ * Get a Map of attributes that are additionally requested for a specific country.
+ *
+ * @param countryCode Country Code
+ * @return Map of AttributeIdentifier, isRequired flag
+ */
+ @NonNull
+ public Map getAttributeSetFromConfiguration(String countryCode) {
+
+ /*
+ * TODO: select set for representation if mandates should be used. It's an open
+ * task in respect to requested eIDAS attributes and isRequired flag, because
+ * there can be a decision problem in case of natural or legal person
+ * representation! From an Austrian use-case point of view, an Austrian service
+ * provider can support mandates for natural and legal persons at the same time.
+ * However, we CAN NOT request attributes for natural AND legal persons on the
+ * same time, because it's not possible to represent both simultaneously.
+ */
+ final Map configAttributes =
+ basicConfig.getBasicConfigurationWithPrefix(
+ MessageFormat.format(
+ Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_CC_SPECIFIC_ONLYNATURAL,
+ countryCode.toLowerCase()));
+ return processAttributeInfosFromConfig(configAttributes);
+
+ }
+
+ private Map processAttributeInfosFromConfig(Map configAttributes) {
+
+ final Map result = new HashMap<>();
+ for (final String el : configAttributes.values()) {
+ if (StringUtils.isNotEmpty(el.trim())) {
+ final List attrDef = KeyValueUtils.getListOfCsvValues(el.trim());
+ boolean isRequired = false;
+ if (attrDef.size() == 2) {
+ isRequired = Boolean.parseBoolean(attrDef.get(1));
+ }
+
+ result.put(attrDef.get(0), isRequired);
+
+ }
+ }
+
+ log.trace("Load #" + result.size() + " requested attributes from configuration");
+ return result;
+
+ }
+
+ public void setEidasAttributesFile(String eidasAttributesFile) {
+ this.eidasAttributesFile = eidasAttributesFile;
+ }
+
+ public void setAdditionalAttributesFile(String additionalAttributesFile) {
+ this.additionalAttributesFile = additionalAttributesFile;
+ }
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasDataStore.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasDataStore.java
new file mode 100644
index 00000000..549aa65c
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/EidasDataStore.java
@@ -0,0 +1,363 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH AT-specific eIDAS Connector has been developed
+ * in a cooperation between EGIZ, A-SIT Plus GmbH, A-SIT, and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License. You may
+ * obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses. The "NOTICE" text file
+ * is part of the distribution. Any derivative works that you distribute must
+ * include a readable copy of the "NOTICE" text file.
+ */
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.service;
+
+//import java.io.File;
+//import java.io.IOException;
+//import java.sql.Connection;
+//import java.sql.DriverManager;
+//import java.sql.PreparedStatement;
+//import java.sql.ResultSet;
+//import java.sql.SQLException;
+//import java.sql.Statement;
+//import java.time.Instant;
+//import java.util.Properties;
+//
+//import javax.annotation.PostConstruct;
+//
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.stereotype.Component;
+//import org.sqlite.SQLiteConfig;
+//import org.sqlite.SQLiteConfig.LockingMode;
+//import org.sqlite.SQLiteConfig.SynchronousMode;
+//import org.sqlite.SQLiteErrorCode;
+//
+//import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+//import at.asitplus.eidas.specific.modules.auth.eidas.v2.DAO.eIDASPersonalIdStoreDAO;
+//import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.SQLiteServiceException;
+//import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+//import at.gv.egiz.eaaf.core.impl.data.Pair;
+//import at.gv.egiz.eaaf.core.impl.data.Trible;
+//
+//@Component
+//@Deprecated
+//public class EidasDataStore {
+//
+// private static final String SQLITE_JDBC_DRIVER_CLASS = "org.sqlite.JDBC";
+// private static final String SQLITE_CONNECTION_PARAM = "jdbc:sqlite:%s";
+// private static final boolean sleep = true;
+// private static final int howLongToSleepOnBusyLock_ = 100;
+//
+// private static final Logger log = LoggerFactory.getLogger(EidasDataStore.class);
+//
+// @Autowired
+// private IConfiguration basicConfig;
+//
+// private String connectionUrl;
+// private Connection conn = null;
+//
+// @PostConstruct
+// private void initialize() throws SQLiteServiceException {
+// try {
+// final String sqlLiteDbUrl = basicConfig.getBasicConfiguration(
+// Constants.CONIG_PROPS_EIDAS_SZRCLIENT_WORKAROUND_SQLLITEDATASTORE_URL,
+// basicConfig.getConfigurationRootDirectory().toString() + "/sqlite/database.db"
+//
+// );
+//
+// log.info("Use SQLite database with URL: " + sqlLiteDbUrl);
+//
+// // check if SQLite lib is in Classpath
+// Class.forName(SQLITE_JDBC_DRIVER_CLASS);
+//
+// // open DB connection
+// boolean isNewFileCreated = false;
+//
+// // open file or create file if not already exists
+// final File dbFile = new File(sqlLiteDbUrl);
+// if (!dbFile.exists()) {
+// log.info("SQLite database does not exist. Creating new database file ... ");
+// dbFile.createNewFile();
+// isNewFileCreated = true;
+//
+// }
+//
+// // open database connection
+// connectionUrl = String.format(SQLITE_CONNECTION_PARAM, dbFile.getPath());
+//
+// // create DB scheme if new DB file was created
+// if (isNewFileCreated) {
+// executeUpdate(startConnection().createStatement(), eIDASPersonalIdStoreDAO.CREATE);
+// log.debug("SQLite db scheme created");
+//
+// }
+//
+// } catch (final ClassNotFoundException e) {
+// log.warn("Can NOT initialize SQLite database for temporarly identity mapping. ", e);
+// throw new SQLiteServiceException("internal.05", new Object[] { e.getMessage() }, e);
+//
+// } catch (SQLException | IOException e) {
+// log.warn("Can NOT initialize SQLite database for temporarly identity mapping. ", e);
+// throw new SQLiteServiceException("internal.05", new Object[] { e.getMessage() }, e);
+//
+// }
+//
+// }
+//
+// /**
+// * Store a mapping entry with eIDAS personal identifier (source country /
+// * destination country / personal identifier) and the identifier that is used
+// * for ERnB communication.
+// *
+// * @param transactionId Id of this authentication transaction
+// * @param eidasId eIDAS personal identifier without country prefixes
+// * @param ernbId personal identifier that is used to request the ERnB
+// * @throws SQLiteServiceException In case of a database error
+// */
+// public void storeNationalId(String transactionId, Trible eidasId, String ernbId)
+// throws SQLiteServiceException {
+// try {
+// final PreparedStatement preStatment = startConnection().prepareStatement(
+// eIDASPersonalIdStoreDAO.INSERT,
+// Statement.RETURN_GENERATED_KEYS);
+//
+// for (int i = 1; i <= eIDASPersonalIdStoreDAO.TABLE_COLS.size(); i++) {
+// final Pair col = eIDASPersonalIdStoreDAO.TABLE_COLS.get(i - 1);
+// if (col.getFirst().equals(eIDASPersonalIdStoreDAO.COLS.timestamp.name())) {
+// preStatment.setDate(i, new java.sql.Date(Instant.now().toEpochMilli()));
+// } else if (col.getFirst().equals(eIDASPersonalIdStoreDAO.COLS.transactionId.name())) {
+// preStatment.setString(i, transactionId);
+// } else if (col.getFirst().equals(eIDASPersonalIdStoreDAO.COLS.eidasId.name())) {
+// preStatment.setString(i, eidasId.getThird());
+// } else if (col.getFirst().equals(eIDASPersonalIdStoreDAO.COLS.eidasSourceCountry.name())) {
+// preStatment.setString(i, eidasId.getFirst());
+// } else if (col.getFirst().equals(eIDASPersonalIdStoreDAO.COLS.eidasDestinationCountry.name())) {
+// preStatment.setString(i, eidasId.getSecond());
+// } else if (col.getFirst().equals(eIDASPersonalIdStoreDAO.COLS.ernbId.name())) {
+// preStatment.setString(i, ernbId);
+// } else {
+// log.warn("SQLite table:" + eIDASPersonalIdStoreDAO.NAME + " contains no col with name:" + col
+// .getFirst());
+// }
+//
+// }
+//
+// // execute SQL query
+// final int sqlResult = preStatment.executeUpdate();
+//
+// if (sqlResult != 1) {
+// log.warn("SQLite query execution FAILED!");
+// throw new SQLiteServiceException("internal.06", new Object[] { "Queryresult is '-1'" });
+//
+// }
+//
+// } catch (SQLiteServiceException | SQLException e) {
+// log.warn("SQLite query execution FAILED!", e);
+// throw new SQLiteServiceException("internal.05", new Object[] { e.getMessage() }, e);
+//
+// }
+//
+// }
+//
+// /**
+// * Get the ERnB related national identifier from mapping database.
+// *
+// * @param eidasId eIDAS related identifier
+// * @return Mapped ERnB identifier
+// * @throws SQLiteServiceException In case of a database error
+// */
+// public String getErnbNationalId(Trible eidasId) throws SQLiteServiceException {
+// try {
+// final PreparedStatement preStatment = startConnection().prepareStatement(
+// eIDASPersonalIdStoreDAO.SELECT_BY_EIDAS_RAW_ID,
+// Statement.RETURN_GENERATED_KEYS);
+//
+// preStatment.setString(1, eidasId.getThird());
+// preStatment.setString(2, eidasId.getFirst());
+//
+// final ResultSet rs = preStatment.executeQuery();
+//
+// if (!rs.next()) {
+// return null;
+// } else {
+// return rs.getString(eIDASPersonalIdStoreDAO.COLS.ernbId.name());
+// }
+//
+// } catch (SQLiteServiceException | SQLException e) {
+// log.warn("SQLite query execution FAILED!", e);
+// throw new SQLiteServiceException("internal.05", new Object[] { e.getMessage() }, e);
+//
+// }
+//
+// }
+//
+// /**
+// * Get the eIDAS identifier from an ERnB identifier.
+// *
+// * @param ernbId ERnB specific identifier
+// * @return eIDAS unqiue identifier
+// * @throws SQLiteServiceException In case of a database error
+// */
+// public String getEidasRawNationalId(String ernbId) throws SQLiteServiceException {
+// try {
+// final PreparedStatement preStatment = startConnection().prepareStatement(
+// eIDASPersonalIdStoreDAO.SELECT_BY_ERNB_ID,
+// Statement.RETURN_GENERATED_KEYS);
+//
+// preStatment.setString(1, ernbId);
+//
+// final ResultSet rs = preStatment.executeQuery();
+//
+// if (!rs.next()) {
+// return null;
+// } else {
+// return rs.getString(eIDASPersonalIdStoreDAO.COLS.eidasId.name());
+// }
+//
+// } catch (SQLiteServiceException | SQLException e) {
+// log.warn("SQLite query execution FAILED!", e);
+// throw new SQLiteServiceException("internal.05", new Object[] { e.getMessage() }, e);
+//
+// }
+//
+// }
+//
+// private Connection startConnection() throws SQLiteServiceException {
+// int i = howLongToSleepOnBusyLock_;
+//
+// while (true) {
+// try {
+// if (conn == null) {
+// log.info("Initializing SQLite database with URL: " + connectionUrl + " ... ");
+// conn = DriverManager.getConnection(connectionUrl, getConnectionProperties());
+//
+// } else {
+// if (!conn.isValid(10)) {
+// log.info("SQLite connection is not valid any more --> restarting connection ...");
+// conn.close();
+// conn = DriverManager.getConnection(connectionUrl, getConnectionProperties());
+// }
+// }
+//
+// log.info("SQLite database connected");
+// return conn;
+//
+// } catch (final SQLException e) {
+// final String msg = e.getLocalizedMessage();
+// if (isBusyLocked(e)) {
+// log.warn(msg, e);
+// try {
+// if (sleep) {
+// Thread.sleep(i++);
+// }
+//
+// } catch (final InterruptedException e1) {
+// throw new SQLiteServiceException("internal.05", new Object[] { e1.getMessage() }, e1);
+//
+// }
+// continue;
+//
+// }
+// throw new SQLiteServiceException("internal.05", new Object[] { e.getMessage() }, e);
+//
+// }
+// }
+// }
+//
+// /*
+// * SQLite query code
+// */
+//
+// protected Properties getConnectionProperties() {
+// final SQLiteConfig config = new SQLiteConfig();
+// config.enforceForeignKeys(true);
+// config.setCacheSize(8000);
+// config.setLockingMode(LockingMode.NORMAL);
+// config.setSharedCache(false);
+// config.setReadUncommited(true);
+// config.setSynchronous(SynchronousMode.NORMAL);
+// return config.toProperties();
+//
+// }
+//
+// private int executeUpdate(Statement statement, String sql) throws SQLiteServiceException {
+// final int i = 10;
+//
+// int rc = -1;
+// while (true) {
+// try {
+// rc = statement.executeUpdate(sql);
+// break;
+//
+// } catch (final SQLException e) {
+// try {
+// if (executeUpdateError(e, i)) {
+// continue;
+// } else {
+// throw new SQLiteServiceException("internal.06",
+// new Object[] { e.getMessage() }, e);
+// }
+//
+// } catch (final SQLiteServiceException e1) {
+// log.warn("\n" + sql + "\n" + e1.getMessage());
+// throw e1;
+//
+// }
+// }
+// }
+//
+// return rc;
+//
+// }
+//
+// private boolean isBusyLocked(SQLException e) {
+// final int eC = e.getErrorCode();
+//
+// if (eC == SQLiteErrorCode.SQLITE_LOCKED.code
+// || eC == SQLiteErrorCode.SQLITE_BUSY.code) {
+// log.trace("SQLite db is busy looked");
+// return true;
+//
+// }
+//
+// final String msg = e.getMessage();
+// if (msg.contains("[SQLITE_LOCKED]") || msg.contains("[SQLITE_BUSY]")) {
+// log.trace("SQLite db is busy looked");
+// return true;
+// }
+//
+// return false;
+// }
+//
+// private boolean executeUpdateError(SQLException e, int theadSleepCounter) throws SQLiteServiceException {
+// if (isBusyLocked(e)) {
+// try {
+// if (sleep) {
+// Thread.sleep(theadSleepCounter++);
+// }
+//
+// } catch (final InterruptedException e1) {
+// throw new SQLiteServiceException("internal.05", new Object[] { e1.getMessage() }, e1);
+//
+// }
+//
+// return true;
+// }
+//
+// return false;
+//
+// }
+//}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/ICcSpecificEidProcessingService.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/ICcSpecificEidProcessingService.java
new file mode 100644
index 00000000..ebbc15e4
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/ICcSpecificEidProcessingService.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.service;
+
+import java.util.Map;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import eu.eidas.auth.commons.light.ILightRequest;
+import eu.eidas.auth.commons.light.impl.LightRequest.Builder;
+
+public interface ICcSpecificEidProcessingService {
+
+ /**
+ * Post-process eIDAS eID attributes into national format.
+ *
+ * @param eidasAttrMap Map of eIDAS attributes in format friendlyName and
+ * attribute
+ *
+ * @return eID attributes for SZR request
+ * @throws EidPostProcessingException In case of a post-processing error
+ * @throws EidasAttributeException In case of an invalid eIDAS attribute value
+ */
+ ErnbEidData postProcess(Map eidasAttrMap) throws EidPostProcessingException,
+ EidasAttributeException;
+
+ /**
+ * Pre Process eIDAS request into national requirements.
+ *
+ * @param selectedCC Citizen Country from selection
+ * @param pendingReq current pending request
+ * @param authnRequestBuilder eIDAS {@link ILightRequest} builder
+ * @throws EidPostProcessingException In case of a pre-processing error
+ */
+ void preProcess(String selectedCC, IRequest pendingReq, Builder authnRequestBuilder)
+ throws EidPostProcessingException;
+
+}
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/szr/SzrClient.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/szr/SzrClient.java
new file mode 100644
index 00000000..1f5837d6
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/szr/SzrClient.java
@@ -0,0 +1,522 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.szr;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.handler.Handler;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.configuration.jsse.TLSClientParameters;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.jaxws.DispatchImpl;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
+import org.apache.xpath.XPathAPI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.SzrCommunicationException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.LoggingHandler;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.data.XmlNamespaceConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
+import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
+import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils;
+import szrservices.GetBPK;
+import szrservices.GetBPKResponse;
+import szrservices.GetIdentityLinkEidas;
+import szrservices.GetIdentityLinkEidasResponse;
+import szrservices.IdentityLinkType;
+import szrservices.JwsHeaderParam;
+import szrservices.ObjectFactory;
+import szrservices.PersonInfoType;
+import szrservices.SZR;
+import szrservices.SZRException_Exception;
+import szrservices.SignContent;
+import szrservices.SignContentEntry;
+import szrservices.SignContentResponseType;
+
+
+@Service("SZRClientForeIDAS")
+public class SzrClient {
+ private static final Logger log = LoggerFactory.getLogger(SzrClient.class);
+
+ private static final String CLIENT_DEFAULT = "DefaultClient";
+ private static final String CLIENT_RAW = "RawClient";
+
+ private static final String ATTR_NAME_VSZ = "urn:eidgvat:attributes.vsz.value";
+ private static final String ATTR_NAME_PUBKEYS = "urn:eidgvat:attributes.user.pubkeys";
+ private static final String ATTR_NAME_STATUS = "urn:eidgvat:attributes.eid.status";
+ private static final String KEY_BC_BIND = "bcBindReq";
+ private static final String JOSE_HEADER_USERCERTPINNING_TYPE = "urn:at.gv.eid:bindtype";
+ private static final String JOSE_HEADER_USERCERTPINNING_EIDASBIND = "urn:at.gv.eid:eidasBind";
+ public static final String ATTR_NAME_MDS = "urn:eidgvat:mds";
+
+ @Autowired
+ private IConfiguration basicConfig;
+
+ // client for anything, without identitylink
+ private SZR szr = null;
+
+ // RAW client is needed for identitylink
+ private Dispatch