aboutsummaryrefslogtreecommitdiff
path: root/id/server
diff options
context:
space:
mode:
Diffstat (limited to 'id/server')
-rw-r--r--id/server/auth/pom.xml5
-rw-r--r--id/server/auth/src/main/webapp/index.html1
-rw-r--r--id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/config/ELGAMandatesMetadataConfiguration.java291
-rw-r--r--id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/config/ELGAMandatesRequestBuilderConfiguration.java187
-rw-r--r--id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/controller/ELGAMandateMetadataController.java97
-rw-r--r--id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/controller/ELGAMandateSignalController.java67
-rw-r--r--id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/exceptions/ELGAMetadataException.java49
-rw-r--r--id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/tasks/ReceiveElgaMandateResponseTask.java224
-rw-r--r--id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/tasks/RequestELGAMandateTask.java160
-rw-r--r--id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java209
-rw-r--r--id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandatesCredentialProvider.java123
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/pom.xml51
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferAuthModuleImpl.java76
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferConstants.java64
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferSpringResourceProvider.java62
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/Pair.java21
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferAuthenticationData.java382
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferContainer.java107
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferOnlineApplication.java453
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java626
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferSignalServlet.java101
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/task/InitializeRestoreSSOSessionTask.java82
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/task/RestoreSSOSessionTask.java196
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/GUIUtils.java148
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/SSOContainerUtils.java477
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider1
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/resources/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransfer.authmodule.beans.xml14
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/resources/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferAuthentication.process.xml24
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/resources/moaid_ssotransfer_auth.beans.xml34
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/resources/sso_transfer_template.html447
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/test/java/at/gv/egiz/tests/Tests.java77
31 files changed, 4856 insertions, 0 deletions
diff --git a/id/server/auth/pom.xml b/id/server/auth/pom.xml
index 2faee730e..e3e9ee4f0 100644
--- a/id/server/auth/pom.xml
+++ b/id/server/auth/pom.xml
@@ -172,6 +172,11 @@
<artifactId>moa-id-modules-federated_authentication</artifactId>
</dependency>
+ <dependency>
+ <groupId>MOA.id.server.modules</groupId>
+ <artifactId>moa-id-module-ssoTransfer</artifactId>
+ <version>${moa-id-version}</version>
+ </dependency>
<!-- transitive dependencies we don't want to include into the war -->
<dependency>
<groupId>iaik.prod</groupId>
diff --git a/id/server/auth/src/main/webapp/index.html b/id/server/auth/src/main/webapp/index.html
index 0c051571b..d2e7d1e1b 100644
--- a/id/server/auth/src/main/webapp/index.html
+++ b/id/server/auth/src/main/webapp/index.html
@@ -77,6 +77,7 @@
<li><a href=#>Demo Clients</a></li>
<!--Link zum Konfigtool-->
<li><a href="https://localhost:8443/moa-id-configuration">Konfiguration GUI</a></li>
+ <li><a href="./TransferSSOSession">Transfer Single Sign-On Session to Smartphone App</a></li>
</ul>
</nav>
diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/config/ELGAMandatesMetadataConfiguration.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/config/ELGAMandatesMetadataConfiguration.java
new file mode 100644
index 000000000..a64fc8bf7
--- /dev/null
+++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/config/ELGAMandatesMetadataConfiguration.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.elgamandates.config;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.NameIDType;
+import org.opensaml.saml2.metadata.ContactPerson;
+import org.opensaml.saml2.metadata.Organization;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+import org.opensaml.xml.security.credential.Credential;
+
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.ELGAMandatesAuthConstants;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.utils.ELGAMandatesCredentialProvider;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.data.Pair;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPMetadataBuilderConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * @author tlenz
+ *
+ */
+public class ELGAMandatesMetadataConfiguration implements IPVPMetadataBuilderConfiguration {
+
+ private String authURL;
+ private ELGAMandatesCredentialProvider credentialProvider;
+
+ public ELGAMandatesMetadataConfiguration(String authURL, ELGAMandatesCredentialProvider credentialProvider) {
+ this.authURL = authURL;
+ this.credentialProvider = credentialProvider;
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getMetadataValidUntil()
+ */
+ @Override
+ public int getMetadataValidUntil() {
+ return ELGAMandatesAuthConstants.METADATA_VALIDUNTIL_IN_HOURS;
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#buildEntitiesDescriptorAsRootElement()
+ */
+ @Override
+ public boolean buildEntitiesDescriptorAsRootElement() {
+ return false;
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#buildIDPSSODescriptor()
+ */
+ @Override
+ public boolean buildIDPSSODescriptor() {
+ return false;
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#buildSPSSODescriptor()
+ */
+ @Override
+ public boolean buildSPSSODescriptor() {
+ return true;
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getEntityIDPostfix()
+ */
+ @Override
+ public String getEntityID() {
+ return authURL + ELGAMandatesAuthConstants.ENDPOINT_METADATA;
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getEntityFriendlyName()
+ */
+ @Override
+ public String getEntityFriendlyName() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getContactPersonInformation()
+ */
+ @Override
+ public List<ContactPerson> getContactPersonInformation() {
+ try {
+ return PVPConfiguration.getInstance().getIDPContacts();
+
+ } catch (ConfigurationException e) {
+ Logger.warn("Can not load Metadata entry: Contect Person", e);
+ return null;
+
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getOrgansiationInformation()
+ */
+ @Override
+ public Organization getOrgansiationInformation() {
+ try {
+ return PVPConfiguration.getInstance().getIDPOrganisation();
+
+ } catch (ConfigurationException e) {
+ Logger.warn("Can not load Metadata entry: Organisation", e);
+ return null;
+
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getMetadataSigningCredentials()
+ */
+ @Override
+ public Credential getMetadataSigningCredentials() throws CredentialsNotAvailableException {
+ return credentialProvider.getIDPMetaDataSigningCredential();
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getRequestorResponseSigningCredentials()
+ */
+ @Override
+ public Credential getRequestorResponseSigningCredentials() throws CredentialsNotAvailableException {
+ return credentialProvider.getIDPAssertionSigningCredential();
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getEncryptionCredentials()
+ */
+ @Override
+ public Credential getEncryptionCredentials() throws CredentialsNotAvailableException {
+ return credentialProvider.getIDPAssertionEncryptionCredential();
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getIDPWebSSOPostBindingURL()
+ */
+ @Override
+ public String getIDPWebSSOPostBindingURL() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getIDPWebSSORedirectBindingURL()
+ */
+ @Override
+ public String getIDPWebSSORedirectBindingURL() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getIDPSLOPostBindingURL()
+ */
+ @Override
+ public String getIDPSLOPostBindingURL() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getIDPSLORedirectBindingURL()
+ */
+ @Override
+ public String getIDPSLORedirectBindingURL() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getSPAssertionConsumerServicePostBindingURL()
+ */
+ @Override
+ public String getSPAssertionConsumerServicePostBindingURL() {
+ return authURL + ELGAMandatesAuthConstants.ENDPOINT_POST;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getSPAssertionConsumerServiceRedirectBindingURL()
+ */
+ @Override
+ public String getSPAssertionConsumerServiceRedirectBindingURL() {
+ return authURL + ELGAMandatesAuthConstants.ENDPOINT_REDIRECT;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getSPSLOPostBindingURL()
+ */
+ @Override
+ public String getSPSLOPostBindingURL() {
+ return authURL + ELGAMandatesAuthConstants.ENDPOINT_POST;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getSPSLORedirectBindingURL()
+ */
+ @Override
+ public String getSPSLORedirectBindingURL() {
+ return authURL + ELGAMandatesAuthConstants.ENDPOINT_REDIRECT;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getSPSLOSOAPBindingURL()
+ */
+ @Override
+ public String getSPSLOSOAPBindingURL() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getIDPPossibleAttributes()
+ */
+ @Override
+ public List<Attribute> getIDPPossibleAttributes() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getIDPPossibleNameITTypes()
+ */
+ @Override
+ public List<String> getIDPPossibleNameITTypes() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getSPRequiredAttributes()
+ */
+ @Override
+ public List<RequestedAttribute> getSPRequiredAttributes() {
+ List<RequestedAttribute> requestedAttributes = new ArrayList<RequestedAttribute>();
+
+ for (Pair<String, String> el : ELGAMandatesAuthConstants.REQUIRED_PVP_ATTRIBUTES)
+ requestedAttributes.add(PVPAttributeBuilder.buildReqAttribute(el.getFirst(), el.getSecond(), true));
+
+ return requestedAttributes;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder#getSPAllowedNameITTypes()
+ */
+ @Override
+ public List<String> getSPAllowedNameITTypes() {
+ return Arrays.asList(NameIDType.PERSISTENT);
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPMetadataBuilderConfiguration#getSPNameForLogging()
+ */
+ @Override
+ public String getSPNameForLogging() {
+ return ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING;
+ }
+}
diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/config/ELGAMandatesRequestBuilderConfiguration.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/config/ELGAMandatesRequestBuilderConfiguration.java
new file mode 100644
index 000000000..b521116d3
--- /dev/null
+++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/config/ELGAMandatesRequestBuilderConfiguration.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.elgamandates.config;
+
+import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.xml.security.credential.Credential;
+
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.ELGAMandatesAuthConstants;
+import at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation;
+
+/**
+ * @author tlenz
+ *
+ */
+public class ELGAMandatesRequestBuilderConfiguration implements IPVPAuthnRequestBuilderConfiguruation {
+
+ private boolean isPassive;
+ private String SPEntityID;
+ private String QAA_Level;
+ private EntityDescriptor idpEntity;
+ private Credential signCred;
+ private String subjectNameID;
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#isPassivRequest()
+ */
+ @Override
+ public Boolean isPassivRequest() {
+ return this.isPassive;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getAssertionConsumerServiceId()
+ */
+ @Override
+ public Integer getAssertionConsumerServiceId() {
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getEntityID()
+ */
+ @Override
+ public String getSPEntityID() {
+ return this.SPEntityID;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getNameIDPolicy()
+ */
+ @Override
+ public String getNameIDPolicyFormat() {
+ return NameID.TRANSIENT;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getNameIDPolicy()
+ */
+ @Override
+ public boolean getNameIDPolicyAllowCreation() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getAuthnContextClassRef()
+ */
+ @Override
+ public String getAuthnContextClassRef() {
+ return this.QAA_Level;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getAuthnContextComparison()
+ */
+ @Override
+ public AuthnContextComparisonTypeEnumeration getAuthnContextComparison() {
+ return AuthnContextComparisonTypeEnumeration.MINIMUM;
+ }
+
+ /**
+ * @param isPassive the isPassive to set
+ */
+ public void setPassive(boolean isPassive) {
+ this.isPassive = isPassive;
+ }
+
+ /**
+ * @param sPEntityID the sPEntityID to set
+ */
+ public void setSPEntityID(String sPEntityID) {
+ SPEntityID = sPEntityID;
+ }
+
+ /**
+ * @param qAA_Level the qAA_Level to set
+ */
+ public void setQAA_Level(String qAA_Level) {
+ QAA_Level = qAA_Level;
+ }
+
+ /**
+ * @param idpEntity the idpEntity to set
+ */
+ public void setIdpEntity(EntityDescriptor idpEntity) {
+ this.idpEntity = idpEntity;
+ }
+
+ /**
+ * @param signCred the signCred to set
+ */
+ public void setSignCred(Credential signCred) {
+ this.signCred = signCred;
+ }
+
+
+ /**
+ * @param subjectNameID the subjectNameID to set
+ */
+ public void setSubjectNameID(String subjectNameID) {
+ this.subjectNameID = subjectNameID;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getAuthnRequestSigningCredential()
+ */
+ @Override
+ public Credential getAuthnRequestSigningCredential() {
+ return this.signCred;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getIDPEntityDescriptor()
+ */
+ @Override
+ public EntityDescriptor getIDPEntityDescriptor() {
+ return this.idpEntity;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getSubjectNameID()
+ */
+ @Override
+ public String getSubjectNameID() {
+ return this.subjectNameID;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getSPNameForLogging()
+ */
+ @Override
+ public String getSPNameForLogging() {
+ return ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPAuthnRequestBuilderConfiguruation#getSubjectNameIDFormat()
+ */
+ @Override
+ public String getSubjectNameIDFormat() {
+ return NameID.PERSISTENT;
+ }
+
+
+}
diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/controller/ELGAMandateMetadataController.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/controller/ELGAMandateMetadataController.java
new file mode 100644
index 000000000..3fa43d0a3
--- /dev/null
+++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/controller/ELGAMandateMetadataController.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.elgamandates.controller;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.ELGAMandatesAuthConstants;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.config.ELGAMandatesMetadataConfiguration;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.utils.ELGAMandatesCredentialProvider;
+import at.gv.egovernment.moa.id.auth.servlet.AbstractController;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPMetadataBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPMetadataBuilderConfiguration;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * @author tlenz
+ *
+ */
+@Controller
+public class ELGAMandateMetadataController extends AbstractController {
+
+ @Autowired PVPMetadataBuilder metadatabuilder;
+ @Autowired AuthConfiguration authConfig;
+ @Autowired ELGAMandatesCredentialProvider credentialProvider;
+
+ public ELGAMandateMetadataController() {
+ super();
+ Logger.debug("Registering servlet " + getClass().getName()
+ + " with mappings '" + ELGAMandatesAuthConstants.ENDPOINT_METADATA
+ + "'.");
+
+ }
+
+ @RequestMapping(value = "/sp/elga_mandate/metadata",
+ method = {RequestMethod.GET})
+ public void getSPMetadata(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ //check PublicURL prefix
+ try {
+ String authURL = HTTPUtils.extractAuthURLFromRequest(req);
+ if (!authConfig.getPublicURLPrefix().contains(authURL)) {
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN, "No valid request URL");
+ return;
+
+ } else {
+ //initialize metadata builder configuration
+ IPVPMetadataBuilderConfiguration metadataConfig =
+ new ELGAMandatesMetadataConfiguration(authURL, credentialProvider);
+
+ //build metadata
+ String xmlMetadata = metadatabuilder.buildPVPMetadata(metadataConfig);
+
+ //write response
+ resp.setContentType("text/xml");
+ resp.getOutputStream().write(xmlMetadata.getBytes("UTF-8"));
+ resp.getOutputStream().close();
+
+ }
+
+ } catch (Exception e) {
+ Logger.warn("Build federated-authentication PVP metadata FAILED.", e);
+ handleErrorNoRedirect(e, req, resp, false);
+
+ }
+
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/controller/ELGAMandateSignalController.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/controller/ELGAMandateSignalController.java
new file mode 100644
index 000000000..585e72c2f
--- /dev/null
+++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/controller/ELGAMandateSignalController.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.elgamandates.controller;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.ELGAMandatesAuthConstants;
+import at.gv.egovernment.moa.id.auth.servlet.AbstractProcessEngineSignalController;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * @author tlenz
+ *
+ */
+@Controller
+public class ELGAMandateSignalController extends AbstractProcessEngineSignalController {
+
+ public ELGAMandateSignalController() {
+ super();
+ Logger.debug("Registering servlet " + getClass().getName()
+ + " with mappings '" + ELGAMandatesAuthConstants.ENDPOINT_POST
+ + "' and '" + ELGAMandatesAuthConstants.ENDPOINT_REDIRECT + "'.");
+
+ }
+
+ @RequestMapping(value = { "/sp/elga_mandate/post",
+ "/sp/elga_mandate/redirect"
+ },
+ method = {RequestMethod.POST, RequestMethod.GET})
+ public void performCitizenCardAuthentication(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ signalProcessManagement(req, resp);
+
+ }
+
+ public String getPendingRequestId(HttpServletRequest request) {
+ return StringEscapeUtils.escapeHtml4(request.getParameter("RelayState"));
+
+ }
+}
diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/exceptions/ELGAMetadataException.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/exceptions/ELGAMetadataException.java
new file mode 100644
index 000000000..6b7c13804
--- /dev/null
+++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/exceptions/ELGAMetadataException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.elgamandates.exceptions;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+
+/**
+ * @author tlenz
+ *
+ */
+public class ELGAMetadataException extends MOAIDException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @param messageId
+ * @param parameters
+ */
+ public ELGAMetadataException(String messageId, Object[] parameters) {
+ super(messageId, parameters);
+ }
+
+ public ELGAMetadataException(String messageId, Object[] parameters, Throwable e) {
+ super(messageId, parameters, e);
+ }
+}
diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/tasks/ReceiveElgaMandateResponseTask.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/tasks/ReceiveElgaMandateResponseTask.java
new file mode 100644
index 000000000..13e17e03e
--- /dev/null
+++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/tasks/ReceiveElgaMandateResponseTask.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.elgamandates.tasks;
+
+import java.io.IOException;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.TransformerException;
+
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.ws.message.decoder.MessageDecodingException;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.security.SecurityException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.ELGAMandatesAuthConstants;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.utils.ELGAMandateServiceMetadataProvider;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.utils.ELGAMandatesCredentialProvider;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IDecoder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.binding.PostBinding;
+import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionValidationExeption;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AuthnResponseValidationException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
+import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor;
+import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
+import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngine;
+import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+/**
+ * @author tlenz
+ *
+ */
+@Component("ReceiveElgaMandateResponseTask")
+public class ReceiveElgaMandateResponseTask extends AbstractAuthServletTask {
+
+ @Autowired SAMLVerificationEngine samlVerificationEngine;
+ @Autowired ELGAMandatesCredentialProvider credentialProvider;
+ @Autowired ELGAMandateServiceMetadataProvider metadataProvider;
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+ InboundMessage msg = null;
+
+ try {
+ IDecoder decoder = null;
+ //select Response Binding
+ if (request.getMethod().equalsIgnoreCase("POST")) {
+ decoder = new PostBinding();
+ Logger.debug("Receive PVP Response from ELGA mandate-service, by using POST-Binding.");
+
+ } else if (request.getMethod().equalsIgnoreCase("GET")) {
+ decoder = new RedirectBinding();
+ Logger.debug("Receive PVP Response from ELGA mandate-service, by using Redirect-Binding.");
+
+ } else {
+ Logger.warn("Receive PVP Response, but Binding ("
+ + request.getMethod() + ") is not supported.");
+ throw new AuthnResponseValidationException("sp.pvp2.03",
+ new Object[] {ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING});
+
+ }
+
+ //decode PVP response object
+ msg = (InboundMessage) decoder.decode(request, response, metadataProvider, true);
+
+ if (MiscUtil.isEmpty(msg.getEntityID())) {
+ throw new InvalidProtocolRequestException("sp.pvp2.04",
+ new Object[] {ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING});
+
+ }
+
+ //validate response signature
+ if(!msg.isVerified()) {
+ samlVerificationEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+ msg.setVerified(true);
+
+ }
+
+ Logger.debug("PVP Response from ELGA mandate-service is cryptographically valid.");
+
+ //validate assertion
+ MOAResponse processedMsg = preProcessAuthResponse((MOAResponse) msg);
+
+ //write ELGA mandate information into MOASession
+ AssertionAttributeExtractor extractor =
+ new AssertionAttributeExtractor(processedMsg.getResponse());
+
+ //check if all attributes are include
+ if (!extractor.containsAllRequiredAttributes(
+ ELGAMandatesAuthConstants.getRequiredAttributeNames())) {
+ Logger.warn("PVP Response from ELGA mandate-service contains not all requested attributes.");
+ throw new AssertionValidationExeption("sp.pvp2.06", new Object[]{ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING});
+
+ }
+
+ //load MOASession object
+ defaultTaskInitialization(request, executionContext);
+
+ //validate receive mandate reference-value
+ String responseRefValue = extractor.getSingleAttributeValue(PVPConstants.MANDATE_REFERENCE_VALUE_NAME);
+ if (!moasession.getMandateReferenceValue().equals(responseRefValue)) {
+ Logger.warn("PVP Response from ELGA mandate-service contains not all requested attributes.");
+ throw new AssertionValidationExeption("sp.pvp2.07",
+ new Object[]{ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING,
+ PVPConstants.MANDATE_REFERENCE_VALUE_FRIENDLY_NAME});
+
+ }
+
+ Logger.debug("Validation of PVP Response from ELGA mandate-service is complete.");
+
+ Set<String> includedAttrNames = extractor.getAllIncludeAttributeNames();
+ for (String el : includedAttrNames) {
+ moasession.setGenericDataToSession(el, extractor.getSingleAttributeValue(el));
+ Logger.debug("Add PVP-attribute " + el + " into MOASession");
+
+ }
+
+ //store MOASession
+ authenticatedSessionStorage.storeSession(moasession);
+
+ //TODO write log entries
+ //revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_INTERFEDERATION_REVEIVED);
+
+ Logger.info("Receive a valid assertion from ELGA mandate-service " + msg.getEntityID());
+
+ } catch (MessageDecodingException | SecurityException e) {
+ String samlRequest = request.getParameter("SAMLRequest");
+ Logger.warn("Receive INVALID PVP Response from ELGA mandate-service: " + samlRequest, e);
+ throw new TaskExecutionException(pendingReq, "Receive INVALID PVP Response from ELGA mandate-service", e);
+
+ } catch (IOException | MarshallingException | TransformerException e) {
+ Logger.warn("Processing PVP response from ELGA mandate-service FAILED.", e);
+ throw new TaskExecutionException(pendingReq, "Processing PVP response from ELGA mandate-service FAILED.", e);
+
+ } catch (CredentialsNotAvailableException e) {
+ Logger.error("ELGA mandate-service: PVP response decrytion FAILED. No credential found.", e);
+ throw new TaskExecutionException(pendingReq, "ELGA mandate-service: PVP response decrytion FAILED. No credential found.", e);
+
+ } catch (AssertionValidationExeption | AuthnResponseValidationException e) {
+ Logger.info("ELGA mandate-service: PVP response validation FAILED. Msg:" + e.getMessage());
+ throw new TaskExecutionException(pendingReq, "ELGA mandate-service: PVP response validation FAILED.", e);
+
+ } catch (Exception e) {
+ Logger.info("ELGA mandate-service: General Exception. Msg:" + e.getMessage());
+ throw new TaskExecutionException(pendingReq, "ELGA mandate-service: General Exception.", e);
+
+ }
+
+ }
+
+ /**
+ * PreProcess AuthResponse and Assertion
+ * @param msg
+ * @throws TransformerException
+ * @throws MarshallingException
+ * @throws IOException
+ * @throws CredentialsNotAvailableException
+ * @throws AssertionValidationExeption
+ * @throws AuthnResponseValidationException
+ */
+ private MOAResponse preProcessAuthResponse(MOAResponse msg) throws IOException, MarshallingException, TransformerException, AssertionValidationExeption, CredentialsNotAvailableException, AuthnResponseValidationException {
+ Logger.debug("Start PVP-2.1 assertion processing... ");
+ Response samlResp = (Response) msg.getResponse();
+
+ // check SAML2 response status-code
+ if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) {
+ //validate PVP 2.1 assertion
+ samlVerificationEngine.validateAssertion(samlResp, true, credentialProvider.getIDPAssertionEncryptionCredential());
+
+ msg.setSAMLMessage(SAML2Utils.asDOMDocument(samlResp).getDocumentElement());
+ return msg;
+
+ } else {
+ Logger.info("Receive StatusCode " + samlResp.getStatus().getStatusCode().getValue()
+ + " from federated IDP.");
+ throw new AuthnResponseValidationException("sp.pvp2.04",
+ new Object[]{ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING,
+ samlResp.getIssuer().getValue(),
+ samlResp.getStatus().getStatusCode().getValue()});
+
+ }
+
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/tasks/RequestELGAMandateTask.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/tasks/RequestELGAMandateTask.java
new file mode 100644
index 000000000..bcd8076bc
--- /dev/null
+++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/tasks/RequestELGAMandateTask.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.elgamandates.tasks;
+
+import java.security.NoSuchAlgorithmException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.opensaml.xml.security.SecurityException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import at.gv.egovernment.moa.id.auth.builder.BPKBuilder;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.ELGAMandatesAuthConstants;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.config.ELGAMandatesRequestBuilderConfiguration;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.exceptions.ELGAMetadataException;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.utils.ELGAMandateServiceMetadataProvider;
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.utils.ELGAMandatesCredentialProvider;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAuthnRequestBuilder;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+/**
+ * @author tlenz
+ *
+ */
+@Component("RequestELGAMandateTask")
+public class RequestELGAMandateTask extends AbstractAuthServletTask {
+
+ @Autowired PVPAuthnRequestBuilder authnReqBuilder;
+ @Autowired ELGAMandatesCredentialProvider credential;
+ @Autowired AuthConfiguration authConfig;
+ @Autowired ELGAMandateServiceMetadataProvider metadataService;
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+ try{
+ // get IDP entityID
+ String elgaMandateServiceEntityID = authConfig.getBasicMOAIDConfiguration(ELGAMandatesAuthConstants.CONFIG_PROPS_ENTITYID);
+
+ if (MiscUtil.isEmpty(elgaMandateServiceEntityID)) {
+ Logger.info("Connect ELGA Mandate-Service FAILED -> not EntityID found!");
+ throw new TaskExecutionException(pendingReq, "Connect ELGA Mandate-Service FAILED",
+ new MOAIDException("service.10",
+ new Object[]{ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING, "Not EntityID found"}));
+
+ }
+
+ //load IDP SAML2 entitydescriptor
+ EntityDescriptor entityDesc = metadataService.getEntityDescriptor(elgaMandateServiceEntityID);
+
+ //load MOASession from database
+ defaultTaskInitialization(request, executionContext);
+
+ //setup AuthnRequestBuilder configuration
+ ELGAMandatesRequestBuilderConfiguration authnReqConfig = new ELGAMandatesRequestBuilderConfiguration();
+ authnReqConfig.setIdpEntity(entityDesc);
+ authnReqConfig.setPassive(false);
+ authnReqConfig.setSignCred(credential.getIDPAssertionSigningCredential());
+ authnReqConfig.setSPEntityID(pendingReq.getAuthURL() + ELGAMandatesAuthConstants.ENDPOINT_METADATA);
+
+ //set bPK of representative
+ String representativeBPK = null;
+
+ String configTarget = authConfig.getBasicMOAIDConfiguration(ELGAMandatesAuthConstants.CONFIG_PROPS_SUBJECTNAMEID_TARGET);
+ if (MiscUtil.isEmpty(configTarget)) {
+ Logger.warn("Connect ELGA Mandate-Service FAILED -> No bPK-Type for SubjectNameID found.");
+ throw new MOAIDException("service.10",
+ new Object[]{ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING, "No bPK-Type for SubjectNameID found in configuration."});
+
+ } else {
+ if (!configTarget.startsWith(Constants.URN_PREFIX_CDID)) {
+ Logger.warn("Connect ELGA Mandate-Service FAILED -> bPK-Type for SubjectNameID has wrong format.");
+ throw new MOAIDException("service.10",
+ new Object[]{ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING, "bPK-Type for SubjectNameID has wrong format."});
+
+ }
+ }
+
+ String sourcePinType = moasession.getIdentityLink().getIdentificationType();
+ String sourcePinValue = moasession.getIdentityLink().getIdentificationValue();
+ if (sourcePinType.startsWith(Constants.URN_PREFIX_BASEID)) {
+ representativeBPK = new BPKBuilder().buildBPK(sourcePinValue, configTarget);
+
+ } else {
+ Logger.debug("No 'SourcePin' found for representative. "
+ + "Check sourcePinType against target from configuration.");
+ if (!configTarget.equals(sourcePinType)) {
+ Logger.warn("Connect ELGA Mandate-Service FAILED -> Generate bPK for configurated bPK-Type is not possible.");
+ throw new MOAIDException("service.10",
+ new Object[]{ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING, "Generate bPK for configurated bPK-Type is not possible."});
+
+ } else {
+ representativeBPK = sourcePinValue;
+
+ }
+ }
+
+ //TODO: check subjectNameID: as per PVP S-Profile specification,
+ // subjectNameID starts with target postfix (like. GH:xxxxxxxxxxxxx)
+ authnReqConfig.setSubjectNameID(representativeBPK );
+
+ //build and transmit AuthnRequest
+ authnReqBuilder.buildAuthnRequest(pendingReq, authnReqConfig , response);
+
+ //TODO: TODO: add revisionslog entries
+
+ } catch (MetadataProviderException e) {
+ throw new TaskExecutionException(pendingReq, "ELGA Mandate-Service metadata problem", new ELGAMetadataException("service.10",
+ new Object[]{ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING, e.getMessage()}, e));
+
+ } catch (MOAIDException e) {
+ throw new TaskExecutionException(pendingReq, "Build PVP2.1 AuthnRequest for ELGA Mandate-Service FAILED.", e);
+
+ } catch (MessageEncodingException | NoSuchAlgorithmException | SecurityException e) {
+ Logger.error("Build PVP2.1 AuthnRequest for ELGA Mandate-Service FAILED", e);
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ } catch (Exception e) {
+ Logger.error("Build PVP2.1 AuthnRequest for ELGA Mandate-Service FAILED", e);
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ }
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java
new file mode 100644
index 000000000..6deb8eb2b
--- /dev/null
+++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.elgamandates.utils;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.opensaml.saml2.metadata.EntitiesDescriptor;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.RoleDescriptor;
+import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider;
+import org.opensaml.saml2.metadata.provider.MetadataFilter;
+import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.opensaml.xml.XMLObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.ELGAMandatesAuthConstants;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.SimpleMOAMetadataProvider;
+import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.MOASPMetadataSignatureFilter;
+import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.SchemaValidationFilter;
+import at.gv.egovernment.moa.id.saml2.MetadataFilterChain;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+/**
+ * @author tlenz
+ *
+ */
+
+@Service("ELGAMandate_MetadataProvider")
+public class ELGAMandateServiceMetadataProvider extends SimpleMOAMetadataProvider {
+
+ @Autowired AuthConfiguration authConfig;
+
+ private HTTPMetadataProvider metadataProvider = null;
+
+ /* (non-Javadoc)
+ * @see org.opensaml.saml2.metadata.provider.MetadataProvider#requireValidMetadata()
+ */
+ @Override
+ public boolean requireValidMetadata() {
+ if (metadataProvider == null) {
+ Logger.fatal("ELGA Mandate-Service metadata-provider is not initialized");
+ return false;
+
+ } else
+ return metadataProvider.requireValidMetadata();
+ }
+
+ /* (non-Javadoc)
+ * @see org.opensaml.saml2.metadata.provider.MetadataProvider#setRequireValidMetadata(boolean)
+ */
+ @Override
+ public void setRequireValidMetadata(boolean requireValidMetadata) {
+ if (metadataProvider == null) {
+ Logger.fatal("ELGA Mandate-Service metadata-provider is not initialized");
+
+ } else
+ metadataProvider.setRequireValidMetadata(requireValidMetadata);;
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.opensaml.saml2.metadata.provider.MetadataProvider#getMetadataFilter()
+ */
+ @Override
+ public MetadataFilter getMetadataFilter() {
+ if (metadataProvider == null) {
+ Logger.fatal("ELGA Mandate-Service metadata-provider is not initialized");
+ return null;
+
+ } else
+ return metadataProvider.getMetadataFilter();
+ }
+
+ /* (non-Javadoc)
+ * @see org.opensaml.saml2.metadata.provider.MetadataProvider#setMetadataFilter(org.opensaml.saml2.metadata.provider.MetadataFilter)
+ */
+ @Override
+ public void setMetadataFilter(MetadataFilter newFilter) throws MetadataProviderException {
+ Logger.fatal("Set Metadata Filter is not implemented her!");
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.opensaml.saml2.metadata.provider.MetadataProvider#getMetadata()
+ */
+ @Override
+ public XMLObject getMetadata() throws MetadataProviderException {
+ if (metadataProvider == null) {
+ Logger.error("ELGA Mandate-Service metadata-provider is not initialized");
+ throw new MetadataProviderException("ELGA Mandate-Service metadata-provider is not initialized");
+
+ }
+
+ return metadataProvider.getMetadata();
+ }
+
+ /* (non-Javadoc)
+ * @see org.opensaml.saml2.metadata.provider.MetadataProvider#getEntitiesDescriptor(java.lang.String)
+ */
+ @Override
+ public EntitiesDescriptor getEntitiesDescriptor(String name) throws MetadataProviderException {
+ if (metadataProvider == null) {
+ Logger.fatal("ELGA Mandate-Service metadata-provider is not initialized");
+ throw new MetadataProviderException("ELGA Mandate-Service metadata-provider is not initialized");
+
+ } else
+ return metadataProvider.getEntitiesDescriptor(name);
+ }
+
+ /* (non-Javadoc)
+ * @see org.opensaml.saml2.metadata.provider.MetadataProvider#getEntityDescriptor(java.lang.String)
+ */
+ @Override
+ public EntityDescriptor getEntityDescriptor(String entityID) throws MetadataProviderException {
+ if (metadataProvider == null)
+ initialize(entityID);
+
+ try {
+ EntityDescriptor entityDesc = metadataProvider.getEntityDescriptor(entityID);
+ if (entityDesc == null) {
+ Logger.error("ELGA Mandate-Service Client ERROR: No EntityID with "+ entityID);
+ throw new MetadataProviderException("No EntityID with "+ entityID);
+ }
+
+ return entityDesc;
+
+ } catch (MetadataProviderException e) {
+ Logger.error("ELGA Mandate-Service Client ERROR: Metadata extraction FAILED.", e);
+ throw new MetadataProviderException("Metadata extraction FAILED", e);
+
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.opensaml.saml2.metadata.provider.MetadataProvider#getRole(java.lang.String, javax.xml.namespace.QName)
+ */
+ @Override
+ public List<RoleDescriptor> getRole(String entityID, QName roleName) throws MetadataProviderException {
+ if (metadataProvider == null)
+ initialize(entityID);
+
+ return metadataProvider.getRole(entityID, roleName);
+ }
+
+ /* (non-Javadoc)
+ * @see org.opensaml.saml2.metadata.provider.MetadataProvider#getRole(java.lang.String, javax.xml.namespace.QName, java.lang.String)
+ */
+ @Override
+ public RoleDescriptor getRole(String entityID, QName roleName, String supportedProtocol)
+ throws MetadataProviderException {
+ if (metadataProvider == null)
+ initialize(entityID);
+
+ return metadataProvider.getRole(entityID, roleName, supportedProtocol);
+ }
+
+ private void initialize(String entityID) throws MetadataProviderException {
+ Logger.info("Initialize PVP MetadataProvider to connect ELGA Mandate-Service");
+
+ String trustProfileID = authConfig.getBasicMOAIDConfiguration(ELGAMandatesAuthConstants.CONFIG_PROPS_METADATA_TRUSTPROFILE);
+ if (MiscUtil.isEmpty(trustProfileID)) {
+ Logger.error("Create ELGA Mandate-Service Client FAILED: No trustProfileID to verify PVP metadata." );
+ throw new MetadataProviderException("No trustProfileID to verify PVP metadata.");
+ }
+
+ //create metadata validation filter chain
+ MetadataFilterChain filter = new MetadataFilterChain();
+ filter.addFilter(new SchemaValidationFilter(true));
+ filter.addFilter(new MOASPMetadataSignatureFilter(trustProfileID));
+
+ metadataProvider = createNewHTTPMetaDataProvider(entityID,
+ filter,
+ ELGAMandatesAuthConstants.MODULE_NAME_FOR_LOGGING);
+
+ metadataProvider.setRequireValidMetadata(true);
+
+
+ if (metadataProvider == null) {
+ Logger.error("Create ELGA Mandate-Service Client FAILED.");
+ throw new MetadataProviderException("Can not initialize ELGA Mandate-Service metadaa provider.");
+
+ }
+ }
+}
diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandatesCredentialProvider.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandatesCredentialProvider.java
new file mode 100644
index 000000000..c6434b901
--- /dev/null
+++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandatesCredentialProvider.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.elgamandates.utils;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import at.gv.egovernment.moa.id.auth.modules.elgamandates.ELGAMandatesAuthConstants;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider;
+import at.gv.egovernment.moa.util.FileUtils;
+
+/**
+ * @author tlenz
+ *
+ */
+@Service("ELGAMandatesCredentialProvider")
+public class ELGAMandatesCredentialProvider extends AbstractCredentialProvider {
+
+ @Autowired AuthConfiguration authConfig;
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#getKeyStoreFilePath()
+ */
+ @Override
+ public String getKeyStoreFilePath() {
+ return FileUtils.makeAbsoluteURL(
+ authConfig.getBasicMOAIDConfiguration(ELGAMandatesAuthConstants.CONFIG_PROPS_KEYSTORE),
+ authConfig.getRootConfigFileDir());
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#getKeyStorePassword()
+ */
+ @Override
+ public String getKeyStorePassword() {
+ return authConfig.getBasicMOAIDConfiguration(ELGAMandatesAuthConstants.CONFIG_PROPS_KEYSTOREPASSWORD).trim();
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#getMetadataKeyAlias()
+ */
+ @Override
+ public String getMetadataKeyAlias() {
+ return authConfig.getBasicMOAIDConfiguration(
+ ELGAMandatesAuthConstants.CONFIG_PROPS_SIGN_METADATA_ALIAS_PASSWORD).trim();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#getMetadataKeyPassword()
+ */
+ @Override
+ public String getMetadataKeyPassword() {
+ return authConfig.getBasicMOAIDConfiguration(
+ ELGAMandatesAuthConstants.CONFIG_PROPS_SIGN_METADATA_KEY_PASSWORD).trim();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#getSignatureKeyAlias()
+ */
+ @Override
+ public String getSignatureKeyAlias() {
+ return authConfig.getBasicMOAIDConfiguration(
+ ELGAMandatesAuthConstants.CONFIG_PROPS_SIGN_SIGNING_ALIAS_PASSWORD).trim();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#getSignatureKeyPassword()
+ */
+ @Override
+ public String getSignatureKeyPassword() {
+ return authConfig.getBasicMOAIDConfiguration(
+ ELGAMandatesAuthConstants.CONFIG_PROPS_SIGN_SIGNING_KEY_PASSWORD).trim();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#getEncryptionKeyAlias()
+ */
+ @Override
+ public String getEncryptionKeyAlias() {
+ return authConfig.getBasicMOAIDConfiguration(
+ ELGAMandatesAuthConstants.CONFIG_PROPS_ENCRYPTION_ALIAS_PASSWORD).trim();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#getEncryptionKeyPassword()
+ */
+ @Override
+ public String getEncryptionKeyPassword() {
+ return authConfig.getBasicMOAIDConfiguration(
+ ELGAMandatesAuthConstants.CONFIG_PROPS_ENCRYPTION_KEY_PASSWORD).trim();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider#getCredentialName()
+ */
+ @Override
+ public String getFriendlyName() {
+ return "FederatedAuth-SP";
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/pom.xml b/id/server/modules/moa-id-module-ssoTransfer/pom.xml
new file mode 100644
index 000000000..8207fc502
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/pom.xml
@@ -0,0 +1,51 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>MOA.id.server.modules</groupId>
+ <artifactId>moa-id-modules</artifactId>
+ <version>${moa-id-version}</version>
+ </parent>
+ <artifactId>moa-id-module-ssoTransfer</artifactId>
+ <name>MOA-ID_SSO_Transfer_modul</name>
+ <description>MOA-ID modul to transfer Single Sign-On sessions to other devices</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>net.glxn</groupId>
+ <artifactId>qrgen</artifactId>
+ <version>1.4</version>
+ </dependency>
+
+ <!-- JSON JWT implementation -->
+ <dependency>
+ <groupId>com.googlecode.jsontoken</groupId>
+ <artifactId>jsontoken</artifactId>
+ <version>1.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <artifactId>google-collections</artifactId>
+ <groupId>com.google.collections</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ <version>1.52</version>
+ <!-- <scope>provided</scope> -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcpkix-jdk15on</artifactId>
+ <version>1.52</version>
+ </dependency>
+
+ </dependencies>
+
+</project> \ No newline at end of file
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferAuthModuleImpl.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferAuthModuleImpl.java
new file mode 100644
index 000000000..2a2b7bf80
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferAuthModuleImpl.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer;
+
+import at.gv.egovernment.moa.id.auth.modules.AuthModule;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+
+/**
+ * @author tlenz
+ *
+ */
+public class SSOTransferAuthModuleImpl implements AuthModule{
+
+ private int priority = 1;
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getPriority()
+ */
+ @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) {
+ Object restoreSSOSessionObj = context.get("restoreSSOSession");
+ if (restoreSSOSessionObj != null && restoreSSOSessionObj instanceof String) {
+ boolean restoreSSOSession = (boolean) Boolean.parseBoolean((String)restoreSSOSessionObj);
+ if (restoreSSOSession)
+ return "SSOTransferAuthentication";
+
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions()
+ */
+ @Override
+ public String[] getProcessDefinitions() {
+ return new String[] { "classpath:at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferAuthentication.process.xml" };
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferConstants.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferConstants.java
new file mode 100644
index 000000000..cc60bbd20
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferConstants.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer;
+
+/**
+ * @author tlenz
+ *
+ */
+public class SSOTransferConstants {
+
+ public static final String MOASESSION_DATA_HOLDEROFKEY_CERTIFICATE = "holderofkey_cert";
+
+ public static final String DH_PRIME_BASE64 = "AO672PgS9gv0vLTDDISxnZ61aroRrvj53F4CX1ffNNdU+PYPv6ff3pkmuaw3av41tpD/Y0ypcCEPLh39GemNDUnehwBfi6PocHdDGPhTvhan5kYgDoWPWebA9P3Qy3eUdslwU+Eusr0SBhN+Cssw7XZ0nue5IiOjBxdzdijJiojH";
+ public static final String DH_GENERATOR_BASE64 = "NuuDqMxQa7T3XP4H6OFR30imozmM0Eho0na9gXak+Qs+J9uE/3xgHspz9PYO/6Lk2wgeOk42Pk4MHamKVPCLdqztlmEFgKPwHiAwNdNr4PklonLWk5zPSEYDVUt/8IFmK+cu0cPomACo0AfSCSZqdexq0FnFey/5mBjOGPimOJQ=";
+
+ public static final String SERVLET_SSOTRANSFER_GUI = "/TransferSSOSession";
+ public static final String SERVLET_SSOTRANSFER_TO_SMARTPHONE = "/TransmitSSOSession";
+ public static final String SERVLET_SSOTRANSFER_FROM_SMARTPHONE = "/SSOTransferSignalEndpoint";
+
+ public static final String REQ_PARAM_GENERATE_QR = "createQR";
+ public static final String REQ_PARAM_TOKEN = "token";
+
+ public static final String SSOCONTAINER_KEY_TYPE = "type";
+ public static final String SSOCONTAINER_VALUE_TYPE_TRANSER = "TRANSFER";
+ public static final String SSOCONTAINER_VALUE_TYPE_PERSIST = "PERSIST";
+
+ public static final String SSOCONTAINER_KEY_URL = "url";
+
+ public static final String SSOCONTAINER_KEY_DH_PUBKEY = "pubKey";
+ public static final String SSOCONTAINER_KEY_DH_PRIME = "prime";
+ public static final String SSOCONTAINER_KEY_DH_GENERATOR = "generator";
+
+ public static final String SSOCONTAINER_KEY_CSR = "csr";
+
+ public static final String SSOCONTAINER_KEY_VALIDTO = "validTo";
+ public static final String SSOCONTAINER_KEY_ENTITYID = "entityID";
+ public static final String SSOCONTAINER_KEY_USERID = "userID";
+ public static final String SSOCONTAINER_KEY_SESSION = "session";
+ public static final String SSOCONTAINER_KEY_RESULTENDPOINT = "resultEndPoint";
+
+ public static final String FLAG_SSO_SESSION_RESTORED = "ssoRestoredFlag";
+ public static final long CERT_VALIDITY = 700; //2 years
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferSpringResourceProvider.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferSpringResourceProvider.java
new file mode 100644
index 000000000..1c7a9f124
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferSpringResourceProvider.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.components.spring.api.SpringResourceProvider;
+
+/**
+ * @author tlenz
+ *
+ */
+public class SSOTransferSpringResourceProvider implements SpringResourceProvider {
+
+ /* (non-Javadoc)
+ * @see at.gv.egiz.components.spring.api.SpringResourceProvider#getResourcesToLoad()
+ */
+ @Override
+ public Resource[] getResourcesToLoad() {
+ ClassPathResource ssoTransferAuthConfig = new ClassPathResource("/moaid_ssotransfer_auth.beans.xml", SSOTransferSpringResourceProvider.class);
+ return new Resource[] {ssoTransferAuthConfig};
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egiz.components.spring.api.SpringResourceProvider#getPackagesToScan()
+ */
+ @Override
+ public String[] getPackagesToScan() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egiz.components.spring.api.SpringResourceProvider#getName()
+ */
+ @Override
+ public String getName() {
+ return "SSO Transfer Module";
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/Pair.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/Pair.java
new file mode 100644
index 000000000..47351b2bd
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/Pair.java
@@ -0,0 +1,21 @@
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer.data;
+
+import java.io.Serializable;
+
+public class Pair<F,S> implements Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1677989418252218345L;
+
+ private F l;
+ private S r;
+ public Pair(F l, S r){
+ this.l = l;
+ this.r = r;
+ }
+ public F getF(){ return l; }
+ public S getS(){ return r; }
+ public void setF(F l){ this.l = l; }
+ public void setS(S r){ this.r = r; }
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferAuthenticationData.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferAuthenticationData.java
new file mode 100644
index 000000000..17e88e381
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferAuthenticationData.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer.data;
+
+import java.security.cert.CertificateEncodingException;
+import java.util.Date;
+import java.util.List;
+
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.auth.data.IdentityLink;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
+import at.gv.egovernment.moa.id.data.AuthenticationRole;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.MISMandate;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * @author tlenz
+ *
+ */
+public class SSOTransferAuthenticationData implements IAuthData {
+
+ private AuthenticationSession authSession = null;
+ boolean isIDPPrivateService = true;
+
+ public SSOTransferAuthenticationData(AuthConfiguration authConfig, AuthenticationSession authSession) throws ConfigurationException {
+ this.authSession = authSession;
+ String domainIdentifier = authConfig.getSSOTagetIdentifier().trim();
+ isIDPPrivateService = domainIdentifier.startsWith(MOAIDAuthConstants.PREFIX_WPBK);
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getIssueInstant()
+ */
+ @Override
+ public Date getIssueInstant() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getIssuer()
+ */
+ @Override
+ public String getIssuer() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#isBusinessService()
+ */
+ @Override
+ public boolean isBusinessService() {
+ return this.isIDPPrivateService;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#isSsoSession()
+ */
+ @Override
+ public boolean isSsoSession() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#isInterfederatedSSOSession()
+ */
+ @Override
+ public boolean isInterfederatedSSOSession() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#isUseMandate()
+ */
+ @Override
+ public boolean isUseMandate() {
+ return this.authSession.getUseMandate();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getFamilyName()
+ */
+ @Override
+ public String getFamilyName() {
+ return this.authSession.getIdentityLink().getFamilyName();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getGivenName()
+ */
+ @Override
+ public String getGivenName() {
+ return this.authSession.getIdentityLink().getGivenName();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getDateOfBirth()
+ */
+ @Override
+ public Date getDateOfBirth() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getFormatedDateOfBirth()
+ */
+ @Override
+ public String getFormatedDateOfBirth() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getBPK()
+ */
+ @Override
+ public String getBPK() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getBPKType()
+ */
+ @Override
+ public String getBPKType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getSsoSessionValidTo()
+ */
+ @Override
+ public Date getSsoSessionValidTo() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getInterfederatedIDP()
+ */
+ @Override
+ public String getInterfederatedIDP() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getIdentificationValue()
+ */
+ @Override
+ public String getIdentificationValue() {
+ return this.authSession.getIdentityLink().getIdentificationValue();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getIdentificationType()
+ */
+ @Override
+ public String getIdentificationType() {
+ return this.authSession.getIdentityLink().getIdentificationType();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getBkuURL()
+ */
+ @Override
+ public String getBkuURL() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getEncbPKList()
+ */
+ @Override
+ public List<String> getEncbPKList() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getIdentityLink()
+ */
+ @Override
+ public IdentityLink getIdentityLink() {
+ return this.authSession.getIdentityLink();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getSignerCertificate()
+ */
+ @Override
+ public byte[] getSignerCertificate() {
+ try {
+ return this.authSession.getSignerCertificate().getEncoded();
+
+ } catch (CertificateEncodingException e) {
+ Logger.error("SSO-Transfer: SignerCertificate encoding FAILED.", e);
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getAuthBlock()
+ */
+ @Override
+ public String getAuthBlock() {
+ return this.authSession.getAuthBlock();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getPvpAttribute_OU()
+ */
+ @Override
+ public String getPvpAttribute_OU() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getAuthenticationRoles()
+ */
+ @Override
+ public List<AuthenticationRole> getAuthenticationRoles() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#isPublicAuthority()
+ */
+ @Override
+ public boolean isPublicAuthority() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getPublicAuthorityCode()
+ */
+ @Override
+ public String getPublicAuthorityCode() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#isQualifiedCertificate()
+ */
+ @Override
+ public boolean isQualifiedCertificate() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getMISMandate()
+ */
+ @Override
+ public MISMandate getMISMandate() {
+ return this.authSession.getMISMandate();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getMandate()
+ */
+ @Override
+ public Element getMandate() {
+ return this.authSession.getMISMandate().getMandateDOM();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getMandateReferenceValue()
+ */
+ @Override
+ public String getMandateReferenceValue() {
+ return this.authSession.getMandateReferenceValue();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getQAALevel()
+ */
+ @Override
+ public String getQAALevel() {
+ return this.authSession.getQAALevel();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getSessionIndex()
+ */
+ @Override
+ public String getSessionIndex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getNameID()
+ */
+ @Override
+ public String getNameID() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getNameIDFormat()
+ */
+ @Override
+ public String getNameIDFormat() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#isForeigner()
+ */
+ @Override
+ public boolean isForeigner() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getCcc()
+ */
+ @Override
+ public String getCcc() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getEIDASQAALevel()
+ */
+ @Override
+ public String getEIDASQAALevel() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.data.IAuthData#getGenericData(java.lang.String, java.lang.Class)
+ */
+ @Override
+ public <T> T getGenericData(String key, Class<T> clazz) {
+ return this.authSession.getGenericDataFromSession(key, clazz);
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferContainer.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferContainer.java
new file mode 100644
index 000000000..eecf03b71
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferContainer.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer.data;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.security.PrivateKey;
+
+import javax.crypto.spec.DHPublicKeySpec;
+
+/**
+ * @author tlenz
+ *
+ */
+public class SSOTransferContainer implements Serializable {
+
+ private static final long serialVersionUID = 3762458954168085854L;
+
+ private String authURL = null;
+ private String tokkenID = null;
+ private String moaSessionID = null;
+
+ //DH parameters
+ private PrivateKey dh_privKey;
+ private BigInteger dh_pubKey;
+ private BigInteger dh_prime;
+ private BigInteger dh_generator;
+
+
+ /**
+ * @return the authURL
+ */
+ public String getAuthURL() {
+ return authURL;
+ }
+ /**
+ * @param authURL the authURL to set
+ */
+ public void setAuthURL(String authURL) {
+ this.authURL = authURL;
+ }
+ /**
+ * @return the tokkenID
+ */
+ public String getTokkenID() {
+ return tokkenID;
+ }
+ /**
+ * @param tokkenID the tokkenID to set
+ */
+ public void setTokkenID(String tokkenID) {
+ this.tokkenID = tokkenID;
+ }
+ /**
+ * @return the moaSessionID
+ */
+ public String getMoaSessionID() {
+ return moaSessionID;
+ }
+ /**
+ * @param moaSessionID the moaSessionID to set
+ */
+ public void setMoaSessionID(String moaSessionID) {
+ this.moaSessionID = moaSessionID;
+ }
+ /**
+ * @return the dhParams
+ */
+ public Pair<DHPublicKeySpec, PrivateKey> getDhParams() {
+ return new Pair<DHPublicKeySpec, PrivateKey>(new DHPublicKeySpec(this.dh_pubKey,
+ this.dh_prime,
+ this.dh_generator), this.dh_privKey);
+ }
+ /**
+ * @param dhParams the dhParams to set
+ */
+ public void setDhParams(Pair<DHPublicKeySpec, PrivateKey> dhParams) {
+ this.dh_privKey = dhParams.getS();
+
+ this.dh_pubKey = dhParams.getF().getY();
+ this.dh_prime = dhParams.getF().getP();
+ this.dh_generator = dhParams.getF().getG();
+ }
+
+
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferOnlineApplication.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferOnlineApplication.java
new file mode 100644
index 000000000..4ba2e1a01
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferOnlineApplication.java
@@ -0,0 +1,453 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer.data;
+
+import java.security.PrivateKey;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;
+import at.gv.egovernment.moa.id.config.auth.data.SAML1ConfigurationParameters;
+import at.gv.egovernment.moa.id.config.stork.CPEPS;
+import at.gv.egovernment.moa.id.config.stork.StorkAttribute;
+import at.gv.egovernment.moa.id.config.stork.StorkAttributeProviderPlugin;
+
+/**
+ * @author tlenz
+ *
+ */
+public class SSOTransferOnlineApplication implements IOAAuthParameters {
+
+ public SSOTransferOnlineApplication() {
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBusinessService()
+ */
+ @Override
+ public boolean getBusinessService() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#useSSO()
+ */
+ @Override
+ public boolean useSSO() {
+ return true;
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBKUURL()
+ */
+ @Override
+ public List<String> getBKUURL() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getFullConfiguration()
+ */
+ @Override
+ public Map<String, String> getFullConfiguration() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getConfigurationValue(java.lang.String)
+ */
+ @Override
+ public String getConfigurationValue(String key) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getFriendlyName()
+ */
+ @Override
+ public String getFriendlyName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getPublicURLPrefix()
+ */
+ @Override
+ public String getPublicURLPrefix() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getOaType()
+ */
+ @Override
+ public String getOaType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getTarget()
+ */
+ @Override
+ public String getTarget() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getTargetFriendlyName()
+ */
+ @Override
+ public String getTargetFriendlyName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isInderfederationIDP()
+ */
+ @Override
+ public boolean isInderfederationIDP() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isSTORKPVPGateway()
+ */
+ @Override
+ public boolean isSTORKPVPGateway() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getIdentityLinkDomainIdentifier()
+ */
+ @Override
+ public String getIdentityLinkDomainIdentifier() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getKeyBoxIdentifier()
+ */
+ @Override
+ public String getKeyBoxIdentifier() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getSAML1Parameter()
+ */
+ @Override
+ public SAML1ConfigurationParameters getSAML1Parameter() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getTemplateURL()
+ */
+ @Override
+ public List<String> getTemplateURL() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getAditionalAuthBlockText()
+ */
+ @Override
+ public String getAditionalAuthBlockText() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBKUURL(java.lang.String)
+ */
+ @Override
+ public String getBKUURL(String bkutype) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#useSSOQuestion()
+ */
+ @Override
+ public boolean useSSOQuestion() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getMandateProfiles()
+ */
+ @Override
+ public List<String> getMandateProfiles() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getIdentityLinkDomainIdentifierType()
+ */
+ @Override
+ public String getIdentityLinkDomainIdentifierType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isShowMandateCheckBox()
+ */
+ @Override
+ public boolean isShowMandateCheckBox() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isOnlyMandateAllowed()
+ */
+ @Override
+ public boolean isOnlyMandateAllowed() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isShowStorkLogin()
+ */
+ @Override
+ public boolean isShowStorkLogin() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getFormCustomizaten()
+ */
+ @Override
+ public Map<String, String> getFormCustomizaten() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getQaaLevel()
+ */
+ @Override
+ public Integer getQaaLevel() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isRequireConsentForStorkAttributes()
+ */
+ @Override
+ public boolean isRequireConsentForStorkAttributes() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getRequestedSTORKAttributes()
+ */
+ @Override
+ public Collection<StorkAttribute> getRequestedSTORKAttributes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBKUSelectionTemplate()
+ */
+ @Override
+ public byte[] getBKUSelectionTemplate() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getSendAssertionTemplate()
+ */
+ @Override
+ public byte[] getSendAssertionTemplate() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getPepsList()
+ */
+ @Override
+ public Collection<CPEPS> getPepsList() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getIDPAttributQueryServiceURL()
+ */
+ @Override
+ public String getIDPAttributQueryServiceURL() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isInboundSSOInterfederationAllowed()
+ */
+ @Override
+ public boolean isInboundSSOInterfederationAllowed() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isInterfederationSSOStorageAllowed()
+ */
+ @Override
+ public boolean isInterfederationSSOStorageAllowed() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isOutboundSSOInterfederationAllowed()
+ */
+ @Override
+ public boolean isOutboundSSOInterfederationAllowed() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isTestCredentialEnabled()
+ */
+ @Override
+ public boolean isTestCredentialEnabled() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getTestCredentialOIDs()
+ */
+ @Override
+ public List<String> getTestCredentialOIDs() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isUseIDLTestTrustStore()
+ */
+ @Override
+ public boolean isUseIDLTestTrustStore() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isUseAuthBlockTestTestStore()
+ */
+ @Override
+ public boolean isUseAuthBlockTestTestStore() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBPKDecBpkDecryptionKey()
+ */
+ @Override
+ public PrivateKey getBPKDecBpkDecryptionKey() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isPassivRequestUsedForInterfederation()
+ */
+ @Override
+ public boolean isPassivRequestUsedForInterfederation() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isPerformLocalAuthenticationOnInterfederationError()
+ */
+ @Override
+ public boolean isPerformLocalAuthenticationOnInterfederationError() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getStorkAPs()
+ */
+ @Override
+ public Collection<StorkAttributeProviderPlugin> getStorkAPs() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getReversionsLoggingEventCodes()
+ */
+ @Override
+ public List<Integer> getReversionsLoggingEventCodes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isRemovePBKFromAuthBlock()
+ */
+ @Override
+ public boolean isRemovePBKFromAuthBlock() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java
new file mode 100644
index 000000000..80c2663fb
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java
@@ -0,0 +1,626 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer.servlet;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.math.BigInteger;
+import java.net.URL;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.Date;
+
+import javax.crypto.KeyAgreement;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPublicKeySpec;
+import javax.security.cert.CertificateException;
+import javax.security.cert.X509Certificate;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.VelocityContext;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.ContentVerifierProvider;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import org.bouncycastle.pkcs.PKCS10CertificationRequest;
+import org.bouncycastle.pkcs.PKCSException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.exception.ParseException;
+import at.gv.egovernment.moa.id.auth.exception.SessionDataStorageException;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.SSOTransferConstants;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.data.Pair;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.data.SSOTransferContainer;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.utils.GUIUtils;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.utils.SSOContainerUtils;
+import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.moduls.SSOManager;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.IDPCredentialProvider;
+import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage;
+import at.gv.egovernment.moa.id.storage.ITransactionStorage;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.id.util.Random;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.FileUtils;
+import at.gv.egovernment.moa.util.MiscUtil;
+import net.glxn.qrgen.QRCode;
+import net.glxn.qrgen.image.ImageType;
+
+
+
+/**
+ * @author tlenz
+ *
+ */
+//@WebServlet(name = "SSOTransferGUI", value = "/TransferSSOSession")
+@Controller
+public class SSOTransferServlet{
+
+ private static final long transmisionTimeOut = 90 * 1000; // default 90 secundes
+
+ @Autowired SSOManager ssomanager;
+ @Autowired IAuthenticationSessionStoreage authenticationSessionStorage;
+ @Autowired SSOContainerUtils ssoTransferUtils;
+ @Autowired ITransactionStorage transactionStorage;
+ @Autowired IDPCredentialProvider idpCredentials;
+ @Autowired AuthConfiguration authConfig;
+
+ public SSOTransferServlet() {
+ super();
+ Logger.debug("Registering servlet " + getClass().getName()
+ + " with mapping {'/TransferSSOSession','/TransmitSSOSession'}"
+ + " Development-EndPoints: {'/TestTransferSSOSession','/TestTransmitSSOSession'}.");
+ }
+
+ /**
+ * Only for development and debugging
+ * This methode create template QR and for the template service
+ *
+ * @param req
+ * @param resp
+ * @throws IOException
+ */
+ @RequestMapping(value = { "/TestTransferSSOSession"
+ },
+ method = {RequestMethod.GET})
+ public void testTransferSSOSessionGUIWithoutAuthentication(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ try {
+ VelocityContext context = new VelocityContext();
+
+ //create first step of SSO Transfer GUI
+ String authURL = HTTPUtils.extractAuthURLFromRequest(req);
+ if (!AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix().contains(authURL)) {
+ Logger.warn("Requested URL is not allowed.");;
+ resp.sendError(500, "Requested URL is not allowed.");
+
+ }
+
+ internalCreateQRCodeForTransfer(resp, authURL,
+ "123456", "/TestTransmitSSOSession", context);
+
+ } catch (MOAIDException | MOADatabaseException e) {
+ e.printStackTrace();
+ resp.sendError(500, e.getMessage());
+
+ } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {
+ e.printStackTrace();
+ resp.sendError(500, e.getMessage());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ resp.sendError(500, e.getMessage());
+ }
+ }
+
+ /**
+ * Only for development and debugging
+ * This methode transfer personal information to smartphone
+ *
+ * @param req
+ * @param resp
+ * @throws IOException
+ */
+ @RequestMapping(value = { "/TestTransmitSSOSession"
+ },
+ method = {RequestMethod.GET, RequestMethod.POST})
+ public void testTransferToPhone(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ Logger.debug("Receive " + this.getClass().getName() + " request");
+ Object tokenObj = req.getParameter(SSOTransferConstants.REQ_PARAM_TOKEN);
+ if (tokenObj != null && tokenObj instanceof String) {
+ String token = (String)tokenObj;
+ try {
+ SSOTransferContainer container = transactionStorage.get(token, SSOTransferContainer.class, transmisionTimeOut * 1000);
+ if (container != null) {
+ AuthenticationSession moaSession = new AuthenticationSession("123456", new Date());
+
+ URL idlURL = new URL(FileUtils.makeAbsoluteURL(
+ authConfig.getMonitoringTestIdentityLinkURL(),
+ authConfig.getRootConfigFileDir()));
+ InputStream idlstream = idlURL.openStream();
+ moaSession.setIdentityLink(new IdentityLinkAssertionParser(idlstream).parseIdentityLink());
+ internalTransferPersonalInformation(req, resp, container, moaSession, true);
+
+ } else {
+ Logger.info("Servlet " + getClass().getName() + " receive a token:" +
+ token + ", which references an empty data object.");
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Empty data object.");
+
+ }
+
+ } catch (MOADatabaseException e) {
+ Logger.info("Servlet " + getClass().getName() + " receive a token:" +
+ token + ", which is UNKNOWN.");
+ resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Transfer token is UNKOWN:");
+
+
+ } catch (AuthenticationException e) {
+ Logger.info("Servlet " + getClass().getName() + " receive a token:" +
+ token + ", which has a timeout.");
+ resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Single Sign-On session transfer token is not valid any more.");
+
+ } catch (OperatorCreationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (CredentialsNotAvailableException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (PKCSException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (CertificateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (InvalidKeyException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (NoSuchAlgorithmException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (InvalidKeySpecException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (SessionDataStorageException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+ } catch (ParseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+
+ } else {
+ Logger.info("Servlet " + getClass().getName() + " receive a NOT valid request.");
+ resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Request not valid.");
+
+ }
+
+ }
+
+
+ @RequestMapping(value = { "/TransmitSSOSession"
+ },
+ method = {RequestMethod.GET})
+ public void transferToPhone(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ Logger.debug("Receive " + this.getClass().getName() + " request");
+
+ Object tokenObj = req.getParameter(SSOTransferConstants.REQ_PARAM_TOKEN);
+ if (tokenObj != null && tokenObj instanceof String) {
+ String token = (String)tokenObj;
+ try {
+ SSOTransferContainer container = transactionStorage.get(token, SSOTransferContainer.class, transmisionTimeOut);
+ if (container != null) {
+ AuthenticationSession moaSession = authenticationSessionStorage.getSession(container.getMoaSessionID());
+ if (moaSession != null) {
+ internalTransferPersonalInformation(req, resp, container, moaSession, false);
+
+
+ } else {
+ Logger.info("Servlet " + getClass().getName() + " receive a token:" +
+ token + ", but the corresponding MOASession is empty");
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "No MOASession.");
+
+ }
+
+ } else {
+ Logger.info("Servlet " + getClass().getName() + " receive a token:" +
+ token + ", which references an empty data object.");
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Empty data object.");
+
+ }
+
+ } catch (MOADatabaseException e) {
+ Logger.info("Servlet " + getClass().getName() + " receive a token:" +
+ token + ", which is UNKNOWN.");
+ resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Transfer token is UNKOWN:");
+
+
+ } catch (AuthenticationException e) {
+ Logger.info("Servlet " + getClass().getName() + " receive a token:" +
+ token + ", which has a timeout.");
+ resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Single Sign-On session transfer token is not valid any more.");
+
+ } catch (OperatorCreationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (CredentialsNotAvailableException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (PKCSException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (CertificateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (InvalidKeyException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (NoSuchAlgorithmException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (InvalidKeySpecException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (SessionDataStorageException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+
+ } else {
+ Logger.info("Servlet " + getClass().getName() + " receive a NOT valid request.");
+ resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Request not valid.");
+
+ }
+
+
+ }
+
+
+ @RequestMapping(value = { "/TransferSSOSession"
+ },
+ method = {RequestMethod.GET, RequestMethod.POST})
+ public void transferSSOSessionGUI(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ //search SSO session
+ String ssoid = ssomanager.getSSOSessionID(req);
+
+ VelocityContext context = new VelocityContext();
+
+ try {
+ if (ssomanager.isValidSSOSession(ssoid, null)) {
+ //Object createQRObj = req.getParameter(SSOTransferConstants.REQ_PARAM_GENERATE_QR);
+
+ //create first step of SSO Transfer GUI
+ String authURL = HTTPUtils.extractAuthURLFromRequest(req);
+ if (!AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix().
+ contains(authURL)) {
+ Logger.warn("Requested URL is not allowed.");;
+ resp.sendError(500, "Requested URL is not allowed.");
+
+ }
+
+ String moaSessionID = authenticationSessionStorage.getMOASessionSSOID(ssoid);
+ if (MiscUtil.isNotEmpty(moaSessionID)) {
+ AuthenticationSession authSession = authenticationSessionStorage.getSession(moaSessionID);
+ if(authSession != null) {
+ internalCreateQRCodeForTransfer(resp, authURL,
+ authSession.getSessionID(),
+ SSOTransferConstants.SERVLET_SSOTRANSFER_TO_SMARTPHONE, context);
+
+ return;
+ }
+ }
+
+ }
+
+ context.put("errorMsg",
+ "No active Single Sign-On session found! SSO Session transfer is not possible.");
+ GUIUtils.printSSOTransferGUI(context, resp);
+
+ } catch (MOAIDException | MOADatabaseException e) {
+ e.printStackTrace();
+ resp.sendError(500, e.getMessage());
+
+ } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {
+ e.printStackTrace();
+ resp.sendError(500, e.getMessage());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ resp.sendError(500, e.getMessage());
+ }
+ }
+
+ private void internalTransferPersonalInformation(HttpServletRequest req, HttpServletResponse resp,
+ SSOTransferContainer container, AuthenticationSession moaSession, boolean developmentMode) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, OperatorCreationException, CredentialsNotAvailableException, PKCSException, CertificateException, SessionDataStorageException {
+ JsonObject receivedData = getJSONObjectFromPostMessage(req, developmentMode);
+
+ if (receivedData == null) {
+ Logger.warn("No data received");
+ throw new IOException("No data received");
+
+ }
+
+ //TODO: check if needed
+ //JsonObject reveivedSession = receivedData.get("session").getAsJsonObject();
+
+ String mobilePubKeyBase64 = receivedData.get(
+ SSOTransferConstants.SSOCONTAINER_KEY_DH_PUBKEY).getAsString();
+ String mobileCSRBase64 = receivedData.get(
+ SSOTransferConstants.SSOCONTAINER_KEY_CSR).getAsString();
+
+ Logger.trace("Receive PubKey:" +mobilePubKeyBase64 +
+ " | CSR:" + mobileCSRBase64);
+
+ //finish DH key agreement
+ BigInteger mobilePubKey = new BigInteger(Base64Utils.decode(mobilePubKeyBase64, false));
+ DHPublicKeySpec mobilePubKeySpec = new DHPublicKeySpec(mobilePubKey,
+ container.getDhParams().getF().getP(),
+ container.getDhParams().getF().getG());
+ byte[] sharedSecret = getSecret(mobilePubKeySpec, container.getDhParams().getS());
+
+ Logger.debug("Finished Diffie-Hellman key exchange. --> Starting CSR decryption ...");
+ //TODO decrypt CSR
+ byte[] decryptedCSR = Base64Utils.decode(mobileCSRBase64, true);
+
+
+ //generate certificate from CSR
+ X509Certificate mobileCert = signCSRWithMOAKey(decryptedCSR);
+
+ moaSession.setGenericDataToSession(
+ SSOTransferConstants.MOASESSION_DATA_HOLDEROFKEY_CERTIFICATE,
+ mobileCert.getEncoded());
+
+ //generate assertion
+ Date now = new Date();
+ String personInformationToTransfer =
+ ssoTransferUtils.generateSignedAndEncryptedSSOContainer(
+ container.getAuthURL(), moaSession, now);
+
+ resp.setContentType("text/html;charset=UTF-8");
+ PrintWriter out = new PrintWriter(resp.getOutputStream());
+ out.print(personInformationToTransfer);
+ out.flush();
+ return;
+
+ }
+
+ private void internalCreateQRCodeForTransfer(HttpServletResponse resp, String authURL,
+ String moaSessionID, String servletEndPoint, VelocityContext context) throws Exception {
+ SSOTransferContainer container = new SSOTransferContainer();
+ String token = Random.nextRandom();
+
+ container.setAuthURL(authURL);
+ container.setTokkenID(token);
+ container.setMoaSessionID(moaSessionID);
+
+ //build Diffie-Hellman parameter for Data transfer
+ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+
+ //TODO: implement worker-thread to generate new parameters every day
+ //generate new DH parameters
+ //SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG-SP80090", "IAIK");
+ //AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator.getInstance("DiffieHellman", "BC");
+ //paramGen.init(1024, secureRandom ); // number of bits
+ //AlgorithmParameters params = paramGen.generateParameters();
+ //DHParameterSpec dhSpec = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class);
+ //DHParameterSpec dhSpec = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class);
+
+ //use predefined parameters
+ BigInteger prime = new BigInteger(Base64Utils.decode(SSOTransferConstants.DH_PRIME_BASE64, false));
+ BigInteger generator = new BigInteger(Base64Utils.decode(SSOTransferConstants.DH_GENERATOR_BASE64, false));
+ DHParameterSpec dhSpec = new DHParameterSpec(prime, generator, 1024);
+
+ Pair<DHPublicKeySpec, PrivateKey> dhKeyIDP = createSpecificKey(dhSpec.getP(), dhSpec.getG());
+ container.setDhParams(dhKeyIDP);
+
+ //store container
+ transactionStorage.put(token, container);
+
+ //build QR code
+ String containerURL = authURL
+ + servletEndPoint
+ + "?"+ SSOTransferConstants.REQ_PARAM_TOKEN + "=" + token;
+
+ JsonObject qrResult = new JsonObject();
+ qrResult.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_TYPE,
+ SSOTransferConstants.SSOCONTAINER_VALUE_TYPE_PERSIST);
+ qrResult.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_URL,
+ containerURL);
+
+ //add DH parameters
+ qrResult.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_DH_PUBKEY,
+ Base64Utils.encode(dhKeyIDP.getF().getY().toByteArray()));
+ qrResult.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_DH_PRIME,
+ Base64Utils.encode(dhKeyIDP.getF().getP().toByteArray()));
+ qrResult.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_DH_GENERATOR,
+ Base64Utils.encode(dhKeyIDP.getF().getG().toByteArray()));
+
+ ByteArrayOutputStream qrStream =
+ QRCode.from(qrResult.toString()).to(ImageType.GIF).withSize(350, 350).stream();
+ String base64EncodedImage = Base64Utils.encode(qrStream.toByteArray());
+ context.put("QRImage", base64EncodedImage);
+
+ context.put("successMsg", "Scan the QR-Code with your <i>SSO-Transfer App</i> to start the transfer operation.");
+
+ GUIUtils.printSSOTransferGUI(context, resp);
+
+
+ }
+
+ private X509Certificate signCSRWithMOAKey(byte[] inputCSR) throws IOException, OperatorCreationException, PKCSException, CredentialsNotAvailableException, CertificateException {
+ PKCS10CertificationRequest csr = new PKCS10CertificationRequest(inputCSR);
+
+ //validate CSR request
+ ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(
+ new BouncyCastleProvider()).build(csr.getSubjectPublicKeyInfo());
+ csr.isSignatureValid(verifier);
+
+ //build certificate with CSR
+ X500Name issuer = new X500Name("CN=IDP");
+ BigInteger serial = new BigInteger(32, new SecureRandom());
+ Date from = new Date();
+ Date to = new Date(System.currentTimeMillis() + (SSOTransferConstants.CERT_VALIDITY * 86400000L));
+ X509v3CertificateBuilder certgen = new X509v3CertificateBuilder(issuer, serial, from, to, csr.getSubject(), csr.getSubjectPublicKeyInfo());
+ certgen.addExtension(Extension.basicConstraints, false, new BasicConstraints(false));
+ //certgen.addExtension(Extension.subjectKeyIdentifier, false, SubjectKeyIdentifier.getInstance(csr.getSubjectPublicKeyInfo()));
+
+ //build signer
+ ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withRSA").build(idpCredentials.getIDPAssertionSigningCredential().getPrivateKey());
+
+ //sign certificate
+ X509CertificateHolder x509CertificateHolder = certgen.build(sigGen);
+
+ return X509Certificate.getInstance(x509CertificateHolder.getEncoded());
+
+
+ }
+
+ private static byte[] getSecret(DHPublicKeySpec kspectrans, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
+ KeyAgreement aKeyAgree = KeyAgreement.getInstance("DiffieHellman");
+ aKeyAgree.init(privateKey);
+
+ KeyFactory kfactory = KeyFactory.getInstance("DiffieHellman");
+ PublicKey pub = kfactory.generatePublic(kspectrans);
+ aKeyAgree.doPhase(pub, true);
+
+ byte[] secretKey = aKeyAgree.generateSecret();
+ return secretKey;
+
+ }
+
+ private JsonObject getJSONObjectFromPostMessage(HttpServletRequest req, boolean developmentMode) {
+ //read POST request
+ StringBuffer sb = new StringBuffer();
+ String receivedPostMessage = null;
+
+ try {
+ BufferedReader reader = req.getReader();
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+
+ receivedPostMessage = sb.toString();
+
+ } catch (IOException e) {
+ Logger.warn("Received POST-message produce an ERROR.", e);
+ Logger.info("Msg: " + receivedPostMessage);
+
+ }
+
+ JsonParser parser = new JsonParser();
+ JsonObject receivedData = null;
+ if (MiscUtil.isNotEmpty(receivedPostMessage))
+ receivedData = (JsonObject) parser.parse(sb.toString());
+
+ else if (developmentMode && MiscUtil.isNotEmpty(req.getParameter("blob"))) {
+ receivedData = (JsonObject) parser.parse(req.getParameter("blob"));
+
+ }
+
+ return receivedData;
+
+ }
+
+ private Pair<DHPublicKeySpec, PrivateKey> createSpecificKey(BigInteger p, BigInteger g) throws Exception {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("DiffieHellman");
+
+ DHParameterSpec param = new DHParameterSpec(p, g);
+ kpg.initialize(param);
+ KeyPair kp = kpg.generateKeyPair();
+
+ KeyFactory kfactory = KeyFactory.getInstance("DiffieHellman");
+
+ Pair<DHPublicKeySpec, PrivateKey> pair = new Pair<DHPublicKeySpec, PrivateKey>(
+ (DHPublicKeySpec) kfactory.getKeySpec(kp.getPublic(), DHPublicKeySpec.class), kp.getPrivate());
+ return pair;
+
+ }
+
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferSignalServlet.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferSignalServlet.java
new file mode 100644
index 000000000..0b3bd892a
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferSignalServlet.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import at.gv.egovernment.moa.id.advancedlogging.TransactionIDUtils;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.servlet.AbstractProcessEngineSignalController;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * @author tlenz
+ *
+ */
+@Controller
+public class SSOTransferSignalServlet extends AbstractProcessEngineSignalController {
+ public SSOTransferSignalServlet() {
+ super();
+ Logger.debug("Registering servlet " + getClass().getName() + " with mappings '/SSOTransferEndpoint'.");
+
+ }
+
+ @RequestMapping(value = { "/SSOTransferSignalEndpoint"
+ },
+ method = {RequestMethod.POST, RequestMethod.GET})
+ public void performSSOTransfer(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ signalProcessManagement(req, resp);
+
+ }
+
+ @Override
+ protected void signalProcessManagement(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ String pendingRequestID = StringEscapeUtils.escapeHtml(getPendingRequestId(req));
+
+ try {
+ if (pendingRequestID == null) {
+ throw new IllegalStateException("Unable to determine MOA pending-request id.");
+ }
+
+ IRequest pendingReq = requestStorage.getPendingRequest(pendingRequestID);
+ if (pendingReq == null) {
+ Logger.info("No PendingRequest with Id: " + pendingRequestID + " Maybe, a transaction timeout occure.");
+ throw new MOAIDException("auth.28", new Object[]{pendingRequestID});
+
+ }
+
+ //add transactionID and unique sessionID to Logger
+ TransactionIDUtils.setSessionId(pendingReq.getUniqueSessionIdentifier());
+ TransactionIDUtils.setTransactionId(pendingReq.getUniqueTransactionIdentifier());
+
+ // process instance is mandatory
+ if (pendingReq.getProcessInstanceId() == null) {
+ throw new IllegalStateException("MOA session does not provide process instance id.");
+ }
+
+ // wake up next task
+ processEngine.signal(pendingReq);
+
+ } catch (Exception ex) {
+ handleError(null, ex, req, resp, pendingRequestID);
+
+ } finally {
+ //MOASessionDBUtils.closeSession();
+ TransactionIDUtils.removeTransactionId();
+ TransactionIDUtils.removeSessionId();
+
+ }
+
+
+ }
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/task/InitializeRestoreSSOSessionTask.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/task/InitializeRestoreSSOSessionTask.java
new file mode 100644
index 000000000..e84c60ec5
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/task/InitializeRestoreSSOSessionTask.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer.task;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.VelocityContext;
+import org.springframework.stereotype.Component;
+
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.utils.GUIUtils;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * @author tlenz
+ *
+ */
+@Component("InitializeRestoreSSOSessionTask")
+public class InitializeRestoreSSOSessionTask extends AbstractAuthServletTask {
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext,
+ HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+
+ try {
+ //create first step of SSO Transfer GUI
+ String authURL = HTTPUtils.extractAuthURLFromRequest(request);
+ if (!AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix().
+ contains(authURL)) {
+ Logger.warn("Requested URL is not allowed.");;
+ response.sendError(500, "Requested URL is not allowed.");
+
+ }
+
+ VelocityContext context = GUIUtils.buildSSOTransferGUI(authURL, pendingReq.getRequestID());
+ GUIUtils.printSSOTransferGUI(context, response);
+
+
+ } catch (WrongParametersException | AuthenticationException e) {
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ } catch (Exception e) {
+ Logger.error(this.getClass().getName() + " has an interal Error.", e);
+ throw new TaskExecutionException(pendingReq, this.getClass().getName() + " has an interal Error.", e);
+
+ }
+
+
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/task/RestoreSSOSessionTask.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/task/RestoreSSOSessionTask.java
new file mode 100644
index 000000000..1d37b916c
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/task/RestoreSSOSessionTask.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer.task;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.velocity.VelocityContext;
+import org.joda.time.DateTime;
+import org.opensaml.saml2.core.Response;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.SSOTransferConstants;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.utils.GUIUtils;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.utils.SSOContainerUtils;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+/**
+ * @author tlenz
+ *
+ */
+@Component("RestoreSSOSessionTask")
+public class RestoreSSOSessionTask extends AbstractAuthServletTask {
+
+ @Autowired SSOContainerUtils ssoTransferUtils;
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext,
+ HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+
+ Logger.debug("Receive " + this.getClass().getName() + " request");
+
+ StringBuffer sb = new StringBuffer();
+ String receivedPostMessage = null;
+ String authURL =null;
+ try {
+ BufferedReader reader = request.getReader();
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+
+ receivedPostMessage = sb.toString();
+
+ } catch (IOException e) {
+ Logger.warn("Received POST-message produce an ERROR.", e);
+
+ }
+
+ //session is valid --> load MOASession object
+ try {
+ defaultTaskInitialization(request, executionContext);
+
+ } catch (MOAIDException | MOADatabaseException e1) {
+ Logger.error("Database Error! MOASession is not stored!");
+ throw new TaskExecutionException(pendingReq, "Load MOASession FAILED.", e1);
+
+ }
+
+
+ if (MiscUtil.isNotEmpty(receivedPostMessage)) {
+ Logger.debug("Receive POST-Message data. Start data-validation process ... ");
+ try {
+ JsonParser parser = new JsonParser();
+ JsonObject reveivedData = (JsonObject) parser.parse(sb.toString());
+ JsonObject reveivedSession = reveivedData.get("session").getAsJsonObject();
+ String validTo = reveivedSession.get("validTo").getAsString();
+ String entityID = reveivedSession.get("entityID").getAsString();
+ String sessionBlob = reveivedSession.get("sessionBlob").getAsString();
+
+ Logger.trace("Blob:" + sessionBlob +
+ " | validTo:" + validTo +
+ " | entityIS:" + entityID);
+
+ if (PVPConfiguration.getInstance().getIDPPublicPath().contains(entityID)) {
+ // stored SSO session data is from this IDP - start local session reconstruction
+ Response ssoInformation = ssoTransferUtils.validateReceivedSSOContainer(sessionBlob);
+
+ //transfer SSO Assertion into MOA-Session
+ ssoTransferUtils.parseSSOContainerToMOASessionDataObject(pendingReq, moasession, ssoInformation);
+
+ // store MOASession into database
+ try {
+ authenticatedSessionStorage.storeSession(moasession);
+
+ } catch (MOADatabaseException e) {
+ Logger.error("Database Error! MOASession is not stored!");
+ throw new MOAIDException("init.04", new Object[] {
+ moasession.getSessionID()});
+ }
+
+ executionContext.put(SSOTransferConstants.FLAG_SSO_SESSION_RESTORED, true);
+ executionContext.put("sessionRestoreFinished", false);
+
+ } else {
+ Logger.info("Received SSO session-data is from IDP: " + entityID
+ + ". Start inderfederation process to restore SSO session ... ");
+ //change to inderfederated session reconstruction
+
+ Logger.warn("Device Session Transfer with interfederation is not implemented, yet!!!!");
+
+ }
+
+ } catch (Exception e) {
+ Logger.error("Parse reveived JSON data-object " + sb.toString() + " FAILED!", e);
+ throw new TaskExecutionException(pendingReq, "JSON data is not parseable.", e);
+
+ }
+
+ } else {
+ Logger.debug("Reveive NO POST-message data. Start check-session process ... ");
+
+ boolean isSSOSessionRestored =
+ BooleanUtils.isTrue((Boolean) executionContext.get(SSOTransferConstants.FLAG_SSO_SESSION_RESTORED));
+
+ if (isSSOSessionRestored) {
+ Logger.info("Found restored SSO session. Resume authentication process ...");
+ executionContext.remove(SSOTransferConstants.FLAG_SSO_SESSION_RESTORED);
+ executionContext.put("sessionRestoreFinished", true);
+
+ } else {
+ DateTime moaSessionCreated = new DateTime(moasession.getSessionCreated().getTime());
+ if (moaSessionCreated.plusMinutes(3).isBeforeNow()) {
+ Logger.warn("No SSO session-container received. Stop authentication process after time-out.");
+ throw new TaskExecutionException(pendingReq, "No SSO container received from smartphone app.", null);
+
+ } else {
+ Logger.debug("No restored SSO session found --> Wait a few minutes and check again.");
+ executionContext.put("sessionRestoreFinished", false);
+
+ VelocityContext context;
+ try {
+ //create first step of SSO Transfer GUI
+ authURL = HTTPUtils.extractAuthURLFromRequest(request);
+ if (!AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix().
+ contains(authURL)) {
+ Logger.warn("Requested URL is not allowed.");;
+ response.sendError(500, "Requested URL is not allowed.");
+
+ }
+
+ context = GUIUtils.buildSSOTransferGUI(authURL, pendingReq.getRequestID());
+ GUIUtils.printSSOTransferGUI(context, response);
+
+ } catch (IOException | MOAIDException e) {
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ }
+
+ }
+ }
+ }
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/GUIUtils.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/GUIUtils.java
new file mode 100644
index 000000000..ee7a397aa
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/GUIUtils.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer.utils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.net.URI;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+import com.google.gson.JsonObject;
+
+import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.SSOTransferConstants;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.util.VelocityProvider;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Base64Utils;
+import net.glxn.qrgen.QRCode;
+import net.glxn.qrgen.image.ImageType;
+
+/**
+ * @author tlenz
+ *
+ */
+public class GUIUtils {
+ private static final String HTMLTEMPLATESDIR = "htmlTemplates/";
+ private static final String GUI_HTML_TEMPLATE = "sso_transfer_template.html";
+
+ public static final int REFESH_TIMEOUT = 5 * 1000; //5 sec
+
+ public static VelocityContext buildSSOTransferGUI(String authURL, String pendingReqID) throws ConfigurationException, IOException {
+ String containerURL = authURL
+ + SSOTransferConstants.SERVLET_SSOTRANSFER_FROM_SMARTPHONE
+ + "?" + MOAIDAuthConstants.PARAM_TARGET_PENDINGREQUESTID + "=" + pendingReqID;
+
+ JsonObject qrResult = new JsonObject();
+ qrResult.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_TYPE,
+ SSOTransferConstants.SSOCONTAINER_VALUE_TYPE_TRANSER);
+ qrResult.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_URL, containerURL);
+
+ ByteArrayOutputStream qrStream =
+ QRCode.from(qrResult.toString()).to(ImageType.GIF).withSize(300, 300).stream();
+ String base64EncodedImage = Base64Utils.encode(qrStream.toByteArray());
+ VelocityContext context = new VelocityContext();
+ context.put("QRImage", base64EncodedImage);
+
+ context.put("successMsg", "Select the SSO Session in your <i>SSO-Transfer App</i> and scan the QR-Code to start the process.");
+
+ context.put("timeoutURL", containerURL);
+ context.put("timeout", REFESH_TIMEOUT);
+
+ return context;
+
+ }
+
+ public static void printSSOTransferGUI(VelocityContext context, HttpServletResponse httpResp) throws MOAIDException {
+ try {
+ Logger.trace("Initialize VelocityEngine...");
+
+ InputStream is = null;
+ String pathLocation = null;
+ try {
+ String rootconfigdir = AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir();
+ pathLocation = rootconfigdir + HTMLTEMPLATESDIR + GUI_HTML_TEMPLATE;
+ File file = new File(new URI(pathLocation));
+ is = new FileInputStream(file);
+ evaluateTemplate(context, httpResp, is);
+
+ } catch (Exception e) {
+ Logger.warn("SLO Template is not found in configuration directory (" +
+ pathLocation + "). Load template from project library ... ");
+
+ try {
+ pathLocation = GUI_HTML_TEMPLATE;
+ is = Thread.currentThread()
+ .getContextClassLoader()
+ .getResourceAsStream(pathLocation);
+ evaluateTemplate(context, httpResp, is);
+
+ } catch (Exception e1) {
+ Logger.error("Single LogOut form can not created.", e);
+ throw new MOAIDException("Create Single LogOut information FAILED.", null, e);
+ }
+
+ } finally {
+ if (is != null)
+ is.close();
+
+ }
+
+ } catch (Exception e) {
+ Logger.error("Single LogOut form can not created.", e);
+ throw new MOAIDException("Create Single LogOut information FAILED.", null, e);
+ }
+ }
+
+ private static void evaluateTemplate(VelocityContext context, HttpServletResponse httpResp, InputStream is) throws Exception {
+
+ VelocityEngine engine = VelocityProvider.getClassPathVelocityEngine();
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is ));
+
+ //set default elements to velocity context
+ context.put("contextpath", AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix());
+
+ StringWriter writer = new StringWriter();
+ //velocityEngine.evaluate(context, writer, "SLO_Template", reader);
+ engine.evaluate(context, writer, "SSO Transfer Template", reader);
+
+
+ httpResp.setContentType("text/html;charset=UTF-8");
+ httpResp.getOutputStream().write(writer.toString().getBytes("UTF-8"));
+
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/SSOContainerUtils.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/SSOContainerUtils.java
new file mode 100644
index 000000000..4d41ff652
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/SSOContainerUtils.java
@@ -0,0 +1,477 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.auth.modules.ssotransfer.utils;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.security.MessageDigest;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.joda.time.DateTime;
+import org.opensaml.Configuration;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.AuthnContextClassRef;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.core.SubjectConfirmationData;
+import org.opensaml.security.SAMLSignatureProfileValidator;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.encryption.EncryptionException;
+import org.opensaml.xml.io.Marshaller;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.io.Unmarshaller;
+import org.opensaml.xml.io.UnmarshallerFactory;
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.parse.BasicParserPool;
+import org.opensaml.xml.parse.XMLParserException;
+import org.opensaml.xml.security.SecurityException;
+import org.opensaml.xml.security.SecurityHelper;
+import org.opensaml.xml.security.credential.Credential;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.SignatureException;
+import org.opensaml.xml.signature.SignatureValidator;
+import org.opensaml.xml.signature.Signer;
+import org.opensaml.xml.validation.ValidationException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import com.google.gson.JsonObject;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.exception.ParseException;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.SSOTransferConstants;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.data.SSOTransferAuthenticationData;
+import at.gv.egovernment.moa.id.auth.modules.ssotransfer.data.SSOTransferOnlineApplication;
+import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.MISMandate;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.assertion.PVP2AssertionBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionAttributeExtractorExeption;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoCredentialsException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SAMLRequestNotSignedException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.IDPCredentialProvider;
+import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor;
+import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
+import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngine;
+import at.gv.egovernment.moa.id.util.Random;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.MiscUtil;
+import iaik.x509.X509Certificate;
+
+/**
+ * @author tlenz
+ *
+ */
+@Service("SSOContainerUtils")
+public class SSOContainerUtils {
+ public static final List<String> REQUIRED_ATTRIBUTES;
+ static {
+ List<String> tmp = new ArrayList<String>();
+ tmp.add(PVPConstants.EID_AUTH_BLOCK_NAME);
+ tmp.add(PVPConstants.EID_IDENTITY_LINK_NAME);
+ tmp.add(PVPConstants.EID_ISSUING_NATION_NAME);
+ tmp.add(PVPConstants.EID_SIGNER_CERTIFICATE_NAME);
+ tmp.add(PVPConstants.EID_SOURCE_PIN_NAME);
+ tmp.add(PVPConstants.EID_SOURCE_PIN_TYPE_NAME);
+ tmp.add(PVPConstants.MANDATE_REFERENCE_VALUE_NAME);
+ tmp.add(PVPConstants.MANDATE_FULL_MANDATE_NAME);
+ tmp.add(PVPConstants.MANDATE_TYPE_NAME);
+ tmp.add(PVPConstants.MANDATE_PROF_REP_OID_NAME);
+ tmp.add(PVPConstants.MANDATE_PROF_REP_DESC_NAME);
+ tmp.add(PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME);
+ tmp.add(PVPConstants.PVP_HOLDEROFKEY_NAME);
+
+ REQUIRED_ATTRIBUTES = Collections.unmodifiableList(tmp);
+ }
+
+ @Autowired IDPCredentialProvider credentials;
+ @Autowired SAMLVerificationEngine samlVerificationEngine;
+ @Autowired AuthConfiguration authConfig;
+
+ public void parseSSOContainerToMOASessionDataObject(IRequest pendingReq, AuthenticationSession moasession, Response ssoInformation) throws AssertionAttributeExtractorExeption, ConfigurationException {
+ AssertionAttributeExtractor attributeExtractor = new AssertionAttributeExtractor(ssoInformation);
+
+ //TODO: maybe change to correct URL
+ //set dummy BKU URLx
+ moasession.setBkuURL("http://egiz.gv.at/sso_session-transfer_app");
+
+
+ String qaaLevel = attributeExtractor.getSingleAttributeValue(PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME);
+ if (MiscUtil.isNotEmpty(qaaLevel)) {
+ if (qaaLevel.startsWith(PVPConstants.STORK_QAA_PREFIX))
+ moasession.setQAALevel(qaaLevel);
+ else
+ moasession.setQAALevel(PVPConstants.STORK_QAA_PREFIX + qaaLevel);
+
+
+ } else {
+ Logger.warn("SSO session-container contains NO QAA-level");
+
+ }
+
+ String authBlock = attributeExtractor.getSingleAttributeValue(PVPConstants.EID_AUTH_BLOCK_NAME);
+ if (MiscUtil.isNotEmpty(authBlock))
+ moasession.setAuthBlock(authBlock);
+ else
+ Logger.warn("SSO session-container contains NO AuthBlock");
+
+ try {
+ String signerCert = attributeExtractor.getSingleAttributeValue(PVPConstants.EID_SIGNER_CERTIFICATE_NAME);
+ if (MiscUtil.isNotEmpty(signerCert))
+ moasession.setSignerCertificate(new X509Certificate(Base64Utils.decode(signerCert, false)));
+ else
+ Logger.warn("SSO session-container contains NO SignerCertificate");
+
+ } catch (CertificateException | IOException e) {
+ Logger.error("SignerCertificate is not parseable.", e);
+
+ }
+
+ String idlStr = attributeExtractor.getSingleAttributeValue(PVPConstants.EID_IDENTITY_LINK_NAME);
+ try {
+ if (MiscUtil.isNotEmpty(idlStr)) {
+ IdentityLinkAssertionParser idlParser = new IdentityLinkAssertionParser(Base64Utils.decodeToStream(idlStr, false));
+ moasession.setIdentityLink(idlParser.parseIdentityLink());
+
+ } else {
+ Logger.warn("SSO session-container contains NO IdentityLink");
+ throw new AssertionAttributeExtractorExeption("SSO session-container contains NO IdentityLink");
+
+ }
+
+ } catch (ParseException e) {
+ Logger.error("IdentityLink is not parseable.", e);
+ throw new AssertionAttributeExtractorExeption("IdentityLink is not parseable.");
+
+ }
+
+
+ String mandateRefValue = attributeExtractor.getSingleAttributeValue(PVPConstants.MANDATE_REFERENCE_VALUE_NAME);
+ if (MiscUtil.isNotEmpty(mandateRefValue)) {
+ moasession.setMandateReferenceValue(mandateRefValue);
+ moasession.setUseMandate("true");
+ Logger.info("Found mandate information in SSO session-container.");
+
+ try {
+ MISMandate mandate = new MISMandate();
+
+ String mandateFull = attributeExtractor.getSingleAttributeValue(PVPConstants.MANDATE_FULL_MANDATE_NAME);
+ if (MiscUtil.isNotEmpty(mandateFull)) {
+ mandate.setMandate(Base64Utils.decode(mandateFull, false));
+
+ } else {
+ Logger.warn("No Full-Mandate information found in SSO session-container.");
+
+ }
+
+ String oid = attributeExtractor.getSingleAttributeValue(PVPConstants.MANDATE_PROF_REP_OID_NAME);
+ if (MiscUtil.isNotEmpty(oid))
+ mandate.setProfRep(oid );
+
+ NodeList mandateElements = mandate.getMandateDOM().getChildNodes();
+ for (int i=0; i<mandateElements.getLength(); i++) {
+ Element mandateEl = (Element) mandateElements.item(i);
+ if (mandateEl.hasAttribute("OWbPK")) {
+ mandate.setOWbPK(mandateEl.getAttribute("OWbPK"));
+ }
+ }
+
+ moasession.setMISMandate(mandate);
+
+ } catch (IOException e) {
+ Logger.error("Full-Mandate information is not parseable.", e);
+
+ }
+ }
+
+
+
+
+
+ }
+
+ public Response validateReceivedSSOContainer(String signedEncryptedContainer) throws IOException, XMLParserException, UnmarshallingException, MOAIDException {
+ byte[] base64decodedContainer = Base64Utils.decode(signedEncryptedContainer, false);
+
+ final BasicParserPool ppMgr = new BasicParserPool();
+ final HashMap<String, Boolean> features = new HashMap<String, Boolean>();
+ features.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
+ ppMgr.setBuilderFeatures(features);
+ ppMgr.setNamespaceAware(true);
+
+ Document document = ppMgr.parse(new ByteArrayInputStream(base64decodedContainer));
+ Element domElement = document.getDocumentElement();
+
+ UnmarshallerFactory saml2UnmarshallerFactory = Configuration.getUnmarshallerFactory();
+ Unmarshaller saml2Unmarshaller = saml2UnmarshallerFactory.getUnmarshaller(domElement);
+ XMLObject responseXMLObj = saml2Unmarshaller.unmarshall(domElement);
+
+ if (responseXMLObj instanceof Response) {
+ Response ssoContainer = (Response) responseXMLObj;
+
+ try {
+ SAMLSignatureProfileValidator sigValidator = new SAMLSignatureProfileValidator();
+ sigValidator.validate(ssoContainer.getSignature());
+
+ } catch (ValidationException e) {
+ Logger.error("Failed to validate Signature", e);
+ throw new SAMLRequestNotSignedException(e);
+ }
+
+ Credential credential = credentials.getIDPAssertionSigningCredential();
+ if (credential == null) {
+ throw new NoCredentialsException("moaID IDP");
+ }
+
+ SignatureValidator sigValidator = new SignatureValidator(credential);
+ try {
+ sigValidator.validate(ssoContainer.getSignature());
+
+ } catch (ValidationException e) {
+ Logger.error("Failed to verfiy Signature", e);
+ throw new SAMLRequestNotSignedException(e);
+ }
+
+ if (ssoContainer.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) {
+
+ //validate PVP 2.1 assertion
+ samlVerificationEngine.validateAssertion(ssoContainer, false, credentials.getIDPAssertionEncryptionCredential());
+ return ssoContainer;
+
+ } else {
+ Logger.debug("Receive StatusCode " + ssoContainer.getStatus().getStatusCode().getValue()
+ + " from interfederated IDP.");
+ throw new MOAIDException("SSO Container has a not valid Status Code", null);
+
+ }
+
+ } else {
+ Logger.warn("SSO Container is not of type SAML2 Response");
+ throw new MOAIDException("SSO Container is not of type SAML2 Response", null);
+
+ }
+ }
+
+
+ public String generateSignedAndEncryptedSSOContainer(String authURL,
+ AuthenticationSession authSession, Date date) {
+ try {
+ String entityID = authURL;
+ AuthnContextClassRef authnContextClassRef = SAML2Utils
+ .createSAMLObject(AuthnContextClassRef.class);
+ authnContextClassRef.setAuthnContextClassRef(authSession.getQAALevel());
+
+ NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class);
+ String random = Random.nextRandom();
+ String nameID = subjectNameID.getValue();
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+ byte[] hash = md.digest((random).getBytes("ISO-8859-1"));
+ subjectNameID.setValue(Base64Utils.encode(hash));
+ subjectNameID.setNameQualifier(null);
+ subjectNameID.setFormat(NameID.TRANSIENT);
+
+ } catch (Exception e) {
+ Logger.warn("PVP2 subjectNameID error", e);
+
+ }
+
+ SubjectConfirmationData subjectConfirmationData = SAML2Utils
+ .createSAMLObject(SubjectConfirmationData.class);
+ long maxSSOSessionTime = AuthConfigurationProviderFactory.getInstance().getSSOCreatedTimeOut() * 1000;
+ Date ssoSessionValidTo = new Date(authSession.getSessionCreated().getTime() + maxSSOSessionTime);
+ subjectConfirmationData.setNotOnOrAfter(new DateTime(ssoSessionValidTo.getTime()));
+
+ String sessionIndex = SAML2Utils.getSecureIdentifier();
+
+ IAuthData authData = new SSOTransferAuthenticationData(authConfig, authSession);
+
+ Assertion assertion = PVP2AssertionBuilder.buildGenericAssertion(
+ authURL,
+ entityID,
+ new DateTime(date.getTime()),
+ authnContextClassRef,
+ buildSSOAttributeForTransfer(authSession, authData),
+ subjectNameID,
+ subjectConfirmationData,
+ sessionIndex,
+ subjectConfirmationData.getNotOnOrAfter());
+
+ String ssoDataBlob = buildSSOContainerObject(authURL, assertion, new DateTime(date.getTime()));
+
+ JsonObject container = new JsonObject();
+ container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_TYPE, "SSO");
+ container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_VALIDTO, subjectConfirmationData.getNotOnOrAfter().toString());
+ container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_ENTITYID, entityID);
+ container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_USERID, authData.getGivenName() + " " + authData.getFamilyName());
+ container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_SESSION, ssoDataBlob);
+
+ //TODO
+ container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_RESULTENDPOINT, "https://demo.egiz.gv.at");
+
+ return container.toString();
+
+ } catch (ConfigurationException | EncryptionException | CredentialsNotAvailableException | SecurityException | ParserConfigurationException | MarshallingException | SignatureException | TransformerFactoryConfigurationError | TransformerException | IOException e) {
+ Logger.warn("SSO container generation FAILED.", e);
+ }
+
+ return null;
+ }
+
+ private String buildSSOContainerObject(String authURL, Assertion assertion, DateTime date) throws ConfigurationException, EncryptionException, CredentialsNotAvailableException, SecurityException, ParserConfigurationException, MarshallingException, SignatureException, TransformerFactoryConfigurationError, TransformerException, IOException {
+ Response authResponse = SAML2Utils.createSAMLObject(Response.class);
+
+ Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class);
+
+ //change to entity value from entity name to IDP EntityID (URL)
+ nissuer.setValue(authURL);
+ nissuer.setFormat(NameID.ENTITY);
+ authResponse.setIssuer(nissuer);
+
+ //set responseID
+ String remoteSessionID = SAML2Utils.getSecureIdentifier();
+ authResponse.setID(remoteSessionID);
+
+
+ //SAML2 response required IssueInstant
+ authResponse.setIssueInstant(date);
+ authResponse.setStatus(SAML2Utils.getSuccessStatus());
+
+ //encrypt container
+// X509Credential encryptionCredentials = credentials.getIDPAssertionEncryptionCredential();
+// EncryptionParameters dataEncParams = new EncryptionParameters();
+// dataEncParams.setAlgorithm(PVPConstants.DEFAULT_SYM_ENCRYPTION_METHODE);
+//
+// List<KeyEncryptionParameters> keyEncParamList = new ArrayList<KeyEncryptionParameters>();
+// KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters();
+//
+// keyEncParam.setEncryptionCredential(encryptionCredentials);
+// keyEncParam.setAlgorithm(PVPConstants.DEFAULT_ASYM_ENCRYPTION_METHODE);
+// KeyInfoGeneratorFactory kigf = Configuration.getGlobalSecurityConfiguration()
+// .getKeyInfoGeneratorManager().getDefaultManager()
+// .getFactory(encryptionCredentials);
+// keyEncParam.setKeyInfoGenerator(kigf.newInstance());
+// keyEncParamList.add(keyEncParam);
+//
+// Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList);
+// //samlEncrypter.setKeyPlacement(KeyPlacement.INLINE);
+// samlEncrypter.setKeyPlacement(KeyPlacement.PEER);
+//
+// EncryptedAssertion encryptAssertion = null;
+//
+// encryptAssertion = samlEncrypter.encrypt(assertion);
+// authResponse.getEncryptedAssertions().add(encryptAssertion);
+
+ //add unencrypted assertion
+ authResponse.getAssertions().add(assertion);
+
+ //sign container
+ Credential signingCredential = credentials.getIDPAssertionSigningCredential();
+ Signature signature = AbstractCredentialProvider.getIDPSignature(signingCredential);
+
+ SecurityHelper.prepareSignatureParams(signature, signingCredential, null, null);
+ authResponse.setSignature(signature);
+
+ DocumentBuilder builder;
+ DocumentBuilderFactory factory = DocumentBuilderFactory
+ .newInstance();
+
+ builder = factory.newDocumentBuilder();
+ Document document = builder.newDocument();
+ Marshaller out = Configuration.getMarshallerFactory()
+ .getMarshaller(authResponse);
+ out.marshall(authResponse, document);
+
+ Signer.signObject(signature);
+
+ Transformer transformer = TransformerFactory.newInstance()
+ .newTransformer();
+
+ StringWriter sw = new StringWriter();
+ StreamResult sr = new StreamResult(sw);
+ DOMSource source = new DOMSource(document);
+ transformer.transform(source, sr);
+ sw.close();
+
+ return Base64Utils.encode(sw.toString().getBytes());
+
+ }
+
+ private static List<Attribute> buildSSOAttributeForTransfer(AuthenticationSession authSession, IAuthData authData) {
+ List<Attribute> attrList = new ArrayList<Attribute>();
+
+ IOAAuthParameters oaParam = new SSOTransferOnlineApplication();
+
+ for (String el : REQUIRED_ATTRIBUTES) {
+ try {
+ Attribute attr = PVPAttributeBuilder.buildAttribute(
+ el, oaParam, authData);
+ if (attr != null)
+ attrList.add(attr);
+ else
+ Logger.info("SSO-Transfer attribute " + el + " is empty!");
+
+ } catch (Exception e) {
+ Logger.warn("Build SSO-Transfer attribute " + el + " FAILED.", e);
+
+ }
+ }
+
+ return attrList;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
new file mode 100644
index 000000000..b0744b49b
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
@@ -0,0 +1 @@
+at.gv.egovernment.moa.id.auth.modules.ssotransfer.SSOTransferSpringResourceProvider \ No newline at end of file
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransfer.authmodule.beans.xml b/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransfer.authmodule.beans.xml
new file mode 100644
index 000000000..1a8709e15
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransfer.authmodule.beans.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
+
+ <context:annotation-config />
+
+ <bean id="ssoTransferAuthModule" class="at.gv.egovernment.moa.id.auth.modules.ssotransfer.SSOTransferAuthModuleImpl">
+ <property name="priority" value="1" />
+ </bean>
+
+</beans>
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferAuthentication.process.xml b/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferAuthentication.process.xml
new file mode 100644
index 000000000..e7d98c8c8
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferAuthentication.process.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pd:ProcessDefinition id="SSOTransferAuthentication" xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1">
+
+<!--
+ STORK authentication both with C-PEPS supporting xml signatures and with C-PEPS not supporting xml signatures.
+-->
+ <pd:Task id="initializeRestoreSSOSessionTask" class="InitializeRestoreSSOSessionTask" />
+ <pd:Task id="restoreSSOSessionTask" class="RestoreSSOSessionTask" async="true" />
+ <pd:Task id="finalizeAuthentication" class="FinalizeAuthenticationTask" />
+
+ <!-- Process is triggered either by GenerateIFrameTemplateServlet (upon bku selection) or by AuthenticationManager (upon legacy authentication start using legacy parameters. -->
+ <pd:StartEvent id="start" />
+
+ <pd:Transition from="start" to="initializeRestoreSSOSessionTask" />
+ <pd:Transition from="initializeRestoreSSOSessionTask" to="restoreSSOSessionTask"/>
+
+ <pd:Transition from="restoreSSOSessionTask" to="restoreSSOSessionTask" conditionExpression="!ctx['sessionRestoreFinished']"/>
+ <pd:Transition from="restoreSSOSessionTask" to="finalizeAuthentication" />
+
+ <pd:Transition from="finalizeAuthentication" to="end" />
+
+ <pd:EndEvent id="end" />
+
+</pd:ProcessDefinition>
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/moaid_ssotransfer_auth.beans.xml b/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/moaid_ssotransfer_auth.beans.xml
new file mode 100644
index 000000000..4a4af4ac5
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/moaid_ssotransfer_auth.beans.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
+
+
+ <bean id="SSOContainerUtils"
+ class="at.gv.egovernment.moa.id.auth.modules.ssotransfer.utils.SSOContainerUtils"/>
+
+
+ <bean id="SSOTransferSignalServlet"
+ class="at.gv.egovernment.moa.id.auth.modules.ssotransfer.servlet.SSOTransferSignalServlet"/>
+
+
+ <bean id="SSOTransferServlet"
+ class="at.gv.egovernment.moa.id.auth.modules.ssotransfer.servlet.SSOTransferServlet"/>
+
+
+<!-- Federated Authentication Process Tasks -->
+ <bean id="RestoreSSOSessionTask"
+ class="at.gv.egovernment.moa.id.auth.modules.ssotransfer.task.RestoreSSOSessionTask"
+ scope="prototype"/>
+
+ <bean id="InitializeRestoreSSOSessionTask"
+ class="at.gv.egovernment.moa.id.auth.modules.ssotransfer.task.InitializeRestoreSSOSessionTask"
+ scope="prototype"/>
+
+</beans> \ No newline at end of file
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/sso_transfer_template.html b/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/sso_transfer_template.html
new file mode 100644
index 000000000..962faa58f
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/resources/sso_transfer_template.html
@@ -0,0 +1,447 @@
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
+
+ <!-- MOA-ID 2.x BKUSelection Layout CSS -->
+ <style type="text/css">
+ @media screen and (min-width: 650px) {
+
+ body {
+ margin:0;
+ padding:0;
+ color : #000;
+ background-color : #fff;
+ text-align: center;
+ background-color: #6B7B8B;
+ }
+
+ #page {
+ display: block;
+ border: 2px solid rgb(0,0,0);
+ width: 650px;
+ height: 460px;
+ margin: 0 auto;
+ margin-top: 5%;
+ position: relative;
+ border-radius: 25px;
+ background: rgb(255,255,255);
+ }
+
+ #page1 {
+ text-align: center;
+ }
+
+ #main {
+ /* clear:both; */
+ position:relative;
+ margin: 0 auto;
+ width: 250px;
+ text-align: center;
+ }
+
+ .OA_header {
+ /* background-color: white;*/
+ font-size: 20pt;
+ margin-bottom: 25px;
+ margin-top: 25px;
+ }
+
+ #leftcontent {
+ /*float:left; */
+ width:250px;
+ margin-bottom: 25px;
+ text-align: left;
+ /*border: 1px solid rgb(0,0,0);*/
+ }
+
+ #leftcontent {
+ width: 300px;
+ margin-top: 30px;
+ }
+
+ h2#tabheader{
+ font-size: 1.1em;
+ padding-left: 2%;
+ padding-right: 2%;
+ position: relative;
+ }
+
+ .setAssertionButton_full {
+ background: #efefef;
+ cursor: pointer;
+ margin-top: 15px;
+ width: 100px;
+ height: 30px
+ }
+
+ #leftbutton {
+ width: 30%;
+ float:left;
+ margin-left: 40px;
+ }
+
+ #rightbutton {
+ width: 30%;
+ float:right;
+ margin-right: 45px;
+ text-align: right;
+ }
+
+ button {
+ height: 25px;
+ width: 75px;
+ margin-bottom: 10px;
+ }
+
+ #validation {
+ position: absolute;
+ bottom: 0px;
+ margin-left: 270px;
+ padding-bottom: 10px;
+ }
+
+ }
+
+ @media screen and (max-width: 205px) {
+ #localBKU p {
+ font-size: 0.6em;
+ }
+
+ #localBKU input {
+ font-size: 0.6em;
+ min-width: 60px;
+ /* max-width: 65px; */
+ min-height: 1.0em;
+ /* border-radius: 5px; */
+ }
+
+ }
+
+ @media screen and (max-width: 249px) and (min-width: 206px) {
+ #localBKU p {
+ font-size: 0.7em;
+ }
+
+ #localBKU input {
+ font-size: 0.7em;
+ min-width: 70px;
+ /* max-width: 75px; */
+ min-height: 0.95em;
+ /* border-radius: 6px; */
+ }
+
+ }
+
+ @media screen and (max-width: 299px) and (min-width: 250px) {
+ #localBKU p {
+ font-size: 0.9em;
+ }
+
+ #localBKU input {
+ font-size: 0.8em;
+ min-width: 70px;
+ /* max-width: 75px; */
+ /* border-radius: 6px; */
+ }
+
+ }
+
+ @media screen and (max-width: 399px) and (min-width: 300px) {
+ #localBKU p {
+ font-size: 0.9em;
+ }
+
+ #localBKU input {
+ font-size: 0.8em;
+ min-width: 70px;
+ /* max-width: 75px; */
+ /* border-radius: 6px; */
+ }
+
+ }
+
+ @media screen and (max-width: 649px) and (min-width: 400px) {
+ #localBKU p {
+ font-size: 0.9em;
+ }
+
+ #localBKU input {
+ font-size: 0.8em;
+ min-width: 70px;
+ /* max-width: 80px; */
+ /* border-radius: 6px; */
+ }
+
+ }
+
+
+
+ @media screen and (max-width: 649px) {
+
+ body {
+ margin:0;
+ padding:0;
+ color : #000;
+ text-align: center;
+ font-size: 100%;
+ background-color: #MAIN_BACKGOUNDCOLOR#;
+ }
+
+ #page {
+ visibility: hidden;
+ margin-top: 0%;
+ }
+
+ #page1 {
+ visibility: hidden;
+ }
+
+ #main {
+ visibility: hidden;
+ }
+
+ #validation {
+ visibility: hidden;
+ display: none;
+ }
+
+ .OA_header {
+ margin-bottom: 0px;
+ margin-top: 0px;
+ font-size: 0pt;
+ visibility: hidden;
+ }
+
+ #leftcontent {
+ visibility: visible;
+ margin-bottom: 0px;
+ text-align: left;
+ border:none;
+ vertical-align: middle;
+ min-height: 173px;
+ min-width: 204px;
+
+ }
+
+ input[type=button] {
+/* height: 11%; */
+ width: 70%;
+ }
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ font-family: #FONTTYPE#;
+ }
+
+ #selectArea {
+ padding-top: 10px;
+ padding-bottom: 55px;
+ padding-left: 10px;
+ }
+
+ .setAssertionButton {
+ background: #efefef;
+ cursor: pointer;
+ margin-top: 15px;
+ width: 70px;
+ height: 25px;
+ }
+
+ #leftbutton {
+ width: 35%;
+ float:left;
+ margin-left: 15px;
+ }
+
+ #rightbutton {
+ width: 35%;
+ float:right;
+ margin-right: 25px;
+ text-align: right;
+ }
+
+/* input[type=button], .sendButton {
+ background: #BUTTON_BACKGROUNDCOLOR#;
+ color: #BUTTON_COLOR#;
+/* border:1px solid #000; */
+/* cursor: pointer;
+/* box-shadow: 3px 3px 3px #222222; */
+/* }
+
+/* button:hover, button:focus, button:active,
+ .sendButton:hover , .sendButton:focus, .sendButton:active,
+ #mandateCheckBox:hover, #mandateCheckBox:focus, #mandateCheckBox:active {
+ background: #BUTTON_BACKGROUNDCOLOR_FOCUS#;
+ color: #BUTTON_COLOR#;
+/* border:1px solid #000; */
+/* cursor: pointer;
+/* box-shadow: -1px -1px 3px #222222; */
+/* }
+
+*/
+ input {
+ /*border:1px solid #000;*/
+ cursor: pointer;
+ }
+
+ #localBKU input {
+/* color: #BUTTON_COLOR#; */
+ border: 0px;
+ display: inline-block;
+
+ }
+
+ #localBKU input:hover, #localBKU input:focus, #localBKU input:active {
+ text-decoration: underline;
+ }
+
+ #installJava, #BrowserNOK {
+ clear:both;
+ font-size:0.8em;
+ padding:4px;
+ }
+
+ .selectText{
+
+ }
+
+ .selectTextHeader{
+
+ }
+
+ .sendButton {
+ width: 30%;
+ margin-bottom: 1%;
+ }
+
+ #leftcontent a {
+ text-decoration:none;
+ color: #000;
+ /* display:block;*/
+ padding:4px;
+ }
+
+ #leftcontent a:hover, #leftcontent a:focus, #leftcontent a:active {
+ text-decoration:underline;
+ color: #000;
+ }
+
+ .infobutton {
+ background-color: #005a00;
+ color: white;
+ font-family: serif;
+ text-decoration: none;
+ padding-top: 2px;
+ padding-right: 4px;
+ padding-bottom: 2px;
+ padding-left: 4px;
+ font-weight: bold;
+ }
+
+ .hell {
+ background-color : #MAIN_BACKGOUNDCOLOR#;
+ color: #MAIN_COLOR#;
+ }
+
+ .dunkel {
+ background-color: #HEADER_BACKGROUNDCOLOR#;
+ color: #HEADER_COLOR#;
+ }
+
+ .main_header {
+ color: black;
+ font-size: 32pt;
+ position: absolute;
+ right: 10%;
+ top: 40px;
+
+ }
+
+ #alert {
+ margin: 100px 250px;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 14px;
+ font-weight: normal;
+ color: red;
+ }
+
+ .reqframe {
+ /*display: none;*/
+ visibility: hidden;
+
+ }
+
+ </style>
+
+ #if($timeoutURL)
+ <script type="text/javascript">
+ function sloTimeOut() {
+ window.location.href="$timeoutURL";
+
+ }
+
+ </script>
+ #end
+
+
+ <title>Single Sign-On Session Transfer</title>
+</head>
+
+#if($timeoutURL)
+ <body onload='setTimeout(sloTimeOut, $timeout);'>
+#else
+ <body>
+#end
+ <noscript>
+ <p>
+ <strong>Note:</strong> Since your browser does not support
+ JavaScript, you must press the Continue button to resume
+ the authentication process after the SSO session transfer from smartphone to application is complete.
+ </p>
+
+ <a href="$timeoutURL">Press this link to resume</a>
+ </noscript>
+
+ <div id="page">
+ <div id="page1" class="case selected-case" role="main">
+ <h2 class="OA_header" role="heading">MOA-ID Single Sign-On Session Transfer Service</h2>
+ <div id="main">
+ <div id="leftcontent" class="hell" role="application">
+
+ #if($errorMsg)
+ <div class="alert">
+ <p>$errorMsg</p>
+ </div>
+ #end
+
+ #if($successMsg)
+ <div>
+ <p>$successMsg</p>
+ </div>
+ #end
+
+ #if($QRImage)
+ <div>
+ <img src="data:image/gif;base64,$QRImage">
+ </div>
+ #end
+
+ </div>
+ </div>
+ </div>
+ <div id="validation">
+ <a href="http://validator.w3.org/check?uri="> <img
+ style="border: 0; width: 88px; height: 31px"
+ src="$contextpath/img/valid-html5-blue.png" alt="HTML5 ist valide!" />
+ </a> <a href="http://jigsaw.w3.org/css-validator/"> <img
+ style="border: 0; width: 88px; height: 31px"
+ src="http://jigsaw.w3.org/css-validator/images/vcss-blue"
+ alt="CSS ist valide!" />
+ </a>
+ </div>
+ </div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/test/java/at/gv/egiz/tests/Tests.java b/id/server/modules/moa-id-module-ssoTransfer/src/test/java/at/gv/egiz/tests/Tests.java
new file mode 100644
index 000000000..1beab574a
--- /dev/null
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/test/java/at/gv/egiz/tests/Tests.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the \"Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.tests;
+
+import java.io.IOException;
+
+import org.hibernate.mapping.Map;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+/**
+ * @author tlenz
+ *
+ */
+public class Tests {
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+// String json =
+// "{\"data\":{\"session\":{\"validTo\":\"2015-10-09T10:55:34.738Z\",\"entityID\":\"https://demo.egiz.gv.at/demoportal_moaid-2.0\",\"userID\":\"Thomas Georg Lenz\",\"sessionBlob\":\"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDJwOlJl\\u000ac3BvbnNlIHhtbG5zOnNhbWwycD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4w\\u000aOnByb3RvY29sIiBJRD0iXzQ5ZjgzMDIyZjRkZjFjODMyMDNlZGU1NTQxZDY1ODU4\\u000aIiBJc3N1ZUluc3RhbnQ9IjIwMTUtMTAtMDlUMTA6MzU6NTEuMDI0WiIgVmVyc2lv\\u000abj0iMi4wIj48c2FtbDI6SXNzdWVyIHhtbG5zOnNhbWwyPSJ1cm46b2FzaXM6bmFt\\u000aZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBGb3JtYXQ9InVybjpvYXNpczpuYW1l\\u000aczp0YzpTQU1MOjIuMDpuYW1laWQtZm9ybWF0OmVudGl0eSI+aHR0cHM6Ly9kZW1v\\u000aLmVnaXouZ3YuYXQvZGVtb3BvcnRhbF9tb2FpZC0yLjA8L3NhbWwyOklzc3Vlcj48\\u000aZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5\\u000aL3htbGRzaWcjIj48ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1l\\u000adGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4\\u000aYy1jMTRuIyIvPjxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8v\\u000ad3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNyc2Etc2hhMjU2Ii8+PGRz\\u000aOlJlZmVyZW5jZSBVUkk9IiNfNDlmODMwMjJmNGRmMWM4MzIwM2VkZTU1NDFkNjU4\\u000aNTgiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRw\\u000aOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVy\\u000aZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8y\\u000aMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2Vz\\u000adE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1s\\u000aZW5jI3NoYTI1NiIvPjxkczpEaWdlc3RWYWx1ZT44eE9qNmlYVzhIQzk5UGhETEZ0\\u000aOVp0M205VWliaVdrdHMzaWVQTS9CZlFZPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpS\\u000aZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5mNjM2\\u000aYjVBeGx6THdUL0I1SmdLdnhNN0haK1lEZGVldUdaRUlxc05KdHdiN05TVFhlbVFC\\u000aTExObDlJTk1aUW1Ybkx3ektCc0pra0tGTXl3MkpsNXVYcWlHWVBzMExTWTNiWTdj\\u000aTTZoeHpDaGdVVHRMWXlPcE9qemxxbE5CN2FKTVpZWU10Q2phcWNqSmxVM0wxTjBv\\u000aYUJ5QlRjaTRHdjd5TUJkdE9nRElHNVVpVEppVmVNOURZcUowZFVaZDNRcG1BK0Zm\\u000aUm10WFVzaVRzU0N0b3lWVHlXYTJWemJweTZxcDMwWkZSTU03LzU0Q0NWZHIvaDZW\\u000aTnZCQ1YydkFEMWdZaUg5VG41aTRSRmRWMFBKNTkrNS9HYXVUMm1HSVRUVmNreVk2\\u000aRlJQSjI2MUV0bmdScE8xK1FYRDZwQVZBM2V6Rm9ZbkkyQ2dYdHQ2K2EyTkV3cnBO\\u000aaHc9PTwvZHM6U2lnbmF0dXJlVmFsdWU+PGRzOktleUluZm8+PGRzOlg1MDlEYXRh\\u000aPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJREZUQ0NBZjBDQkZVQm5MNHdEUVlKS29a\\u000aSWh2Y05BUUVMQlFBd1R6RUxNQWtHQTFVRUJoTUNRVlF4RFRBTEJnTlZCQWNNQkVk\\u000aeQpZWG94RFRBTEJnTlZCQW9NQkVWSFNWb3hJakFnQmdOVkJBTU1HVTFQUVMxSlJD\\u000aQkpSRkFnS0ZSbGMzUXRWbVZ5YzJsdmJpa3dIaGNOCk1UVXdNekV5TVRRd016UXlX\\u000aaGNOTVRjeE1qQTFNVFF3TXpReVdqQlBNUXN3Q1FZRFZRUUdFd0pCVkRFTk1Bc0dB\\u000aMVVFQnd3RVIzSmgKZWpFTk1Bc0dBMVVFQ2d3RVJVZEpXakVpTUNBR0ExVUVBd3da\\u000aVFU5QkxVbEVJRWxFVUNBb1ZHVnpkQzFXWlhKemFXOXVLVENDQVNJdwpEUVlKS29a\\u000aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSUp2MHFlOVVkdkZZU0w1STAy\\u000aR29rd0VWZnNJR2M3STdFaFZOT3hZCjltdFVlbm1ocU5yTHNMQkZnMUlpUGJrMElT\\u000aV2hPUndQeVZwL1AzK0d5R1AzMzlxWjY4VUNHVjM2MUUwUW03Y2pQZS9PMytyM0hB\\u000aTTIKWkJOOG9BWm9IbXBock5TNmZLZlk1OGt5Z3RyVWErWnlNellXVFRpUzMyU0NN\\u000aOEg1NWJsdUVGYmVaa3NuYlAwWTk0SWprZkpkZ3Z6bApNeHpybFN5b1YyeW1XQmp2\\u000aUzV3ZWxESGdiQ0t5anNqSWhUUmpKdS9vbEdKeWVuMDEvRXBJVnRTeURYTy8ySVMy\\u000adjJPOVVpRndBb3lCCllBalBubDNIeEsyQTU3N25SNjNNeGxnUDAvcytyODR1QnFP\\u000aQWxiNHFuYnBVN2x1NUd4bENQa1ptcFJvb0NRWVVSaW9DK3dqUzZsTUMKQXdFQUFU\\u000aQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFCcU83a2txL2dSYWhBdnBzUWc1TExa\\u000aUk9HRnI5cElQcnlOOXhtSkdnUG83agpLTmw3cnM3Z05TMGxtdWx1WVdXbkpjd0FQ\\u000aYndGZWI5NTRWTUI5eDlwOVFFdzVSblhhbVVZOXFhMExnY1MvdC9XWDZ2SmtaUE5o\\u000aV3BoCjhiWHdoME12bHNiZnJ2RFRKcjhjakgzcWZ4SVRwN3BhM3hiMXFFN3N1UmZm\\u000aVlVkRFhhd2lYWG5XSi9XSnIrdHdWVkhIRXFuWnoxbEEKclNETHhNOHNDakc4RGVK\\u000adzh2blF5NW1QR3JHVlRCYmE0dXBjOFVUWTFuUFY5VTJHQkpWWXVBa29WUmpiVGxO\\u000adnJMNUpxTnF5cEtjRwpiZWpqV3hncnpaa2VRZVUyaEZjanVubWd3R1ordWcyZnE0\\u000aa0trUWZ0d2NxZUpUenl6Qm9vMitPbzRUbWZic2gvb254UFdBPT08L2RzOlg1MDlD\\u000aZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25h\\u000adHVyZT48c2FtbDJwOlN0YXR1cz48c2FtbDJwOlN0YXR1c0NvZGUgVmFsdWU9InVy\\u000abjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPjwvc2Ft\\u000abDJwOlN0YXR1cz48c2FtbDI6RW5jcnlwdGVkQXNzZXJ0aW9uIHhtbG5zOnNhbWwy\\u000aPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj48eGVuYzpF\\u000abmNyeXB0ZWREYXRhIHhtbG5zOnhlbmM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEv\\u000aMDQveG1sZW5jIyIgSWQ9Il8zZmQzNTg5MmU5YThlYWNiOGUwOGYyODBhODNmY2I3\\u000aNCIgVHlwZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjRWxlbWVu\\u000adCI+PHhlbmM6RW5jcnlwdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cu\\u000adzMub3JnLzIwMDEvMDQveG1sZW5jI2FlczEyOC1jYmMiIHhtbG5zOnhlbmM9Imh0\\u000adHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jIyIvPjxkczpLZXlJbmZvIHht\\u000abG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6\\u000aUmV0cmlldmFsTWV0aG9kIFR5cGU9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQv\\u000aeG1sZW5jI0VuY3J5cHRlZEtleSIgVVJJPSIjX2E3NDBjZjA5MTViZDE1MmRiNzRk\\u000aMDNjZDQ1NzUyMTM3Ii8+PC9kczpLZXlJbmZvPjx4ZW5jOkNpcGhlckRhdGEgeG1s\\u000abnM6eGVuYz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjIj48eGVu\\u000aYzpDaXBoZXJWYWx1ZT43R0hKY0NYYXlzME1pY2ZvYXc3cnFNeTZ1bUQyd0FEQmtH\\u000aOThKclJ2UUdMczJneTBOSWFvSlM2SWM1Z254RXBNcUZHZ2ZLNHBBWGxRUVh3K1h6\\u000aY0RNaURhY2tqS1c5ckptNTh0b3dxNmFEbWVIU2doTTRDVzhVb1RaQlFlazVvY1dU\\u000aNmRIT3hPVzFFOFUrTXprTEg1NjVXUWxLYkdHamVSSGNzb3V3MXFuNk1XS01EU0V4\\u000aRzQrZERzSVliMk1uaEc3OEh6TDNZK0VMVG40TWd1cXF4bmpTVC9rRkpTK2dSMm93\\u000aL2tHVHN2ZnlLWmdMZUVYTzRpVHlNM2RzRk1Ma05rM0tHSHVHRmhGeUxycUR3Sko2\\u000aTmY5OVZRTmlDZDlrUnpxOE1qWklpNWQ0SjlhSmgvRk93NFI0TXAveCsvaC9hYVhk\\u000acDVyQ09CcUVaZ3FZUXlqT2FIMlAxRHR0VkU5SU5xS2w1OXh5ZTJaR0tDd1p5TTgr\\u000adWdSRnVDbTJ2RFlRSUx1T1RTaVNpbkJsNnBpLzFYRktNL1lVbTRJMXA0N21LNDlE\\u000aeW9Ia0lBaUk0NjQ2ejNJZ0tMZTBnaFlQYUlvTHhNcDE1ZE83RHRDQzhsZnYwb3Qx\\u000aYVdvTy9TcGpXaVJiOEhCaXdleGxTdHV4dVorUGVqZDlzUS9neTNFOFp1MWJXRmsv\\u000aTDVrNTZqUTAxZStIcEdORW5FSml1c1RHWldMRTZBY1lvd1NCeEZidC9RUHhGTlhh\\u000aRFBmcmlGRGZMK1RuMngyc2Rwb1RlMVpZM1JnZXo5b1Y2QUtJQWZZWC8zMllsT0NK\\u000aTlV5Myt4OU5teHljOFdKNTBjQ2RTd3ZuNTRBc1Z2U0xYRi9sbHIwQmh2cWRWQ0dP\\u000aTy82WGQvdEtpblFPWHdmeEJBMDVJZSs5MFZhU1J2NGFrRXJ4dHhrekVIeXB3R01j\\u000aVStieTYybDh5Q2Qya01vMnpQK0hmZ3NkTU9Ba2hrbDUvRXB2NVdiZGMzeElKRUhK\\u000aOVptbitUdGNWR2FiOHNPeSsyblIwQWNwZDJxeVIvNkNUd3dodk5nbXF1TldiLy9P\\u000aaGNxdDMvR1dPZkt0NGhrRnQxeGE2allTSXVoNHVWMHJqcENvK21ISFk4ZFZaTGZ6\\u000aNE9oR3dpNGd4bDBlV3hYUWF3UGpMWlI5RzdpQ1NCT2ZPV0d5bkdydklKSFF2VUJD\\u000aUVUwLzh3eFNxRmkxcVdQVXN2ZWtxV012SFpYTGdMMGZNYUJEa1ZZTm5YT2FlalJU\\u000aVHNZeENZc1AxYlRCNDY5ZytjRkQ1bEd0VDErTi95S3dKOUJTTGhaenhzRVhVWkhG\\u000aQ1NJTk1vTTlnaVF4TzI2L0VLUENMdXp2bnkyN3orNWdxcURkVzhlVUFCUmEyeFpp\\u000aZ204YmFkSllGWE12dkdDUVBjcmhiN3c1c3dSL2I1TXNiZXV4L3F0RFQ4R3VWcUNG\\u000ac3JDL3E4MlZpOUd5b3VCWDdGRk50UWhWRDFFVWtCQWZTYWE2UDhKU2VPdE01TVYr\\u000aV21OcGJrQ0U2M2hZS2g4cHN5MUdMdlRZRVA3Slh3TmNIWXlmS3FtdXk5S1dOVmUv\\u000aT2JPZTM5azhCWE5tWE9DejRJay93ajZqaU1DWEsrblhwdTBZQ1Z2ODJXM1BMeGlR\\u000ab1liRURMMjNHV05sNFFHQzQ1dE45WUpwK29CSGZjRStmUHk4S1FrOFBDK0s4SFFr\\u000aK21HV3NkTVUxUitTaTExY0VYdzBKTTRTczJzTWpZb05tQXd6a2RvRHliVkdnK3B3\\u000aSnUrUmFmaEJrSmpIU0FMeVQ3Y1R3dncrOW56S1BIdUhvWW5wSTRLQSt6U2xrYkUr\\u000aQ0dSbzd1MUxXVFl0cGZTYnFtd1NjYVlxU01WaTZ5QVdkRnoyS001LzlkVHB6alBY\\u000aNGhOZW82ZE96eVRHUkFMVnVUZi9Ma0RqaElqWGJ0Z2J6ZnU0aWdrWXg3Q2d1RnZ0\\u000abVlkTEhNSE4yRnFOTkN1UWk2bTJLUGYyUG5HdmVrSFVwMEJYZ3NEOUhkZFJtNHBF\\u000aYnE1VEsvV05RTzBuS0g0M1owOU9NcWZZbHEybk5mTi84ZnMyTjc1c2h5NmtheElK\\u000aL0FZUlNkOUU5M1VjOWJmV2FIeUwraWNNTE1GelU5MytMZlhpREkyWDVScEVtSnFB\\u000aSUMwVlJ0NWtXdnlVNGVlWnhOdE8zWUtxUnN2YVo0dzhnZ0I3dkxheFFKUWtnMWhs\\u000acVAzQzhDQW5HWnkrdDR5alRVejA1LzlpQi9HRk1DdDNteEpPajUvaVdTOTZRRW54\\u000aVm8wdVYvYzhDRFd6OERHYzYvLzFBQzBWS0VmaGRsSmFGOHg1NzVHNTI2dHoxTVln\\u000aMHBaaitNRzlsRUxkNm12d011cVE3VEVZdEYyN0Y4Vk5iQ29ZWXUraDhJTCs1Y0Vr\\u000acnBjakUzMm9MbWx4ZjBjNnpZaDhwa3FsVTR2RHlQeGJJcm50WkFPcThMUzk5Vktr\\u000aUjdFL0w5OXNoZUxqd3I0bTJtQ21CZ2tGZVZhVG1Ca00vSFd4MUNEYjlIcVM0N25Z\\u000aSWJaQW94ampIK0QzR1EweXlES1R3aG1iSXNHMFQ4Ry96eStRR0pmNkg2MXg0M1ZJ\\u000abkNwRkxmQjNiQUNJay9OanhCeFdheGVwMXRMMTRBSlRMZlROTnA3K3dCT016THhm\\u000aSHBjSUlWT2dOeXJ6UVk2Q0x6eXlDM2hub212a0hadFJ2WmpBYmExMmJSZ3VoTUJX\\u000aOFZiaHNKMmZaekZ3TXp0amxzSEkwREc2OGs1R0JDemFDQVRPZlBBWnFPN2lEQ2JC\\u000aMW1KSEgzTmxvQ2xuL1pTY01rOUVqTERyTndIWHZ4ZEFTRFMwS1RrZVNxS21TZm54\\u000aUWlSQ3lLNjhrSEZNc0trUTRYS3JKZjZGMWRreVYrL3NFdzRsS1FFYW52VkVVSTJx\\u000aUExDSVZnVWVkQVFaeFAxeVp0dDA1V2ptSUdhZnhQMldWNE9PYm8vTGFaamo0YW9H\\u000aNjNxWkdGdGJyWUt4TVc1Ny9RL0ZkbjN5TUpmUlkxVGU0UCtpTTNHUjNRcU1QeVMr\\u000aZWZDMlRDNk9pYithOHZ2SVcxTFI4OGV0V2t4SHJzMEpVcVRpM1ZEY1lXNEcwUHVn\\u000aTFhsZEYwWVVod1RLaTlOUjZmWTNXMXBTQUlNRGYvbk5hcVBIUnNLVWU4Z3pwcll3\\u000aOUdWLytXWjkrNUxEQnYzWmNKVGlLcllOcG1TUHl2MDdvNWx2Mmo2MXJtaEdsQVJ6\\u000aODJzWlhDUzA5K0lyaUpmVUg4bko0NFRFUk8wb1pBd2RxZWhEVmQ2YzZIV044dlJI\\u000aeEVJZWhmeXJhUVZ5Q3FlQkU3d3VPcXZFSmI2R0Urc1czNlBMNGFwT2ZMcCtISU5V\\u000aMkRhbVBrWHJWdVV6Q1dWZWlXaGIzSVBPNk81WkNENVp5RHlQc0liV3RuMnc2bnpI\\u000aU3EyUDhOdmZZRHhTcmM2YlU1aThoQ0FOZFdudTliMWJia0tXTXhUazhjamQ2bk8w\\u000aN1FtZnJFZGJCQ1ptWmh6blJ2cmRYMDdHSXo0YXhtM0Z2UHBtazBvZ1FaUzBieDd1\\u000aSWhFTDhGR2ozQW9lSllpOFB0dFA3NmFKaTRPYndlUmhlWVE2L1p0NHlPcXhabUph\\u000aMEFnTjJieTlpT1kyZ2tLclg2RTY1UWMzM2Q0Wlh6aXdDc1BsNVlGQmY1bG9ndGFE\\u000acXFVU0p1TEQyUEMyZEZNeDAzaGkrcUpSNmxPZ3ozYjJrM3dUTjhGTjJBMnQycHo2\\u000aNjJSS3IyQVRuSklrZkdndHVTcFlicGdab05VL0pheS9qMERWMXRaMkFmODdsUU43\\u000ablphdmF0YjVvbWx1Vi8yU3ZVYk5rbW1HdUhrTmFjQnNuTjIza3FOTEFrMmZvQ0xZ\\u000aT1FZaG5uQm1ZTUdYdS9tOG9haXdmUzhxRlZyYllTc0tKSWpLU1ptaFZBU3hXa01t\\u000aT3lSVUcrYkhlQ3RuT3ljWmlhb25XZElvbFUzT2hJMi9JTkpDSUNzQjJNWGhtNkpa\\u000aOEFtcUlqSGQxR1JvVElRTDlFNlBUbGF1MVB5dDhmbnl0aERac2R5L1dmMGU2SGRy\\u000abXJleXBiaE5PYTh4NUF4ckhaRGxjemttaUJyOHEzU0dYU1JVWUt0YndGUk5DZjFX\\u000aYkVyci9uN3duVmlZOENiS0wxZGJzMzlDNmtaVGlUVE16b1NCaFVKcW0xeUpHZUM3\\u000aT2pLRC9VNUFUK2NmOXV3c2hVNDhKZHNUNDVOWjJnOFNkL21xODlyTFBRVTAxNG9h\\u000aNUhRbzV4bEkvaldPUE1MM0R3MmtFVkkyZ3R0eG5HamExVk9aZVlJSGM1amJWenBx\\u000aSDMxZ2ZNYkZLTTNqNHRyaFVKVmFyM29ZWndZWnR6c1IyNmg5NWxIVlNNQzJ2MGZH\\u000aZ29nRFBMYzROejFtelNUNzQ2OFFTeVJJTzZtOTVTOTV3UWxiWXFoRzhMLzJsZW13\\u000aS1JNMUNUSGVUeVFjQlRNb1lrdU9wNFRZaVlXZzAwMjlXelNyMkhCUlFXZm9zNzc0\\u000abWlBbjBEQWtxcysybzFOdUtjTmU3cVFmY1Vnd2lHNzZJK1FZcEZPbkJSeUh1d1px\\u000acHR1WmpKTWV5amtZWC9wRE5VRkxYMmNWRGgrT0FSRUFaT3NBSVlPbnU1OWZnRHVB\\u000aM2RrOVNHMGVIclNXVkR2dU5yTDJiWm1hUXJxQmZ4bXRaall2Q0lmdDFXcmQvUkFo\\u000aeUs4bEFMNWFJZ1pZajV4WjBtV2hXd2hHTFBKNXBnMXpCeHFmZ2hyNzhRSVBQNGEr\\u000aT3YwU21qTmdwbVNQQzc4d2RPNVh6N3NzeU1mUC9uWkhVZEVJbUNqUGVMM2lJalhn\\u000aVVY1SjRnckc1cWY3WHZJQzBpNGZBdktnZ01LYXFYWGRZclBCZzFWQm5vR3BNVWZm\\u000aUU9Wa29pcjNjL2hYNWxlN1BoQlp3OVlWaEN3UDg2VU1oeGFmclp6blQzbnVUV0lL\\u000aRUMxOWVXNDJSak0wU3V2dWlreFY0L1o1UUhxcUtvNmRPamJZL1NKR1FQU1VWczdx\\u000aU3owNks1bTF4Q3Mybk51QWR2V0lVS25leE1oRUxsRTVGbGJQVkZ0Nkc3d0dLNUxv\\u000aNkV0bVZPWnE3bXpxWS84RHdUMnpUbm1UbW1lZEdIZDlUUWRCM1gxU2orUHlFRDFr\\u000aT01kYUkvVlVOWCt4bFlmUkd4RHF1Rlp2YmdTVSsxaDJHSjQ5M3VsYk9KVmJjeXpP\\u000acFFmTks5UTNNNEp2V1hPRVUzT2NPVkMwbkZGUUVEbDFEZ2h2Wldoeit6dy9sZkg1\\u000ab3UvV0kvOUpmKzB6ajJNNDE2YytTbkpneCtaSVZUd0lTQlhDc1NicW5tbG54ZE9a\\u000aSnhrbElrWXlwMGVNZ0RkTzZscHdTbXlLc21KMFVaM3ZPUFRuQXBxdTROeUxLOXUw\\u000aNzFZRVB5WUhWWnRXOUdITm5LM3RvZm5TVVZpMSsrVEx5bDY4aWRqS0RCa2hFVWNy\\u000aeWU5QkFhak1VR3VSc00zQ0RNZGlrSEd6eDVwM2RoeGIwczJTcGhxREhFLzJMSlBj\\u000aU2kyQkFVWTA1WXNDUytiWDgzb3VESDRXSmozZDM0NFFTcnFwQnk0ek11UHJPdWdT\\u000aRWo1a1Z1MjhMT1RKcnZPL09jbmxoTUYvWndielBRVVI5TmhUV21GOFV4WEE0Vjd0\\u000aK2RQNDVnTFFvYnNnVHY4MXkrUDVuTnZ2alNtL2I3aVpzZXJhV0VaSHlwNGo0bis0\\u000aSWJJTmZrcXVYVG9pcTlyVHFvZFdyemN4TkJCdDBOMTFtRWpwM2ZvYjJiVFU5QkVn\\u000aalZlTHRFSGxqVFJJV1ovK1IvTHpTaXRJL241MlNvTUI4RlVZc2lXQzF3WVBOY2lR\\u000aeEJYdFRNZ2xLY3NiVkUyN0dxSEtueDVkMlVHSE9iQVVIOGpKdmVaZUNRYVExWEZu\\u000aZ1ROdXVNcVBzdERaSFNPQ1pWVXhJajkyQTFUNkVTaFo3cTY1VjhadFEwNmdYb3dB\\u000ab1ZDc2xjaUJEZHZwUEZCL2FlV3hjbHc3cFZBQ2xBQ0ltVmhMRG5YNEtGWUNIUE5n\\u000ac2FLYU9ua05SVVZSc0Vad1pad2x2bklRdXpBRW9KTmtremd3Z2dtdHgyL09EK0NY\\u000aaVlLdE5pT3hHWDlKZEUveVovUk9qbHlSNUo5Q09CL3JNMmdlY0FWZ2dmcXQ4RUc5\\u000aQUJNVHZhN3RpVHF0M2Q4V2NjREV5S1F0aTlySXhoNWZVWGkwbTFrNlJGblNEajZN\\u000aRXZBNjBULzRJY1hPUERtYTJ2WU9EZ0NBS21IMWtnNzY1dDI4MFNtcFNnMFlnQUpV\\u000adkphSXlsdGY4VWhPWE9DdE1RaXdEVlVjSCtDTHBiSXh4a25Pa2Q5K1hYNDU3bm1j\\u000adjc5S0FMbzRjbEp0RWpqS3h1aUIrK1ZwNGxzRVlENkI2RVkzMjJiNmk4ZExkQkJu\\u000aZ0JKdXUwMDFBSjlWUFlIWlJBeDNRNDh4UU11dUp3WWdZNmlEV3hzY3lheDdENkxu\\u000aS2czbnBaYmhmVzRlc1l2NjBqdkhTNDZwem1lSlVKVmNmVUFFeWQ4azFXK3huWHFi\\u000aN1dxRFRGNXhaTHgrZHRlQk90UmR5U1NIR2cvcUhQNEFvZ3VSc2JvVFU5OEJqOWIy\\u000aSysvSEU0ZTIveDk2bkg3VzRlU0tGRGsxaWxoNk9EckE5SE1uQ3h1QWFxZXB5VTFo\\u000aRGNsZjNEVXdGamdRR3Vnb29TNHpITElvbnpxVFVjcTRzcC9SZ0YzRk00TGxpL2NC\\u000aTDdSbTYxMHZBYUprcmZWRG1JZGZ0NHd0SVVTVysyRGtoQ2lyb21LL3RLckZUbC96\\u000aTk5HMGpBTmo3SjllRWhQaE9kdzFVMHRlN3ZlakVwMGRLb09NRkRTSTNaWWJieWNs\\u000aUHJ3bkw2ZW5ocmlrWHBzNXVMVDRqT2p2NFVJSVRQSjJLN2NjWUZmQzJqZlJKMDJt\\u000aRk1wRkc0MGplcEdHblJ3cTNRZzQ5NEVhVGN2dG13SVdjbEtlVmJ5MW04N3ppc3hV\\u000aT1JWQXlnUlljU3ZvVXdxdWMzakx3MGJYVzBmUkFYVTMyaFlWUWZJUTFwY01pSDRW\\u000aRStyL3AvRGpJWS9zYngzVm1Hc1dCTGhNOFIweElVWm5YSnJyejk3S09GQkE3NGdu\\u000abVluSXJQa3lmT2hQUGVFSDQyL2VpRHUybWRWL2U0UGEzS1VLZFhjeUo4cm85MjZC\\u000aSTF3aGk4Q2h4SVVtZzZNaDQrOHg4YjhjS3VpZWtFaWZ2cU52aG1KQ3hlaThTYSty\\u000aUVpQMEx2aHAvekEwRWIxY1d0ek1VTUlFdUhJcDREa1hhY1dNZ2NuV3U0L2d4Q3Vi\\u000aMXhHaE5xWDI5U2p4SUhHeFdJRkNvQU9lVkNkL2xiSlFPS3V4R3BnMmR2RjdDUUhM\\u000adGYxQVRQaEQxRVNsNnR5dTg0dndWcTk3U3lTcktweWJxenZydHdSTFhwb0kyUHA5\\u000aWEd6S3BtaXIrT1Fva1dwSUhZTElzU0hmditDWjJDaW5aaUpEWWdtL3ZyOUZWdFpv\\u000aU0JKN2puYlA2TkpKYTlidGd0QzBFZnRTcGxPSHpicm1nMVR4M3gvNytTRlRGc1Yz\\u000ac29yejcwTWxIZE43M1ZjK3B2a080LzM4ZVF6SEFqdkhlTVgybGFMT1Ntb2Z5Nmpw\\u000aOVBWV1RMWFJmSi9kOTRNbmhaK1lvQ04vSVl2cWsyTzlPcDlzWnY3SGNHdHBMYlFr\\u000aUkh3WG9od1VpSFRxVkhEQVVxbEszUkdHdDk3ZHZJY1owSUdlRFJROGtULytCUTZ4\\u000aVGpxN3pvQmpMaGwxT2M1cUxkYldUM2FLbVNoL09Tb1BPWlR1OG5QYXROdjFIektB\\u000aOUE1UGovaDlRTCtGeldrMXM1MzZYRzJHaXRwckdiMERQaUF6MzVaU3dCdVpGbFBs\\u000acmpZbVhONWdsOEpwSVh5c3R0SFdqNTVDSWlJbHYrSnhGOXBGaSs3M0pHNkNUVkNa\\u000acVEzM2p0SmVWLzVsTnFJcGhUUUQzcS9rbDlGNTNPMGRQa0UwM01lWDJkS3p2VkV3\\u000aYldDbnNQMm5rVEhDMDloVDdkSjhVU3NMaElCZnZ4dFJ3VG1nbnRoSE5seVZrR1pK\\u000aWmxVa21QMXFHZU9tdmU4RjgzYlpSMTBNK1dyZmV1ZEJYbVJZUHgzRW5FVHkvK3B4\\u000ad1d1cVczd21WV2JxM3BsRnJCNFd3eUZuc2NNUkNuSjNuQlJQK3ZCYXprb0hpVXk0\\u000aOEJPVkJvMm0zWFRUVmRVcWRmbksvUlpXc0RhaEZKYnpWQ3cvSTlJM0lySkFRa1N2\\u000aSG1qUkRsMW5aeDdCaHU2WTR2ODZKa2dmSk5UMzRocHlYQkRaUW1YNEh0NXZacnlj\\u000aVTE0cTJ4SWVoUGNVRmMyZmQxMmNkWERvazVrSi94ZWF4Zi9RbDMxRUFzQ0xDR0x6\\u000aWFI1b24zL1VaMGtGNEx2Y3IvTVJ0VjhJWWdjbDUxcHlMbjhnbnh0ZmErVmZpMStD\\u000aQ1kySXFJUkpTeGtmWGgvTlhWam5MeFZaem42d1pGWFZ4UXBBUE03TjR5V1pkT242\\u000aMFlXK3ZCTmRGVExKZkxnTVA2UDBZWFZNRlpUVFRtVE04eWRGd2tFZDF2OUUrcysx\\u000abDRzNU50Z01yaEZVTkwxOVo0VVdSNVE5YTQwSXhhK3hBbVdPTElDQjFuUmxkZHll\\u000aeDdmVmtYSDE2WUV3RnZDVlpTWGRZODdaK3JENmZCbEtKL2lvandRbnZPV1hPS1dj\\u000aTmdEemc2bFoyYnVtREJpM1FlSllkNnU1Vk1ybGIxYk81dGZMa0xvM25ZMXROL2ZO\\u000aWmF2NDY1MnM3K3dRaFh4eVZ5bzMzQmY5d0VxaGxwN2pmcnRmY011MS9zcEhwQ1ls\\u000aOWF0MFdVbTR4UytaN3gybkgxUWtJanh4U3RaUVNmQ21LbzdiN0pGUFloVGg4QktR\\u000aQ2U2VnYzemYrUlloMkVNR0d5RXFMdWIvdG1Od2FnRGdGYXk3L3NEaTNTNnUzSmpy\\u000aQlE2b2R2ZkNrU240cytaYUdqb1I2VkNtUHF3VlorTXZQRXBKQURRUm5HS1ludlhs\\u000aUVU4dUo2MWpZNXpUUE0rUExaYytCNmdpdzZlZmNIenp6ejJJUmRPWEJGNFE0RVFO\\u000aek55ZVFrYTNoUUk5TWtFbnc0SDlZV2ljTkV4NVpKazR2NmJzeVl6T0Y3dVdiMi84\\u000ab09NNnRhWHdOWWFTSWRyQ1JxVGl3MFZOR3hVOFgvNGNwU05lSmNsRGRxVXg4TEli\\u000aazdxaCtXYkkwSnNLdHE4d3c0VDlvN3Q5MExpSTl6RWdjUisrbGVvajhxV2Z1aDZp\\u000aL0tzRGtTNFBHMmw1VFBqUWhWMHJaY1FhdW1hRzU3dXc1eUl0RnM4QVVlbTF6VWxN\\u000adjcydDhSalNnTWdBOWdWdGNCcUNlWjIwZzk4ZThWc1FwQ1Y2SDlpSWRIalZTZkFK\\u000aMG5MbnJud1BucWJPZFdvL2xJYXR4dnFSb2hwWFhyR2loSjBPMEpNNkw4Y0JJQlFl\\u000adkZxSE9qVlRIVGFpSVhxL2dQcThVUzZtcTNIS0U0S2tUR09zMXdzV0ZFRmpKei9m\\u000aeUxmYk5sVklIQ0tRTjhjb1lKdFNlSEZUMTNZdm8reTNBa1VRb2hWTno4RXg1TUJ4\\u000aMkYyeGtoZ1BLdDl2aUlLWXdGRlpOQVU5ZzZDWVRjOVY3WmtHTFRBT1JqQ0IwNTVm\\u000aTnBkSGVvRWpydElMU1lTMjZhV3Q1TmtnVVJsV2dEalpTN0t1UWZuY1dXMjQrOVND\\u000ab0xCV1VzSXhVTWVsZTEwZDhwbGxsZ01YRUR6aWEyc0NEemxvOFdOa2h2M3hZZjFT\\u000aYXBjMk8wTnVmS1p2NEVWMXhzMy8wblIrMHc1b3ZHa1UyY0ZXMnpBVUcwaGU2azhZ\\u000aTjR6QVJRallUem4wajNVa3F3Vkl5dGZuUlRYUzZEODZkTVAxaG9ETWY3N0duMzI1\\u000aRUpKM1lGanpFbEFjaURlRkgvMS93Wm4ybm1ST3hDU0p5SUxXNnJiTUdyV1JDSjc0\\u000acFNyNkZUcXRsVFdNWkExL01ZeEk4a0JlWThHaEQwWGZ4bWdPaTI5NjcxSHI4SFVL\\u000admNLYk8zWUxHemhqaEtCWklEWkNwanlUY3p6VkN0MzVOcXpGUnMzM1Z6Y0VDU0I0\\u000aWmVZSCtxS1RDZEhPK0J6VE9HOVh1am5HazJVb3BkdldldkovdVh0SDlmTGhUQjJn\\u000abUQ4azZSa3FSTnUzUjZlN1NJTlhpejFuc3pqMmo3QTlDNXE1c1VkNThjVTdNRlg3\\u000aMGkzVHJ0NUh0MloyaFNQY1hPNTU3Sk1LRVdVcFZxS1l0WmhQTWN1a2hHb0hVekJJ\\u000aTUV1bDlSYXo5c3M2RndsZHo1QmFvWDZJcW5yd2pGaXRnTjVnWUZpaHJEbmlXUVhx\\u000aaXQyTWtETmFROTIvWUlHRlJGMm5iaUdPWDFUamxqQ0VDMU1DQUwvSWxqRU4vM0ZZ\\u000aOEJLWElpdkU0RTNNRGt0eXJzWC8zOGxUZjN0YXZOVk5aVnFESHMxUmxuRUM4WEZI\\u000aUVFNZXdXWjF1RlZVM3pGOVVlcXYzcTRxZUVQREZ5R2lFN2dEV2tNbW5xYnZURiti\\u000aVysyMVJzTHBpbUphS3dqclRMTWtoaCt4Z3hvK0paWml4c1NxNXgrK0NCdEtOQ3BC\\u000aNkUwTnc1SUlnUnVzL1kwMmxQMWZ5OFVsdjU4eHBNUjVETWRmeHZ1cjlPd05BTTY4\\u000aNi9zeUwrbHVwVDZhNnRhOC82YlNPVWphNGRtMXgxWHBhWkZ1Qy9EMGxkU3ZPdTZv\\u000aQmhVVUtuYXhCalpIeXl1UkNQVlpwY0tFZDFkemE4THdJcjY0Q09CeDl5OVJSZTlV\\u000abmN0L1dIanlQSnZsWWx5OTBLZ3JFOWYzMUdkeEFoK2hHVjZrbWhIUUhpRnB2ckRi\\u000ad05tRWdhNzZlTHRLdHpGNDh2cDdZYWdOaERjZlBCbzVJMW5pOGxZcFFDeW50WVB1\\u000aWnRIZWNyNWFDQS9RSWpGZGdUSkRXaGJkVW5rbzgwa1RGRTZ1czByVUNuLzNrcUhK\\u000aeC9Lc2R3S0VxQ2ZzNUVhWW5LbVhvQW5HZWZYYVdoNkU4Mm96Tk5qVzhBSUpJcENJ\\u000aTTZrbkFjWi9mVGVjL255azZmTisyeXltaWFXWkN1ai9lS0piMWZFK1MybWxpbjEw\\u000aM05oWmtNTkJHUDNqTUF2K0l6dGVuMFFDazdySmJ6cmlTeUFGYml2aFB4bjZqQnlx\\u000aaTJKRU4xd29KOU9MYWwvaURBSXNoRXUwQ0dwQ1JMRnUralI5WE9zdktjNTdGVVo0\\u000aSHo2Z0ZBYjEvNkszWnNWSXRGZElvL2tmbHJ3Ukttc0hTN2VuZ1phOVdYSVFHb3FR\\u000ablVaYXVjb1JRVWEwa0haN0UwK0szNVpZa1lZVFRwUHJuQWhQbTJBaXdmRUpzVmQy\\u000aM0tnWUx6QW9tQ0J4Wm41RkFFd3lMVUZSTFAzOGRZR0hlZnhyR1FiemNzOUtpS3I2\\u000aQUFVRTVSM09yMHdDTUpLV1Jmbk9QZjZQdmtIdlcrSFZhZStBeEV6ZXF4TzFwOVVU\\u000ab1hoVlcra3NoRzZ3QTIvL2NkR3Y0MHJrVEh1RFE1c0Y3Q0ZGckNodlJZb0MwMzJJ\\u000aS01qa1Rzc2FKS3dqSEZlSVMzc0tjbmdEL05WR3pTK2xOcGNwSDg2RkJGQTd5SzNq\\u000aVzBrZHRmblRaLzlSSkNXblV0YXFpM3BFaWFlak0rbEs2cXRuVzdVcHhVV2o2K21x\\u000aZzNtb1FCUjZ2Yk4vS0xrSkpsUjhsUWNnQzVLamJLOUd4YXpGZlErbGprcGhKRHBi\\u000adERUZThEZ3dBSmlraGlZT1YzYjU4aTA5MXo1V0JZSmFtQmxodS80MzF2TWIwNFJw\\u000aVVdOSlphSEdySWdCNXNwdFV2SVNxSDRBYm9xN0ZNMVZjZS9pOXpMcXlGVVhXZEhl\\u000aaDBmTWFKUVp1S3NPNDFmQUtsNHhLWE9icUF6eXo5ampGTnJjZDQ4MlNZVzhrVGlW\\u000aZklEUHN3eFc2aEVhd1psaUxRYUtIa1pSU1JYempUVE4wc1draXhmU0dPTDRYNXNy\\u000adXVuajQxNDJyRW80L0NYRzhwODRWTnBrVmRXYk1USEIwT3JmcDdvQWdiLzFRUlZt\\u000aUmpyaUhMZ0Jzb25sWUJvQmNKaVpjb1ljNFJoVmROSnVGdldUaUg5MWM5dXZkdUsz\\u000aeHhoMDNlUCtTRld3Wm44NDZjZ2lGL1pDZTY0d0tVemNPT0JvbkoyVm1JZlFWYUdq\\u000aTmUyY1ZDZVNhM0IwUi9PZXBBRk1ZQmozTTM4djdabFJRUXJMVnRzVXZXMEtjbnRJ\\u000aaHZWa2NYVkpZM3RRYkFKWm44aVUzWnhiN2VvUnF0MjFGem9raVVWbzV6d0FuNDV6\\u000aZVVWUUEwaFhaN0s2K2RmUnJCSGFaMkRob0RLc3FaYkFjVDhTTExxY3dJTlBsdHha\\u000aWkUrUUdMSGc2SXhHdWZmT1VEaEtmdUtoVUlOQ0dwSisycjJqSEZrZGJRaTl1R0Ux\\u000acWh5WmtrcGhEcDRnZ2Z4RjB6QkNQZWJDOHBXRDAxaEdSUFdDVkNzRjBMdGlQV1Mv\\u000aSnU2Q09MWXZKeWhlWURYeWNFLy8wOUkxYTdYRGFaLzBLSWlhNjY5YWNZQ3pGWnEv\\u000aYkxkZjZoWWg1UHp6RlZYNjI4eUJuRnRvbm9MMGlSdlo3eEkvbXQ1alBFc05CYXgx\\u000abGhhdXZJVXlNVEdvM0xGcHZrYStiN2dYZmFPZXgyajZwb0FDdVVZKzJtZmY5Und2\\u000aWitVQThheFB1N3NydUdCaEpJZ2JyeUx0QlNwL09ZZlIzZ0ZSdjA0a3l2bVdkL2w5\\u000aTGxRanVwQ2JvUm81RjFVb09Lb28vQ2l2dWp4WmVDd09QSmdEYndNVWZ1ZUZLazcr\\u000acjFCcktGdWNzbVlhc1dYYUNua0I2TUxOVDdoeHFqYk1hM3JXcVVFa1JyNXJzWWZq\\u000aSFo3SloxdGZacHVyK1Y4M2c5V01rSkFFclhaQnRibFJMM0UxamNicmdBRXQ5MzZP\\u000aR2U3MndPTUg4akNMU2FSSzVUSHlWZmdiUDluYlcxeWdsNHdIQ0tmQlh6RVZ3bWpa\\u000aSmdKWWxtbHp0SnBNcTZJNWJBc2Y2aWlKNFJyQUJmV1VKbkdGNEhuL1RoYTBVZi9p\\u000aMEQrSi9ZUE1RNWIrTmRvajNuSU15UFk3blJ5WWNNVEpaa1lFSWJ1dzd2MXhxUGJz\\u000aTmlSZkczMmJ3dll3QlBVNTduN2lLZXJFTmpnQll6RFVSZWtmVWVxYWZtUHBPWFU2\\u000aZDBBRDJTcjM4M1BnekhsdW0wWmhEUUlnaThycmkyNVU1eDEvdmEyK1YwZWlCdnhH\\u000aTE40b0dZQjZ4a2ZFa3NNTkV4ZlpYU1dCdzlzVnBMeEVxclVqV1NGdk4xbjV5c2Nk\\u000aTi9JY3EzTDhvWDZ6WmR6bFFqWFN4amZ0L0hMR3FrSTVZTTM2K0V0MStXUFFLcG5t\\u000acEpVVnFWemJ1ei9VK0dpcUhSVGVqRDY2a01lUUJnWHB1djFRY3FBU21Tcmtyd21E\\u000aRmVCbXA0amxHV1NCM0R6djBHb2tvK1VrRWxENmRhSGtjQkJCeTlPWEdCTXhKemt5\\u000admNhQkpOY1E5KzN0SjNnVUI2c2QzR3l6ZGNienhMcWFPcFh0bkkyRVZjYXlLekRL\\u000aZ0E5RGRUNHpva3hTTzhObVFOTVMrdFprQ0hJK2ErQW5iSFRvNlJQZ3JpRVg0TG0y\\u000aTGJsUy9UZjRKbjlHaVh0V2V0UWNpbU12UXJxd0UrbTRmTEpURGgxb0ViRFhXL3Vw\\u000aSDdFTktQV3F5bEhwTFZTV2ZJcjR0QVJMaEl4NlhLeXNwYTJvY1h1UWpzRXkvVmZ3\\u000aQUlyMi9NNVZOR3JDcEdmY2Y5U3U4NTBEWFMzVUg1Ri9KM1ZEWlYwL2tiOXNVT09s\\u000aa3dnZ3VGYXR0T3l2QmZFTnNOeklUd2V2VC9mOXgzMjlyL1MxYlhJbmRvM3NHRmNk\\u000aQnlKWUFROGM4OXFaaDJsSHkrWmRvWlRiTXZESFhKOTdJVERwb2dHOExrYU1EUWhv\\u000aaExjOUhHRFluVnkrRGsxWE56d1RlajJmWS9qZWRXcUxXVDcvNm1kSmlUL1NmZW55\\u000aQ0lzQ01TU0tTZ2pVenY0TmY3SUVyeUpvYXhET1UvRGRpOTBXWjlBZ29MUi9JK0F5\\u000acDZ4ZERMV1BUZGpsa0RYbHRaQlp5MXRmV3N0QWpqM0Y0Sm5xMHBHcDBqTVJNUXg3\\u000aQWtHMGpycVFpamh6NCsvd1lrNFhLUGtsZDlQQXQ3b1lQbHdWRERMSGtIVTBOeXBs\\u000aMTVNa1lvRks5TWhNVWdJZWpoTU1UZER0eHV5Q05PVWkzUHVrdmFFVmN6SWI2RXpM\\u000ad0JyYUpzNjN0VmhPQ3lMdXBuZ2VOajNLNHltSWxhVlpHVUdxWDlrRERzbG5oZmpi\\u000aeU1Gd3lVUERtUFM3VlpJdDFVRjJZTWE1ODBjNXFpZnF2YWxFZktlQmFXdUMvOStX\\u000aREgyM3VvYjRiazMxT1JxUjRvbTNrdzZRSzhkaDZETHllNTRoSFVhdnIwNkZ6SWF5\\u000aNkZNcDZhMUljbnpGT0tremtDeWk2OW8vdFZyWHg0alVnYnNtcDlQaFUweVpKRHFH\\u000aYWFINjJyeEcwZEpkNUh3ZkZkUnpXbnBSV0JEajlFbkFkaE5VYnpLNVRJaWZaZE5h\\u000aNnJ2aXBsUk1ZK2N6ZW9CSTU0VHd5d2FPZ0dCcjJIaUVqRUhCY3pvWXdkSXNrY3Rt\\u000aRjZtZTA1N3U1RS9uMFVkTmMzbENJZXNqZml5SVdDTUxkeFNnQktXalBjSnRDSjRR\\u000aTmFFK2p2bUpCbk13cFI3enhOMU85b2tCWHFZWnozWUFUY1ZtdTgvY3V0NWs1Rk12\\u000aZTkxUlF3MysyL0FTVnRmdU91L1JOMTBYWm40ZldiWEZjcDI3NG02OUs2RkRYOVcz\\u000aNXVSWEhZeHp6OHl1L1k2TitVNzBoOStXL0psRi8zTFh4S3FveVlwZUtXdlVWRG1r\\u000aT1ArMUhhNmxNbm1BQm1Cdy9KYVg2WWN3bk1ibkZuekFVWTJvRE9lT2o0dkt6cWly\\u000aMkZMQXVUSWo1Q0VWZStHa3ZHRU4wTFNkNlZzTzIrNXBVRHc3b0FmU0IrUXd6bzFx\\u000aN2Urbm8vWWtuancwOVdEeEtpVWxoWHRqN2s5K1p1VjVWYWhmczR2bExLaVBPbmhI\\u000aQTFlRHdXRFlVdDdRSDRQUWUrZjhaV2dtcTFaTnhVUzE2Q2d0ZU9MYjFJZXVucERN\\u000aeFZUSFZaVy9sQmlzakFCaEJpY2x6a3cvWTkrcTlEdU1hbGQvU3plVHZVaXpvaUVi\\u000aM1RTVGluVUozUUt6a2lJWityOFJrdnB0WDlnZks4VWdva1BFa0tleGd3bFdmTjRr\\u000aRzMrdDlsaGw4Mm1oZzQ3bTk3Z252Qnc0L1JtOGlaNXJXRzhqOWlEbHJaMkJWVzRz\\u000aMGNmdmZsaUFTVjMzRElNenJveWFFaXBFdlZMTW96a0loTm9OdkZpRXp3NWpUdWgv\\u000aWXB3c0NtaVJ0NDVnUURyUzF2WE9lRzNSdmdPdC9rMXdhUWZIQ0ZjNkFlWVRKdXd4\\u000aWENMOU1laDFhd05qd3BFZThBbU9oK1dkYk92ZklvVXRVcXRXb1pkR0NXdWZoY0d6\\u000aNldESUxpYmUrZ1Rsem1sTitEQml3ZXRNMGt0N2V4eGg5ank5MTA0a2pkdTMydkIz\\u000aa054WWtOaUVsWUNSMnBBSHNhWC9mczE4YjJzdTRUUlRUSG1MWFVrbXdwcmhSUXpG\\u000aMkpVOWlWV3NmbEVqN2d6SlBMNGRyckxsKzkrUUdGUG44VHZFY2U2TTdLRGZUWkNP\\u000aV3o4Y0FjcW9ibVJjNGZDVFRNN0ZKRXVGUklIcXdvaERRYXZlOFJSUG5BZk1XckZy\\u000aTUJOekpUTWllY3lpWWZIcGE2U2NseExoaU9aYm8wbWo4OGpLN2FXVXdqdng2THRJ\\u000aQ3RqbTk1LzZQcjV1L05lUDJORFZ5dXVBK1pCRjl0YXNhOVBLbVY5K25uMUg5bU11\\u000aR2pndlQvUHJmMS9RUGFMUEltUjhOTFlPamdhb3crRUEzWVBZMytIT0RDQzVlRnZF\\u000aOC9PNVg2QmRpTElzVU9uL21ReUZSS0JHNEpySThkSzRyZlJXTmgvYXg3a0h5amFB\\u000aVkNGV2pQdGp4TDJjaFZ5UjBUMDE5eWdGUGwrRVZUcDFML2UxWGo0RjhRTFZzZGYz\\u000aUXNaM2g0ZGpvREVUZ3V0OFZTOTFuSDRnMzJPYjJndnEzOWtQRjNERzRjUU1kRzha\\u000aeFZEaWtIbTJrU0RjMThaTE82RkFqeXpncmp4ZWVaeFhvVzc3QWZGM1YyaWt1Yi94\\u000aamQvOFhJZzFNZHkwVHNEbGorVEpBUVVwOVBOZkN4MmxUNlBuN0dZMVNBUGptSS9a\\u000aUkVJSEdncEx4cUcrSkdBVXlROTR6b1ZnM3ZYOTNkZStXV1JEWWpxaXRXYjlvbU9R\\u000aYXhmVDF5Mk5yeWtib1pXaWNTb3lMWnhZVFU2bktrbTdUb3lMU2F5ZFo2MWhzUlB6\\u000aZXNlcDA3S3NxTU1Zc2lRT0J4VHN5a1EwcHhVenRqczRJeVkxWWtmcUdvaXZPQW9E\\u000aVStxN1dOTEpuRDZnd2x3bklSSUR3aVpuREJrckNZc0JFK3c4QUNoaTBiN3RqR3Qy\\u000aaG4zVmRjd0FabmQzOWo2RlF2Z0JtWGZERzlJRi9SUTBTNWN1OFh4OTNFaGhoOE9B\\u000aK1hTNlkyci9rbTZwTm9NaVA3TERJSk02SmRrVlRGT1h6VWszdzVrS1liQVZwRy9r\\u000aandjRGJnZVlHUkNxVHBmMFBXeG1YTU4zWjZtS2J6MVFaNnd0TGx4L0FNYTA1Tkgx\\u000aYk1zbE14TE1WWlEwdHNsdVVqSWNVamRNdGlTb3BaYzBOOWZDY3pmN3VBMUl4Skc4\\u000adFIwdnltdkVQSGdKVXVSYXhxZ1crSHV5eDd4ZVAvNVJGS2VBZmdNcTBzaS85OHVS\\u000aSFlZZFVORUZSUmQ4WXluR2lqZFlxZ1lZZkNnZnM4bmcyWDlsdnUzaFNIMkdQM2Z0\\u000aVUdMS295L24ybE43ekdjMFdxQWxDYXh0WWdNMFVwMmpQWDd2N2ZySUlTc0sxYmdX\\u000aSnZXN0xEQThJMjVEVDZaVkdOY244WkZ6RWV3VGJSdlBFNk9oeDdSc1ZBL2JwbVBP\\u000aR3prQ3N1V3A5OVhSa2tQQTNaQmluejJ1RXIzQ0NTRU04eitIeTZrV2RRTExSTlpO\\u000aZnQyV3dBWFVwc25tL0YwNmpVZXU4Nk4yWnNMeEN4S28xYnNYYlorKzNCM0NTMFYz\\u000aYXVBYXN5aGwwa1NWczI4eTdYaTFSajFZV1VabHNmQVYvR282SXZyNE5YTklpK1hY\\u000aWVJtaXNRVGI0UzNHUXRvRmhvcXdOZ1p1L3A1dzBmc2lVTDBFK1BDMjRvVkIzNzlj\\u000aUG1pUXUzdTZ5eE0vUVVCVW4vNlQ1U215MEszaUFGdTJEVU5ZRkg5NllEdFNZK0RV\\u000aVDJJVTByK1F2K24rYUJ2SC9xRmVLWXhNZTZMVlF4KzRNTk8xZzh5M0ZvYTNzckZV\\u000aT0R5azM3YlVrQUZWUXNPUWNEV2d4S2l0TU1kbWdpc0JwQXNNeTRXQTAvTnVqVGZy\\u000aUmZWVFRWVjFxWFJZL2dMVVNGbmMxMjNkbW11WEF4UjM1cFVzWERwbk0vallRcHRM\\u000aSmtNcHpPWnZmTEhNVmpVQU05WUtSOUhxSFBxaWVoN1ZZT0t4ZnlTL21ZbnpVWE1T\\u000ad3l1VHdRL0VLaEFkaVo1bHdhYnBhcEYwb1RCWWN3ZkVnejRRZDZjZVgvOWh0S0xx\\u000ab3o3RGpMVVlqRThPK1JxanpVeGJTbThvMnpHWG5yL1B3Mm5COEw4bE1yQlpTaUN4\\u000aUkJuK3lkeHZ0UnRGSm4yMWZMVmlqYzVOVFpDUVZ1bThGUlpTa2FLc2JkQmVERFNJ\\u000aaVJ3NGErY09mc3FPZjNQa2ZScTNraDJ6TUd6Ylk5b1MzWnFxSTJHdGowUmJaMFZ5\\u000ac1VTVWJnVU5uQ0lSR1RtOHE0T3J0Skp6Rk1oYm5Yc0R1MUxJbFY4b3ZTaW9VanZr\\u000aU2I3bnhQUTQxMGljZEt2NkczNmx0VFhVVkhnM0RzMFFrK2Vha3ErUk85clhBYkxD\\u000aYzBxTDhkOUFELys5NFZ0eEZ3a1M4NzltUmhGZDlZQ1FPVU9HYWRXbzJUYnoxM0hs\\u000aRDNUUUVvQ3JkQ0lwdGdhVTZ3WURjZzRtbi9IcW1aK1RuMzFJTERDejlvb2pPM2dl\\u000aYVE2aUR2eTlhVEl2TUdrKy9GR1B1emRHYmhRWmorSFFvbWNDaVMvYWxES3h0c0Nx\\u000aU3RkaWRQTmZwa3ZVSHA5UmNERHorVmlMMUlKRGcwVkg4N1N6VmNjd3Bva0NIaW9B\\u000aZGsyLy9SQ1lwbHFQWGdHbFZSV05jK0w1M3BhVFpPT3IrQXpFNUI5dVNFRDI4c0lw\\u000aVnZIb0lBbGhpZFNDT3M5UzJjdGhqYTk5WlQzREFMbFRYcFd3NDdpZmhkZ09aVkZU\\u000aNFJEYUlpMm9TMVp0SStkNXJSQ21PN1lEa3liNjhkc201UGlLZUVGdHJNYm1mcUNV\\u000adDhSWUNEd0dnNHF1UEI3Z3V3bExhNnhHczNJQTV3VVNJN0FUWC9CME9Jc1NsSFRO\\u000aZU1TYjlVbTdQTGhieUc3T1JKaXNLUjMwWEtkVFVRUjJGMzZWdzErZDVHMTBUWisz\\u000aaE9XSEc2bWlHU2hPZkFJY1hBN205VkFNWXhJM2lSUFBqLzE2STRGeExTdVFDYmFa\\u000aUmptb1hDRGRidHRYNXFqS0NXRDBBTEl3RmZ1VEFMNlVQV0NDYzRKOHpnMnJpc2pm\\u000aZ09tU015RUJ6UHVBRkc1Uk1lZi9DNGJzdHVGd1JDaUc1WkZlNmhyMUE0RkxLODAw\\u000aemw2ZDVjYkQzN3Q3amxXNmIwVHZpaVFrUS81K2dqak5QaXdPTGxPRU8vWHhXN1gv\\u000ac00zWm1EZlovZUhLMDM3VXd0QkRpNTBGaURXSHJON2svNXladnZFL2lUcUh4OHBW\\u000aSjZ4UXF2QWdLRlpFamE1Y0hEcE5MdWFTb0RIMjBzelNNL0NmU3g1SyttZ2c4L2ht\\u000aRHlBbXVPT3RJVnk4N2RQY1phUWcyZ1d0K05vbnN5eXgwR2k0eGNuNWZEZzVPQ0xT\\u000aeC81dm95REJNQnltZFp3aS9QSEtBZlRMWlBlaGlvemRDb21vS01nQ21JQ2tJS0hl\\u000aM2M0TkFTN1B2S1hSWDI3V2gwbk1aNFo5TUQxVzlVeUIvMFVoVjJQUHdLVnpvY09w\\u000aT3NEZk1WWXI0TXdxZjlXTEtFME9BQ0E2T1ppZFJYRnBKN0lUNW8wMFNzNStXZTNh\\u000aa3dER0hRRVhPN1JQc0U5SzloVmJDUDBuUk1YUDU3bFZ4WXBPRG5pRS9lK21MekFT\\u000aVm5rVlYvWUM2N0ovM1E5ZXpQdlE5VzJYcDFRTzlRUjRkVGpnTTEyRVBmUEpyTDV3\\u000aaUxaeW0zeitVNlNpUFFXQTNMSDVOdzVCQlRGMGlGRGxOaEExTVorUlIzRXU5eEQ4\\u000aWkVaV0VMMkIySGR1L1JGcDRkaFI2VE9FZDNTTDhIaDJYcm9pRE1YVnBnWU5FS1lG\\u000abENQMnlDTUNsQkFEcnNuQWVRR1Q0bVh0Rm5aMmVCSGtHNEhTUVRtQkM1NVgzRjMv\\u000aYTAxRmtNcTBtelYwSWVzUGM2UTRVc1lMWHZIQkl4L1lrT2hhTnVMMmprWnRGejdL\\u000aTDFQblRESEt5bWJJcFc1RFZuVDlFU3pHbUlDSG0xZ0lleVRMN0x5MldSTCtBTFdw\\u000aOW1aaHhJS2FxdmdmK29jNWFGaGlQellEaDFjS3ZxVDdHakxBTHk1amJrbDI4QzhO\\u000aSlFXZU9QR0hFVjRsUXJmNy9oejEzK0VrTGRaUHJuM2tJOGVzVStURXVST3pkSXN4\\u000aWUgrU1hpOGhxeGt1ZVByN0Z2aEF6bXk1WWFXYTZJT3JHNkM1RTZNTndCcmhVYXNF\\u000aMlQ5bE5OcG05a0Ywc0o5aTFud2o3WW93S3BnTVR2cWJFWUszTE05SGUzMnhRN3ZI\\u000aN2dncHloVmhBYk85cCtBZHQzT0lsanVrTC9NUGxRM3dnWDNyS1lBM205RWlyaDJ4\\u000adHhQVWR6cTI2NzNabjMwaU9vcWRBQzhVaGZFN1R2RUdMS2dZb0FlSGlqMS8wekRC\\u000aUEJNUVkyaWNwblpyK2dNV2huRlBtN1dXUmNkQ00yOFhsZTVBa3ZoSGtmM25tOU9P\\u000aV0RESStERkRPOHJhQ0N5SzI0QVhMNWxMZWwySTRlTW8zNU5kT1dRaWtidU0vWlNW\\u000aM3Y1WUdSMjB1OHlSajdrZ2Uva2FvSXk5ck8xaFA1MDFxV0xOd2owUFpIZTZ3TDhI\\u000aT1d5WHhnMmZweFRlbjRpUVFRcDJqRmEzR3hJbDk5U042emJvcEVZL3FGa0hjR2t3\\u000aeFk5S3EyOE01Rzc0ek1xK1JaTFYxVFVRV1h0Sk9lOHZWUDFkMDZPRHFSMlZrOUla\\u000aaTRwSGd5Zk9XNlBWT01WcVRGRkpJWU53cW04alJCakV2OUZ3dUluajA3ekpXRUp2\\u000aMC9sdXdaRFQ4R3pEY0RoaHdyWVFFR3BaVkl1ZVlXbkRoZnRxVkloS25zTW5KREFG\\u000aQ04zSEhFTG1VbjdJRVpIdU9Sa3A0alpSc0x6dTliK1RmSDhGYmU1d0pJVHBiSDhB\\u000adzhweUx6VTdqMk5xd28vYU5oZ0FUUmcxL3BERWpOWlArcEJ1T3hIRy9ldVM4YTBz\\u000aeEVETXFTclUxSG5jaWxFSkpMRU9yZ0tURkx2ZDB0eE8wamRGUGFLOGttRWtmWVVn\\u000aSDdJbTNudVQxSjVScDEvRXR1d0E1Mmg3YTVHWEhaTmduR2hzbE9kN1ZRLzBCQ1dL\\u000aNG9OaHBTY0FybUZibEhVMDRLY1V4dlAzV2MwNGZJOEV5ZHdZczFDbm1iLzQ1TXU3\\u000abnRCM1RkUDJOdXVoZlZHQUJyOEF5eS9UTDBSYytZdTcyQUxFZ0w2MkNtekNyOG9R\\u000aaExEVkQ2RnRDM29PQ3lMNXJhbVNKTzVXZ2d4bTA1WlE1UFN0TWx2RmVrNnhnd216\\u000aeUNBSTRzUkc1SUV3NTQvM2N0TjZxUzRYTEFVVWNlRUg0eUQ3N1VyZEdmdWw0dU91\\u000aOGNJZEk3alFkcGZQMW5XSjZRZUgvRDFCUEZOREtwQkhCY3hRbjd3aTBGckZOSTZw\\u000aTFpEeTFZYjhYNHQxaVkvVzE1b0NQUGw1a0hoOGpyeXpUb2tRN3NSbWcvaHh0UEpv\\u000aaHNqM3dSeW9OS2ZWSHMzbzg4dExWTlpQYUNPKzhUWGxlRm5ycGU0N01QZE9ldU5n\\u000ac0luaWk4a0s4bDJ0UUVpMlVpTmtER1pGdGliR2pxdXE5cm9nUWpSMXZMNDF2czBy\\u000aaGdXL1I5OHp4RDgzUzV3c29qQndEWXpPTzBtNDB2WVFFUEVoV0NXV043SlRaWEN4\\u000aMXR2U0hDMmZUSDREa3RjaHkya29CZ28zUDdYTXZPUnYyU0w3ZGkrajlKdkVqVWxx\\u000aVkRFTWRQRDc2b1RYYXh5T3lLUzVVbE4xTDJYbWk3QlRYMmlxL2xueGwyd2VONEx6\\u000aWFBsTmdEaHN0KzRSS1VtYVB4a1QrdlJpdTZ6b3dEV0ZlNGQwUHE2azhRZU1HT1My\\u000aUFFETnhuWHNXUXZoc0UvWGJ1SEl2Y1ptUVlKTjh2bHdGSjBzdnFkV05URWlDNGdJ\\u000aWlJxWHJ1MnUybG03b2RCSVZrdjUwcVVnRENLVG9xS2tkdkYwOVhnKzZsOUNiZjJy\\u000aQWE3d1RjMlU0ZEVtR3VxZ1pyR3VYRnhVZmlKYVR5TFE5KzFLcDNnZFRJQTVFVVRZ\\u000aOUs4cWhnS2lHdjNlQmdIamU1VXhITUMvMGFwWGhiNkFySEM3RW5yOHhEbmN5YU5v\\u000aOXJmSTBjT3RCT1g1QVZsS0xZcVdnWEp1bDZTNmZSWWpvdVVjaVF2UHpBRU1iUERV\\u000aaU95ZVVTQzd6SHpHcTZ4LzlBQXFySEZrbkIxS1lYdFJYWk5zQlNJRCtTV2NNMEZG\\u000aK1B5amxJbVQ0K2pYOFJBVjVGdTNpL09hcjBJNk1NVldSZzhNQ1RsRzVWWDd3cmt4\\u000aQ2pGUW5scGs4U2NrbzlRZkNjb1FsTlhyK1Fuay9rcFROOHJHQktvQ0xZVkpNWS83\\u000aa2RYZlluOXBOWTJXejlYSlJXcXh1dFRoMXU0K0ZZUzcrY2h5b3g0Q3ZHTTZjR1BP\\u000adDFZY1BJMjl3cnlYOTFiMks1MWdOQkNzSThPQlJXTkdkdXhMUzA3aDh3eDFSOHVS\\u000aY2dETm9kWnJQQ0pnQ3ovYjd5R0EyMDFManUySEFqeUR4N0pnOUJzTmJ3dTZnZW1z\\u000ackNnOHpJQjdZOFdsQWZueUhuOWRma1dhNFRZMGx6VEZoUStOZUtEM1RaUklrV21J\\u000aQkpUcitwaW1FWmJUSFIxSk5PeUh4L0M0cFlTem94MXhGYmMxbndMck5rd1lyRElN\\u000aM3YxaDQ4eldub3Zad2hIUmk5d1kxdngzQ3RiVXVOMVYwZnVGU0U4K1pvYmNaYzd4\\u000aZDVNdUJ4RW1rYUFneWJSQ2JSRlZvUFgxdjdGMklkZGd3TFRYM1ozSGNZdG85eWJM\\u000acWowZ0FNbUpadTJGM3pYUkkxUFczc25STFpubTd6TnBCYVUrL1luQzRjSUlYL0Er\\u000aMy9zZ0tYeDR1U2tqTGlwN2lTU2xoTTRmZFQwcFBSaUVoTkRyTG16UzErWmM1UXpN\\u000aaVVFVGM5L3Q4bFJDa0E1UXhYZkdmZmJvTFNGT2VMNTV5NWEzYXhNMUtZK0VzOFBx\\u000aRnk0cGhYY0dLVHZ6dDcrdXRlOEVUdWJKUUR2cStFUnhTeWkwWm9kK2RyTC9zSmty\\u000aa2tMRnU0ZGEzOTlkS3VobGRMekM3MlZxS3VDTUN6eGtOU2NOT3ZRSlRYVHlEblkz\\u000aa3pXRnFKK2l6SXRvTm9ydVRNUEJTNkpOMEJWQmlBOFF2bjhWd1dyOXEySDBzWlJ2\\u000aNWxsUkZZZnM1bEZ5TkI5bkpONnVPZ2JMU0pNSm02ZGc2NHlITDdFOXE4OE5rZDVx\\u000aMXVhY21pd0VUN0VzVGpSUXdLMm5oN05lMC96VGVpSzdiVG1RMW1KUGpwZEEycXp6\\u000aZ3lIRGoxRVlNenhoZFZIb3lHQW4wWlhDak96T21SR0F3U05pY3VhR1I3aERpRzNU\\u000aZllxSkxLWUorUHBnYTh4NlRha0xwcnZyK2F4c01wSWNPWkFpQy9jQUV0REFQV1lN\\u000aQmZaeEI3cFdSR2NqVThPbDhzUnlwTXZ4ZDByWlpoZDR6K2NSQ0p4aEM2RDl4blMv\\u000aVHd5MWVxOFd5TmNLdDYyRkVaU0dMWXFCaWVUSUp6ODRLMnpTWFdYVzBDZnhrcDVu\\u000aZXlnbTc2eFlyWmJLUndPcmxuRVFwaEVUbVl1SzB6RjdtOERKOVBtNlBNeVl3SVVP\\u000aL2t5aVYwU0R3WW5CM05HMFdSNEtFN01jOUZOMWFtM3l2N2IvOFBPRWlNVDBpK2o5\\u000aWm5lajRMT2ZVcnVVTDBqc1UyRkxSLy9RVXpaZUpxL2NaenBKc1VEY2ZvcW1qNERI\\u000abTk1YW5IQXNPdnZJZXBqdDJsQ0dLZVExRm1yb1h1NzQyc1BQMndySmtyMDd1SThM\\u000abnN0R2xucFNPNzZ2ZnRDa2kvYjc4THJOc0VIRm42ZDgzM1JXbzUrWVhaUXllWWUw\\u000aUEovWUpad0c4bFkyRS9YZWFrTjAxSjJpT2tNK0lmVkhnYWsvUG5PRVhhOFFqOXdu\\u000aejBNKzY5eVFGVksyVDJxRW5PUmtEZmtacFJtM2x0WXdqcFhCbDJrdDVKUE5qVStH\\u000ad1A5SjJHdExWR2IyNmJleCs1QmlVNWtxbUQzaGdHUlRsVmp1WXFkS3pYL3Z5bVJP\\u000acm9MZWhHMEZtMjFpYXFvZitQd1I3ZmlOUHh4WitLa1Axb2JGb2xDalo3S2o0OWdj\\u000aR1JNSnE5U3lya3BWcVkwS21YMGw1SnpERE9QUWdiRDhlRlQ1ckhjbFc2SHVCZFdB\\u000aOHAyckhQNG5BaXhiazIrSGRsMG5Rd3QwalNwUHNsSmJrYkpYQWtaZnZJNVVwU0RY\\u000aZGpRQmlXOFNJRWY1QXhPaUFveEdGQksxKzZzS2xJMzMzNCtKYmlSOVZDQlE1akQx\\u000acjM0MnlPcDlzc2VjZEFGVmRNQXZOQk1jQlQ3Nmx1ZmVlRkNCUFRQOC9sZFF4dmxy\\u000ac1Z0SEZoRHBHa2FYSk9hck5TVlV6d25uU0djTTZUMEM3ZTJLV3l3VUpLb1pYdmwv\\u000ac3czdG5KaFhTaDE5SUJxS3BLYjBTV1piTTZFaHlPTmZHc0hqSkhuR28rVHlBQlRu\\u000abWtNY25tTkxPSjcxYzNnMjJKdk8zS0diMGRQZTNYMTEyS09LNmpEdFZPVjRIS1Ax\\u000aK3UzRkRCT2pqYWU2SC8vYjN4RVNXWTB0VmlNSEN2YUVVYkhKL0dyQXpNWElwNTNB\\u000aYVRoSXEzVlVOckJlTDVraFFjbDl3ejcxM3JLRHkzSG0wRWxnQUpYSEt2cHpYS3BC\\u000aUm1pUDFJVHdRQ1F6L3lTREF5ZldpK2pxT0hNdUxaR1oxcW9qT3V1UnhIdWFTeU95\\u000aQWFwU3F3TUtFQTlIeGlZeFB3UUEvcHFySENJS0JDRWtSUnRrNDloQlY2VXdsOVdv\\u000aMnlJQm11cC93UE9rRVVRRW9NckxKL1FMSlZyUzd0N3BaRkNXdmdwV3RoZXcwMjBj\\u000aNTQ4QmkreEl5UjdFeVFmaXB4NmFtM3JzUUNLdDdMTXIwTXkvNVBkL2d4bWVNRjlG\\u000aUmNCdUtEQ3FlWEwzeWZWZmhwMjZQQzZTenFBdmJsbzh2ZG9EWXZKenFkWGVlMXFw\\u000aYzJmeHF6bFBkMXpicEJzeTh5NjRMM2V6M1NqWDBubnMwU2NvaVVuQkozci9hUG1E\\u000aR2tzUU1UaFBlbzVOcWpVTmc2d3FUQXlDMThqc1ByNkd0VXFMQ3lSOU9UZW5RaDdM\\u000aNXVSK0FMTVRscC81N1pMMjJkc2liUUJEdmVhNEtISGhzWjZzbDBGKy9YdmR5a1gr\\u000aZWU1eExVMnFES1RlRVkwNmt3elNQSTVxWkYrTXRtVVJTUWtoYVRuRGJYRy9kd1Ir\\u000aaHdRb1RQcXpBeURLRi9ITmRZVDdzM0lxYS9zQkEyTjJZVXFJbElId3Y1TUFGclE5\\u000abXYwbFhrc0FHbzF6TUpKdVRNUFY4alFmdDh0NFB4aUY1Uml6b0s4cWI4TjBLK3RQ\\u000aTGRJdWJtcnlJRitYSXhkV0t6NDhvMWR5MWYyalFIV0V5eVJNZTNvM2NTSCtDRU5S\\u000aanM2aDdPUjhyekd3ZFJxVmlEeHRtR3FMc3lhYVZYWUoreVZ4Zm5kNmg1RGNTNlI2\\u000aclAzOS96WEtSS0dYU05zd0EyMjBjTy9ER3VsYVdtT0pLand1TkNFRHpFM01sWHc2\\u000aLzB1cllNUktsVUVVTmpDTVVxbEFPSUJ1Y3g5YnhEYmpzU0lHN0wrSDUzSFFXZnI4\\u000abVlaOXhjYnFidXc2Yk1PQi94Z28xK0RyZkQ3VzJ3YVdoOGpKUW03NFN1L1ltQldT\\u000aUjBOVEQyNXd5R21zTVJOYmZvS3VTbUZNM05pVXdOcU40eVNQa1FOaTZod1ErNmVC\\u000aT2lPcmY3aDJqdE1VUU1HVFk2dEYyZzhzUVRRZVRVa0NqRkordExVVXBlR3BRaTE2\\u000aKytHa0UwV1dJWlBzeGtuT2Q0U1lXdHZBUWxBWTV3RXlTejFYQVNLNU45cmx3TldX\\u000aWE4vSjVIaVZacE5tVDUycjkvSTlzRlhpeWN4d3NPL1prd3lMeWFnaUw1cE9hQ1g5\\u000aUzJuNmVDcmk0cjBpcUtSWTE0QlhaZEdrNGlnbHpQR2tPMU1zc3JEU2FsejZIdGJY\\u000aMWgyd1VSMHdTZGlETHpUc3o1QmR6USs1ZlVwOHMxNkFicWlxQU82Y2Y3WlpPRWFs\\u000aOFBVZlI1bzZQZ2llZVFqN1lQUjdqcmVtT1RwUDZqaXZZLzFyQzBJYThLQ2pyNzF1\\u000adVBEa3VVVlZ0MXJiZzNZaCtWVE00aWU5VS95U3lXSFUwejZIbU1icHZCZ3AzUTV5\\u000aaXN2azdtVFFDdE1uNkR5VTlKSWlDRHBhZWVGUGpaVWJiSXRqbytiWFV2SW5ZbUxu\\u000aankwaUVJYW80YmhOcERGSjAzcnltQ3NMeTRSb1ZZczQ4NWxMd3hEcEFLbG4vMWFY\\u000abUFiK0p2VFFlTE1xNmMrRUtqR1FITXJycmU2T3VaamxiKzRDVVlBYkdLclA3b2Mz\\u000aL0tVL0JrTGVpdm9lQjFXaUgvSHBncDZSNVh3VTNvUXBXTUtlc244UkhMU0NsYWUz\\u000aaW5ic2FsNUpGK25KUDFSaXZldnNya0IyMWU0OXcxU2NIbmJVdDgrZEJJc1ZqOGhD\\u000aT1p2SjdqTVR1YUJteDV6UnJGUk9OSHJuTjdOMlFPQklpUmxDVFRmSUJTci8zdkwr\\u000admxObm9GLzlMcTU5c1gxY0JrVk9qQmI5cEFJRm85TnFRMHFLdGw1YXZiSkxXdG02\\u000aa21lei9xcG9HT0FRWnF3VE4xeHpwTWtSRTBpVExPQk50TkcyazM1RUJwUUI4WmQr\\u000aekFJM3d2ZGFPV3FsRk1oSHVQTHVTejliaHhEa1RicTVwSzhMWGxNVldURFVUM29L\\u000aM0g5d1M4bTE4aW9IRnpPUUtSMnVXc0FrZ09yMEt5b0Iyb1pEN0cxejJOYWNLTmgr\\u000aOFlyZXdOanVnZTBSbDJaWmVSVkNLc015UTRqT0diSmV5K1hQWkVyWHRGNWtsMC8w\\u000aZDdMT3BVQjRUcWM2NVp3NmpBOTFRK0c0dURuN0xicXY5LzVoUFllblBHeHM2Snhl\\u000aQVNhTW41OVR4L2JYUlEyQVIrbnpyNDRMTG9xVEN2dzJCRzJ5ZlBzb3pwZlpITlIv\\u000aMWE3cGRRdjdvVzhwdWV2WjYrb1p5R3p1NDhPRmRTZjFjWnNVMUhXdnUxd2J0blgx\\u000aSGdFWU1hNm10MWR4WjlNMktzMWpMc252eDdyTjJBMHlUeXA3WndadTZCQlRTeHVS\\u000aSjJiYjY4THJFZDlSbU9FN0VKZkhpZjB1a0tKWnIwZndJM2o5bkNnWk1hMml2Yzk0\\u000ac0NSMXV5c2pWcGc3d2FoOGUyRkg5cFN4U2VZa3RqVzBnY3ZvVndLNmZiRThiWVp5\\u000aQU1DL1A0Z2JxSlRIWkZzeVA3dVVIaVhQdXoxTEhnNXdOSk5BdXYxSFEvVTlLQlBF\\u000ac1lKd1R3YmxEa0RqK0RCbE4yZEVtVHpaVkpWbGU4SGlINGhzT1NoNDQ1Q2xHREFn\\u000aL2hZTE1kYTBqSDJaS2NneVZSMnhNMVlYd3NMZTR3QnNBNUdLRkJTWERFQjZmMkIv\\u000adDJIU3VZczFmNldpbEFEaDBqaU1JcllTTnM0Z2tOTFJYU3IxbkxpaGxMV1FWNzZk\\u000aU09YOW55MTJONFFwZ2wxTzVSSzUwWjB4SktNNE0xN09xZldHcVVFNnlSYWx5V29D\\u000aakFjZzhSdE5TZzViSjhDUnRQaFJFcnNZeE51VzRVZHJSaEk5dThxU3dERTl5QmNQ\\u000aUWoyUzhodm9FYlRMbXV0SW9zRXdvdFFOeXVvU1NuN2lVQXJwSWpuVzhLc1U2VTAy\\u000aeCtzd2NYSDl4VU92ZE9ZczhCWE1tSC84bXFxV0UzMkpVcGJGNUlaWEw3TUIzMEc1\\u000aTTg2NFZmWG5HK1FUbmkzbFlSWEhyd0Z4R1FPUTY0M2hzVkZDSVVvYVhiczRkM2RE\\u000aajZPUVZhVGxtM0k4R0ttYVNNSSszR0pYNWZFVHNOYkdGcCs0ZStNZEZkak1Yb1hR\\u000abjZjSFVGN3NYd2FIVVRtekphNDZaZDBLSjVVeEdicU1oMUo5cWJLamUvWWJzNjNZ\\u000aTjAzanNWNGljZy9qNngzb1VvRWdnd2lDSW1td3pIbDZVd20zNGNmZ3g2WEFJM3BW\\u000aaTIxMHhBTll3K2M4WDNPbGxnbHlEWjlaOHE1bTZOMnV6UUZMTFRDYzVIUVU2eWkx\\u000aU2g5d2pjOUdkakJSSDErdFZ2cVVDbnUrZXZNanBZL1A4R1hDZXRIdEhGa2xER3dF\\u000aMnNQRUI1WkZVZFkvcm9WeDdRczVSWVpkMVdOVEovRkMxRk1YTkVtTkNqRFNUUk9X\\u000aVUZlaHF2d3RjUmVQVHdkdEdjVWdONmVqSXBOdTlzSWNoUFI3UkVOYWtRRWR2UERF\\u000adWl0dWpQc1g5a2ptV3A3TnB6MU1XQzV3MGlEOXdLVkhHc01jWGF1SlBwVFVCdzUz\\u000aS2M5RTNGc3F3Q0J1cGNscDRZMWpzRk94WkYrbTBweFlnSUxPS2JSTjBjZHFGT2ll\\u000aRzhKcVJidXBpaGovOEpwaVg2RlI4dWxXSXZzZ3RSU21pSVZodlo5L3V5cjVXbkxJ\\u000aNklDV1hWVHRWYVY0clF0QUFSV1VlY0JYY0FXRHcwOEhzL0sydGpNQ0t3WXIxYzg4\\u000aSU4veXdaVnBuT0lveHdxNU9wczg3cnBqS2hvaHlCMk9ORUlNZlBEM0hYZG9OQWRY\\u000aTlF0SysreG4xN05XNHF0WHFxQitFeFRDNWRGQVpvT0I3QnpiVFdKbjV4NGMvUTNw\\u000aeEMxY3Q4L291ZERnQ1drTGZpT0NYWEwxbzlqRjN4SEsvL3hhMEducFh3Nm1IRndw\\u000aNW5XZk5UMFFDSmRJcWRrM05WbklIcTJwRmhSTDFwSUptdHBTOUNuSlFiNWZLVkcr\\u000aNXFTM2pXMkNzdTZTTWFiSkpNQm5vT2l0cWpTRzJxL0pIMENKaElCZk5IeXVxK1NF\\u000aN3FhaEJmZ2dtNlRQUkMzWXFjc2V1R2Zqa1N2RnBXN3hNU3c2QlNvZWljdktVTUNp\\u000aQW1GQVB1MXBNam5MMUp3VkpFUkxHcVZrVFdZanZqanduY0pWZWhJQTFNeHNHWWsv\\u000ab0ZpbnF5TDVsSVUySmNYMi9kcXlKclB1dzR6eWxIU0ZXT0FPSWtsSEN6eVFSN0lr\\u000aeFphbGJDYmpjWGRFVFZFV1YxSnJsZzVaMHhNbG5jYnZjQnUyNWtUMC9oYmh0alNK\\u000aUnJMU0dqOGx0Vm9ONCtCWmt4Y1ZTVUtLVGhSTGtKeENBdlQwV0RkQjM4aDh3eWtD\\u000aODVib0ZmU092UWsvdXFWalczK3ZzY283V2NzRmE2OEVKdWN1Y1Y1QzhiOEJ2dFV4\\u000aRWRiUXZuMlNkcjNUTEFqazlsQ2ZtcUM2Mm05VEpHOXVxdi9Fc1BxNmxtWFNLdHpv\\u000aWmo2Z1Z5ZGd2T2FXajZLMnF2R20xSGZiOTlpWkdhWEV3Y1U1bUZGNVBZYlMrdVVl\\u000aTlRPODgwdTl1dVJlYzJlR2dBMVR4SlZTVHY3N3ZuRTI4cnBzQUZycWl0ZklwTXll\\u000aUW10RzAvQU05bTNMelJmT3dLNTRBeEdDRk5CV2txYmpRUll0bUlaa0hWdDVkQS9Z\\u000aaXF3KytQQjkxaWJIQ0l3WnAwdWYvL1AzdHRzVDRHUy9KNjBoZ2pWNEJwek5FVVJJ\\u000aODNkSEo2SGZHM2dlaXlNeGYwd0ZuNjVpd1loc2s0bng2WjlleDVEN0J6Y0U5K24z\\u000aWFVBVkJmcXV1V3d2Qitxb0RBK1RpMVRDQ1gzTElteVM2RkhJZU50Y0lOQTc0UldO\\u000ac3ZtY01mZTlYUi9IQ1RERzMydXk3QzhiR29RQ3JFcllreTRXTVlhSGZScXN2cjRa\\u000aWGV6TGpENTJkbHkrV3UxQVd0YmtxbzU4am9pNzgrYjhhaEREVG5ib2ZFOXdoeGxW\\u000abTdGYXB0Z2NET3E1TER1WDlNTHdZRmM2WGludDZIUGtHMUhoeE1rMGdIRk1xTzJs\\u000acm1lQ09nb2t2MndwYk1MZ0txRUxZR252amNzR3R3WDZQMzlWNnlFRmcrOCtFZzFP\\u000aR2tRUmkvbzRScTRjSm1QZ0x6ajZKVC9FK1VZV2NjQitLaXc4S29NOEJBVGVsNEsz\\u000aVFlhcHlBeUVyYW13d1NGWldKOGJDdUx6WWNRODVEWkxCRy9UaWtDUHA2RmZzQy9V\\u000aNDBCWGdzZ2IvOERKS3U4SnNQRWZ5WEhFR1I2cEZSVHoyVmE0YXRiL1hCc3NMcmpm\\u000aTUsrTVJ3dXZnTTZmQjBjbUh5eXRkbjVrdVBCUitSa0FnLzgwMVRhR3RJUml5UnlQ\\u000aYmU2aXZSa21tY29idTVGc3F4eFlCa3V0VUxoZm1JaE5Ma3EvQUhvWGZZTzdpZnRW\\u000aMkljTmE2QkZQU0NaajZ1SlY2MDBKN2swRjRnZ292UmVWZmlTMFFoSk5TeEZ2YUQ4\\u000aZVRuUHlVc21SWjY3blMvenp4QVFyN0FrTXN1S2xLVlBReVlVOTAwcFZsaGRlNEVH\\u000aalRTREcxTjYvV0crdWN0SFo3Mm1DM3VYQTdoUUVLZEdxbUs5WER6Qmp2MU1UWDQ1\\u000aakhFR3JWbU5GaytKVHJFSkVsdEdRTmJqRE96UklORklxMVgzalRtN1pZTWQ4MVNv\\u000aOS91Tk14Y2hDcXExUzkybHMrUkl0elJJSVRjZVVDMkp5NVdtQjUzUHNqdDNWYW4x\\u000aSThBaTN1OUxUa2djaGk4N2QyNXVRbEhFd0RGMWZydjgrb3NubUZBQy9GbXQ0YXA3\\u000abjRKenFzVUhDV0RucVU4RjNEVVBTRXBsSEY2UFFNc04wd0JnaEdDNmdpTDFVU2ti\\u000aci81UUlhNlZWV1B1MHE5OFdyVlNCT2dnMUxHVVZvUFVXOHdlaWdRelpXYW1PU1hs\\u000aY0FkL2lrQmVaSW9iVlY5VDlDZytWbUN4Ynk2eGhBL2kvRzZDSmVjc0c4UnpTM1dN\\u000aY1did3RyeFZicy82bVhoWGtRZWhCckhTSDZyUTdvckdMakljQk52WXRyR3FJeFF4\\u000aNDRKQjJIdUdyTUR2QW9rSEJCYXMvWlBsOGdOTVZ0L2ZqQm1ZbFdRSi84WFdBT0Rm\\u000aa0JHMG5HLzRBUldUanpkM1lsb2xKQW10Qnp0YkNGWWkvNTlaWFZvV1hBbVg2b0g3\\u000aNUhvZmcrRHdmQW1nalYzR0VvKzhUR3VnQ1BqMFRJRERvUEUzV0IvR0wvUlAyRHRz\\u000aZVZ3c0pxak1UM0tWYjVTTHZkdjNLWFJXdVF4K2JNaVZCckZQSy9uKzhZNTJENjJi\\u000aT1NPZHVka01jQVVnaHpuRUpNWUJPZGtZNnplUjRLbnljVW5wc2xiTXhVRUtsMGht\\u000aL0JiM0FCUWdzMXVGZmg5QUVEUjJ0ZmJKNEd5RE5lZSswVEVYbDlTRHFRazB1eFAv\\u000aTEFMTUp2Z1ZPdHZqaVg1bjQ5a21icVdQbldWRGo2OUxPNGgxN05IWFNhQU9uNHk4\\u000acnVrSnh0akw4VTZLdTNST0tjMnlEZVpwNUc0V1dUNVVndjJQSUdyencyM2FqMWNj\\u000abE0ycmpqeFF2V1RQS0cvaDl5bm9GWjMzWm5LNkdGSnRYUTJFQ21VTGZ4OVZ3UDZj\\u000adWpzdVNwRVQwUlo5NXk4Tzc1dmNBRnhXNnpubnZSNkkvRlBxbHE3MzM5UnBJRUFH\\u000aTFRuaUQvZkJLSi9hS1RyMXlaM0IveldiVmlsYkdYWlp3UW9uZnptYy9qS1orVTl6\\u000aWXlTMTZ2Yy9TV0k0aytiQmpNM2hoS1pKaWJFeGpGalpIQStVU2lQS2Z1VDV3T0tx\\u000aU2lsbWJLcWJNbWtNLzNKelZCTlJtSnZwNkxHdnRJdDVJMkYyRS9DTXlPMjRHQ3RQ\\u000aajdlYjlYNlA4cUd3SG81VHlmWm9Vb2VPaXNMVFFmZXpISHhXUHFGeVdKY2VmSE9B\\u000aM0VjVTgwWHhPdlhyUWlKR2laUlRWWVB6dnAzU1ovYnJRRk51bHM2Rm5FYW1hRER2\\u000aNDJqSTRyVi9TYVFPZ3dRTHdYMEd0MCtvdGRRbjd4S1diZVNHNWhNbzFXMkdFRC9r\\u000aelpJRGM5ay8vZXdkMXg0UGhGekRFcjMzSDVtQ09mYTcvTi9KR2wvYXpFUnl3Qm1j\\u000aTDZ1enBFQWd0YXRrSjViQytnVy9objM3WDRRZml6cnZzQURXVU5uMTljK3ZzZG9M\\u000aelNwUmVzNDB2azQxUk9SakZ6eFEraUZnRTluVXZLSEx2ZnpwSHVkeGZKRzlRZGQ3\\u000aTk9mU2NRaisvTzBHbnhOZDgySnBXZ1p0SnZHRzBGWkZ6Z29aaXhBcWorLzIrRHJJ\\u000aUjRYeUdQa29aVDJLVGYxU0RNbTR1dEhuRkYyRldtV0hxWVYxSjdwMkwxZ01kYW8z\\u000aeVA5TDFFME8xMWNBSVVNaGIvMWhvSEFIbldBYlF2OEJQUnNVTE9SdUI2dENWTGNj\\u000aenlEY3UrR01nYWU3bUdPWERaTmczM0gyTnNmV1RJMWpCd0JSYUhYaGoxUHhJc0tQ\\u000aOVdnWENNQkxlWHdHV0s0WUpDdmNUTjZoUlIzZWZ6aHd2UzZjM0k5clVDc05HaTBk\\u000aWEdIc0QyRWV5RjdtYm96cm9Zb0tSWDhXL0Ntejh4TnI2eitNS1RwSWZmb3QrZ0NP\\u000aaTN4QkJxQ2pLdmg5eTdLMVQ2MkdEVElqUjdOaXEwUkwxTEU0cVFSbDFmNkNWMGJI\\u000aMzQvMzMraERCWnJmREVmekRSNlpSTGhycmI0c01DU0ZiaUYyaXlqY1QycVJTZkVH\\u000aZENwanlHcVZQZWpWT3VvK0JZUkhoZURqVHZwNHUwV0NBS0cyNHViM0VQWnYwS3Ey\\u000aNHZGOEhQclJIcFBSVkNqdUZHa0dNK3NqWWlkeHh4VnBDa2hsZmxZZnJFUjJSMGtM\\u000aTW9Hamkway9wYnlRdEd1dnk3RDFQZ0V6UEhCUUVHSzZhaTc2U2pWNU9HUUdzMzFz\\u000aYzJKMFlRME14Ky9wNEZtb3hvek02bkxrVkNObUxWMStPSXZHaFV3cEFUd25XZTZP\\u000aUFBHeUVyVFpvalZlZXVqa3Q2ejFzNUtVdEo2YVRpMWZxRlRiY2tmUGpaaGt0K2Ru\\u000aTUdmNHVxdXhza0VDYmJTOEVEUm1DUlM4Z0poM05GQ3VGR0pzWW94OVBvWk5BaHhK\\u000abEYzaDhFNk1UWkxNUFRrWHhHS3B0VndqR3IxTmx0VGRycVNKRVFtSUZTWDQ4cUwx\\u000aeWtudXY3WEV0TWxxUGxVUVBrd1l2THhpeHNqTHJEV1R5UG5MY3RRR3EvVDJ0cFp1\\u000aYjc4cXM3Y0NoSFNMVWV5OEt3ejVxS0ZpS3ZBTjBBOEhvalhzOElZa0F0NDFJdVZm\\u000aYW9oTHVEcER2Nk5wTmtLaUV5ckZyclVuZjY4cFNybHNiTHpSTmgyek9DTitDaXZ0\\u000aOTB5S0JXbjlUeXkrdHhIcy9EL25qMzl3Y3ExWXc2VDhlR0txVDR1OExOUGJ3L05o\\u000aMm1ramxQaE5SR0R1SUZON3MyKzlmYjhlYmJQRG5LL2ozdUtieWRjNEM1QWhDbUFk\\u000aYWpzVXA0Q3dpNTVGTjJreXRZZkZ6TTlyZk95T0VlZ084bzdDOFB6WDVjcENIbHdo\\u000aZmtMWHFwMDBPUktXZ0RQQlZnaVkyT2JFaU1CeUFOZFVOK2k0dVJqUjZJUnBMMXlU\\u000aY1F4Z3JlWmVkK1hWK3BwWEtWb1dVMEowR3o1cE94MDRYY244UUh2Zno3MjdtN1NL\\u000aWDdKaVVwY1dJc1g5UmZjdFlJb1FxSkY1endSN0s0WDJYV252NVBtTk9YLzVGU2Qy\\u000abXcyN240WlFqRjZYdFRUbzZZeTF5d2dzOUpELzdnSmIwTkczMjhQcU5Hd3FFUzBo\\u000aUnBYR2RydHY5S21hbzFjWFNGN2drVHZ5RFRScXRYcHYzeER5bXROSW1pUlNOOXlk\\u000abHV4aFUydG50dXVUVlN1WEUrTkJ1QXovQXdPSU05cnNOL1F6QzZXT2hGWkNjd1lF\\u000aK3pGa0FLVUJLUzBvSG4xbmR5dVQ5d1ZqbnVDL3ZhbWNTVmwwWnhJODlpcTc1Tzd1\\u000aS0V1dGt3Wlhnei9YekdVS01NZmo4Qi9oYW40WlE3MFRidHZDNkszYUpLWXB5RlQ5\\u000aby9OazZkMzQ5MFV4Z3AyclZVQnprV3JucmtZUy8rRkV2VUd1cW51V3BrZzZra2Y2\\u000aWmFtbTVidVk2Rmx3WTJIODVxQkV5a0haWGc4RU5tWVBtc09QOFM1TU10bEZYbXgz\\u000adnJUVUlRY2RtUHV4V1RYNlArSEtvOWZyandLMkxFTmhYUXN0aldZbW5VWW93TUZH\\u000aY3l1NlR2TTdWZDUrb2VOU0tGaldQNGgxbUFMNVYyTHZWU0JSYTYxb29mQ3VPODZI\\u000aWmNQbzRPNEZoVlFXeFkrYzBLT0tFbzVlSjZiemlneTVvclM5WmY3OTlQTXdRbVJy\\u000aZmVjWDF6R3ZYMEZTeE9KdzZEM0FVZ1VhR3dSb3M3d1FlREd3QWdmUGJ3bTJLcFda\\u000aK3pGK204cTJXOHlUbitGR3J5czJ2bXJKczRTZ1YybU4yN28wRFRQV1p0a3h6Y3gx\\u000aU1JoUjM3Z3d1NUdreGVpL3A5NVdTeHNVdEozUUd4Rk91dnQ3T284V09rRjNlN3FK\\u000aSnQ5U2tYSVVpMVNGYzVRblZ6Mno1MmYzVStabzlwdlBVVnN2UlkwelFuSU1xVTFE\\u000aN2FwTEdhWGltMm84MWszQ1gwVmRJQXlaYmlGUHVEcGtZOWdvcE1FcjgrclFIQWRB\\u000aMlRZalpwQlhCV3NyNDg2Z202Um5tc1luVXlRRnFTSkNFcWhCUnhXekhBQk5GdVZS\\u000abEF6ZE5DV1Z2L1RLVXV4WmV2bTVCTWNyL3V4ZmgyTDNpUmh4Zm96cU5HMnh1RXFS\\u000adTFSR1pTRWFkVmUwaUdUVlhWcnQ1WHU5QXMxdXY0QlJGcm1GY0FpbWkxQ1ZqbUJq\\u000ad1pPNTVmeUdrL1haNGgrQklkaXJyK2Vxdm01ZmhZV1JKMmk1YmNUUE9WYTFpeXlm\\u000aZUlaNkppMC8wMk1BTVdlSzB4L0puWW90clJXblA1MGJFOC9XT3hTZ2VMRFNaLy90\\u000ad2pGaUpSTlpEQkdZcCszZGFrZ0R5VHo3Q1hWV1FRTFlGL0NLOGpXRXI4RE9ySUFp\\u000aVjNheFBaNG96YVlqWGVXNHNxQkpkTkdkZ1VzV203bmJnMDRNcCtIL2dDbmQva0py\\u000aOVNmSklaaXdtbnpJR1hXVHV6ZjlTV1ljYU5DK3dzTVBpQURPNjJsUDhoN29xWk5F\\u000ac1dpQmRTTEZ6ak9zdm5rM0Rvak1GeFFxTzlGaHF4ZWtFbmtiS0xoTFQ1d0hhZ1V6\\u000aNE43Vmk5ejNRMFI0VUoxV1pHVGF5dDVkVElYZVppWkpyc0dVc3BiVEFQTElndnM0\\u000aais4aXFwL2pGZWNpclpDRUpuOEo0V3R3UWYxYXROWC8yMlpQWWpZb2lqYXVWTm1l\\u000ac3lTUXRIbzNFYVZmVmljRzUrcHQxYm1ReE5rNlh2ZHUvbVlkVUpMSFZ6VHVpcDVO\\u000aYjdId2VYTFo5WjZwSnZMeEdJSndmR21HZjY5a3Ara2RZODhHN3JvQnN0bk9lMVZU\\u000aUjVuR0lyblhJRDlqcXdQZWF2RlAzV3BjWXRsdzJVQStZdUVVRkJkUkpDRiszdkx0\\u000aQ1pyUm4xNnlYU2tRN1FpSmdHeXV2V0p4QUdZRzYxZGJ4bG41d1ArejlWcUlyMUVr\\u000aY0pXcjZtME9takNJOCswL3lFNXdGbjdEbHlWRWxVRW5ZNzdyOGh6QXFJTUMwSTI5\\u000aNUpnc3BGY2lSaTI1eWRLMzE5c3dLc1dHVFEwZ0xFWlVnNDVxWjAyalBqRWRsM2ZJ\\u000aTm90VGl6TVBVWkdHeTlmK2JpOE9UYld6NlF1K2YxNFk5UkltbWx6N1BmUmltRzVJ\\u000aZ254ZUljRkpxcDBacW9WZ3NpeWtyTVdIaUdDVUMzejZ0d2FnT2lFZlU1bXJ0RGJn\\u000aVkU4NkFROVhWZ3hhZitpRzhYb1JVNmhIVkpNM2dhWk9EVmFYY0tiQkg5L1NaN3p4\\u000aZlI3UjBwVnJyc0U1UHE5cGJ0VUphRmRvK2hpQnpxdGRLdEJrUDdjYkFEVER2eHU4\\u000aYjhkSDdhYVMzUzlxS0dmaHUzMW0xK0hVSjZHYmhTRW9sYnlGcTJySVkyV1p1K3FX\\u000aUHVxU3NtV3NEeVRDSGJ0d2N6RVkvOCtUdEhUa1pFYmpkN0F0RGZ6dmlJRW1aazRh\\u000aRFpCdEdYMTc1NlFIb2hJT21KdGVPTWlqSEtqdk1VNHlYZVh3VkkwcFVwc09JZVhZ\\u000aNStSOWVGQVFFZUJTTG9FOU93ekpOYm1idFJvSHMyQVJWUFlaN0lZMUxOM1oxdnNI\\u000aYVY4czZVbnB6TXZNRjBMdGw1UmEycmxwa0NsOHR0a3p3bDF0T0NVYmRmc0d2UVhu\\u000aZktjVllNN3d3bXFQakFRdWJpK2dEcHZrcnVFZTFxekd1NlA4cFlsY28yN1o3WUFE\\u000aL2dzL0s2ZittSGI0VXlpeXI3cklaampSb2c5UWN4NDR3TXF3RWZvbWQwQXFlbWo0\\u000aQTZ3Q1ZVSjFUN1ZwVmYyc0FSWWVnLzAzbWMvTzZySTZtSTVTQ0tKZ0J2UWhvNEN2\\u000aWVYrNzNNbVg3Z1dNUHRkUExydE9vbk13M1V5aEtxODNuV05nSUFhbDZySlhaV1Bl\\u000aYXVVbjVVdm5jeElNZFMzWjFjRndsRHhVd0ltRytGWnJrTGpqWm1XaDRjdzVGOGNj\\u000aOXhSZk93WW5aaTJJMVRUeExLcTlDOUgrak1sOUxna2hoemtWZDFSZUFkcFpZYUdw\\u000aZnlSUzZsWlBWaDZiNlA3a0lsdlhremplcDhkZUprNm5ycWlQL2ZBdFNTQVNUcTdY\\u000aVVVQUEhnSW0rNTR4UWcrdlQ2MHVHY2ZPaHljN0owd29ia1lYMDJ1Q3p0c2lranRa\\u000aRW03WTEvOWRjekx2c2xodUZ0d1UzTWF5Q0QwakRmRkhKbVJCMmVLWmxRZHZmU1A0\\u000acmJ6SGdwMEpzQUJlNndTMlkzdDd2VTJDdklqM3djTlZRTkZCQnZYbmk5SWNxQVNm\\u000aREVWMGhYc3F4YWtQNFAvRTVDMCtkNVR6eDBIRlF6czk2ajNEcnlHNjl4eTByRzBV\\u000adGZLRDBmK3VMc3NQVERybWNhU1ppVXh0WmJqbGtpR0hDU2R5YVo2RlNSYWhMcXpH\\u000aWVJ3YW9wRENDVHhQNXh6WnZaMGIxWDlveWE5c2JRZWFEVEtJZmdmMnc3RVEyZEZn\\u000aLzdCN25lZUxJSVdWTXZvK1pzMUpsR0RuWWpvVUdRYU9ITWI4ZFlIWUJnbEZ6UjJp\\u000aZUN4SjFhU3haQkFQNGFtalErQWp2RDE0MXk3WWsrVnNMeG9jdHcrbzVCRndHOU5m\\u000aVHJzT3MyQ09IckRoZW43TzYwMFNuNWh6MVNhclJHbzBTQjZBOUxJdnc3OUwxZFJ1\\u000aeUc4aWVjaURhRmVVb0M3OERCTjFGRFJyNEpxYmlHTjdXZ0JLQUpyRmd0L1dZMjNV\\u000aSEJPTFpOSHBGZ2lwNnFmNEtTNENRWFFuL1o1MUx3MXhHQUFRSWc0RUxGbjlDcitz\\u000aME94czZkWXZmeVhMWVhiOXkwa3ZyTnZXZDVZUkFWWHZENkFpVTRtOUJZNmZEWFNa\\u000aWm9ma0w5em1BU3Q4anpVZnRPWU94OWVqNzRJeDRQdmRyYmdVV2MyV3hvOWc0U092\\u000aTy9jVlFjd1RPYmFxNkFuVjZIVkl4dGtpakRkeG96dDhYTEJCdVBncFlZWnRWcHJ4\\u000aTGlVb3g3ZGpDRml3cVVYZEo4Mzg1a1gvcXdVNXlYZWwyMnM2c1BHSU95RlI4REw1\\u000ac2ZacW1Qei95bDA1RGJMaTBoTjlBaU9jQStVQ1ExT1ByVllNZ3ZqUjl3ODIwemZh\\u000aTStmOTgvNC9FNW5mVWoxdXlwU3RpbC9tWTJqeWZxd2hnaUpjcFdhWWNZenFQYkY5\\u000aMDVsUkJpa0hNQTBzSGxyeVJpUVdBc1Baa0lxclN1SHg2aGpHSDNGeGpTSnYxZzhp\\u000aVHllL1V4MDBucGVYV1c2ZFg5cGJHYWlOcmZDeGZlOHQzWDcvc3dPTUJyR0VEdEhr\\u000aZWhoWWNybm16U01yZVY4dTV5dDVFL3dmUzJKejNTeGVoTmp5cHhEQUNFSDk4dTFJ\\u000aUUg2d0ZaanlHYVhSQWNqTnVqTTNPbk12NHFKSThzVTdHcE02VHZFcXdrSG0zUjF5\\u000aY3ZhSTRDd0l3d3FzUFlFdUQ4dkIrNks0WGIzQXJzTnd3Qm45ZjZqZzYzZlFvbERL\\u000aZG1zbEJiUGhkdXY3QzJYM21qVnJBUnl4bWdKZGhKckNmbG1hU05rTTIzTWxCZzRQ\\u000aSVR2ZTNhSGFxVnVFVy9jUHVPMTR3alBGdzNDa2RzSWtuancvWTNkOWJiQzl0UHVC\\u000abG0zcXRMQWhSWVJtT1dvWE9malFCUG93WldlMm1RQnJ1TFV1VzhhRG5WU0NTVUNw\\u000ab2lWWnVNYXhuVWpscTAzZ3V1OUcrOVRPZU8xMnJFQkY4cDhtWVA1STU3aWF2enVP\\u000aUjZQa3BWSU5ERVRrQWxqNjZOMDA3T1Zid0IzUk80bDJYTHV5emQxWDI2b1VFUTVl\\u000aamp4LzY1RUdZd0E5ajZpMFE0YTZkZzkxbDBMTndiaGhVbk4wM3dvM3BTRmoraU9F\\u000acUpMc2RUY3pkalllazFlMFlDYU1wVW9ITDlzVkFlcStld1A3VU9wdisxTlF1SnM3\\u000aTWQzUVJnNW9RSzN1NzhYdXNzaGpTZHFpd3RkQTcvVm5SQzN3Mk01bWJLd0VlVGNT\\u000abjl3Ri9GZXBGcTkwQ29wL0hGc1hxeXNVRU51NWtTY3E5dHpESmhnOGJpSmJkVXN4\\u000acU54NFRYWmExZnA2ZU52ZGFzdjVsOUo1bnBmWDZvbjA2MG9CelZvMk9JNXhRMTBH\\u000ac0J0MW5YNWIrQ2UySjk0ekVObXQrYnFLZ0VoNUlzWlZ0YTlhNnYzcWhtYmQvNGJK\\u000admdhTzVmNmd1Y1BRL3JxcjFVbGtDa2dQdnZyWm1zWWVyUDlzeWE2YWhBbDJHaGo0\\u000aekh6eTBDSytEdkxBU0s4MEhCN0tWZFc0dUpxRDYycGlLYkxKVUU5aUhoVTRRVVpu\\u000aeG14eGtNZmJnQS9pdVR0NG9vdy9LOWtIcDkrUWJVazlFUGc5Rno0TVE3bDNiTUxo\\u000aZzdVMjR1N1hTdlR4TUxuMis4ODB6TDNudUJhRUhkYTRic2VDYzBwaDdOS2s5YUFl\\u000aTWF0cWZycjNTSVpycklDZHVETkNhMmRVZXl1d0x1Lzd1Zi92Wm1oVEpaV3c2MjlG\\u000ad2thdjdhaGJRYU1NZ042NXBhL29BR2IwMXJrc1NYZ1hkRjdhc3JVR3YzSGM5ajhu\\u000aSXh1NThqWHh6TGM1d2l1WmIxRFB0OE9mSmdXYTBGeVJKajZBSEY1SEdicWFGTTlV\\u000aRU15SXU5Q3I4c3BGNHJURTVBNjRrb3hqZTNtWGZIVVNVanBUemtLMlllMkpLaFk2\\u000aY0dYc0t2aE4xbHlBblNQTEZ4Tm9sc2k2cHJDWTFaeUdQdVl2bm8ybDdQbFRGblAx\\u000aM1orMCtRMGxCdG02eHZCQm4rUGl5bWxtOWV2TUpoeHNOeGlaN2NZMzNPQnl3NGJ4\\u000aRlQvN2RmUngyUWxxT09BTHI2a1c2ZXI2WUVuQ21CNWdGWDVsSEZML3UzQTRPUFAz\\u000aZ3k2aUdjQ1pPVnJrOTdUQ0NZZDJ6UTVkZVFKSWlKeFFQQnlGbVlQTzg5eU40QlVI\\u000aOWtRVFNDZUdvbVYveWNIYVpkSGwyQ2JIVFd2aGdCcWFiTWJYSnhWRVdac1MrLzJN\\u000aaGttZE5aSThaV0VnYm5odFlXVHUybjhtOGZBREYwMll4UjFjTG9Fa25FN3p0TkpZ\\u000aZE1MZWUyOEMxRk5kbDNtUzVyRlYvclhXVUdtQXAzZ09Lb1NXUmJMRDNlSi9ybE9U\\u000aL1NwVGJFUDVJNGdsQ3AwOHYxOXBMK2krTDlpSkVhWmp3dHd2M1BXRElBekkrWWlr\\u000aZGJnR01uYitYeWwyUDk0R2c0cVk1RTRQN2ZTcFllaVZiVEJleUpRMG9JUzhuUDlI\\u000aUHpwV2NSRjNFOGkyVmhCSU1aYjdSNWtJSVdxa0lMbXJwNnBrejA2NUNKQlNDay9U\\u000aYkYzaVhadU1kcE9udFhMYk5Wc3VGdVJud2FYZkpwVE5LT3U2K2VTcC9rSDE1cFda\\u000adjVJMlFSN0FGaElXSHFCYXo4Z3k0QzdVcS9uVWVqN2ZHM0V2c2ozTVJ4YlNTUjhG\\u000aSnFGZDB4MSt4SzgxTnM4QmlqYUVPV2xBRDFvMU05WEFGTXFWM3pVNEVuQjIwaUl3\\u000aYW5DclBGemJidWNUcVU4RHMzb2k3Yy83emU5Z3ByRHFtK2hKcXRTYXEyNkIxeXZp\\u000acXl6VTd4UVZEczU5VCt0VGkvdDFwalZkclJIVWNWZVZSQ3h6NFl1N1k5TFVaWDA3\\u000aM2o4eXk1MktLZXk3dk95VzBkNWxKVHpkWEpmZkhlQlNhQ2ltMnVwZWZaeTZKeTla\\u000aZWkydDBOMENIUUtzRnkyQk90bTl0MnNUUXFQREJFR0dDdGVRTFB1Y1BOL1doZS93\\u000aZC9Ma0cyNXFOTit2MTJybUNWTE9CM1JiRFpOYnB2Yldxcks5azR0UFF4MkM3M0d4\\u000aeXNIMjNzNWhJOEtvWVVJSEgrQnUvMWF6SDVZTjVhanVXcTNKV1hZVHk1S1crOE4y\\u000aamdvNk9qTENIVzBzUzU5TXcrQU1MajFCaWl2WG5Uc0xTeHBTSVByb21Dei80c2Ri\\u000aM0N3a296akZSOUxLRUJTS0NNK3RxMXA4ZUtTZ3NqUzVuaCtwU2NNRkpxWjdhekRB\\u000aeEhXYVoyNTQ1bWpEdVJOV0Z2M1lsTEhXczZBM24xSExCdnVOUWs1ek05RnYzT2tm\\u000aTzBqOVlVUWFnWjdCMTlUVjVCNDhwQnAxNGdYNS9TR1VmOTZOaWQwWmdURVhQRU8x\\u000aM1JnRU45cWVsazRPQk1icXJQNlZ0d1FPT3BjNXVEWHgzcEdWQkhTejZrb2JRNDV5\\u000aU2l5SUI2L3BiUGlsbjlDdmhNSWVyNWp2YlZneEtCdkFyajB4RFRWWVpGcVVYZVhz\\u000abHRlSE5WN0czd0E2dG9DWU1ZZ3R5UHRtWjd6MDMxZGVEemtwQnBBV21HOW85OVEw\\u000aSC8yV0EwaXNQdVVhbU8zbjFFUG9BRFZQZHF6UFpUOThPeDRjS3kyQmdBWmJBZVgr\\u000aR3lRTzgyblhudE1hWmUwbVV3cnFPbE13clZZNGhlaXY0aFEwOG1VekdkVXRSY0lL\\u000aTGpITm1OcXZvdTdlY2ZHdVhTcnhvMXVJdkdIbzNuVlVZTWc2ZEFRRlpnWUh2ejdZ\\u000aREFKWTBEWGYzTHVFZTR6bVh1azhlNm4vVU5BbE1ZQUlvdEsxY2Z2TDV0bnQ0akVD\\u000aRFFjb3lZaDRjUlVFei9XUXdudEE4Wm5sQUxRMlJOUDY0NXhjU0JOMEVCYUkyb2tB\\u000aNXI5TEYzK1h2UjdxQTB4b3VoNEMrNWZRTnpHdTdwTjFUck9WblYvQXBsMlNaMmtD\\u000aTEJQN0hjWWt2b3ZBYWFick8zeGtrUmtsdFRCd01rR3RmRC9NTm13WW14NTN3U0RL\\u000aUjE3NG1uckRCRDdOb2d0S3NTNG03Yk5iZUZyTE1hdDYwYmZVWWsweFp0YWxuSDdP\\u000aU0xqcURHdmhYQlBDaVFLNzNNVXppdU1qWFZXMTVUWWJDempuMHV0Q3d4Szk4TVlv\\u000aY1lNV0o1UGQ3WG0zejRva2prNDVFTU9DZVRGRmdZclpVNzlWYmdERVFpbUd4a0Ni\\u000aOGR4ejRMZkh4N1NGUXVhSEpNSjh4SUxZTWFSL3doQ2F4ODUydlNRaElJWG0zZ05n\\u000aWHNyeTZ3M3EzLzQ1WDd4OHVPd0p1T29GUGd1NEtNVDBTUkUwSmZRaFhQUDdpTXVJ\\u000aYnRrd0ZXeWxGQno1SmhVMzhzZ2JGdjlaVnczQzcvbnFZVUVDMXZRWHRnbEs4bGJj\\u000aazlUMzU5YVFpclBkcHF3NjA5OFFGVktyNmliTlMySk0wTHFlM21neTBYQ1RTYXUx\\u000aVE4xeXN2SHBpdU1jSW5BZWFyL3d5b1lsek5BZU1kbUQxUTduaWNBK0pWTWM4elJn\\u000aZ1NKcnRoZDZ0emd4NTFFTUNoQUpFaGR6UkpjRG03Z2c5eE9TTzNPTGpRdW05K29k\\u000adjY0b3NZNVNtbDJHSkgzZ0pzRmdyc2d0TXpTMCt1dnYwdGlZY1BoY0VsL040Vlh6\\u000aV1FTNjByZERQMTlUMFFYREMxc1luSS9rZFREcG40WnNyNFZOUzRkM0cwaEQ2Rnh3\\u000aZzlVdXBzN3k0MjRzcmlOWDgzZS9CWFhZTzNBWlZCS3czUlBVWnl1RFRZY0V4cnFM\\u000ad1RPWnJNQUJrVTBuNnBpYVRqMWZhRDJpZUZxcEFycGxIZzdrTW5ZdVN2MVFDekl3\\u000aL21GR0VEWVFqSWFiWXNRelZMRzd4YjJxbkkvTWdTbUdGUFN1VkhKNDBMNzRPYTh5\\u000aSklyeUxvV29ZSDZYZGo2WkdqZXlpT25YcEJFOUgwT2RlMUJJMkJTTjVwWFFZc0hH\\u000abFUzQ1preHdHdUZ5WnVzamVDRW9kZURPQ2lveUJha2kwSzB0cE4wTWZYS0Zubjd0\\u000aVitWb2FXV0dQSEtBa2c0eGJIcjJnYWltWW43UlN5cVcvcUVkdzFVTEgrR1RMQVds\\u000aS0F0eG1LR0ZnNkhtNzFtY2kzNXBGTW1QakROeER0RktZWm40Y3RMZURIR2ZVSEI3\\u000aZlBEOHRjZ0c0VmxTSktwTWVYR2RRT21qMkJubFQrTFYvN2JLbFQ3aSsxTWk2QnVZ\\u000aUmNBbW1GZnU3ZGF2Z2IyVFRvMVM4aTNPdkNieTgyMW16OXNjZllyVjd1bWhYWTJU\\u000aU2ZIQllyeXFtTzlHOXBuSGpTejlsTko0aEdpdU1hR3hNSWhOYUE1Q0trNTd5OEE2\\u000aSW9hWjFWL01BRmJyNXB6RXNlckx4VzdLbld3cjB5WGE2U2hCSDVwSGFXR3hRRlBS\\u000aNEs2bEJKZXpjUlM1ZUcwdjV1SHBQWTYrR2J3dFBUNHBDcENIdHBKNk56dlNVNlFP\\u000aNGVHYUY4b1NEV3pPRXRJVEJCdlBuUWFxa010L2V3Vi9qZldMNVhJbll1aHV2RGtu\\u000aNnZhbTRzenBONWs2WFRYVjh1QXNWY3VaQ3dLRXBKZldSQ0V4dGZqZVIzZ2E4U28x\\u000aeWg4Qm1QSFNBd2FxOUVHc3pBcmdScm40QllKZ1B3VWZ2WkY2c0pIV0pKSm54YUdI\\u000adUNBK1dHejBrcFRpVlJLYVM0SkUvODBHOUxKZjcvTTlvWEVULzFTbWRUaWEzM3lY\\u000abFVSb0xGdVE2OWZuTzhDUzVNM0IxM01HTHN4Wll4aUdTUkpYYkxHVWQ2bnNsQzJ0\\u000aNlh5SUZNdVFtSFcvQVJSNXVNL0o0VStWSUdUZlFPTlowVnZoQStuNlUxNDRtR3Jk\\u000aU251dWROWEpXRk83N0JzZWp2dHMvRWJXNHFOcHE1NWNQQmY0MzFEQ0NoMVJNdTJ3\\u000aNnZUZUJRNitJcllOMGo3aTllcng1UFEvYXN1NkRvMnNRWFZhNTZHVXFNUmJKVUNs\\u000aaFBNM0F0SDFmZ3VucnAvODU3a290UEhkUURBM05hOURNT2lvTEpSM3puN0tiSWlU\\u000aNEo3THFtbUpET05WcW10LzdpeGwwTVlDTDh3azFHOXlnWUhxR0ZsWGoxUXpxTlVS\\u000acHhUU0pualYyTjZOejZmYy9MVW9NR1E5OE5yb1Q5YjhhclNBcVN1TmhCaGwvbEto\\u000aNDJ4QXp0UVdDNkZEY3Nmd2FrUUpGeGs4OEdWWk9hMHJ3UFNEM29LcUMxc05sc2VW\\u000adzVzMWRjK2dodzJKTGRmeUcwWk1yZ3NaQm5uV3RHanhEdFg1WmUxZ0VKbUo3cnN3\\u000aTGsvWW80S1VuWkZ2REF5d2t5VllMY2hwMVJ2ejJKeTNGcHVpWU5sRXRkMHZKRjlX\\u000aR2dkeUd2L1JpN1pEd2tybzYxS3lMallvMVhaelBmUTlscEVqMGRTKzBCZllZUjcv\\u000ac0crcW1qZEZFb2YybmJLRWVaU1N0K010UTdnR1ZGUy9ENmtvWmZNSlM3c0svSTBh\\u000aekVrdkxRR0hTWDN0QW13YXB6K284VDlEYUZxTDFDYjZSNXluUUNucjZ2Vk1QMG1F\\u000aRm5GbURxWVMzY2c4cldyeEdrQmFUcTFDTDZKblhzb0x4dHMxV2N3QmVmR3NyM2Yy\\u000adEZMcXN2TjFHOG9nYm1pN0JDSWthcFdEK3FzRUI2UmtNeStGRVQxaEhuMEZyNEk4\\u000ad2l2YnE0cVpsd0NncHZ4Ui9tYU9iRTZiTjBjK093a1dxcEpRTUl5aDZJcXZsTUtP\\u000aR1d5YmR2aWEzemJMNk5XY05IUnk5aWl0bERzdjJSNy9QMXNqR1I1ZmI1NGRkbXhO\\u000aMmlFVzZLdEFZRU5Bb2VwSUtrWkVDNUJ3QUNYajZrM1Y5dXBNYzcrZnlOSEFBbmZr\\u000aaTZ5amRVa1BZMzVsbmNhcTJRcDd6Q3BWdk1qbTlTK1dtWHV2ZlNwc3EwZlVxWlN3\\u000aNmluZnpncjhlNy9zZDhIc1hVL1BmSDY3S0ZzWElOQlpMVm41QXF5b01YTVVNY3dV\\u000aVCs3RjhnSGl3NUpRcnhELzhvcVhUL3dvLzIxcFJObXF2ZDQreG5hcGtDZnBpOUlv\\u000adFNjd054ZlpmelkrdDZyRmJyU3VWMXZQVHJaSWNrT2ZXNmt5MHp2UmRCL2hna2Ur\\u000aNVBvVGRnd0diSnp0Ylo5R1pYSGpGZFVLWFFKVWxscmJWRGhUTkNoakhxNGE2QzhH\\u000aWWRMV1hxNzZxWlEwWnhvRjJxdUtkM3NjazEvaUxIY3owMEVuRGExK3BXd2VTMVhU\\u000adUZaR1lFTXNGeUptWSt5QmdRK3Z4aHQ2bFArKzZzSW9pbUF4cUMweWU1SC9McHFM\\u000aaFBTQlVpZHppcnlTblZ2SjZmcjI3TVRQUTBoci9JYUFXRlZnUG1yNEdqd3gxdWh0\\u000ad1J4aVU3K0lwUUxNSVVZYU1nVldnaTZvbU5aM25mcHZyYUdwWWxvaE84Z3ZXK0lL\\u000aWFJNWEJBR0Y4TlQ5UG1ZazNXa3NPVU8rVS9XKzlOL1d2algzc2haZWpGd21GYVg1\\u000aWVhyREE1MS9icDRvQWlIMzd2TmZqTGxzd1piZ2o4NVFsbXBydlhuY1dnS1RZN1pP\\u000aSmMxcmhmQnA5ZUhuUm1nQkVyNHZXOGROdkxibVFSa1dhTmxrTFBSeGd5NHU3d1p3\\u000aN1dmZnYvOG5uWEhsbWoxNDVWQ0NxOHlJR2FiM2tqQ1dvQnFQbnh0Vko5VVFNME9D\\u000aSVFhay9mWjJvdDV6Vk92dGhJeE1pK0MzNVAwRjVkUi80RVBaS3g4a1AyVnZ6RkZy\\u000aN3hFUlBSZFJnbjRqWDlFREVZQTJoWVlwRWRLRUdGai9aZTlKRlJrNmxQZjlVY05Y\\u000aRkgxd0srMW5HZi83WnZzd3dSYnNzalZjRXlMODVQU2F5eVl1ZXQrMUZ5UFpKRk9J\\u000aRnVSRm9vMWhaYUp1cGlTdm5yL1VSSXlGWEhMQ1B2Sld5MnZQVzBibVphR1NRVEJZ\\u000aYlRMcVl0UzBvdTJxOHVBd01vZUYyT25FVDdaTENjMVhTV3lFWWErWFJ0MkduMHBl\\u000aUEkxUW91NGduby8yRGlrN3NxTERydnFRbVpTOFNISlFSQVJaSnh1UUJBWDUrNzgy\\u000aYU9uaWN1aUtTbmwyeHFkM2pYRTRuUS82S2phbmhlVXpzdVRrWHFQcG4xbWlPQi9H\\u000aTFNUQ3VaWHRXcjdlSFpFb3RhZ0pOQm9OSlBYdG5KSElQb1VTdHpGTG9HM01Vc3dY\\u000aeFlCMG0xc2FjaTdaRlJ5cU1sMGtvKytlN1VCSEZOMi9UNS9ybXdsbEhaZ3A3Mm8r\\u000aWjZzWERyVXdxMW8zSVVocnRYNkJPYzJKOWladTVaenVRNkxNNkRhY0Z4bEdtcXRh\\u000aeDB3SlQyZkxpblRRU1ZIeDZDeWRMU3dTcDREOHlPd00zUEc5Zks5VklSRm05S2VY\\u000aaEd3dWxyMXBHVTAwTDU4QUVBb2ZxRmt6eEZneE0vRlRBTVZ1NWxCd29QNDYycSt6\\u000aM3pHQXkyemFTcndJKzdiWnd2OHVTMnpKOEtPajU4MHpKb2JOdU9YdC8vVHlMOGFV\\u000aZ1BtVFB2aTV3eDJGMHRVUGlzL0tUemZoZkR1NTExQXJOS2szZXIva1BrUTVmL1BC\\u000aTVBBSEpPQ3crLzh6NEVDdE9tL3g0UkliR3VIbDExNzdhQkh2WDc1TzloYnBaSkhV\\u000ac1ZlWGJOa3VUQjU2YWVoVkl3T3hHQitDeTR5eGZDb1JJRENXdy9oa1FVNjlZUUhL\\u000aQ1dhUXYydE16eVRkOXFsMFlRc3VBR0h3TDJTWTVKeDJ3RjZ6elMwRUVCMGtCU281\\u000aNlhYZmVwRGZnclVleUlzV2Rwc2hrQUQ2T1NsVDVaQTFHMWtpZHMzRUZiSFlxbmJh\\u000aVzFTZUtoc05QamVBcWErWE4zNnFYQ0NVclIrNlJDK01xTVc5a29XWjFqSzZqMkNq\\u000abHNWVjhkVGI5OXY4alVuSEgrbCtrbituaWo1MllRRzk3eCsrQkVMZ0FZVWQ5Ykxi\\u000aMmI3OWYwSnJYc2s4V1psajZ4Q0l4VXI5ZnZ0c05aa3NEWTI2NXl1VGtoNzE3Smho\\u000aaXFaUHowVi9HcGdVaHJDSmdhbVR1WEo1SmdMdEtJZ1Y4WFVQWXd5QWFUdGpvcGJT\\u000aSmx0MDVJVGtka25LVEZidjNxd28xNWllS1ZBUHhvNVVoZEN6a0xUZ1hyWStjMldo\\u000aOGd1R0JPbFlSVGVRbUlHK1Qram0zRGpyMHVLSEx1U2lmQ3JlMXdyaHp6dUF6MTd4\\u000aaXVkbFczR1I2UGVmbDZOdUt5WG1VU25LL1F6MXJNZVVjT2p1UzBmTkdlWVQ5bHNz\\u000adGt0Mm5TVVdKZnBaQzhZRGlPWDd2TUZSUFZOSXo2Vk9lbHJDS0hHMXlTc3Vkc2JP\\u000aVTRiMEg2KzVPVWphYlJuOSt2YnQ4T1BNbE9BVDBEcDJ1TnMxNlBSYjJPMGp6NWlo\\u000aL3FwYjVZMENnK0VlYWFPMGdxdXN0WGdDUHJPbktYM3JLcU4wUG5lMXpmYkZqVklJ\\u000abWk4NjcvRGUyYmt0RThtdTQrWTJIeUg1K3JUVnBkMlRxWExaOUhEaUFMaWZ5NjJL\\u000aWFVjQ3NEanJEMGhyWTdYZzdTNnVjSW00ejNqSDV0amtOczZxMEFqMnhscG5zbi9D\\u000aejVmd2FPUS93ZEpPSjB5aTVtanRjOFBRdnJ6UFhNQ0tIZU9hUGJmVHZ1SmFwOC9Z\\u000aVmpTNkw2NjNxNVVkaFlGcTJlblp5ek1LYUwvU0RmYVhyZzZrREw4d1podXZuRlJx\\u000aYmthVmp5S0FQYlFFUGhvdmJCYW5DajVwUGh1MHJoeFh4T05rbkhmaDhneGxudWlx\\u000aKzdzTmxoeXBSUXk2N3NNSVluMmdnS3dRL0ZCVlZ4SXBRNG5oMUw0ZldOS29MY0tX\\u000aZFBCSktHUUQxNCtPUXRXcVEydDRKYS9KVlpxZVlQRFJxSUtPNStEeUdLemRPK2Q4\\u000adTJhNUZkaUo5UG9SUmJqekszbnhYa1A1TTgvYytCWkdMK1lURmtVOGREZW83L3I1\\u000aeDVVOWk2TEhpT1FhMDZMWlpGQWttSEdMbjhtNVRPbllWbGhzdUVlZUdWU1hscVVh\\u000aV1dhSFppc3FrWVl6am1Cako5T3JsUU55aEhRR3Q1cXFNM0FTandMQitoQ3dwaXZH\\u000aRXZ0aStHdy9IbDZiQlpFa3FoaDlCUlh0TU0zT2d4Rm9kd25nTmpHSUpDak1xZGhk\\u000aTkFjNWpBQWlsUlJ5dWRQdFFsQ2tObHpCV3gyZjhCMDBDVmZQNkwvd1J6WFRFOEhR\\u000aK2JiL0F6SkhCYnM0YjR4M2o1ZnpOS1doOFJZc0x2VklmVkdBUjJEcjlJTUp5NkpP\\u000aTzIzdlRmbWVPcFBudmpvdlhkbTI3WlcrdzdGSElrdU1peENqckh3NTgvQjkvWUx4\\u000aVGRoSzlFY1dOcXMvclA0TEYvMEJVSS8xdVdsa05pdTBJNjk5UHRkWTdzQThNVUdO\\u000aT3VhTTYveGNZN25DMGRjVXRCcjBXSmoyZmRtYmlTM0Nld0VrT2c2L2tQQkNHVHVi\\u000adVNSdUVLYUNWNXRFZktlZEtERStIaTFuK3g0U3h6U09KanhYZUJTb2hEWTdlNVVu\\u000aN2ZRcHdvVEdiTUVHUjZJc0pOaUNzR0dSbkR6ajd0aDFSOE94ckVLRWx1dXQ0Ym9u\\u000aOEo5ejlxWGRVSUtlQ09va0dQNStrWW5BbHBrNWVQNzltM1gwS2dSUW9kSGN1N1pP\\u000aeTRBdm9GTXpYd0pFVDdzYnNaQVB4Z21VeXZFbDVRdzNBQzhBaXRybmFBWm40Sml6\\u000aZTdKSEtFdXpHczlBa0IyVG9hWXcwRE5zbWdzSncwWElTSzFsSzBUWjVDUTlPQ1VN\\u000aeHFZYWNPRTEwa3VTVUtQTUpoTHo5UHhrRDhnbE0vZEV2OWFLc2VqczFXMkF1VytU\\u000adldzM0crZ0cwRkNHajljeEJBa3VRSDZNb0tOMG96VWExUTBxcU9JRjRiRFZJZFFI\\u000aTHE1ODRvbTluU1IvV0ZIRHY1dWxSeTZteWpIMU0xUFB6azJ6K1drQW84TFhRaXpM\\u000aWjZmblFpTEZ6OFVzZGQvTzVIM2xCcUFUZUpvRzRVdTRCMjVuRjhOK2JabEdoM2d6\\u000aK2xTZG16YVlUR0oxWFZPNTdNR0hla0dyZjJRZndoeU1zZFlsZFpQZXBNQnB5YU5R\\u000aOXpvR3ZNQ0ZnYlR4c0JFRmN4aWM5TmdZUWNDVk5xcTBnS1F6SmtxUHZtV2o3WnpP\\u000aMWZJS3Rnb1FmZ1k4a2JSSFRPMGJIRXlsNm5EcldRR2RXbkQ4d2ErNGNLSnU2bkpH\\u000aWng2QWVGdXI5QzJsZzBWdWZGNGlqVGVrcWlEb3U2Y2x3czkzRHdWa2VPNmxsQzJm\\u000acUpUcm1zQy9DTC9oYzZuckZ0RERsV3Buc0Jkc29ydEtxN2lVTGF1ekRIRnA5MVI3\\u000aaTdCanBuMTNWcXlZMjVUVXlSWUovYlN0NWVGR0FINnpQZHE5RkhqTWhyeGZpTURC\\u000aK3NTRUxqd2FJR2ZxWDBQSG82UmZ1Ky9tOWlpRWwzRWxrSWJpYVMycmdFWHkxZFgr\\u000admdBZkYzOWQzWEFTdmI5aElrNXg0OGltcHRtaDBPaHgwWENOMThtNnpvQndKajNw\\u000acmNnK2ZNWHE0UzZMdlJjQTdtV0MwRzcrdVdXdi9GblkxYUg0a3NPcHRmeWkydU16\\u000aS3kwQTJFbWNad3YyZktYdmljcnQ0Ry9yWU1ZZnlic2loQS8rcXhReTlERmlEek9n\\u000aZXZzZTZ2NnFTUE5TY1lYLzlYRUxKMzh2dmpMTTNjZHlQNEJOMVF3UENtRmFrVm1K\\u000aRTNKRzU0RXhycHRUdGdKTERaNW5FYTY4Mjc4dnRJL3JVR3k2OFFuNTJyMHVXc0ZX\\u000abk5obFRPR2RxYzZzdjdNTGdTYkQ3RUVmNWNiVHNKV3JQZ1ZHbUQ1Q2o5Y3ZmRjlR\\u000aakMvM1RiSXFWVE5QSkhhbXpnbUJsSFJZSGJQN1p0a3ZUZDBnTkF2SXllZGY1MkdY\\u000aUzhESkQwTStrSS8xNmF4dm0zSlB4RC9BVHE1Ri9xdmtIWFRUVStCSEtUTWk2dnk1\\u000aMkNEUmh0YkQ1dVNNa1YyQmROK0c5Y0xnL3hTeTc3TjBnTEc4WDZ6ODM1cllYbE0r\\u000aaGloeGx2UWtiSHR0eE9EN3VBYnpFcExEaC95NFFtZVRSK1FaQU9QeUc3azhGdENG\\u000aam5TM0lLWkFTVldFTVVFODlGTG1hdFhMNERvaHlXWnViSDJPVXlGUHp5ZnNvNWNF\\u000aNEpLVnBIb21NVWZWcjk5bUZnVk1ESUdyUEdFcFRmU2NqZ01wRmlDaEFxU1djUWFH\\u000aU2cwdlBrRkdlWXFIek15SENqMndxc3VDV3BIZWlyU25ncHNXa1RLMjFLRG42TDVx\\u000aaENpRk5wM3JWNUJFMkwwcEhqQnZEVmFrZXdqcnF0a1puZ3FKcHhZalhyV0dxUjVP\\u000aV3IraWhxZ0VJZ011WGhkdUxqR2wrWVZkU1d5ZTlER05OS29DN2FlUGhJMTJQRmg3\\u000aSlJoZjdIYWVlQUNPaGZaTndDWitXMndRb3hCZHpwYzltVCtDVlpxOUo2NkNyTlFI\\u000adTBtaStlaVRTdXNEVHR2b3RmQi9IQ20wMXVaZmgxbE1JQWdMNXozSTFHRVcvREpX\\u000aMk8wdWZBKzVPV2pnWFlzOG9aUlRCMnhYOWhmSW81eDREVXNiTFM1ZzgvbFBUVndF\\u000aamYxQlg2dU9vaTVvV2lJWVJqQmpmSWdVTEVURnhMTGtBUnJQTzJETzU1ekJnMi9Q\\u000adE9mdG00SzFjeWI3V0h2QkdrcmRYanlQUXlYYzRJVXU0SzR0aTlPSlE1eVRmWUN0\\u000aY2o1OWMya05BNHlOWmdwd3kxVnAvSytGdHVlZ0xsd2l4ZTRwakR5ekNJSnBnU0ZD\\u000acmtxREV1K0hqOFZWNXMweFFXc1d5ZWdOUUpldVBheWVSY0RGMzBoMWc2WmZGQjNa\\u000adE9RWWpFQnFyVWVZNkJndk5OWU42TWFrUndnRDBja2NDbEoyMUhZNGpvU2twcE9Z\\u000aZ3NUeTNrR1laNHFUelJNY0lsQ0REaXQ4ZENHZm9Cb3JKQ2t5NTUvNDFiV3FtbTdt\\u000aTElRVzJBTG9kdktQbVVXeFhibzN5WGNnSTRKdnFjZlAzRVVXTytjV3VIZEFSN2VF\\u000aOTc3MytSVUV2TXROdnMzWWxqeERrTmFNNzZ0VjhqanhRcFJZNEc0RWRSaUs0MTN3\\u000aWUkyWTE3UWE2ZEs4K2FhaHRad0JtVWpBSVkvREdZa2VOY2wzWjdxaWpJMTMvUnpn\\u000aNXlWcjl4VUsvSUFGUVlhNDlXQ1RRYTlzVWYzeEgzZUYvTW9HN0ZmMTdrOC8xMURx\\u000aTE5YQzUvSGhOeDJ2S09CTmx1RXJodURjYjNMZmJ5TGlRVllEMkhYeGRyTkc5M1E0\\u000aNGJPajRWb0xZV0hndTI5UG9sL0htRHhUSDFwdHBQVmM5K0U0R2RwN21yVmF1bHU1\\u000acXhDOWliRzlKV3ljUUdkMUJuMG9RMjluSGlMcGd4K25HOFlkZHdPVWRkRzRndkpq\\u000aS21iUTl5aTAwYXdUamhOUE9GZXEvejVuVFJHQ3liSDZsWW9MVGtueE9UQiszMkpy\\u000aQ2pBbDVMRG90amtDZWtBUllwbVVxOWhSY2I3c3l0ME1RY1BBZUg0VlBHNmhFMUpN\\u000aYkxpTXdUWVdKNWtTM3F1elp1SkZQSUl4SFp3UmtJUzFjTnBjL0FtSUpwZm04RCtL\\u000aYUEvVmdoRkJpdnZzZnlUNndoNVRybENBcE9DcHNOTlNWbWRLRHF5QVBFTENuaURj\\u000adTRwcmpZRU5JU2tKdExUTVdBSzVCWWdRZ1ZQOVcrekJyMjNuSGlZVnhLWWhjdm9M\\u000aYTh6dUdLYlJtY2xpL3o0cXpmWnk5RGlJNmoxdWFUT1FMQzEvMzIwT2xBRGtSOVUy\\u000aT3hYZFVuSTFaSzFyY0hRZnllS3BsbUFsRTJDM3MzYkFkR3V5bXRKTDQ2M1dqZm9P\\u000aUkhHWWpvZnZNQTI0cHhnY3hFRnU5YVRFamdFVVBNeHBzN2Y4TVMyaVJvL3dxU3pX\\u000aZ0lwN1EvZHVYY1FQb0dSS2JrR0FySnNJVGdVT3BSQ3hxTFlXbk5UUy8xbmxCeXk3\\u000aQVBjcGRaRmk1WjRqM1IvbGJ0T2Era1ZiYmo4ZC8wazMwTnlDVjJGRVZGV2tPbG9z\\u000aNTFQNUNOUiswNUh6QkhQM3V3N3VyODRZYkRGdHd2UjhNM29UMXNtbXljYUsxMkpE\\u000aZGNBOUQ2YWErY2k5Wmh0UWNhbUw0Z1pjZmVpZllHNEt6NWsyT3lpMlpUNkZKOUV4\\u000aMHQ1T1d5MjZUSjllQmlCcGRaV25XZDB3bzZOMU5ST0xLdFY5L052d3R1WlZSRkxS\\u000aRUg1WGNLMnRMcTFWczFaVkg4MXM4R29UOUQ4VkFEaGFwVDBCU0xsR3A4TkNZdUdK\\u000aeXI1YVVwODdPZEl4RCt3S244NTRteVlKaXlVZnIwWmtGNGhoOEtkTXcvemg3RVQv\\u000aYkxIWlVxUXozdUV3QkcvODRuR1E9PTwveGVuYzpDaXBoZXJWYWx1ZT48L3hlbmM6\\u000aQ2lwaGVyRGF0YT48L3hlbmM6RW5jcnlwdGVkRGF0YT48eGVuYzpFbmNyeXB0ZWRL\\u000aZXkgeG1sbnM6eGVuYz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMj\\u000aIiBJZD0iX2E3NDBjZjA5MTViZDE1MmRiNzRkMDNjZDQ1NzUyMTM3Ij48eGVuYzpF\\u000abmNyeXB0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAw\\u000aMS8wNC94bWxlbmMjcnNhLW9hZXAtbWdmMXAiIHhtbG5zOnhlbmM9Imh0dHA6Ly93\\u000ad3cudzMub3JnLzIwMDEvMDQveG1sZW5jIyI+PGRzOkRpZ2VzdE1ldGhvZCB4bWxu\\u000aczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyIgQWxnb3Jp\\u000adGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjwv\\u000aeGVuYzpFbmNyeXB0aW9uTWV0aG9kPjxkczpLZXlJbmZvIHhtbG5zOmRzPSJodHRw\\u000aOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6WDUwOURhdGE+PGRz\\u000aOlg1MDlDZXJ0aWZpY2F0ZT5NSUlERlRDQ0FmMENCRlVCbkw0d0RRWUpLb1pJaHZj\\u000aTkFRRUxCUUF3VHpFTE1Ba0dBMVVFQmhNQ1FWUXhEVEFMQmdOVkJBY01CRWR5CllY\\u000ab3hEVEFMQmdOVkJBb01CRVZIU1ZveElqQWdCZ05WQkFNTUdVMVBRUzFKUkNCSlJG\\u000aQWdLRlJsYzNRdFZtVnljMmx2Ymlrd0hoY04KTVRVd016RXlNVFF3TXpReVdoY05N\\u000aVGN4TWpBMU1UUXdNelF5V2pCUE1Rc3dDUVlEVlFRR0V3SkJWREVOTUFzR0ExVUVC\\u000ad3dFUjNKaAplakVOTUFzR0ExVUVDZ3dFUlVkSldqRWlNQ0FHQTFVRUF3d1pUVTlC\\u000aTFVsRUlFbEVVQ0FvVkdWemRDMVdaWEp6YVc5dUtUQ0NBU0l3CkRRWUpLb1pJaHZj\\u000aTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFJSnYwcWU5VWR2RllTTDVJMDJHb2t3\\u000aRVZmc0lHYzdJN0VoVk5PeFkKOW10VWVubWhxTnJMc0xCRmcxSWlQYmswSVNXaE9S\\u000ad1B5VnAvUDMrR3lHUDMzOXFaNjhVQ0dWMzYxRTBRbTdjalBlL08zK3IzSEFNMgpa\\u000aQk44b0Fab0htcGhyTlM2ZktmWTU4a3lndHJVYStaeU16WVdUVGlTMzJTQ004SDU1\\u000aYmx1RUZiZVprc25iUDBZOTRJamtmSmRndnpsCk14enJsU3lvVjJ5bVdCanZTNXdl\\u000abERIZ2JDS3lqc2pJaFRSakp1L29sR0p5ZW4wMS9FcElWdFN5RFhPLzJJUzJ2Mk85\\u000aVWlGd0FveUIKWUFqUG5sM0h4SzJBNTc3blI2M014bGdQMC9zK3I4NHVCcU9BbGI0\\u000acW5icFU3bHU1R3hsQ1BrWm1wUm9vQ1FZVVJpb0Mrd2pTNmxNQwpBd0VBQVRBTkJn\\u000aa3Foa2lHOXcwQkFRc0ZBQU9DQVFFQUJxTzdra3EvZ1JhaEF2cHNRZzVMTFpST0dG\\u000acjlwSVByeU45eG1KR2dQbzdqCktObDdyczdnTlMwbG11bHVZV1duSmN3QVBid0Zl\\u000aYjk1NFZNQjl4OXA5UUV3NVJuWGFtVVk5cWEwTGdjUy90L1dYNnZKa1pQTmhXcGgK\\u000aOGJYd2gwTXZsc2JmcnZEVEpyOGNqSDNxZnhJVHA3cGEzeGIxcUU3c3VSZmZWVWRE\\u000aWGF3aVhYbldKL1dKcit0d1ZWSEhFcW5aejFsQQpyU0RMeE04c0NqRzhEZUp3OHZu\\u000aUXk1bVBHckdWVEJiYTR1cGM4VVRZMW5QVjlVMkdCSlZZdUFrb1ZSamJUbE52ckw1\\u000aSnFOcXlwS2NHCmJlampXeGdyelprZVFlVTJoRmNqdW5tZ3dHWit1ZzJmcTRrS2tR\\u000aZnR3Y3FlSlR6eXpCb28yK09vNFRtZmJzaC9vbnhQV0E9PTwvZHM6WDUwOUNlcnRp\\u000aZmljYXRlPjwvZHM6WDUwOURhdGE+PC9kczpLZXlJbmZvPjx4ZW5jOkNpcGhlckRh\\u000adGEgeG1sbnM6eGVuYz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMj\\u000aIj48eGVuYzpDaXBoZXJWYWx1ZT5Sb1NHTGFDbDN3ZkRXdDlXMm9JSDNUQ3JPTVN4\\u000aL3Y1S0pQV2hndmhWNml2RmZXSWFJeDB5RnV2NVZTME5VZ2FUVGIwVjhUYnNGN1Vz\\u000aRllzQ0xldkVUa2lWbG5OeWE4dlVoL2lYTDYzT0JmdzR3T3pSNVZheVBuaWFwWFdM\\u000aa0RHTmQ5Y3E2QU8zR1JoTWJaZDdma2NhRWNJVTB2bGtZeUJJNmE0Yms4bHM3Mm0v\\u000aZkxKQS8vaWl5L2piODkzQkZ4dk9EMk5hT1pabXhzSlI4YlFmWWpBMHdXa1pBcW56\\u000aN0EzY3lhcHV3aXVTc01wc1hYSnFjVXp2TS9GS090dE1wTnhSUVprdk1RZlNnMCtM\\u000aUVM5M0IxN0ZUZFE2OHNRL3dZQmhubFBEZXFZK0NnY1VjeVYzOVdjTjAwcUtVYmNQ\\u000aM2kzSWRWUVRkcEJQUTdRS01HR2JmS1Y0RlE9PTwveGVuYzpDaXBoZXJWYWx1ZT48\\u000aL3hlbmM6Q2lwaGVyRGF0YT48eGVuYzpSZWZlcmVuY2VMaXN0Pjx4ZW5jOkRhdGFS\\u000aZWZlcmVuY2UgVVJJPSIjXzNmZDM1ODkyZTlhOGVhY2I4ZTA4ZjI4MGE4M2ZjYjc0\\u000aIi8+PC94ZW5jOlJlZmVyZW5jZUxpc3Q+PC94ZW5jOkVuY3J5cHRlZEtleT48L3Nh\\u000abWwyOkVuY3J5cHRlZEFzc2VydGlvbj48L3NhbWwycDpSZXNwb25zZT4=\",\"dateTimeCreated\":\"2015-10-09T10:36:02.075Z\",\"id\":1}}}";
+//
+// try {
+// java.util.Map test1 = new ObjectMapper().readValue(json, java.util.Map.class);
+//
+// JsonParser parser = new JsonParser();
+// JsonObject reveivedSession = null;
+// reveivedSession = (JsonObject) parser.parse(json);
+//
+//
+//
+// JsonObject test = reveivedSession.get("data").getAsJsonObject();
+// JsonObject test2 = test.get("session").getAsJsonObject();
+// JsonElement validTo = test2.get("validTo");
+// JsonElement entityID = test2.get("entityID");
+// JsonElement sessionBlob = test2.get("sessionBlob");
+
+
+
+
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+
+ }
+
+}