diff options
| author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-01-22 13:52:48 +0100 | 
|---|---|---|
| committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-01-22 13:52:48 +0100 | 
| commit | 5b0754bddacd5bc7586b56c5a93e78f67d5cb060 (patch) | |
| tree | a318ee77db5ac52afd2fda9412e7bcc7deab362d /id/server | |
| parent | e2ca81976097a5f83183e091ec6a5c9a6afb5269 (diff) | |
| parent | 1672ef1dc32bf37c966660c33e422729addd5b41 (diff) | |
| download | moa-id-spss-5b0754bddacd5bc7586b56c5a93e78f67d5cb060.tar.gz moa-id-spss-5b0754bddacd5bc7586b56c5a93e78f67d5cb060.tar.bz2 moa-id-spss-5b0754bddacd5bc7586b56c5a93e78f67d5cb060.zip | |
Merge branch 'eSense_eIDAS_development' into moa-id-3.2_(OPB)
Conflicts:
	id/server/idserverlib/pom.xml
	id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java
	id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfiguration.java
	id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java
Diffstat (limited to 'id/server')
79 files changed, 4335 insertions, 455 deletions
| diff --git a/id/server/auth/pom.xml b/id/server/auth/pom.xml index 96f51666f..98ec73a25 100644 --- a/id/server/auth/pom.xml +++ b/id/server/auth/pom.xml @@ -132,17 +132,25 @@  				</exclusion>  			</exclusions>  		</dependency> -        <dependency> +		 +		<!-- Adding eIDAS module dependency automatically adds eIDAS protocol capabilities. --> +		<dependency> +			<groupId>MOA.id.server.modules</groupId> +			<artifactId>moa-id-module-eIDAS</artifactId> +		</dependency> +		 +		 +<!--         <dependency>              <groupId>eu.stork</groupId>              <artifactId>oasis-dss-api</artifactId>              <version>1.0.0-RELEASE</version> -        </dependency> +        </dependency> --> -        <!-- Adding stork module dependency automatically adds stork capabilities. --> -		<dependency> + <!--         Adding stork module dependency automatically adds stork capabilities.  --> +<!-- 		<dependency>  			<groupId>MOA.id.server.modules</groupId>  			<artifactId>moa-id-module-stork</artifactId> -		</dependency> +		</dependency> -->  		<!-- Adding monitoring module dependency automatically adds monitoring capabilities. -->  		<dependency> diff --git a/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml b/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml index 8f01ca22b..c3cf396b3 100644 --- a/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml +++ b/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml @@ -93,6 +93,10 @@          <from>^/stork2/RetrieveMandate$</from>          <to type="forward">/dispatcher?mod=id_stork2&action=MandateRetrievalRequest&%{query-string}</to>      </rule> +    <rule match-type="regex"> +        <from>^/eidas/ColleagueRequest$</from> +        <to type="forward">/dispatcher?mod=eidas&action=AuthenticationRequest&%{query-string}</to> +    </rule>      <rule match-type="regex"> diff --git a/id/server/data/deploy/conf/moa-id/eIDAS/EncryptModule.xml b/id/server/data/deploy/conf/moa-id/eIDAS/EncryptModule.xml new file mode 100644 index 000000000..9fef4fa2e --- /dev/null +++ b/id/server/data/deploy/conf/moa-id/eIDAS/EncryptModule.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> + +<properties> +    <comment>SWModule encrypt with JKS.</comment> +    <entry key="keystorePath">keys/eidasKeyStore.jks</entry> +    <entry key="keyStorePassword">local-demo</entry> +    <entry key="keyPassword">local-demo</entry> + +    <!-- Management of the encryption activation --> +    <entry key="encryptionActivation">eIDAS/encryptionConf.xml</entry> + + +    <entry key="responseToPointIssuer.BE">CN=local-demo-cert, OU=DIGIT, O=European Comission, L=Brussels, ST=Belgium,C=BE</entry> +    <entry key="responseToPointSerialNumber.BE">54C8F779</entry> + +    <!--  If not present then no decryption will be applied on response --> +    <entry key="responseDecryptionIssuer">CN=local-demo-cert, OU=DIGIT, O=European Comission, L=Brussels, ST=Belgium, C=BE</entry> +    <entry key="serialNumber">54C8F779</entry> + +    <entry key="keystoreType">JKS</entry> +</properties>
\ No newline at end of file diff --git a/id/server/data/deploy/conf/moa-id/eIDAS/SamlEngine_basics.xml b/id/server/data/deploy/conf/moa-id/eIDAS/SamlEngine_basics.xml new file mode 100644 index 000000000..2327fb0d8 --- /dev/null +++ b/id/server/data/deploy/conf/moa-id/eIDAS/SamlEngine_basics.xml @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> + +<properties> +	<comment>SAML constants for AuthnRequests and Responses.</comment> + +	<!-- +		Types of consent obtained from the user for this authentication and +		data transfer. +		Allow values: 'unspecified'. +	--> +	<entry key="consentAuthnRequest">unspecified</entry> +	<!-- +	Allow values: 'obtained', 'prior', 'curent-implicit', 'curent-explicit', 'unspecified'. +	--> +	<entry key="consentAuthnResponse">obtained</entry> + +	<!--URI representing the classification of the identifier +		Allow values: 'entity'. +	--> +	<entry key="formatEntity">entity</entry> +	 +	<!--Only HTTP-POST binding is only supported for inter PEPS--> +	<!--The SOAP binding is only supported for direct communication between SP-MW and VIdP--> +	<entry key="protocolBinding">HTTP-POST</entry> +	 +	<entry key="eIDSectorShare">false</entry> +	<entry key="eIDCrossSectorShare">false</entry> +	<entry key="eIDCrossBorderShare">false</entry> +	 +	<!-- Attributes with require option --> +	<entry key="isRequired">true</entry> +	 +	<!-- A friendly name for the attribute that can be displayed to a user --> +	<entry key="friendlyName">false</entry> +	 +	<!--PEPS in the Service Provider's country--> +	<entry key="requester">http://S-PEPS.gov.xx</entry> + +	<!--PEPS in the citizen's origin country--> +	<entry key="responder">http://C-PEPS.gov.xx</entry> + +	<!--Subject cannot be confirmed on or after this seconds time (positive number)--> +	<entry key="timeNotOnOrAfter">300</entry> + +	<!--Validation IP of the response--> +	<entry key="ipAddrValidation">false</entry> +	 +	<!--One time use--> +	<entry key="oneTimeUse">true</entry> + +	<!--Subject Attribute Definitions--> +	<entry key="eIdentifier">http://www.stork.gov.eu/1.0/eIdentifier</entry> +	<entry key="givenName">http://www.stork.gov.eu/1.0/givenName</entry> +	<entry key="surname">http://www.stork.gov.eu/1.0/surname</entry> +	<entry key="inheritedFamilyName">http://www.stork.gov.eu/1.0/inheritedFamilyName</entry> +	<entry key="adoptedFamilyName">http://www.stork.gov.eu/1.0/adoptedFamilyName</entry> +	<entry key="gender">http://www.stork.gov.eu/1.0/gender</entry> +	<entry key="dateOfBirth">http://www.stork.gov.eu/1.0/dateOfBirth</entry> + 	<entry key="countryCodeOfBirth">http://www.stork.gov.eu/1.0/countryCodeOfBirth</entry> +	<entry key="nationalityCode">http://www.stork.gov.eu/1.0/nationalityCode</entry> +	<entry key="maritalStatus">http://www.stork.gov.eu/1.0/maritalStatus</entry> +	<entry key="textResidenceAddress">http://www.stork.gov.eu/1.0/textResidenceAddress</entry> +	<entry key="canonicalResidenceAddress">http://www.stork.gov.eu/1.0/canonicalResidenceAddress</entry> +	<entry key="eMail">http://www.stork.gov.eu/1.0/eMail</entry> +	<entry key="title">http://www.stork.gov.eu/1.0/title</entry> +	<entry key="residencePermit">http://www.stork.gov.eu/1.0/residencePermit</entry> +	<entry key="pseudonym">http://www.stork.gov.eu/1.0/pseudonym</entry> +	<entry key="age">http://www.stork.gov.eu/1.0/age</entry> +	<entry key="isAgeOver">http://www.stork.gov.eu/1.0/isAgeOver</entry> +	<entry key="signedDoc">http://www.stork.gov.eu/1.0/signedDoc</entry> +	<entry key="citizenQAALevel">http://www.stork.gov.eu/1.0/citizenQAALevel</entry> +	<entry key="fiscalNumber">http://www.stork.gov.eu/1.0/fiscalNumber</entry> +	<entry key="unknown">http://www.stork.gov.eu/1.0/unknown</entry> + + +	<!--Subject Attribute Definitions eidas format, natural person --> +	<entry key="eidas/attributes/CurrentFamilyName">http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName</entry> +	<entry key="eidas/attributes/CurrentGivenName">http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName</entry> +	<entry key="eidas/attributes/DateOfBirth">http://eidas.europa.eu/attributes/naturalperson/DateOfBirth</entry> +	<entry key="eidas/attributes/PersonIdentifier">http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier</entry> +	<entry key="eidas/attributes/BirthName">http://eidas.europa.eu/attributes/naturalperson/BirthName</entry> +	<entry key="eidas/attributes/PlaceOfBirth">http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth</entry> +	<entry key="eidas/attributes/CurrentAddress">http://eidas.europa.eu/attributes/naturalperson/CurrentAddress</entry> +	<entry key="eidas/attributes/Gender">http://eidas.europa.eu/attributes/naturalperson/Gender</entry> +	<!--Subject Attribute Definitions eidas format, legal person --> +	<entry key="eidas/attributes/LegalPersonIdentifier">http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier</entry> +	<entry key="eidas/attributes/LegalAddress">http://eidas.europa.eu/attributes/legalperson/LegalAddress</entry> +	<entry key="eidas/attributes/LegalName">http://eidas.europa.eu/attributes/legalperson/LegalName</entry> +	<entry key="eidas/attributes/VATRegistration">http://eidas.europa.eu/attributes/legalperson/VATRegistration</entry> +	<entry key="eidas/attributes/TaxReference">http://eidas.europa.eu/attributes/legalperson/TaxReference</entry> +	<entry key="eidas/attributes/D-2012-17-EUIdentifier">http://eidas.europa.eu/attributes/legalperson/D-2012-17-EUIdentifier</entry> +	<entry key="eidas/attributes/LEI">http://eidas.europa.eu/attributes/legalperson/LEI</entry> +	<entry key="eidas/attributes/EORI">http://eidas.europa.eu/attributes/legalperson/EORI</entry> +	<entry key="eidas/attributes/SEED">http://eidas.europa.eu/attributes/legalperson/SEED</entry> +	<entry key="eidas/attributes/SIC">http://eidas.europa.eu/attributes/legalperson/SIC</entry> + +</properties>
\ No newline at end of file diff --git a/id/server/data/deploy/conf/moa-id/eIDAS/SignModule.xml b/id/server/data/deploy/conf/moa-id/eIDAS/SignModule.xml new file mode 100644 index 000000000..745580428 --- /dev/null +++ b/id/server/data/deploy/conf/moa-id/eIDAS/SignModule.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> + +<properties> +	<comment>SWModule sign with JKS.</comment> +	<entry key="keystorePath">keys/eidasKeyStore_Service_CB.jks</entry> +	<entry key="keyStorePassword">local-demo</entry> +	<entry key="keyPassword">local-demo</entry> +	<entry key="issuer">CN=cpeps-cb-demo-certificate, OU=STORK, O=CPEPS, L=EU, ST=EU, C=CB</entry> +	<entry key="serialNumber">54C8F839</entry> +	<entry key="keystoreType">JKS</entry> + +	<entry key="metadata.keystorePath">keys/eidasKeyStore_METADATA.jks</entry> +	<entry key="metadata.keyStorePassword">local-demo</entry> +	<entry key="metadata.keyPassword">local-demo</entry> +	<entry key="metadata.issuer">CN=metadata, OU=DIGIT, O=EC, L=Brussels, ST=EU, C=BE</entry> +	<entry key="metadata.serialNumber">561BC0C8</entry> +	<entry key="metadata.keystoreType">JKS</entry> +</properties> diff --git a/id/server/data/deploy/conf/moa-id/eIDAS/encryptionConf.xml b/id/server/data/deploy/conf/moa-id/eIDAS/encryptionConf.xml new file mode 100644 index 000000000..ff8307f10 --- /dev/null +++ b/id/server/data/deploy/conf/moa-id/eIDAS/encryptionConf.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> +<properties> +	<entry key="EncryptTo.CA">false</entry> + +	<entry key="EncryptTo.CB">false</entry> + +	<entry key="EncryptTo.CC">false</entry> + +	<entry key="EncryptTo.CD">false</entry> + +	<entry key="EncryptTo.CF">false</entry> + +</properties>
\ No newline at end of file diff --git a/id/server/data/deploy/conf/moa-id/keys/eidasKeyStore.jks b/id/server/data/deploy/conf/moa-id/keys/eidasKeyStore.jksBinary files differ new file mode 100644 index 000000000..c8a28d0ae --- /dev/null +++ b/id/server/data/deploy/conf/moa-id/keys/eidasKeyStore.jks diff --git a/id/server/data/deploy/conf/moa-id/keys/eidasKeyStore_METADATA.jks b/id/server/data/deploy/conf/moa-id/keys/eidasKeyStore_METADATA.jksBinary files differ new file mode 100644 index 000000000..e52051dd8 --- /dev/null +++ b/id/server/data/deploy/conf/moa-id/keys/eidasKeyStore_METADATA.jks diff --git a/id/server/data/deploy/conf/moa-id/keys/eidasKeyStore_Service_CB.jks b/id/server/data/deploy/conf/moa-id/keys/eidasKeyStore_Service_CB.jksBinary files differ new file mode 100644 index 000000000..9275f9fdd --- /dev/null +++ b/id/server/data/deploy/conf/moa-id/keys/eidasKeyStore_Service_CB.jks diff --git a/id/server/data/deploy/conf/moa-id/moa-id.properties b/id/server/data/deploy/conf/moa-id/moa-id.properties index 49e69c561..09568ce68 100644 --- a/id/server/data/deploy/conf/moa-id/moa-id.properties +++ b/id/server/data/deploy/conf/moa-id/moa-id.properties @@ -48,6 +48,12 @@ stork.fakeIdL.keygroup=  stork.documentservice.url= +## eIDAS protocol configuration +moa.id.protocols.eIDAS.samlengine.config.file=eIDAS/SamlEngine_basics.xml +moa.id.protocols.eIDAS.samlengine.sign.config.file=eIDAS/SignModule.xml +moa.id.protocols.eIDAS.samlengine.enc.config.file=eIDAS/EncryptModule.xml +moa.id.protocols.eIDAS.metadata.validation.truststore=eIDAS_metadata +  ##Protocol configuration##  #PVP2  protocols.pvp2.idp.ks.file=file:$PATH_TO_CONFIG$/conf/moa-id/keys/moa_idp[password].p12 diff --git a/id/server/data/deploy/conf/moa-spss/SampleMOASPSSConfiguration.xml b/id/server/data/deploy/conf/moa-spss/SampleMOASPSSConfiguration.xml index 9d130971d..ce5a21d57 100644 --- a/id/server/data/deploy/conf/moa-spss/SampleMOASPSSConfiguration.xml +++ b/id/server/data/deploy/conf/moa-spss/SampleMOASPSSConfiguration.xml @@ -47,6 +47,10 @@  					<cfg:Id>C-PEPS</cfg:Id>  					<cfg:TrustAnchorsLocation>trustProfiles/C-PEPS</cfg:TrustAnchorsLocation>  				</cfg:TrustProfile> +        <cfg:TrustProfile> +					<cfg:Id>eIDAS_metadata</cfg:Id> +					<cfg:TrustAnchorsLocation>trustProfiles/eIDAS_metadata</cfg:TrustAnchorsLocation> +				</cfg:TrustProfile>  			</cfg:PathValidation>  			<cfg:RevocationChecking>  				<cfg:EnableChecking>true</cfg:EnableChecking> diff --git a/id/server/data/deploy/conf/moa-spss/trustProfiles/eIDAS_metadata/eIDAS_test_node.crt b/id/server/data/deploy/conf/moa-spss/trustProfiles/eIDAS_metadata/eIDAS_test_node.crt new file mode 100644 index 000000000..14e5e5cb5 --- /dev/null +++ b/id/server/data/deploy/conf/moa-spss/trustProfiles/eIDAS_metadata/eIDAS_test_node.crt @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIFMTCCAxkCBFYbwMgwDQYJKoZIhvcNAQENBQAwXTELMAkGA1UEBhMCQkUxCzAJBgNVBAgMAkVV +MREwDwYDVQQHDAhCcnVzc2VsczELMAkGA1UECgwCRUMxDjAMBgNVBAsMBURJR0lUMREwDwYDVQQD +DAhtZXRhZGF0YTAeFw0xNTEwMTIxNDE2NDBaFw0xNjEwMTExNDE2NDBaMF0xCzAJBgNVBAYTAkJF +MQswCQYDVQQIDAJFVTERMA8GA1UEBwwIQnJ1c3NlbHMxCzAJBgNVBAoMAkVDMQ4wDAYDVQQLDAVE +SUdJVDERMA8GA1UEAwwIbWV0YWRhdGEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCN +5mYsOKzSJ9ksT9dHtFOztF1M8GIMeBLm6chIvtKHwXVLzO53RKhcOwt0j847VL6m5PcAAp57SutC +DeukA8p6UCUA905p+m7+dt7iEsUV3yje4M8dDFS/LwEF9GhFm3v471ZRYPDW769v14QkmnA9vxWB +WAj4WcMRMats9choHJdnRa1xUnVjx8yMojoVaPwt1tkG/rRnPev2o0g+VI63XkYd1pLKAU5Pt+n7 +LevLPJsvgkKLQhEB7bvMG1tZ1P4fJ0n3FOHmfLHJ/yEWA+hHXorX5T3G8Fq6GsI5O/c1zkZ7QMSw +WwzXDbq5qrfyzesdlTPfdsPnFIRddCgx8NuVwI+brlYDSdLGEm+byfM9W4WmfDN6SK1oGMSibuz7 +K49Xh0MFVKNyxT9hCz309UiV71RGnveZxdMGu4vdzP74Ll3G48IIgQ4ymFPMONYBesuorxDunSqs +R2F1+Th7k7UXL1xblFRaEyqdHlvhVrJqDP6sM9k3lM75aN4L4QMOyKRAqar+Q7f7NoUcx8cvHfqD +GLJUPcqn2msMa3mAXO5ihA2ERN41wmnmeJzsd/UiFkaqIvXUTZVwxUfQWn3D9uCg2lRAvOTHydkP +Cfwj4BtL0P9L3eSZ9NM8IGlTmlyApp2bPlzO92BsE8RE7feOmSLZESDKosqkQzZo2CMr/7V9XQID +AQABMA0GCSqGSIb3DQEBDQUAA4ICAQALfSi+sa90MbJkAeTIA/la1ibtRkPX6jIjHBvkeq8IYEZi +XxjJvI4CuQY6WSPMoDY0w9iJvKIygCxRlVi77CtFzu/otOLrXb8ozInopykRMIH4TyVmKYf//CoE +fkQ3vThaf1JLpKpLuhtqHwV03f7jwODaJBqvqdaBX3VHHMPDOeAWQTAd2abMoHgYRlUgB9TKcbJ1 +akWUyX7hnwZSCiKWbL4nrwsFJc0skFVkfjEQxlZUeRXj/bKgnb0BYUsPsFfxXKJIsIc8CmXGvxKz +B5TSpYIR79WliT9Fo8T1dJ9a/wr+bOXeM/aSUxLechCl+uDuP8yI2iRz9LT++/16HOrRSUuefHpo +7wJLJnALMABW21eMwS2XBInUBrBN9CVGAJUDF6GQWMbfxA8x0uh4oKoa/4stP5maaf/FBe52pNNv +Tacb7P3xJc0mS7jatuAHH0UfXy3+3D3z+SJY4Vy2a1cj5U1nUuxxwIRwsoRtWph0BER4RlOz4lXS +N8ZK9ahgmCsndm+eDvIJm706s7bd8m/X8Xc/lMK+eKhrK6uIIMmkwbdzbgsOS7Plj9IMGm0S4Kdb +rnAKhkhAXUi4zbd55aTx1kDodpid/dYPiqxSauyYmCXKbyFCAfY76Zw9SuFBRJClx4h5Mxb/EEpq +1WHM9IyZshufnuZ587WzqtGmJJubTA== +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/id/server/idserverlib/pom.xml b/id/server/idserverlib/pom.xml index afc432628..9c9dd123c 100644 --- a/id/server/idserverlib/pom.xml +++ b/id/server/idserverlib/pom.xml @@ -33,7 +33,7 @@  			<version>6.1.1</version>
  			<scope>test</scope>
  		</dependency>
 -	<dependency>
 +<!-- 	<dependency>
  		<groupId>eu.stork</groupId>
  		<artifactId>oasis-dss-api</artifactId>
  		<version>1.0.0-RELEASE</version>
 @@ -43,7 +43,7 @@  				<artifactId>commons-io</artifactId>
  			</exclusion>
  		</exclusions>
 -	</dependency>
 +	</dependency> -->
      <dependency>
      	<groupId>at.gv.egiz.components</groupId>
 @@ -90,6 +90,11 @@              <artifactId>Commons</artifactId>
              <version>1.4.0</version>
          </dependency> -->
 +<!--         <dependency>
 +            <groupId>eu.stork</groupId>
 +            <artifactId>SamlEngine</artifactId>
 +            <version>1.5.1</version>
 +        </dependency> -->
  		<dependency>
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java index 022ec9def..038a35d42 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java @@ -14,9 +14,10 @@ import javax.activation.CommandMap;  import javax.activation.MailcapCommandMap;  import at.gv.egovernment.moa.id.config.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.AuthConfigLoader;  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.MOAGarbageCollector; +import at.gv.egovernment.moa.id.util.AxisSecureSocketFactory;  import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;  import at.gv.egovernment.moa.id.util.SSLUtils;  import at.gv.egovernment.moa.logging.Logger; @@ -157,7 +158,7 @@ public class MOAIDAuthInitializer {          // Starts the session cleaner thread to remove unpicked authentication data          AuthenticationSessionCleaner.start(); -        AuthConfigLoader.start(); +        MOAGarbageCollector.start();      }  } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java index 57a5316e8..fe29dd2b7 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java @@ -32,7 +32,9 @@ import java.security.PrivateKey;  import java.util.ArrayList;  import java.util.Arrays;  import java.util.Date; +import java.util.Iterator;  import java.util.List; +import java.util.Map.Entry;  import java.util.regex.Matcher;  import java.util.regex.Pattern; @@ -62,6 +64,7 @@ import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameTy  import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType;  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.AuthenticationSessionStorageConstants;  import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;  import at.gv.egovernment.moa.id.auth.data.IdentityLink;  import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; @@ -69,6 +72,7 @@ import at.gv.egovernment.moa.id.auth.exception.BuildException;  import at.gv.egovernment.moa.id.auth.exception.DynamicOABuildException;  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.exception.WrongParametersException;  import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;  import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; @@ -790,16 +794,24 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants {  		//set STORK attributes  		if (extractor.containsAttribute(PVPConstants.EID_STORK_TOKEN_NAME)) {				 -			authData.setStorkAuthnResponse(extractor.getSingleAttributeValue(PVPConstants.EID_STORK_TOKEN_NAME));				 -			authData.setForeigner(true); +			try { +				authData.setGenericData(AuthenticationSessionStorageConstants.STORK_RESPONSE,  +						extractor.getSingleAttributeValue(PVPConstants.EID_STORK_TOKEN_NAME)); +				authData.setForeigner(true); +				 +			} catch (SessionDataStorageException e) { +				Logger.warn("STORK Response can not stored into generic authData.", e); +				 +			}				 -		} -	 -		if (!extractor.getSTORKAttributes().isEmpty()) { -			authData.setStorkAttributes(extractor.getSTORKAttributes()); -			authData.setForeigner(true);  		} +	 +//		if (!extractor.getSTORKAttributes().isEmpty()) { +//			authData.setStorkAttributes(extractor.getSTORKAttributes()); +//			authData.setForeigner(true); +//			 +//		}  		authData.setSsoSession(true);  		authData.setInterfederatedSSOSession(true); @@ -889,10 +901,22 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants {  		authData.setBkuURL(session.getBkuURL()); -		authData.setStorkAttributes(session.getStorkAttributes()); -		authData.setStorkAuthnResponse(session.getStorkAuthnResponse()); -		authData.setStorkRequest(session.getStorkAuthnRequest()); -		 +		//copy all generic authentication information to authData +		if (session.getGenericSessionDataStorage() != null &&   +				!session.getGenericSessionDataStorage().isEmpty()) { +			Iterator<Entry<String, Object>> copyInterator = session.getGenericSessionDataStorage().entrySet().iterator(); +			while (copyInterator.hasNext()) { +				Entry<String, Object> element = copyInterator.next(); +				try { +					authData.setGenericData(element.getKey(), element.getValue()); +					 +				} catch (SessionDataStorageException e) { +					Logger.warn("Can not add generic authData with key:" + element.getKey(), e); +					 +				}				 +			}									 +		} +								  		authData.setSignerCertificate(session.getEncodedSignerCertificate());  		authData.setAuthBlock(session.getAuthBlock()); @@ -923,9 +947,12 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants {  			}  			if (MiscUtil.isEmpty(authData.getCcc())) { -				if (authData.getStorkAuthnRequest() != null) { -					authData.setCcc(authData.getStorkAuthnRequest().getCitizenCountryCode()); -					Logger.info("Can not extract country from certificate -> Use country from STORK request."); +				String storkCCC = authData.getGenericData( +						AuthenticationSessionStorageConstants.STORK_CCC, String.class); +				 +				if (MiscUtil.isNotEmpty(storkCCC)) { +					authData.setCcc(storkCCC); +					Logger.info("Can not extract country from certificate -> Use country:" + storkCCC + " from STORK request.");  				} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java new file mode 100644 index 000000000..e321c9d05 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java @@ -0,0 +1,172 @@ +/* + * 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.builder; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +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.ServiceException; +import at.gv.egovernment.moa.id.auth.invoke.SignatureVerificationInvoker; +import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.Constants; + +/** + * @author tlenz + * + */ +public class SignatureVerificationUtils { +	  /** shortcut for XMLNS namespace URI */ +	  private static final String XMLNS_NS_URI = Constants.XMLNS_NS_URI; +	  /** shortcut for MOA namespace URI */ +	  private static final String MOA_NS_URI = Constants.MOA_NS_URI; +	  /** The DSIG-Prefix */ +	  private static final String DSIG = Constants.DSIG_PREFIX + ":"; +	   +	  /** The document containing the <code>VerifyXMLsignatureRequest</code> */ +	  private Document requestDoc_; +	  /** the <code>VerifyXMLsignatureRequest</code> root element */ +	  private Element requestElem_; +	 +	   +	  public SignatureVerificationUtils() throws BuildException { +		  try { +		        DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();         +		        requestDoc_ = docBuilder.newDocument(); +		        requestElem_ = requestDoc_.createElementNS(MOA_NS_URI, "VerifyXMLSignatureRequest"); +		        requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns", MOA_NS_URI); +		        requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns:" + Constants.DSIG_PREFIX, Constants.DSIG_NS_URI); +		        requestDoc_.appendChild(requestElem_);  +		         +		  } catch (Throwable t) { +		        throw new BuildException( +		          "builder.00",  +		          new Object[] {"VerifyXMLSignatureRequest", t.toString()},  +		          t); +		  } +	  } +	   +	  public VerifyXMLSignatureResponse verify(byte[] signature, String trustProfileID) throws MOAIDException {		   +		  try { +			  //build signature-verification request +			  Element domVerifyXMLSignatureRequest = build(signature, trustProfileID); + +			  //send signature-verification to MOA-SP  +			  Element domVerifyXMLSignatureResponse = new SignatureVerificationInvoker() +			  		.verifyXMLSignature(domVerifyXMLSignatureRequest); +			 +			// parses the <VerifyXMLSignatureResponse> +			VerifyXMLSignatureResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser( +					domVerifyXMLSignatureResponse).parseData(); +			 +			return verifyXMLSignatureResponse; +			   +		  } catch (ParseException e) { +			  Logger.error("Build signature-verification request FAILED." ,e); +			  throw e; +			 +		  } catch (ServiceException e) { +			  Logger.error("MOA-SP signature verification FAILED." ,e); +			  throw e; +			   +		} +		 				   +	  } +	   +	/** +	   * Builds a <code><VerifyXMLSignatureRequest></code> +	   * from an IdentityLink with a known trustProfileID which  +	   * has to exist in MOA-SP +	   * @param signature - The XML signature as byte[] +	   * @param trustProfileID - a preconfigured TrustProfile at MOA-SP +	   *  +	   * @return Element - The complete request as Dom-Element +	   *  +	   * @throws ParseException +	   */ +	  private Element build(byte[] signature, String trustProfileID) +	    throws ParseException  +	  {  +	    try { +	      // build the request +	      Element verifiySignatureInfoElem =  +	        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); +	      requestElem_.appendChild(verifiySignatureInfoElem); +	      Element verifySignatureEnvironmentElem =  +	        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); +	      verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); +	      Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); +	      verifySignatureEnvironmentElem.appendChild(base64ContentElem); + +	      // insert the base64 encoded signature	       +	      String base64EncodedAssertion = Base64Utils.encode(signature); +	      //replace all '\r' characters by no char. +	      StringBuffer replaced = new StringBuffer(); +	      for (int i = 0; i < base64EncodedAssertion.length(); i ++) { +	        char c = base64EncodedAssertion.charAt(i); +	        if (c != '\r') { +	          replaced.append(c); +	        } +	      } +	      base64EncodedAssertion = replaced.toString(); +	      Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); +	      base64ContentElem.appendChild(base64Content);       +	      +	      // specify the signature location +	      Element verifySignatureLocationElem =  +	        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); +	      verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); +	      Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); +	      verifySignatureLocationElem.appendChild(signatureLocation);       +	       +	      // signature manifest params +	      Element signatureManifestCheckParamsElem =  +	        requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); +	      requestElem_.appendChild(signatureManifestCheckParamsElem); +	      signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); + +	      Element returnHashInputDataElem =  +	        requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); +	      requestElem_.appendChild(returnHashInputDataElem); + +	      //add trustProfileID +	      Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); +	      trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); +	      requestElem_.appendChild(trustProfileIDElem); +	    } catch (Throwable t) { +	      throw new ParseException("builder.00",  +	        new Object[] { "VerifyXMLSignatureRequest (IdentityLink)" }, t); +	    } + +	    return requestElem_; +	  } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java index 59482c4a8..ae3ec9a9b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java @@ -44,13 +44,15 @@ import java.security.cert.CertificateException;  import java.util.ArrayList;  import java.util.Date;  import java.util.List; +import java.util.Map; +import org.apache.commons.collections4.map.HashedMap; -import eu.stork.peps.auth.commons.IPersonalAttributeList; -import eu.stork.peps.auth.commons.STORKAuthnRequest; +import at.gv.egovernment.moa.id.auth.exception.SessionDataStorageException;  import at.gv.egovernment.moa.id.data.MISMandate;  import at.gv.egovernment.moa.logging.Logger;  import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.MiscUtil;  /**   * Session data to be stored between <code>AuthenticationServer</code> API calls. @@ -215,129 +217,28 @@ public class AuthenticationSession implements Serializable {  	 * accept. The infobox identifiers are comma separated.  	 */  	private String pushInfobox; -	 -	/** -	 * The STORK AuthRequest to be sent to the C-PEPS -	 */ -	private STORKAuthnRequest storkAuthnRequest; -	 -	private String storkAuthnResponse; -	 +		  	// private AuthenticationData authData;  	// protocol selection  	private String action;  	private String modul; +	private String processInstanceId; +	  	private boolean authenticated;  	private boolean authenticatedUsed = false;  	private boolean ssoRequested = false; -	 +		  	private String QAALevel = null; -	 -//	private OAuth20SessionObject oAuth20SessionObject; -	 -	// /** -	// * Indicates if target from configuration is used or not -	// */ -	// private boolean useTargetFromConfig; -	 -	// /** -	// * Authentication data for the assertion -	// */ -	// private AuthenticationData assertionAuthData; -	// -	// /** -	// * Persondata for the assertion -	// */ -	// private String assertionPrPerson; -	// -	// /** -	// * Authblock for the assertion -	// */ -	// private String assertionAuthBlock; -	// -	// /** -	// * Identitylink assertion for the (MOA) assertion -	// */ -	// private String assertionIlAssertion; -	// -	// /** -	// * Signer certificate (base64 encoded) for the assertion -	// */ -	// private String assertionSignerCertificateBase64; -	// -	// /** -	// * bussiness service for the assertion -	// */ -	// boolean assertionBusinessService; -	// -	// /** -	// * timestamp logging when authentication session has been created -	// */ -	// private Date timestampStart; -	// private CreateXMLSignatureResponse XMLCreateSignatureResponse; -	 +		  	private VerifyXMLSignatureResponse XMLVerifySignatureResponse;  	private boolean isForeigner; - -	private IPersonalAttributeList storkAttributes; +	private Map<String, Object> genericSessionDataStorate = new HashedMap<String, Object>(); -	//Temporary store SignRequest for local processing -	private String signedDoc; -	//Temporary store SAMLResponse for processing after user signed signedDoc locally -	private String SAMLResponse; -	// -	private StringBuffer returnURL; -	private IPersonalAttributeList authnResponseGetPersonalAttributeList; -	private String authnContextClassRef; -	// private String requestedProtocolURL = null; -	 -	private String processInstanceId; -	 -	public String getAuthnContextClassRef() { -		return authnContextClassRef; -	} - -	public void setAuthnContextClassRef(String authnContextClassRef) { -		this.authnContextClassRef = authnContextClassRef; -	} - -	public IPersonalAttributeList getAuthnResponseGetPersonalAttributeList() { -		return authnResponseGetPersonalAttributeList; -	} - -	public void setAuthnResponseGetPersonalAttributeList(IPersonalAttributeList authnResponseGetPersonalAttributeList) { -		this.authnResponseGetPersonalAttributeList = authnResponseGetPersonalAttributeList; -	} - -	public String getSAMLResponse() { -		return SAMLResponse; -	} - -	public void setSAMLResponse(String samlResponse) { -		SAMLResponse = samlResponse; -	} - -	public StringBuffer getReturnURL() { -		return returnURL; -	} - -	public void setReturnURL(StringBuffer returnURL) { -		this.returnURL = returnURL; -	} - -	public String getSignedDoc() { -		return signedDoc; -	} - -	public void setSignedDoc(String signedDoc) { -		this.signedDoc = signedDoc; -	} -  	public String getModul() {  		return modul;  	} @@ -353,15 +254,7 @@ public class AuthenticationSession implements Serializable {  	public void setAction(String action) {  		this.action = action;  	} -	 -	// public AuthenticationData getAuthData() { -	// return authData; -	// } -	// -	// public void setAuthData(AuthenticationData authData) { -	// this.authData = authData; -	// } -	 +		  	public boolean isAuthenticatedUsed() {  		return authenticatedUsed;  	} @@ -378,14 +271,6 @@ public class AuthenticationSession implements Serializable {  		this.authenticated = authenticated;  	} -	// public String getRequestedProtocolURL() { -	// return requestedProtocolURL; -	// } -	// -	// public void setRequestedProtocolURL(String requestedProtocolURL) { -	// this.requestedProtocolURL = requestedProtocolURL; -	// } -	  	/**  	 * Constructor for AuthenticationSession.  	 *  @@ -395,8 +280,7 @@ public class AuthenticationSession implements Serializable {  	public AuthenticationSession(String id, Date created) {  		sessionID = id;  		sessionCreated = created; -		// setTimestampStart(); -//		infoboxValidators = new ArrayList(); +		  	}  	public X509Certificate getSignerCertificate() { @@ -760,98 +644,7 @@ public class AuthenticationSession implements Serializable {  	public void setIssueInstant(String issueInstant) {  		this.issueInstant = issueInstant;  	} -	 -//	/** -//	 * Returns the iterator to the stored infobox validators. -//	 *  -//	 * @return Iterator -//	 */ -//	public Iterator getInfoboxValidatorIterator() { -//		if (infoboxValidators == null) return null; -//		return infoboxValidators.iterator(); -//	} -	 -	// /** -	// * Adds an infobox validator class to the stored infobox validators. -	// * -	// * @param infoboxIdentifier -	// * the identifier of the infobox the validator belongs to -	// * @param infoboxFriendlyName -	// * the friendly name of the infobox -	// * @param infoboxValidator -	// * the infobox validator to add -	// */ -	// public Iterator addInfoboxValidator(String infoboxIdentifier, -	// String infoboxFriendlyName, InfoboxValidator infoboxValidator) { -	// if (infoboxValidators == null) -	// infoboxValidators = new ArrayList(); -	// Vector v = new Vector(3); -	// v.add(infoboxIdentifier); -	// v.add(infoboxFriendlyName); -	// v.add(infoboxValidator); -	// infoboxValidators.add(v); -	// return infoboxValidators.iterator(); -	// } -	 -//	/** -//	 * Tests for pending input events of the infobox validators. -//	 *  -//	 * @return true if a validator has a form to show -//	 */ -//	public boolean isValidatorInputPending() { -//		boolean result = false; -//		Iterator iter = getInfoboxValidatorIterator(); -//		if (iter != null) { -//			while (!result && iter.hasNext()) { -//				Vector infoboxValidatorVector = (Vector) iter.next(); -//				InfoboxValidator infoboxvalidator = (InfoboxValidator) infoboxValidatorVector.get(2); -//				if (!ParepUtils.isEmpty(infoboxvalidator.getForm())) result = true; -//			} -//		} -//		return result; -//	} -	 -	// /** -	// * Returns the first pending infobox validator. -	// * -	// * @return the infobox validator class -	// */ -	// public InfoboxValidator getFirstPendingValidator() { -	// Iterator iter = getInfoboxValidatorIterator(); -	// if (iter != null) { -	// while (iter.hasNext()) { -	// Vector infoboxValidatorVector = (Vector) iter.next(); -	// InfoboxValidator infoboxvalidator = (InfoboxValidator) infoboxValidatorVector -	// .get(2); -	// String form = infoboxvalidator.getForm(); -	// if (!ParepUtils.isEmpty(form)) -	// return infoboxvalidator; -	// } -	// } -	// return null; -	// } -	 -	// /** -	// * Returns the input form of the first pending infobox validator input -	// * processor. -	// * -	// * @return the form to show -	// */ -	// public String getFirstValidatorInputForm() { -	// Iterator iter = getInfoboxValidatorIterator(); -	// if (iter != null) { -	// while (iter.hasNext()) { -	// Vector infoboxValidatorVector = (Vector) iter.next(); -	// InfoboxValidator infoboxvalidator = (InfoboxValidator) infoboxValidatorVector -	// .get(2); -	// String form = infoboxvalidator.getForm(); -	// if (!ParepUtils.isEmpty(form)) -	// return form; -	// } -	// } -	// return null; -	// } -	 +		  	/**  	 * Returns domain identifier (the register and number in the register parameter).  	 * <code>null</code> in the case of not a business service. @@ -954,26 +747,7 @@ public class AuthenticationSession implements Serializable {  	public void setMandateReferenceValue(String mandateReferenceValue) {  		this.mandateReferenceValue = mandateReferenceValue;  	} -	 -	/** -	 * Gets the STORK SAML AuthnRequest -	 *  -	 * @return STORK SAML AuthnRequest -	 */ -	public STORKAuthnRequest getStorkAuthnRequest() { -		return storkAuthnRequest; -	} -	 -	/** -	 * Sets the STORK SAML AuthnRequest -	 *  -	 * @param storkAuthnRequest -	 *            STORK SAML AuthnRequest -	 */ -	public void setStorkAuthnRequest(STORKAuthnRequest storkAuthnRequest) { -		this.storkAuthnRequest = storkAuthnRequest; -	} -	 +		  	public String getCcc() {  		return ccc;  	} @@ -1054,24 +828,8 @@ public class AuthenticationSession implements Serializable {  	}  	/** -	 * Memorizes the stork attribute list. -	 * -	 * @param personalAttributeList the new stork attributes -	 */ -	public void setStorkAttributes(IPersonalAttributeList personalAttributeList) { -		this.storkAttributes = personalAttributeList; -	} -	 -	/** -	 * Recalls the stork attribute list. -	 * -	 * @return the stork attributes -	 */ -	public IPersonalAttributeList getStorkAttributes() { -		return this.storkAttributes; -	} - -	/** +	 * eIDAS QAA level +	 *   	 * @return the qAALevel  	 */  	public String getQAALevel() { @@ -1079,6 +837,8 @@ public class AuthenticationSession implements Serializable {  	}  	/** +	 * set QAA level in eIDAS form +	 *   	 * @param qAALevel the qAALevel to set  	 */  	public void setQAALevel(String qAALevel) { @@ -1086,20 +846,6 @@ public class AuthenticationSession implements Serializable {  	}  	/** -	 * @return the storkAuthnResponse -	 */ -	public String getStorkAuthnResponse() { -		return storkAuthnResponse; -	} - -	/** -	 * @param storkAuthnResponse the storkAuthnResponse to set -	 */ -	public void setStorkAuthnResponse(String storkAuthnResponse) { -		this.storkAuthnResponse = storkAuthnResponse; -	} - -	/**  	 * @return the sessionCreated  	 */  	public Date getSessionCreated() { @@ -1121,5 +867,89 @@ public class AuthenticationSession implements Serializable {  	public void setProcessInstanceId(String processInstanceId) {  		this.processInstanceId = processInstanceId;  	} + +	public Map<String, Object> getGenericSessionDataStorage() { +		return genericSessionDataStorate; +	} +	 +	/** +	 * Returns a generic session-data object with is stored with a specific identifier  +	 *  +	 * @param key The specific identifier of the session-data object +	 * @return The session-data object or null if no data is found with this key +	 */ +	public Object getGenericDataFromSession(String key) { +		if (MiscUtil.isNotEmpty(key)) { +			return genericSessionDataStorate.get(key); +			 +		}  +		 +		Logger.warn("Can not load generic session-data with key='null'"); +		return null; +				 +	} +	 +	/** +	 * Returns a generic session-data object with is stored with a specific identifier  +	 *  +	 * @param key The specific identifier of the session-data object +	 * @param clazz The class type which is stored with this key +	 * @return The session-data object or null if no data is found with this key +	 */ +	public <T> T getGenericDataFromSession(String key, final Class<T> clazz) { +		if (MiscUtil.isNotEmpty(key)) { +			Object data =  genericSessionDataStorate.get(key); +			 +			if (data == null) +				return null; +			 +			try { +				@SuppressWarnings("unchecked") +				T test = (T) data; +				return test; +				 +			} catch (Exception e) { +				Logger.warn("Generic authentication-data object can not be casted to requsted type", e); +				return null; +				 +			} +			 +		}  +		 +		Logger.warn("Can not load generic session-data with key='null'"); +		return null; +				 +	} +	 +	/** +	 * Store a generic data-object to session with a specific identifier +	 *  +	 * @param key Identifier for this data-object +	 * @param object Generic data-object which should be stored. This data-object had to be implement the 'java.io.Serializable' interface +	 * @throws SessionDataStorageException Error message if the data-object can not stored to generic session-data storage +	 */ +	public void setGenericDataToSession(String key, Object object) throws SessionDataStorageException { +		if (MiscUtil.isEmpty(key)) { +			Logger.warn("Generic session-data can not be stored with a 'null' key"); +			throw new SessionDataStorageException("Generic session-data can not be stored with a 'null' key", null); +			 +		} +		 +		if (object != null) { +			if (!Serializable.class.isInstance(object)) { +				Logger.warn("Generic session-data can only store objects which implements the 'Seralizable' interface"); +				throw new SessionDataStorageException("Generic session-data can only store objects which implements the 'Seralizable' interface", null); +				 +			}						 +		} +		 +		if (genericSessionDataStorate.containsKey(key)) +			Logger.debug("Overwrite generic session-data with key:" + key); +		else +			Logger.trace("Add generic session-data with key:" + key + " to session."); +		 +		genericSessionDataStorate.put(key, object); +	} +	  } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSessionStorageConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSessionStorageConstants.java new file mode 100644 index 000000000..648dcf6f1 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSessionStorageConstants.java @@ -0,0 +1,42 @@ +/* + * 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.data; + +/** + * @author tlenz + * + */ +public class AuthenticationSessionStorageConstants { + +	public static final String PREFIX_STORK = "stork_";  +	public static final String PREFIX_eIDAS = "eIDAS_"; +	 +	public static final String STORK_ATTRIBUTELIST = PREFIX_STORK + "attributelist"; +	public static final String STORK_REQUEST = PREFIX_STORK + "request"; +	public static final String STORK_RESPONSE = PREFIX_STORK + "response"; +	public static final String STORK_CCC = PREFIX_STORK + "ccc"; +	 +	public static final String eIDAS_ATTRIBUTELIST = PREFIX_eIDAS + "attributeList"; +	public static final String eIDAS_RESPONSE = PREFIX_eIDAS + "response"; +} + diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/SessionDataStorageException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/SessionDataStorageException.java new file mode 100644 index 000000000..203be784e --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/SessionDataStorageException.java @@ -0,0 +1,45 @@ +/* + * 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.exception; + +/** + * @author tlenz + * + */ +public class SessionDataStorageException extends MOAIDException { + +	/** +	 *  +	 */ +	private static final long serialVersionUID = 5743057708136365929L; + +	/** +	 * @param messageId +	 * @param parameters +	 */ +	public SessionDataStorageException(String messageId, Object[] parameters) { +		super(messageId, parameters); +		 +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java index 72a7d3ba1..72a7d3ba1 100644 --- a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java index 7bce406e0..7bce406e0 100644 --- a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfiguration.java index 65dcc7bf3..1f9259696 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfiguration.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfiguration.java @@ -25,6 +25,14 @@ public interface AuthConfiguration extends ConfigurationProvider{  	public String getConfigurationWithKey(final String key); +	/** +	 * Get a configuration value from basic file based MOA-ID configuration +	 *  +	 * @param key configuration key  +	 * @return configuration value +	 */ +	public String getBasicMOAIDConfiguration(final String key); +	  	public int getTransactionTimeOut();  	public int getSSOCreatedTimeOut();  	public int getSSOUpdatedTimeOut(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IGarbageCollectorProcessing.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IGarbageCollectorProcessing.java new file mode 100644 index 000000000..a1008e883 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IGarbageCollectorProcessing.java @@ -0,0 +1,36 @@ +/* + * 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.config.auth; + +/** + * @author tlenz + * + */ +public interface IGarbageCollectorProcessing { + +	/** +	 * This method gets executed by the MOA garbage collector at regular intervals. +	 *  +	 */ +	public void runGarbageCollector(); +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigLoader.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/MOAGarbageCollector.java index 1f43a0d8a..1072bec5c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigLoader.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/MOAGarbageCollector.java @@ -23,36 +23,53 @@  package at.gv.egovernment.moa.id.config.auth; -import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; -import at.gv.egovernment.moa.logging.Logger; +import java.util.ArrayList; +import java.util.List; +import at.gv.egovernment.moa.logging.Logger; -public class AuthConfigLoader implements Runnable { +public class MOAGarbageCollector implements Runnable { -	private static final long INTERVAL = 24 * 60 * 60; // 24 hours +	private static final long INTERVAL = 24 * 60 * 60; // 24 hours	 +	private static final List<IGarbageCollectorProcessing> processModules =  +			new ArrayList<IGarbageCollectorProcessing>();   	public void run() {  		while (true) {  			try { -				Thread.sleep(INTERVAL * 1000);						 -				Logger.trace("Check consistence of PVP2X metadata");										 -				MOAMetadataProvider.reInitialize(); +				Thread.sleep(INTERVAL * 1000); +				 +				try { +					for (IGarbageCollectorProcessing element : processModules) +						element.runGarbageCollector(); -						 +				} catch (Throwable e1) { +					Logger.warn("Garbage collection FAILED in some module.", e1); +				} +								  			} catch (Throwable e) { -				Logger.warn("MOA-ID Configuration validation is not possible, actually. Reuse old configuration.", e); +				Logger.warn("MOA-ID garbage collection is not possible, actually.", e);  			} finally { -				 -				 +								  			}  		}	  	} -	public static void start() { +	/** +	 * Add a module to MOA internal garbage collector. Every module is executed once a day  +	 *  +	 * @param modul Module which should be executed by the garbage collector. +	 */ +	public static void addModulForGarbageCollection(IGarbageCollectorProcessing modul) { +		processModules.add(modul); +		 +	} +	 +	public static void start() {				  		// start the session cleanup thread -		Thread configLoader = new Thread(new AuthConfigLoader(), "ConfigurationChecker"); -		configLoader.setName("ConfigurationChecker"); +		Thread configLoader = new Thread(new MOAGarbageCollector(), "MOAGarbageCollector"); +		configLoader.setName("MOAGarbageCollectorr");  		configLoader.setDaemon(true);  		configLoader.setPriority(Thread.MIN_PRIORITY);  		configLoader.start(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java index 7b798f522..18926046c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java @@ -197,6 +197,11 @@ public class PropertyBasedAuthConfigurationProvider extends ConfigurationProvide  		}  	} +	public String getBasicMOAIDConfiguration(final String key) { +		return properties.getProperty(key); +		 +	} +	  	/* (non-Javadoc)  	 * @see at.gv.egovernment.moa.id.config.auth.AuthConfiguration#getPropertyWithKey(java.lang.String)  	 */ diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/AuthenticationData.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/AuthenticationData.java index e2892e70a..53be0881b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/AuthenticationData.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/AuthenticationData.java @@ -29,13 +29,16 @@ import java.text.SimpleDateFormat;  import java.util.ArrayList;  import java.util.Date;  import java.util.List; +import java.util.Map; +import org.apache.commons.collections4.map.HashedMap;  import org.w3c.dom.Element; -import eu.stork.peps.auth.commons.IPersonalAttributeList; -import eu.stork.peps.auth.commons.STORKAuthnRequest; -  import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.exception.SessionDataStorageException; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionAttributeExtractorExeption; +import at.gv.egovernment.moa.id.util.PVPtoSTORKMapper;  import at.gv.egovernment.moa.logging.Logger;  import at.gv.egovernment.moa.util.DOMUtils;  import at.gv.egovernment.moa.util.DateTimeUtils; @@ -122,9 +125,8 @@ public class AuthenticationData  implements IAuthData, Serializable {  	  * STORK attributes from response  	  */  	  private String ccc = null; -	  private IPersonalAttributeList storkAttributes = null; -	  private String storkAuthnResponse; -	  private STORKAuthnRequest storkRequest = null; +	   +	  private Map<String, Object> genericDataStorate = new HashedMap<String, Object>();  	  private byte[] signerCertificate = null; @@ -397,23 +399,6 @@ public class AuthenticationData  implements IAuthData, Serializable {  		this.identityLink = identityLink;  	} - -	/** -	 * @return the storkAttributes -	 */ -	public IPersonalAttributeList getStorkAttributes() { -		return storkAttributes; -	} - - -	/** -	 * @param storkAttributes the storkAttributes to set -	 */ -	public void setStorkAttributes(IPersonalAttributeList storkAttributes) { -		this.storkAttributes = storkAttributes; -	} - -  	/**  	 * @return the signerCertificate  	 */ @@ -495,9 +480,47 @@ public class AuthenticationData  implements IAuthData, Serializable {  	 * @return  	 */  	public String getQAALevel() { -		return this.QAALevel; +		if (this.QAALevel != null &&  +				this.QAALevel.startsWith(PVPConstants.EIDAS_QAA_PREFIX)) { +			String mappedQAA = PVPtoSTORKMapper.getInstance().mapeIDASQAAToSTORKQAA(this.QAALevel); +			if (MiscUtil.isNotEmpty(mappedQAA)) +				return mappedQAA; +			 +			else { +				Logger.error("eIDAS QAA-level:" + this.QAALevel  +						+ " can not be mapped to STORK QAA-level! Use " +						+ PVPConstants.STORK_QAA_1_1 + " as default value."); +				return PVPConstants.STORK_QAA_1_1; +				 +			} +			 +			 +		} else +			return this.QAALevel;  	} +	 +	public String getEIDASQAALevel() { +		if (this.QAALevel != null &&  +				this.QAALevel.startsWith(PVPConstants.STORK_QAA_PREFIX)) { +			String mappedQAA = PVPtoSTORKMapper.getInstance().mapSTORKQAAToeIDASQAA(this.QAALevel); +			if (MiscUtil.isNotEmpty(mappedQAA)) +				return mappedQAA; +			 +			else { +				Logger.error("STORK QAA-level:" + this.QAALevel  +						+ " can not be mapped to eIDAS QAA-level! Use " +						+ PVPConstants.EIDAS_QAA_LOW + " as default value."); +				return PVPConstants.EIDAS_QAA_LOW; +				 +			} +			 +			 +		} else +			return this.QAALevel; +		 +	} +	  	/**  	 * @return @@ -516,13 +539,16 @@ public class AuthenticationData  implements IAuthData, Serializable {  	/** +	 * Store QAA level in eIDAS format to authentication Data +	 *   	 * @param qAALevel the qAALevel to set +	 * @throws AssertionAttributeExtractorExeption   	 */  	public void setQAALevel(String qAALevel) { -		QAALevel = qAALevel; +			QAALevel = qAALevel; +			  	} -  	/**  	 * @return the ssoSession  	 */ @@ -539,35 +565,6 @@ public class AuthenticationData  implements IAuthData, Serializable {  	}  	/** -	 * @param storkRequest the storkRequest to set -	 */ -	public void setStorkRequest(STORKAuthnRequest storkRequest) { -		this.storkRequest = storkRequest; -	} - -	/* (non-Javadoc) -	 * @see at.gv.egovernment.moa.id.data.IAuthData#getStorkAuthnRequest() -	 */ -	@Override -	public STORKAuthnRequest getStorkAuthnRequest() { -		return this.storkRequest; -	} - -	/** -	 * @return the storkAuthnResponse -	 */ -	public String getStorkAuthnResponse() { -		return storkAuthnResponse; -	} - -	/** -	 * @param storkAuthnResponse the storkAuthnResponse to set -	 */ -	public void setStorkAuthnResponse(String storkAuthnResponse) { -		this.storkAuthnResponse = storkAuthnResponse; -	} - -	/**  	 * @return the mandateReferenceValue  	 */  	public String getMandateReferenceValue() { @@ -743,5 +740,68 @@ public class AuthenticationData  implements IAuthData, Serializable {  	public void setIsBusinessService(boolean flag) {  		this.businessService = flag; -	}	 +	} +	 +	/** +	 * Returns a generic data-object with is stored with a specific identifier  +	 *  +	 * @param key The specific identifier of the data object +	 * @param clazz The class type which is stored with this key +	 * @return The data object or null if no data is found with this key +	 */ +	public <T> T getGenericData(String key, final Class<T> clazz) { +		if (MiscUtil.isNotEmpty(key)) { +			Object data = genericDataStorate.get(key);			 +			 +			if (data == null) +				return null; +			 +			try { +				@SuppressWarnings("unchecked") +				T test = (T) data; +				return test; +				 +			} catch (Exception e) { +				Logger.warn("Generic authentication-data object can not be casted to requsted type", e); +				return null; +				 +			} +			 +		}  +		 +		Logger.warn("Can not load generic session-data with key='null'"); +		return null; +				 +	} +	 +	/** +	 * Store a generic data-object to session with a specific identifier +	 *  +	 * @param key Identifier for this data-object +	 * @param object Generic data-object which should be stored. This data-object had to be implement the 'java.io.Serializable' interface +	 * @throws SessionDataStorageException Error message if the data-object can not stored to generic session-data storage +	 */ +	public void setGenericData(String key, Object object) throws SessionDataStorageException { +		if (MiscUtil.isEmpty(key)) { +			Logger.warn("Generic session-data can not be stored with a 'null' key"); +			throw new SessionDataStorageException("Generic data can not be stored with a 'null' key", null); +			 +		} +		 +		if (object != null) { +			if (!Serializable.class.isInstance(object)) { +				Logger.warn("Generic data can only store objects which implements the 'Seralizable' interface"); +				throw new SessionDataStorageException("Generic data can only store objects which implements the 'Seralizable' interface", null); +				 +			}						 +		} +		 +		if (genericDataStorate.containsKey(key)) +			Logger.debug("Overwrite generic data with key:" + key); +		else +			Logger.trace("Add generic data with key:" + key + " to session."); +		 +		genericDataStorate.put(key, object); +	} +	  } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/IAuthData.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/IAuthData.java index 09b0d7971..91d40fcc3 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/IAuthData.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/IAuthData.java @@ -27,9 +27,6 @@ import java.util.List;  import org.w3c.dom.Element; -import eu.stork.peps.auth.commons.IPersonalAttributeList; -import eu.stork.peps.auth.commons.STORKAuthnRequest; -  import at.gv.egovernment.moa.id.auth.data.IdentityLink;  /** @@ -82,6 +79,7 @@ public interface IAuthData {  	 String getMandateReferenceValue();  	 String getQAALevel(); +	 public String getEIDASQAALevel();  	 String getSessionIndex();  	 String getNameID();  @@ -89,8 +87,7 @@ public interface IAuthData {  	 boolean isForeigner();  	 String getCcc(); -	 STORKAuthnRequest getStorkAuthnRequest(); -	 String getStorkAuthnResponse(); -	 IPersonalAttributeList getStorkAttributes(); +	  +	 public <T> T getGenericData(String key, final Class<T> clazz);  } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/opemsaml/MOAStringRedirectDeflateEncoder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/opemsaml/MOAStringRedirectDeflateEncoder.java index ece1a805d..acbb67b34 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/opemsaml/MOAStringRedirectDeflateEncoder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/opemsaml/MOAStringRedirectDeflateEncoder.java @@ -27,6 +27,7 @@ import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder;  import org.opensaml.ws.message.MessageContext;  import org.opensaml.ws.message.encoder.MessageEncodingException; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.MOADefaultBootstrap;  import at.gv.egovernment.moa.logging.Logger;  /** @@ -45,6 +46,9 @@ public class MOAStringRedirectDeflateEncoder extends HTTPRedirectDeflateEncoder  					"Invalid message context type, this encoder only support SAMLMessageContext");  		} +		//load default PVP security configurations +		MOADefaultBootstrap.initializeDefaultPVPConfiguration(); +		  		SAMLMessageContext samlMsgCtx = (SAMLMessageContext) messageContext;  		String endpointURL = getEndpointURL(samlMsgCtx).buildURL(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/EIDSTORKTOKEN.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/EIDSTORKTOKEN.java index 84b791708..43a0458cb 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/EIDSTORKTOKEN.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/EIDSTORKTOKEN.java @@ -24,6 +24,7 @@ package at.gv.egovernment.moa.id.protocols.builder.attributes;  import java.io.IOException; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;  import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;  import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;  import at.gv.egovernment.moa.id.data.IAuthData; @@ -47,7 +48,8 @@ public class EIDSTORKTOKEN implements IPVPAttributeBuilder  {  			throw new UnavailableAttributeException(EID_STORK_TOKEN_NAME);  		} else { -			String storkResponse = authData.getStorkAuthnResponse(); +			String storkResponse = authData.getGenericData( +					AuthenticationSessionStorageConstants.STORK_RESPONSE, String.class);  			if ( MiscUtil.isEmpty(storkResponse) ) {  				throw new UnavailableAttributeException(EID_STORK_TOKEN_NAME); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java index 168f2362a..dc0cab8c3 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java @@ -41,6 +41,11 @@ public interface PVPConstants {  	public static final String STORK_QAA_1_3 = "http://www.stork.gov.eu/1.0/citizenQAALevel/3";  	public static final String STORK_QAA_1_4 = "http://www.stork.gov.eu/1.0/citizenQAALevel/4"; +	public static final String EIDAS_QAA_PREFIX = "http://eidas.europa.eu/LoA/"; +	public static final String EIDAS_QAA_LOW = EIDAS_QAA_PREFIX + "low"; +	public static final String EIDAS_QAA_SUBSTANTIAL = EIDAS_QAA_PREFIX + "substantial"; +	public static final String EIDAS_QAA_HIGH = EIDAS_QAA_PREFIX + "high"; +	  	public static final String STORK_ATTRIBUTE_PREFIX = "http://www.stork.gov.eu/";  	public static final String URN_OID_PREFIX = "urn:oid:"; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java index 8a6b09376..b8f7e6d80 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java @@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse;  import org.apache.velocity.app.VelocityEngine;  import org.opensaml.common.SAMLObject;  import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.binding.SAMLMessageContext;  import org.opensaml.common.xml.SAMLConstants;  import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;  import org.opensaml.saml2.binding.encoding.HTTPPostEncoder; @@ -50,6 +51,7 @@ import org.opensaml.xml.security.x509.X509Credential;  import at.gv.egovernment.moa.id.config.ConfigurationException;  import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.MOADefaultBootstrap;  import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;  import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;  import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessageInterface; @@ -75,6 +77,9 @@ public class PostBinding implements IDecoder, IEncoder {  			X509Credential credentials = CredentialProvider  					.getIDPAssertionSigningCredential(); +			//load default PVP security configurations +			MOADefaultBootstrap.initializeDefaultPVPConfiguration(); +			  			VelocityEngine engine = VelocityProvider.getClassPathVelocityEngine();  			HTTPPostEncoder encoder = new HTTPPostEncoder(engine,  					"resources/templates/pvp_postbinding_template.html"); @@ -110,6 +115,9 @@ public class PostBinding implements IDecoder, IEncoder {  			X509Credential credentials = CredentialProvider  					.getIDPAssertionSigningCredential(); +			//load default PVP security configurations +			MOADefaultBootstrap.initializeDefaultPVPConfiguration(); +			  			Logger.debug("create SAML POSTBinding response");  			 VelocityEngine engine = VelocityProvider.getClassPathVelocityEngine(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java index 0a459a9be..f48d216dd 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java @@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletResponse;  import org.opensaml.common.SAMLObject;  import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.binding.SAMLMessageContext;  import org.opensaml.common.xml.SAMLConstants;  import org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoder;  import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder; @@ -51,6 +52,7 @@ import org.opensaml.xml.security.x509.X509Credential;  import at.gv.egovernment.moa.id.config.ConfigurationException;  import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.MOADefaultBootstrap;  import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;  import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;  import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessageInterface; @@ -74,6 +76,9 @@ public class RedirectBinding implements IDecoder, IEncoder {  			X509Credential credentials = CredentialProvider  					.getIDPAssertionSigningCredential(); +			//load default PVP security configurations +			MOADefaultBootstrap.initializeDefaultPVPConfiguration(); +			  			Logger.debug("create SAML RedirectBinding response");  			HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); @@ -104,6 +109,9 @@ public class RedirectBinding implements IDecoder, IEncoder {  			X509Credential credentials = CredentialProvider  					.getIDPAssertionSigningCredential(); +			//load default PVP security configurations +			MOADefaultBootstrap.initializeDefaultPVPConfiguration(); +			  			Logger.debug("create SAML RedirectBinding response");  			HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java index 2ef861e20..c1e94ff36 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java @@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;  import org.opensaml.common.SAMLObject;  import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.binding.SAMLMessageContext;  import org.opensaml.common.xml.SAMLConstants;  import org.opensaml.saml2.binding.encoding.HTTPSOAP11Encoder;  import org.opensaml.saml2.core.RequestAbstractType; @@ -47,6 +48,7 @@ import org.opensaml.xml.security.credential.Credential;  import org.opensaml.xml.signature.SignableXMLObject;  import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.MOADefaultBootstrap;  import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AttributQueryException;  import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception;  import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessageInterface; @@ -142,6 +144,9 @@ public class SoapBinding implements IDecoder, IEncoder {  			Credential credentials = CredentialProvider  					.getIDPAssertionSigningCredential(); +			//load default PVP security configurations +			MOADefaultBootstrap.initializeDefaultPVPConfiguration(); +			  			HTTPSOAP11Encoder encoder = new HTTPSOAP11Encoder();  			HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter(  					resp, true); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/MOADefaultBootstrap.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/MOADefaultBootstrap.java index 80789cd12..b731e2a95 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/MOADefaultBootstrap.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/MOADefaultBootstrap.java @@ -50,7 +50,10 @@ public class MOADefaultBootstrap extends DefaultBootstrap {      } -     +    public static void initializeDefaultPVPConfiguration() { +    	initializeGlobalSecurityConfiguration(); +    	 +    }      /**       * Initializes the default global security configuration. diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java index f33cadc41..03fa686f9 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java @@ -55,18 +55,20 @@ import at.gv.egovernment.moa.id.commons.utils.MOAHttpProtocolSocketFactory;  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.IGarbageCollectorProcessing; +import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector;  import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;  import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;  import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SchemaValidationException;  import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SignatureValidationException;  import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.InterfederatedIDPPublicServiceFilter; -import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.MetadataFilterChain; +import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.PVPMetadataFilterChain;  import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.SchemaValidationFilter;  import at.gv.egovernment.moa.logging.Logger;  import at.gv.egovernment.moa.util.Base64Utils;  import at.gv.egovernment.moa.util.MiscUtil; -public class MOAMetadataProvider implements ObservableMetadataProvider{ +public class MOAMetadataProvider implements ObservableMetadataProvider, IGarbageCollectorProcessing {  	private static MOAMetadataProvider instance = null;  	private static Object mutex = new Object(); @@ -77,18 +79,32 @@ public class MOAMetadataProvider implements ObservableMetadataProvider{  			synchronized (mutex) {  				if (instance == null) {  					instance = new MOAMetadataProvider(); +					 +					//add this to MOA garbage collector +					MOAGarbageCollector.addModulForGarbageCollection(instance); +										  				}  			}  		}  		return instance;  	} -	public static void reInitialize() { +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing#runGarbageCollector() +	 */ +	@Override +	public void runGarbageCollector() { +		reInitialize(); +		 +	} +	 +	private static void reInitialize() {  		synchronized (mutex) {  			/**add new Metadataprovider or remove Metadataprovider which are not in use any more.**/  			if (instance != null) -				try {					 +				try { +					Logger.trace("Check consistence of PVP2X metadata");	  					instance.addAndRemoveMetadataProvider();  				} catch (ConfigurationException e) { @@ -422,8 +438,8 @@ public class MOAMetadataProvider implements ObservableMetadataProvider{  		internalProvider = chainProvider;  	} -	private MetadataFilterChain buildMetadataFilterChain(OAAuthParameter oaParam, String metadataURL, byte[] certificate) throws CertificateException { -		MetadataFilterChain filterChain = new MetadataFilterChain(metadataURL, certificate); +	private PVPMetadataFilterChain buildMetadataFilterChain(OAAuthParameter oaParam, String metadataURL, byte[] certificate) throws CertificateException { +		PVPMetadataFilterChain filterChain = new PVPMetadataFilterChain(metadataURL, certificate);  		filterChain.getFilters().add(new SchemaValidationFilter());  		if (oaParam.isInderfederationIDP()) { @@ -435,7 +451,7 @@ public class MOAMetadataProvider implements ObservableMetadataProvider{  		return filterChain;		  	} -	private HTTPMetadataProvider createNewHTTPMetaDataProvider(String metadataURL, byte[] certificate, String oaName, MetadataFilterChain filter) { +	private HTTPMetadataProvider createNewHTTPMetaDataProvider(String metadataURL, byte[] certificate, String oaName, PVPMetadataFilterChain filter) {  		HTTPMetadataProvider httpProvider = null;  		Timer timer= null;  		MOAHttpClient httpClient = null; @@ -470,7 +486,7 @@ public class MOAMetadataProvider implements ObservableMetadataProvider{  			//httpProvider.setRefreshDelayFactor(0.1F);  			if (filter == null) {			 -				filter = new MetadataFilterChain(metadataURL, certificate); +				filter = new PVPMetadataFilterChain(metadataURL, certificate);  			}  			httpProvider.setMetadataFilter(filter);  			httpProvider.initialize(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java index 26b3bfbd1..9c294245f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java @@ -38,9 +38,6 @@ import org.opensaml.saml2.core.StatusResponseType;  import org.opensaml.saml2.core.Subject;  import org.opensaml.xml.XMLObject; -import eu.stork.peps.auth.commons.PersonalAttribute; -import eu.stork.peps.auth.commons.PersonalAttributeList; -  import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;  import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionAttributeExtractorExeption;  import at.gv.egovernment.moa.logging.Logger; @@ -50,7 +47,7 @@ public class AssertionAttributeExtractor {  	private Assertion assertion = null;  	private Map<String, List<String>> attributs = new HashMap<String, List<String>>(); -	private PersonalAttributeList storkAttributes = new PersonalAttributeList(); +	//private PersonalAttributeList storkAttributes = new PersonalAttributeList();  	private final List<String> minimalAttributeNameList = Arrays.asList(  			PVPConstants.PRINCIPAL_NAME_NAME,  @@ -77,9 +74,9 @@ public class AssertionAttributeExtractor {  						for (XMLObject el : attr.getAttributeValues())  							storkAttrValues.add(el.getDOM().getTextContent()); -						PersonalAttribute storkAttr = new PersonalAttribute(attr.getName(),  -								false, storkAttrValues , "Available"); -						storkAttributes.put(attr.getName(), storkAttr ); +//						PersonalAttribute storkAttr = new PersonalAttribute(attr.getName(),  +//								false, storkAttrValues , "Available"); +//						storkAttributes.put(attr.getName(), storkAttr );  					} else {  						List<String> attrList = new ArrayList<String>(); @@ -155,9 +152,9 @@ public class AssertionAttributeExtractor {  	} -	public PersonalAttributeList getSTORKAttributes() { -		return storkAttributes; -	} +//	public PersonalAttributeList getSTORKAttributes() { +//		return storkAttributes; +//	}  	public String getNameID() throws AssertionAttributeExtractorExeption {		 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/PVPMetadataFilterChain.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/PVPMetadataFilterChain.java new file mode 100644 index 000000000..4c1da747b --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/PVPMetadataFilterChain.java @@ -0,0 +1,54 @@ +/* + * 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.protocols.pvp2x.verification.metadata; + +import java.security.cert.CertificateException; + +import at.gv.egovernment.moa.id.saml2.MetadataFilterChain; + +/** + * @author tlenz + * + */ +public class PVPMetadataFilterChain extends MetadataFilterChain { + +		 +	/** +	 * @throws CertificateException  +	 *  +	 */ +	public PVPMetadataFilterChain(String url, byte[] certificate) throws CertificateException { +		addDefaultFilters(url, certificate); +	} +	 +	public void addDefaultFilters(String url, byte[] certificate) throws CertificateException { +		addFilter(new MetadataSignatureFilter(url, certificate)); +		 +	} + + + + + +	 +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/MetadataFilterChain.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/saml2/MetadataFilterChain.java index 4e1d939ff..e7412a0fc 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/MetadataFilterChain.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/saml2/MetadataFilterChain.java @@ -20,9 +20,8 @@   * 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.protocols.pvp2x.verification.metadata; +package at.gv.egovernment.moa.id.saml2; -import java.security.cert.CertificateException;  import java.util.ArrayList;  import java.util.List; @@ -39,25 +38,23 @@ import at.gv.egovernment.moa.logging.Logger;  public class MetadataFilterChain implements MetadataFilter {  	private List<MetadataFilter> filters = new ArrayList<MetadataFilter>(); -	 +		  	/** -	 * @throws CertificateException  +	 * Return all actually used Metadata filters  	 *  +	 * @return List of Metadata filters  	 */ -	public MetadataFilterChain(String url, byte[] certificate) throws CertificateException { -		addDefaultFilters(url, certificate); -	} -	 -	public void addDefaultFilters(String url, byte[] certificate) throws CertificateException { -		filters.add(new MetadataSignatureFilter(url, certificate)); -		 +	public List<MetadataFilter> getFilters() { +		return filters;  	}  	/** -	 * @return the filter +	 * Add a new Metadata filter to filterchain +	 *  +	 * @param filter   	 */ -	public List<MetadataFilter> getFilters() { -		return filters; +	public void addFilter(MetadataFilter filter) { +		filters.add(filter);  	} @@ -67,16 +64,10 @@ public class MetadataFilterChain implements MetadataFilter {  	@Override  	public void doFilter(XMLObject arg0) throws FilterException {  		for (MetadataFilter filter : filters) { -			Logger.trace("Use MOAMetadatafilter " + filter.getClass().getName()); +			Logger.trace("Use MOAMetadataFilter " + filter.getClass().getName());  			filter.doFilter(arg0);  		}  	} - - - - - -	  } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/PVPtoSTORKMapper.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/PVPtoSTORKMapper.java index 5ef9494f4..099a70470 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/PVPtoSTORKMapper.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/PVPtoSTORKMapper.java @@ -37,10 +37,14 @@ public class PVPtoSTORKMapper {  	private static final String PVP_SECCLASS_PREFIX = "http://www.ref.gv.at/ns/names/agiz/pvp/";  	private static final String STORK_QAA_PREFIX = "http://www.stork.gov.eu/1.0/"; +	private static final String eIDAS_QAA_PREFIX = "http://eidas.europa.eu/";  	private static final String MAPPING_RESOURCE =   			"resources/properties/pvp-stork_mapping.properties"; +	private static final String MAPPING_SECCLASS_PREFIX = "secclass_"; +	private static final String MAPPING_EIDAS_PREFIX = "eidas_"; +	  	private Properties mapping = null;  	private static PVPtoSTORKMapper instance = null; @@ -68,6 +72,47 @@ public class PVPtoSTORKMapper {  	} +	/** +	 * Map STORK QAA level to eIDAS QAA level +	 *  +	 * @param storkQAA STORK QAA level +	 * @return +	 */ +	public String mapSTORKQAAToeIDASQAA(String storkQAA) { +		if (mapping != null) { +			String input = storkQAA.substring(STORK_QAA_PREFIX.length());			 +			String mappedQAA = mapping.getProperty(MAPPING_EIDAS_PREFIX + input); +			if (MiscUtil.isNotEmpty(mappedQAA)) { +				Logger.info("Map STORK-QAA " + storkQAA + " to eIDAS-QAA " + mappedQAA); +				return mappedQAA; +				 +			}						 +		}		 +		Logger.warn("No eIDAS-QAA mapping for STORK-QAA " + storkQAA +" !"); +		return null; +		 +	} +	 +	/** +	 * Map eIDAS QAA-level to STORK QAA-level +	 *  +	 * @param qaaLevel eIDAS QAA-level +	 * @return STORK QAA-level +	 */ +	public String mapeIDASQAAToSTORKQAA(String qaaLevel) { +		if (mapping != null) { +			String input = qaaLevel.substring(eIDAS_QAA_PREFIX.length());			 +			String mappedQAA = mapping.getProperty(input); +			if (MiscUtil.isNotEmpty(mappedQAA)) { +				Logger.info("Map eIDAS-QAA " + qaaLevel + " to STORK-QAA " + mappedQAA); +				return mappedQAA; +				 +			}						 +		}		 +		Logger.warn("No eIDAS-QAA mapping for eIDAS-QAA " + qaaLevel +" !"); +		return null; +	} +	  	/**Map a STORK QAA level to PVP SecClass  	 *   	 * @param STORK-QAA level @@ -76,7 +121,7 @@ public class PVPtoSTORKMapper {  	public String mapToSecClass(String storkQAALevel) {  		if (mapping != null) {  			String input = storkQAALevel.substring(STORK_QAA_PREFIX.length());			 -			String mappedQAA = mapping.getProperty(input); +			String mappedQAA = mapping.getProperty(MAPPING_SECCLASS_PREFIX + input);  			if (MiscUtil.isNotEmpty(mappedQAA)) {  				Logger.info("Map STORK-QAA " + storkQAALevel + " to PVP SecClass " + mappedQAA);  				return mappedQAA; @@ -125,4 +170,5 @@ public class PVPtoSTORKMapper {  		Logger.warn("NO mapping for PVPRole "+ el.getRoleName() + " !");  		return null;  	} +  } diff --git a/id/server/idserverlib/src/main/resources/resources/properties/pvp-stork_mapping.properties b/id/server/idserverlib/src/main/resources/resources/properties/pvp-stork_mapping.properties index ca12fada4..63a679db5 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/pvp-stork_mapping.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/pvp-stork_mapping.properties @@ -25,7 +25,19 @@ secclass/0-2=http://www.stork.gov.eu/1.0/citizenQAALevel/4  secclass/0-3=http://www.stork.gov.eu/1.0/citizenQAALevel/4  ##STORK-QAA to PVP SecClass mapping -citizenQAALevel/1=http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0 -citizenQAALevel/2=http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0-1 -citizenQAALevel/3=http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0-2 -citizenQAALevel/4=http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0-2
\ No newline at end of file +secclass_citizenQAALevel/1=http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0 +secclass_citizenQAALevel/2=http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0-1 +secclass_citizenQAALevel/3=http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0-2 +secclass_citizenQAALevel/4=http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0-2 + + +##STORK-QAA to eIDAS-QAA mapping +eidas_citizenQAALevel/1=http://eidas.europa.eu/LoA/low +eidas_citizenQAALevel/2=http://eidas.europa.eu/LoA/low +eidas_citizenQAALevel/3=http://eidas.europa.eu/LoA/substantial +eidas_citizenQAALevel/4=http://eidas.europa.eu/LoA/high + +##eIDAS-QAA to STORK-QAA mapping +LoA/low=http://www.stork.gov.eu/1.0/citizenQAALevel/1 +LoA/substantial=http://www.stork.gov.eu/1.0/citizenQAALevel/2 +LoA/high=http://www.stork.gov.eu/1.0/citizenQAALevel/4
\ No newline at end of file diff --git a/id/server/modules/moa-id-module-eIDAS/pom.xml b/id/server/modules/moa-id-module-eIDAS/pom.xml new file mode 100644 index 000000000..b43efac9e --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/pom.xml @@ -0,0 +1,111 @@ +<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-eIDAS</artifactId> +  <name>MOA-ID eIDAS Module</name> +  <description>Inbound / outbound implemention of eIDAS protocol for MOA-ID</description> +   +  <properties> +		<repositoryPath>${basedir}/../../../../repository</repositoryPath> +		 +		<eidas-commons.version>eidas.1.0</eidas-commons.version> +		<eidas-saml-engine.version>eidas.1.0</eidas-saml-engine.version> +		 +	</properties> +   +  <dependencies> +  	<dependency> +			<groupId>org.springframework</groupId> +			<artifactId>spring-test</artifactId> +			<scope>test</scope> +		</dependency> + +		<dependency> +			<groupId>junit</groupId> +			<artifactId>junit</artifactId> +			<scope>test</scope> +		</dependency> +   +		<!-- eidas Commons --> +		<dependency> +    		<groupId>eu.eidas</groupId> +    		<artifactId>eidas-commons</artifactId> +    		<version>${eidas-commons.version}</version> +			<!--scope>provided</scope--> +            <exclusions> +                <exclusion> +                    <groupId>log4j</groupId> +                    <artifactId>log4j</artifactId> +                </exclusion> +                <exclusion> +                	<artifactId>log4j-over-slf4j</artifactId> +                	<groupId>org.slf4j</groupId> +                </exclusion> +            </exclusions> +		</dependency> + +		<!-- eidas SAML Engine --> +		<dependency>  +    		<groupId>eu.eidas</groupId> +    		<artifactId>saml-engine</artifactId> +    		<version>${eidas-saml-engine.version}</version> +    		<scope>compile</scope> +			<exclusions> +				<exclusion> +					<groupId>org.slf4j</groupId> +					<artifactId>slf4j-simple</artifactId> +				</exclusion> +				<exclusion> +					<groupId>org.slf4j</groupId> +					<artifactId>jcl-over-slf4j</artifactId> +				</exclusion> +				<exclusion> +					<groupId>org.slf4j</groupId> +					<artifactId>slf4j-api</artifactId> +				</exclusion> +				<exclusion> +					<groupId>org.slf4j</groupId> +					<artifactId>jul-to-slf4j</artifactId> +				</exclusion> +				<exclusion> +					<groupId>org.slf4j</groupId> +					<artifactId>log4j-over-slf4j</artifactId> +				</exclusion> +                <exclusion> +                    <groupId>xalan</groupId> +                    <artifactId>serializer</artifactId> +                </exclusion> +                <exclusion> +                    <groupId>xalan</groupId> +                    <artifactId>xalan</artifactId> +                </exclusion> +                <exclusion> +                    <groupId>xerces</groupId> +                    <artifactId>xercesImpl</artifactId> +                </exclusion> +                <exclusion> +                    <groupId>xml-resolver</groupId> +                    <artifactId>xml-resolver</artifactId> +                </exclusion> +                <exclusion> +                    <groupId>xml-apis</groupId> +                    <artifactId>xml-apis</artifactId> +                </exclusion> +			</exclusions> +		</dependency>   +   +  	<dependency> +			<groupId>org.bouncycastle</groupId> +			<artifactId>bcprov-jdk15on</artifactId> +			<version>1.52</version> +			<!-- <scope>provided</scope> --> +		</dependency> +   +   +  </dependencies> +   +</project>
\ No newline at end of file diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java new file mode 100644 index 000000000..5166f090d --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java @@ -0,0 +1,75 @@ +/* + * 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.eidas; + +/** + * @author tlenz + * + */ +public class Constants { + +	public static final String eIDAS_SAML_ENGINE_NAME = "default"; +	public static final String SSLSOCKETFACTORYNAME = "eIDASMetadataSSLSocketFactory"; +		 +	//default keys for eIDAS SAML-engine configuration +	public static final String eIDAS_SAML_ENGINE_NAME_ID_BASICCONFIG = "SamlEngineConf"; +	public static final String eIDAS_SAML_ENGINE_NAME_ID_SIGNATURECONFIG = "SignatureConf"; +	public static final String eIDAS_SAML_ENGINE_NAME_ID_ENCRYPTIONCONFIG = "EncryptionConf"; +	public static final String eIDAS_SAML_ENGINE_NAME_ID_CLASS = "class"; +	 +	//default implementations for eIDAS SAML-engine functionality +	public static final String SAML_SIGNING_IMPLENTATION = "eu.eidas.auth.engine.core.impl.SignSW"; +	public static final String SAML_ENCRYPTION_IMPLENTATION = "eu.eidas.auth.engine.core.impl.EncryptionSW"; +	 +	//configuration property keys +	public static final String CONIG_PROPS_EIDAS_PREFIX="moa.id.protocols.eIDAS"; +	public static final String CONIG_PROPS_EIDAS_SAMLENGINE="samlengine"; +	public static final String CONIG_PROPS_EIDAS_SAMLENGINE_PREFIX=CONIG_PROPS_EIDAS_PREFIX + "." + CONIG_PROPS_EIDAS_SAMLENGINE; +	public static final String CONIG_PROPS_EIDAS_SAMLENGINE_BASIC_CONFIGFILE = CONIG_PROPS_EIDAS_SAMLENGINE_PREFIX + ".config.file";	 +	public static final String CONIG_PROPS_EIDAS_SAMLENGINE_SIGN="sign"; +	public static final String CONIG_PROPS_EIDAS_SAMLENGINE_ENCRYPT="enc"; +	public static final String CONIG_PROPS_EIDAS_SAMLENGINE_SIGN_CONFIGFILE = CONIG_PROPS_EIDAS_SAMLENGINE_PREFIX + "."  +			+ CONIG_PROPS_EIDAS_SAMLENGINE_SIGN + ".config.file"; +	public static final String CONIG_PROPS_EIDAS_SAMLENGINE_ENC_CONFIGFILE = CONIG_PROPS_EIDAS_SAMLENGINE_PREFIX + "."  +			+ CONIG_PROPS_EIDAS_SAMLENGINE_ENCRYPT + ".config.file";	 +	public static final String CONIG_PROPS_EIDAS_METADATA_VALIDATION_TRUSTSTORE = CONIG_PROPS_EIDAS_PREFIX + ".metadata.validation.truststore"; +	 +	//timeouts and clock skews +	public static final long CONFIG_PROPS_SKEWTIME = 2 * 60 * 1000;  			//2 minutes skew time for response validation +	public static final int CONFIG_PROPS_METADATA_SOCKED_TIMEOUT = 20 * 1000;  	//20 seconds metadata socked timeout +	public static final long CONFIG_PROPS_METADATA_GARBAGE_TIMEOUT = 7 * 24 * 60 * 60 * 1000;	//remove unused eIDAS metadata after 7 days +		 +	//eIDAS attribute names +	public static final String eIDAS_ATTR_PERSONALIDENTIFIER = "PersonIdentifier"; +	public static final String eIDAS_ATTR_DATEOFBIRTH = "DateOfBirth"; +	public static final String eIDAS_ATTR_CURRENTGIVENNAME = "CurrentGivenName"; +	public static final String eIDAS_ATTR_CURRENTFAMILYNAME = "CurrentFamilyName"; +		 +	//http endpoint descriptions +	public static final String eIDAS_HTTP_ENDPOINT_SP_POST = "/eidas/sp/post"; +	public static final String eIDAS_HTTP_ENDPOINT_SP_REDIRECT = "/eidas/sp/redirect"; +	public static final String eIDAS_HTTP_ENDPOINT_IDP_POST = "/eidas/idp/post"; +	public static final String eIDAS_HTTP_ENDPOINT_IDP_REDIRECT = "/eidas/idp/redirect"; +	public static final String eIDAS_HTTP_ENDPOINT_METADATA = "/eidas/metadata"; +	 +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAIDCertificateManagerConfigurationImpl.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAIDCertificateManagerConfigurationImpl.java new file mode 100644 index 000000000..9b634ff4d --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAIDCertificateManagerConfigurationImpl.java @@ -0,0 +1,118 @@ +/* + * 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.eidas.config; + +import java.util.HashMap; +import java.util.Map; + +import at.gv.egovernment.moa.logging.Logger; + +import eu.eidas.config.ConfigurationException; +import eu.eidas.samlengineconfig.AbstractCertificateConfigurationManager; +import eu.eidas.samlengineconfig.EngineInstance; +import eu.eidas.samlengineconfig.SamlEngineConfiguration; +import eu.eidas.samlengineconfig.impl.SamlEngineConfigurationImpl; + +/** + * @author tlenz + * + */ +public class MOAIDCertificateManagerConfigurationImpl extends +		AbstractCertificateConfigurationManager { + +    private SamlEngineConfiguration samlEngineConfiguration =null; +	 +    @Override +	public boolean isActive() { +		return true; +	} +     +    /** +	 *  +	 */ +	public MOAIDCertificateManagerConfigurationImpl() { +		try { +			initalizeConfiguration(); +			 +		} catch (at.gv.egovernment.moa.id.config.ConfigurationException e) { +			Logger.error("eIDAS SAML-engine initialization FAILED", e); +			 +		} +	} +     +	 +	/* (non-Javadoc) +	 * @see eu.eidas.samlengineconfig.CertificateConfigurationManager#addConfiguration(java.lang.String, java.lang.String, java.util.Map, boolean) +	 */ +	@Override +	public void addConfiguration(String paramString1, String paramString2, +			Map<String, String> paramMap, boolean paramBoolean) { +		throw new ConfigurationException("","not yet implemented"); + +	} + +	/* (non-Javadoc) +	 * @see eu.eidas.samlengineconfig.CertificateConfigurationManager#getInstance(java.lang.String) +	 */ +	@Override +	public EngineInstance getInstance(String paramString) { +		return getConfiguration().get(paramString); +		 +	} + +	/* (non-Javadoc) +	 * @see eu.eidas.samlengineconfig.CertificateConfigurationManager#getConfiguration() +	 */ +	@Override +	public Map<String, EngineInstance> getConfiguration() { +		if(samlEngineConfiguration == null){ +			try { +				initalizeConfiguration(); +				 +			} catch (at.gv.egovernment.moa.id.config.ConfigurationException e) { +				Logger.error("eIDAS SAML-engine initialization FAILED", e); +				 +			} +			 +		} +		 +		return samlEngineConfiguration==null?new HashMap<String, EngineInstance>():((MOAeIDASSAMLEngineConfigurationImpl) samlEngineConfiguration).getInstanceMap(); +		 +	} +	 +	 +	/** +	 * Initialize eIDAS SAML-engine from MOA-ID configuration +	 * @throws at.gv.egovernment.moa.id.config.ConfigurationException  +	 *  +	 */ +	private void initalizeConfiguration() throws at.gv.egovernment.moa.id.config.ConfigurationException { +		//initialize configuration +		MOAeIDASSAMLEngineConfigurationImpl tmp = new MOAeIDASSAMLEngineConfigurationImpl(); +		tmp.initialize(); +				 +		//set initialized configuration +		samlEngineConfiguration = tmp; +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java new file mode 100644 index 000000000..584910ea5 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java @@ -0,0 +1,268 @@ +/* + * 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.eidas.config; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineConfigurationException; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.FileUtils; +import at.gv.egovernment.moa.util.MiscUtil; + +import eu.eidas.samlengineconfig.BinaryParameter; +import eu.eidas.samlengineconfig.ConfigurationParameter; +import eu.eidas.samlengineconfig.EngineInstance; +import eu.eidas.samlengineconfig.InstanceConfiguration; +import eu.eidas.samlengineconfig.PropsParameter; +import eu.eidas.samlengineconfig.SamlEngineConfiguration; + +/** + * @author tlenz + * + */ +public class MOAeIDASSAMLEngineConfigurationImpl extends +		SamlEngineConfiguration { +	 +    private static final String KEYSTORE_PATH="keystorePath"; +    private static final String METADATA_KEYSTORE_PATH="metadata.keystorePath"; +    private static final String ENCRYPTION_ACTIVATION="encryptionActivation"; +    private static final String[] BINARY_PARAMETERS={KEYSTORE_PATH, ENCRYPTION_ACTIVATION,METADATA_KEYSTORE_PATH}; +		 +    public List<EngineInstance> getInstances(){ +        return super.getInstances(); +    } +	 +    @Override +    public void setInstances(List<EngineInstance> engineInstances) { +        super.setInstances(engineInstances); +         +    } +     +    public Map<String, EngineInstance> getInstanceMap() { +        Map<String, EngineInstance> result = new HashMap<String, EngineInstance>(); +        for(EngineInstance instance:getInstances()) { +        	 +            result.put(instance.getName(), instance); +        } +         +        return result; +    } +     +    //initialize +    public void initialize() throws ConfigurationException {  +    	//create an eIDAS SAML-engine instance +    	EngineInstance engineInst = new EngineInstance(); +    	engineInst.setName(Constants.eIDAS_SAML_ENGINE_NAME);    	    	 +    	List<InstanceConfiguration> engineConfigs = new ArrayList<InstanceConfiguration>(); +		 +    	 +		//add configurations +		 +		//add basic eIDAS SAML-engine configuration +		MOAeIDASSAMLInstanceConfigurationImpl samlBaseConfig = new MOAeIDASSAMLInstanceConfigurationImpl(); +		samlBaseConfig.setName(Constants.eIDAS_SAML_ENGINE_NAME_ID_BASICCONFIG);				 +		samlBaseConfig.addParameter(loadConfigurationFromExternalFile(Constants.CONIG_PROPS_EIDAS_SAMLENGINE_BASIC_CONFIGFILE)); +		engineConfigs.add(samlBaseConfig); +				 +		//add signing eIDAS SAML-engine configuration +		MOAeIDASSAMLInstanceConfigurationImpl samlSignConfig = new MOAeIDASSAMLInstanceConfigurationImpl(); +		samlSignConfig.setName(Constants.eIDAS_SAML_ENGINE_NAME_ID_SIGNATURECONFIG);		 +		samlSignConfig.addParameter(Constants.eIDAS_SAML_ENGINE_NAME_ID_CLASS,  +				Constants.SAML_SIGNING_IMPLENTATION); +		 +		//TODO: load signing keys directly from MOA-ID configuration in finale version +		samlSignConfig.addParameter(loadConfigurationFromExternalFile(Constants.CONIG_PROPS_EIDAS_SAMLENGINE_SIGN_CONFIGFILE)); +		engineConfigs.add(samlSignConfig); +		 +		//add encryption eIDAS SAML-engine configuration +		MOAeIDASSAMLInstanceConfigurationImpl samlEncConfig = new MOAeIDASSAMLInstanceConfigurationImpl(); +		samlEncConfig.setName(Constants.eIDAS_SAML_ENGINE_NAME_ID_ENCRYPTIONCONFIG); +		samlEncConfig.addParameter(Constants.eIDAS_SAML_ENGINE_NAME_ID_CLASS,  +				Constants.SAML_ENCRYPTION_IMPLENTATION); + +		//TODO: load encryption keys directly from MOA-ID configuration in finale version +		samlEncConfig.addParameter(loadConfigurationFromExternalFile(Constants.CONIG_PROPS_EIDAS_SAMLENGINE_ENC_CONFIGFILE)); +		engineConfigs.add(samlEncConfig); +		 +		engineInst.setConfigurations(engineConfigs);   +		super.addInstance(engineInst); +		 +    } +     +    /** +     *	Load an external eIDAS SAML-engine configuration file, which is referenced from MOA-ID configuration +     *  +     * @param key Configuration key, which is used in property based MOA-ID configuration file +     * @return eIDAS SAML-engine configuration object +     * @throws ConfigurationException +     */ +         +    private ConfigurationParameter loadConfigurationFromExternalFile(String key) throws ConfigurationException { +		String configFile =  +				AuthConfigurationProviderFactory.getInstance().getBasicMOAIDConfiguration(key); +		if (MiscUtil.isEmpty(configFile)) { +			Logger.warn("No eIDAS SAML-engine configuration key: "  +					+ key + " found in MOA-ID properties configuration file."); +			//throw new EIDASEngineConfigurationException("No eIDAS SAML-engine configuration property.", null); +			return null; +		} +		 +		Properties inputProps = loadPropsFromXml(configFile);    	 +		return buildPropsParameter(inputProps, configFile); +    	 +    } +     +     +    private PropsParameter buildPropsParameter(Properties inputProps, String fileName) throws EIDASEngineConfigurationException { +    	PropsParameter outputProps = new PropsParameter(); +    	outputProps.setFileName(fileName); +    	 +    	//original eIDAS SAML-engine use this identifier +    	outputProps.setName("fileConfiguration"); +    	 +    	outputProps.setValue(inputProps); + +    	//post-process special parameters +    	for(String key:BINARY_PARAMETERS) { +            Object keystorePath = inputProps.get(key); +            if (keystorePath != null) { +            	if (keystorePath instanceof String &&  +            			isBinaryParameter((String)keystorePath) ) { +            		BinaryParameter bp = new BinaryParameter(); +            		bp.setValue(loadBinaryFile(keystorePath.toString())); +            		bp.setName(key); +            		bp.setUrl(keystorePath.toString()); +            		inputProps.put(key, bp); +                 +            	} else { +            		Logger.warn("eIDAS SAML-engine keyStore parameter has an unsuspected type. +" + +            				"(Type: " + keystorePath.toString() + ")"); +            	 +            	} +            } +        } +    	 +    	return outputProps; +    } +     +    private boolean isBinaryParameter(String parameter) { +    	if (MiscUtil.isNotEmpty(parameter)) { +    		String absoluteConfigFile; +			try { +				absoluteConfigFile = FileUtils.makeAbsoluteURL( +						parameter, +						AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir()); +				File file = new File(new URL(absoluteConfigFile).toURI()); +	    		return file.exists(); +	    		 +			} catch (ConfigurationException | MalformedURLException | URISyntaxException e) { +				Logger.warn("Binary eIDAS SAML-engine configuration parameter: "  +						+ parameter + " is not loadable."); +				 +			} +     		 +    	} +    	 +    	return false; +         +    } +     +    private byte[] loadBinaryFile(String fileName) throws EIDASEngineConfigurationException{ +    	InputStream is = null; +    	byte data[]=null; +    	try { +    		String absoluteConfigFile = FileUtils.makeAbsoluteURL( +    				fileName, +    				AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir()); +    		 +    		File file = new File(new URL(absoluteConfigFile).toURI()); +    		is = new FileInputStream(file); +    		data=new byte[is.available()]; +            is.read(data); +    		 +    	} catch (ConfigurationException | URISyntaxException | IOException e) { +    		throw new EIDASEngineConfigurationException("eIDAS SAML-engine configuration FAILED", null, e); +    				 +    	} finally { +    		if (is != null) +				try { +					is.close(); +					 +				} catch (IOException e) { +					Logger.warn("eIDAS SAML-engine configuration is not closeable.", e); +					 +				} +    		 +    	} +    	 +    	return data; +         +    } +     +    private Properties loadPropsFromXml(String configFile) throws EIDASEngineConfigurationException { +    	Properties props = new Properties(); +    	InputStream is = null; +    	try { +    		String absoluteConfigFile = FileUtils.makeAbsoluteURL( +    				configFile, +    				AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir()); +    		 +    		File file = new File(new URL(absoluteConfigFile).toURI()); +    		is = new FileInputStream(file); +    		props.loadFromXML(is); +    		 +    	} catch (ConfigurationException | URISyntaxException | IOException e) { +    		throw new EIDASEngineConfigurationException("eIDAS SAML-engine configuration FAILED", null, e); +    				 +    	} finally { +    		if (is != null) +				try { +					is.close(); +					 +				} catch (IOException e) { +					Logger.warn("eIDAS SAML-engine configuration is not closeable.", e); +					 +				} +    		 +    	} +    	 +    	return props; +    	    	 +    } +     +     +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLInstanceConfigurationImpl.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLInstanceConfigurationImpl.java new file mode 100644 index 000000000..dccd39905 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLInstanceConfigurationImpl.java @@ -0,0 +1,60 @@ +/* + * 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.eidas.config; + +import java.util.ArrayList; +import java.util.List; + +import eu.eidas.samlengineconfig.ConfigurationParameter; +import eu.eidas.samlengineconfig.InstanceConfiguration; +import eu.eidas.samlengineconfig.StringParameter; + +/** + * @author tlenz + * + */ +public class MOAeIDASSAMLInstanceConfigurationImpl extends +		InstanceConfiguration { + +	public void addParameter(ConfigurationParameter param) { +		if (param != null) { +			List<ConfigurationParameter> paramList = super.getParameters(); +			if (paramList == null) { +				paramList = new ArrayList<ConfigurationParameter>(); +				super.setParameters(paramList); +			 +			} +		 +			paramList.add(param); +		}		 +	} +	 +	public void addParameter(String key, String value) { +		StringParameter param = new StringParameter(); +		param.setName(key); +		param.setValue(value);		 +		addParameter(param); +		 +	} +		 +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASAuthenticationModulImpl.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASAuthenticationModulImpl.java new file mode 100644 index 000000000..7b044522c --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASAuthenticationModulImpl.java @@ -0,0 +1,72 @@ +/* + * 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.eidas; + +import org.apache.commons.lang3.StringUtils; + +import at.gv.egovernment.moa.id.auth.modules.AuthModule; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; + +/** + * @author tlenz + * + */ +public class eIDASAuthenticationModulImpl implements AuthModule { + +	private int priority = 1; + +	@Override +	public int getPriority() { +		return priority; +	} + +	/** +	 * Sets the priority of this module. Default value is {@code 0}. +	 * @param priority The priority. +	 */ +	public void setPriority(int priority) { +		this.priority = priority; +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process.api.ExecutionContext) +	 */ +	@Override +	public String selectProcess(ExecutionContext context) { +		if (StringUtils.isNotBlank((String) context.get("ccc")) ||  +				StringUtils.isNotBlank((String) context.get("CCC")))  +			return "eIDASAuthentication"; +		else +			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/eidas/eIDAS.Authentication.process.xml" }; +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASSignalServlet.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASSignalServlet.java new file mode 100644 index 000000000..49f0451cb --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASSignalServlet.java @@ -0,0 +1,95 @@ +/* + * 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.eidas; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang.StringEscapeUtils; + +import at.gv.egovernment.moa.id.auth.servlet.ProcessEngineSignalServlet; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +@WebServlet(urlPatterns = { "/eidas/sp/post",  "/eidas/sp/redirect"}, loadOnStartup = 1) +public class eIDASSignalServlet extends ProcessEngineSignalServlet { + +	private static final long serialVersionUID = 8215688005533754459L; + +	public eIDASSignalServlet() { +		super(); +		Logger.debug("Registering servlet " + getClass().getName() +  +				" with mappings '/eidas/sp/post' and '/eidas/sp/redirect'."); +		 +	} +	 +	 +	@Override +	/** +	 * Protocol specific implementation to get the sessionID  +	 * from http request object +	 *  +	 * @param request The http Servlet-Request object +	 * @return The SessionId  +	 *  +	 */ +	public String getMoaSessionId(HttpServletRequest request) { +		String sessionId = super.getMoaSessionId(request); +		 +		try { + +			// use SAML2 relayState +			if (sessionId == null) { +				sessionId = StringEscapeUtils.escapeHtml(request.getParameter("RelayState")); +			} + +			// take from InResponseTo attribute of SAMLResponse +			if (sessionId == null) { +				String base64SamlToken = request.getParameter("SAMLResponse"); +				if (base64SamlToken != null && false) { +//					byte[] samlToken = Base64Utils.decode(base64SamlToken, false); +//					Document samlResponse = parseDocument(new ByteArrayInputStream(samlToken)); +// +//					XPath xPath = XPathFactory.newInstance().newXPath(); +//					SimpleNamespaceContext nsContext = new SimpleNamespaceContext(); +//					nsContext.bindNamespaceUri("saml2p", "urn:oasis:names:tc:SAML:2.0:protocol"); +//					xPath.setNamespaceContext(nsContext); +//					XPathExpression expression = xPath.compile("string(/saml2p:Response/@InResponseTo)"); +//					sessionId = (String) expression.evaluate(samlResponse, XPathConstants.STRING); +//					sessionId = StringEscapeUtils.escapeHtml(StringUtils.trimToNull(sessionId)); +				} else { +					Logger.warn("No parameter 'SAMLResponse'. Unable to retrieve MOA session id."); +				} +			} + +		} catch (Exception e) { +			Logger.warn("Unable to retrieve moa session id.", e); +		} + +		return sessionId; +	} +	 +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java new file mode 100644 index 000000000..965abcde1 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java @@ -0,0 +1,370 @@ +package at.gv.egovernment.moa.id.auth.modules.eidas.engine; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Timer; + +import javax.net.ssl.SSLHandshakeException; +import javax.xml.namespace.QName; + +import org.apache.commons.httpclient.MOAHttpClient; +import org.apache.commons.httpclient.params.HttpClientParams; +import org.opensaml.saml2.metadata.EntitiesDescriptor; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.RoleDescriptor; +import org.opensaml.saml2.metadata.provider.ChainingMetadataProvider; +import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; +import org.opensaml.saml2.metadata.provider.MetadataFilter; +import org.opensaml.saml2.metadata.provider.MetadataProvider; +import org.opensaml.saml2.metadata.provider.MetadataProviderException; +import org.opensaml.saml2.metadata.provider.ObservableMetadataProvider; +import org.opensaml.xml.XMLObject; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.commons.ex.MOAHttpProtocolSocketFactoryException; +import at.gv.egovernment.moa.id.commons.utils.MOAHttpProtocolSocketFactory; +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.IGarbageCollectorProcessing; +import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SchemaValidationException; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SignatureValidationException; +import at.gv.egovernment.moa.id.saml2.MetadataFilterChain; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; +import eu.eidas.auth.engine.AbstractSAMLEngine; + +public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvider, IGarbageCollectorProcessing { + +	private static MOAeIDASChainingMetadataProvider instance = null; +	private static Object mutex = new Object(); +	 +	private MetadataProvider internalProvider; +	private Map<String, Date> lastAccess = null; +	 +	 +	public static MOAeIDASChainingMetadataProvider getInstance() { +		if (instance == null) { +			synchronized (mutex) { +				if (instance == null) { +					instance = new MOAeIDASChainingMetadataProvider(); +					MOAGarbageCollector.addModulForGarbageCollection(instance); +				} +			} +		} +		return instance; +	} +	 +	 +	private MOAeIDASChainingMetadataProvider() { +		internalProvider = new ChainingMetadataProvider(); +		lastAccess = new HashMap<String, Date>(); +		 +	} +	 +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing#runGarbageCollector() +	 */ +	@Override +	public void runGarbageCollector() { +		if (!lastAccess.isEmpty()) { +			Date now = new Date(); +			Date expioredate = new Date(now.getTime() -  +					Constants.CONFIG_PROPS_METADATA_GARBAGE_TIMEOUT); +			Logger.debug("Starting eIDAS Metadata garbag collection (Expioredate:"  +					+ expioredate + ")"); +			 +			List<String> expiredEntities = new ArrayList<String>(); +			 +			Iterator<Entry<String, Date>> lastAccessInterator = lastAccess.entrySet().iterator(); +			while(lastAccessInterator.hasNext()) { +				Entry<String, Date> element = lastAccessInterator.next(); +				if (element.getValue().before(expioredate)) { +					Logger.debug("Remove unused eIDAS Metadate: " + element.getKey()); +					expiredEntities.add(element.getKey()); +					 +				}								 +			} +		 +			if (!expiredEntities.isEmpty()) {			 +				ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; +			 +				//get all actually loaded metadata providers +				Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders(); +			 +				for (String expired : expiredEntities) { +					if (loadedproviders.containsKey(expired)) { +						HTTPMetadataProvider provider = loadedproviders.get(expired); +					 +						//destroy metadata provider +						provider.destroy(); +					 +						//remove from map +						loadedproviders.remove(expired); +					 +						/*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException) +						 *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/ +						//chainProvider.removeMetadataProvider(provider);					 +						Logger.info("Remove not used eIDAS MetadataProvider " + expired  +								+ " after timeout."); +										 +					} else +						Logger.warn("eIDAS metadata for EntityID: " + expired  +								+ " is marked as unsed, but no loaded metadata provider is found."); +				 +				} +			 +				try { +					synchronized (chainProvider) { +						chainProvider.setProviders(new ArrayList<MetadataProvider>(loadedproviders.values())); +					 +						emitChangeEvent();	 +					} +					 +				} catch (MetadataProviderException e) { +					Logger.warn("ReInitalize eIDASA MetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy", e); +				 +				} +			} +		}					 +	} +	 +	 +	 +	private HTTPMetadataProvider createNewHTTPMetaDataProvider(String metadataURL) { +		HTTPMetadataProvider httpProvider = null; +		Timer timer= null; +		MOAHttpClient httpClient = null; +		try { +			AuthConfiguration authConfig = AuthConfigurationProviderFactory.getInstance(); +			 +			httpClient = new MOAHttpClient(); +			 +			HttpClientParams httpClientParams = new HttpClientParams(); +			httpClientParams.setSoTimeout(Constants.CONFIG_PROPS_METADATA_SOCKED_TIMEOUT); +			httpClient.setParams(httpClientParams); +			 +			if (metadataURL.startsWith("https:")) { +				try { +					MOAHttpProtocolSocketFactory protoSocketFactory = new MOAHttpProtocolSocketFactory( +							Constants.SSLSOCKETFACTORYNAME,  +							authConfig.getCertstoreDirectory(),  +							authConfig.getTrustedCACertificates(), +							null, +							AuthConfiguration.DEFAULT_X509_CHAININGMODE,  +							authConfig.isTrustmanagerrevoationchecking()); +					 +					httpClient.setCustomSSLTrustStore(metadataURL, protoSocketFactory); + +				} catch (MOAHttpProtocolSocketFactoryException e) { +					Logger.warn("MOA SSL-TrustStore can not initialized. Use default Java TrustStore."); +					 +				} +			} +			 +			timer = new Timer(); +			httpProvider = new HTTPMetadataProvider(timer, httpClient,  +					metadataURL); +			httpProvider.setParserPool(AbstractSAMLEngine.getNewBasicSecuredParserPool()); +			httpProvider.setRequireValidMetadata(true); +			httpProvider.setMinRefreshDelay(1000*60*15); //15 minutes +			httpProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours +			//httpProvider.setRefreshDelayFactor(0.1F); +			 +			//add Metadata filters +			MetadataFilterChain filter = new MetadataFilterChain(); +			filter.addFilter(new MOAeIDASMetadataSignatureFilter( +					authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_METADATA_VALIDATION_TRUSTSTORE))); +			httpProvider.setMetadataFilter(filter); +			 +			httpProvider.initialize(); +									 +			return httpProvider; +						 +		} catch (Throwable e) {			 +			if (e.getCause() != null && e.getCause().getCause() instanceof SSLHandshakeException) { +				Logger.warn("SSL-Server certificate for metadata "  +						+ metadataURL + " not trusted.", e); +				 +			} if (e.getCause() != null && e.getCause().getCause() instanceof SignatureValidationException) {				 +				Logger.warn("Signature verification for metadata"  +						+ metadataURL + " FAILED.", e); +			 +			} if (e.getCause() != null && e.getCause().getCause() instanceof SchemaValidationException) { +				Logger.warn("Schema validation for metadata "  +						+ metadataURL + " FAILED.", e);								 +			} +			 +			Logger.error( +					"Failed to add Metadata file for " +							+ metadataURL + "[ " +							+ e.getMessage() + " ]", e); +						 +			if (httpProvider != null) { +				Logger.debug("Destroy failed Metadata provider"); +				httpProvider.destroy(); +			} +			 +			if (timer != null) { +				Logger.debug("Destroy Timer."); +				timer.cancel(); +			} + +			 +		} +		 +		return null;	 +	} + +	private Map<String, HTTPMetadataProvider> getAllActuallyLoadedProviders() { +		Map<String, HTTPMetadataProvider> loadedproviders = new HashMap<String, HTTPMetadataProvider>(); +		ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; +		 +		//make a Map of all actually loaded HTTPMetadataProvider +		List<MetadataProvider> providers = chainProvider.getProviders(); +		for (MetadataProvider provider : providers) { +			if (provider instanceof HTTPMetadataProvider) { +				HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; +				loadedproviders.put(httpprovider.getMetadataURI(), httpprovider); + +			} +		} +		 +		return loadedproviders;		 +	} +	 +	public boolean refreshMetadataProvider(String metadataURL) { +		try { +			if (MiscUtil.isNotEmpty(metadataURL)) { +				Map<String, HTTPMetadataProvider> actuallyLoadedProviders = getAllActuallyLoadedProviders(); + +				// check if MetadataProvider is actually loaded +				if (actuallyLoadedProviders.containsKey(metadataURL)) { +					actuallyLoadedProviders.get(metadataURL).refresh();						 +					Logger.info("eIDAS metadata for "  +							+ metadataURL + " is refreshed."); +					return true; +					 +				} else { +					//load new Metadata Provider				 +					ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider;						 +					HTTPMetadataProvider newMetadataProvider = createNewHTTPMetaDataProvider(metadataURL);										 +					chainProvider.addMetadataProvider(newMetadataProvider); +					 +					emitChangeEvent(); +					Logger.info("eIDAS metadata for "  +							+ metadataURL + " is added."); +					return true; +										 +				} +														 +			} else +				Logger.debug("Can not refresh eIDAS metadata: NO eIDAS metadata URL."); +																								 +		} catch (MetadataProviderException e) { +			Logger.warn("Refresh eIDAS metadata for "  +					+ metadataURL + " FAILED.", e); +			 +		} +		 +		return false; +		 +	} +	 + +	public boolean requireValidMetadata() { +		return internalProvider.requireValidMetadata(); +	} + +	public void setRequireValidMetadata(boolean requireValidMetadata) { +		internalProvider.setRequireValidMetadata(requireValidMetadata); +	} + +	public MetadataFilter getMetadataFilter() { +		return internalProvider.getMetadataFilter(); +	} + +	public void setMetadataFilter(MetadataFilter newFilter) +			throws MetadataProviderException { +		internalProvider.setMetadataFilter(newFilter); +	} + +	public XMLObject getMetadata() throws MetadataProviderException { +		return internalProvider.getMetadata(); +	} + +	public EntitiesDescriptor getEntitiesDescriptor(String entitiesID) +			throws MetadataProviderException { +		Logger.warn("eIDAS metadata not support 'EntitiesDescriptor' elements!");		 +		return null; +		 +	} + +	public EntityDescriptor getEntityDescriptor(String entityID) +			throws MetadataProviderException { +		EntityDescriptor entityDesc = null; +		try { +			entityDesc = internalProvider.getEntityDescriptor(entityID); +			if (entityDesc == null) { +				Logger.debug("Can not find eIDAS metadata for entityID: " + entityID  +						+ " Start refreshing process ..."); +				if (refreshMetadataProvider(entityID)) +					entityDesc =  internalProvider.getEntityDescriptor(entityID); +									 +			} else { +				if (!entityDesc.isValid()) +					if (refreshMetadataProvider(entityID)) +						entityDesc = internalProvider.getEntityDescriptor(entityID); +									 +			} +			 +			 +		} catch (MetadataProviderException e) { +			Logger.debug("Can not find eIDAS metadata for entityID: " + entityID  +					+ " Start refreshing process ..."); +			if (refreshMetadataProvider(entityID)) +				entityDesc = internalProvider.getEntityDescriptor(entityID); +			 +		} +		 +		if (entityDesc != null) +			lastAccess.put(entityID, new Date()); +		 +		return entityDesc; +	} + +	public List<RoleDescriptor> getRole(String entityID, QName roleName) +			throws MetadataProviderException { +		return internalProvider.getRole(entityID, roleName); +	} + +	public RoleDescriptor getRole(String entityID, QName roleName, +			String supportedProtocol) throws MetadataProviderException { +		return internalProvider.getRole(entityID, roleName, supportedProtocol); +	} + +	/* (non-Javadoc) +	 * @see org.opensaml.saml2.metadata.provider.ObservableMetadataProvider#getObservers() +	 */ +	@Override +	public List<Observer> getObservers() { +		return ((ChainingMetadataProvider) internalProvider).getObservers(); +	} + +	protected void emitChangeEvent() { +		if ((getObservers() == null) || (getObservers().size() == 0)) { +			return; +		} + +		List<Observer> tempObserverList = new ArrayList<Observer>(getObservers()); +		for (ObservableMetadataProvider.Observer observer : tempObserverList) +			if (observer != null) +				observer.onEvent(this); +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java new file mode 100644 index 000000000..e3ae5c046 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java @@ -0,0 +1,120 @@ +/* + * 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.eidas.engine; + +import java.security.KeyStore; + +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.IDPSSODescriptor; +import org.opensaml.saml2.metadata.RoleDescriptor; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.provider.MetadataProvider; +import org.opensaml.saml2.metadata.provider.MetadataProviderException; + +import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.auth.engine.metadata.MetadataProcessorI; +import eu.eidas.engine.exceptions.SAMLEngineException; + +/** + * @author tlenz + * + */ +public class MOAeIDASMetadataProviderDecorator implements MetadataProcessorI { + +	private MetadataProvider metadataprovider = null; +	 +	/** +	 *  +	 */ +	public MOAeIDASMetadataProviderDecorator(MetadataProvider metadataprovider) { +		this.metadataprovider = metadataprovider; +		 +	} +	 +	/* (non-Javadoc) +	 * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#getEntityDescriptor(java.lang.String) +	 */ +	@Override +	public EntityDescriptor getEntityDescriptor(String url) +			throws SAMLEngineException {		 +		try { +			return this.metadataprovider.getEntityDescriptor(url); +			 +		} catch (MetadataProviderException e) { +			throw new SAMLEngineException("eIDAS Metadata processing FAILED.", e); +			 +		} +	} + +	/* (non-Javadoc) +	 * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#getSPSSODescriptor(java.lang.String) +	 */ +	@Override +	public SPSSODescriptor getSPSSODescriptor(String url) +			throws SAMLEngineException { +		return getFirstRoleDescriptor(getEntityDescriptor(url), SPSSODescriptor.class); +		 +	} + +	/* (non-Javadoc) +	 * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#getIDPSSODescriptor(java.lang.String) +	 */ +	@Override +	public IDPSSODescriptor getIDPSSODescriptor(String url) +			throws SAMLEngineException { +		return getFirstRoleDescriptor(getEntityDescriptor(url), IDPSSODescriptor.class); +		 +	} + +	/* (non-Javadoc) +	 * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#checkValidMetadataSignature(java.lang.String, eu.eidas.auth.engine.EIDASSAMLEngine) +	 */ +	@Override +	public void checkValidMetadataSignature(String url, EIDASSAMLEngine engine) +			throws SAMLEngineException { +		//Do nothing, because metadata signature is already validated during  +		//metadata provider initialization  +		 +	} + +	/* (non-Javadoc) +	 * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#checkValidMetadataSignature(java.lang.String, java.security.KeyStore) +	 */ +	@Override +	public void checkValidMetadataSignature(String url, KeyStore trustStore) +			throws SAMLEngineException { +		//Do nothing, because metadata signature is already validated during  +		//metadata provider initialization  +		 +	} + +    protected <T extends RoleDescriptor> T getFirstRoleDescriptor(EntityDescriptor entityDescriptor, final Class<T> clazz){ +        for(RoleDescriptor rd:entityDescriptor.getRoleDescriptors()){ +            if(clazz.isInstance(rd)){ +                return (T)rd; +            } +        } +        return null; +    } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataSignatureFilter.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataSignatureFilter.java new file mode 100644 index 000000000..c9f3e5bcd --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataSignatureFilter.java @@ -0,0 +1,132 @@ +/* + * 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.eidas.engine; + +import java.io.IOException; +import java.io.StringWriter; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +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.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.provider.FilterException; +import org.opensaml.saml2.metadata.provider.MetadataFilter; +import org.opensaml.xml.XMLObject; + +import at.gv.egovernment.moa.id.auth.builder.SignatureVerificationUtils; +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +public class MOAeIDASMetadataSignatureFilter implements MetadataFilter { + +	private String trustProfileID = null; +	 +	/** +	 *  +	 */ +	public MOAeIDASMetadataSignatureFilter(String trustProfileID) { +		this.trustProfileID = trustProfileID; +		 +	} +	 +	 +	/* (non-Javadoc) +	 * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject) +	 */ +	@Override +	public void doFilter(XMLObject metadata) throws FilterException { +		if (metadata instanceof EntityDescriptor) { +			if (((EntityDescriptor) metadata).isSigned()) {				 +				EntityDescriptor entityDes = (EntityDescriptor) metadata; +				//check signature; +				try { +					Transformer transformer = TransformerFactory.newInstance() +							.newTransformer();	 +					StringWriter sw = new StringWriter(); +					StreamResult sr = new StreamResult(sw); +					DOMSource source = new DOMSource(metadata.getDOM()); +					transformer.transform(source, sr); +					sw.close(); +					String metadataXML = sw.toString(); +					 +					SignatureVerificationUtils sigVerify =  +							new SignatureVerificationUtils(); +					VerifyXMLSignatureResponse result = sigVerify.verify( +							metadataXML.getBytes(), trustProfileID); +					 +					//check signature-verification result +					if (result.getSignatureCheckCode() != 0) { +						Logger.warn("eIDAS Metadata signature-verification FAILED!" +								+ " Metadata: " + entityDes.getEntityID() +								+ " StatusCode:" + result.getSignatureCheckCode()); +						throw new FilterException("eIDAS Metadata signature-verification FAILED!" +								+ " Metadata: " + entityDes.getEntityID() +								+ " StatusCode:" + result.getSignatureCheckCode()); +						 +					} +					 +					if (result.getCertificateCheckCode() != 0) { +						Logger.warn("eIDAS Metadata certificate-verification FAILED!" +								+ " Metadata: " + entityDes.getEntityID() +								+ " StatusCode:" + result.getCertificateCheckCode()); +						throw new FilterException("eIDAS Metadata certificate-verification FAILED!" +								+ " Metadata: " + entityDes.getEntityID() +								+ " StatusCode:" + result.getCertificateCheckCode()); +						 +					} +					 +				 +				} catch (MOAIDException | TransformerFactoryConfigurationError | TransformerException | IOException e) { +					Logger.error("eIDAS Metadata verification has an interal error.", e); +					throw new FilterException("eIDAS Metadata verification has an interal error." +							+ " Message:" + e.getMessage()); +					 +				} +				 +				 +			} else { +				Logger.warn("eIDAS Metadata root-element MUST be signed."); +				throw new FilterException("eIDAS Metadata root-element MUST be signed.'"); +				 +			} +						 +		} else { +			Logger.warn("eIDAS Metadata root-element is not of type 'EntityDescriptor'"); +			throw new FilterException("eIDAS Metadata root-element is not of type 'EntityDescriptor'"); +			 +		} +		 +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineConfigurationException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineConfigurationException.java new file mode 100644 index 000000000..98bc559d2 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineConfigurationException.java @@ -0,0 +1,60 @@ +/* + * 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.eidas.exceptions; + +import at.gv.egovernment.moa.id.config.ConfigurationException; + +/** + * @author tlenz + * + */ +public class EIDASEngineConfigurationException extends ConfigurationException { + +	/** +	 *  +	 */ +	private static final long serialVersionUID = 1L; +	 +	/** +	 * @param messageId +	 * @param parameters +	 * @param wrapped +	 */ +	public EIDASEngineConfigurationException(String messageId, +			Object[] parameters, Throwable wrapped) { +		super(messageId, parameters, wrapped); +	} + +	/** +	 * @param string +	 * @param object +	 */ +	public EIDASEngineConfigurationException(String string, Object[] object) { +		super(string, object); +	} + + + +	 +	 +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java new file mode 100644 index 000000000..95690bbeb --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java @@ -0,0 +1,45 @@ +/* + * 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.eidas.exceptions; + + +/** + * @author tlenz + * + */ +public class EIDASEngineException extends Exception { + +	/** +	 * @param string +	 * @param e +	 */ +	public EIDASEngineException(String string, Throwable e) { +		super(string, e); +	} + +	/** +	 *  +	 */ +	private static final long serialVersionUID = 1559812927427153879L; + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java new file mode 100644 index 000000000..7840ae2e6 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java @@ -0,0 +1,38 @@ +/* + * 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.eidas.exceptions; + +/** + * @author tlenz + * + */ +public class eIDASAttributeException extends Exception { + +	private static final long serialVersionUID = 1L; +	 +	public eIDASAttributeException(String message) { +		super(message); +		 +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java new file mode 100644 index 000000000..f4d6c4ad4 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java @@ -0,0 +1,185 @@ +/* + * 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.eidas.tasks; + +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +import eu.eidas.auth.commons.IPersonalAttributeList; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; +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.AuthenticationSessionStorageConstants; +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +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.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAttributeException; +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.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +/** + * @author tlenz + * + */ +public class CreateIdentityLinkTask 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{ +			String moasessionid = (String) executionContext.get(MOAIDAuthConstants.PARAM_SESSIONID);	    	 +			String pendingRequestID = (String) executionContext.get("pendingRequestID"); + +			//load pending request +			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}); +			 +			} +    	 +			//load MOASession object and OA-configuration +			AuthenticationSession moasession = AuthenticationSessionStoreage.getSession(moasessionid); +			IOAAuthParameters oaConfig = pendingReq.getOnlineApplicationConfiguration(); +			 +			//get eIDAS attributes from MOA-Session +			IPersonalAttributeList eIDASAttributes = moasession.getGenericDataFromSession( +					AuthenticationSessionStorageConstants.eIDAS_ATTRIBUTELIST,  +					IPersonalAttributeList.class); +			 +			AuthConfiguration config = AuthConfigurationProviderFactory.getInstance(); +			IdentityLink identityLink = null; +			 +			//connect SZR-Gateway +			//TODO: implement SZR-Gateway communication!!!! +			if(true) { +								 +				// create fake IdL +				// - fetch IdL template from resources +				InputStream s = CreateIdentityLinkTask.class.getResourceAsStream("/resources/xmldata/fakeIdL_IdL_template.xml"); +				Element idlTemplate = DOMUtils.parseXmlValidating(s); + +			    identityLink = new IdentityLinkAssertionParser(idlTemplate).parseIdentityLink(); + +			    // replace data +	            Element idlassertion = identityLink.getSamlAssertion(); +	             +	            // - set bpk/wpbk; +		        Node prIdentification = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH);		        		         +		        if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)) +		        	throw new eIDASAttributeException("PersonalIdentifier is missing"); +		        String eIdentifier = eIDASAttributes.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).getValue().get(0); +		        prIdentification.getFirstChild().setNodeValue(eIdentifier); + +		        // - set last name +		        Node prFamilyName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_FAMILY_NAME_XPATH); +		        if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_CURRENTFAMILYNAME)) +		        	throw new eIDASAttributeException("currentFamilyName is missing"); +				String familyName = eIDASAttributes.get(Constants.eIDAS_ATTR_CURRENTFAMILYNAME).getValue().get(0); +				prFamilyName.getFirstChild().setNodeValue(familyName); + +		        // - set first name +		        Node prGivenName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_GIVEN_NAME_XPATH); +		        if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_CURRENTGIVENNAME)) +		        	throw new eIDASAttributeException("currentGivenName is missing"); +				String givenName = eIDASAttributes.get(Constants.eIDAS_ATTR_CURRENTGIVENNAME).getValue().get(0); +				prGivenName.getFirstChild().setNodeValue(givenName); + +		        // - set date of birth +		        Node prDateOfBirth = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_DATE_OF_BIRTH_XPATH); +		        if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_DATEOFBIRTH)) +		        	throw new eIDASAttributeException("dateOfBirth is missing"); +				String dateOfBirth = eIDASAttributes.get(Constants.eIDAS_ATTR_DATEOFBIRTH).getValue().get(0); +				dateOfBirth = new SimpleDateFormat("yyyy-MM-dd").format(new SimpleDateFormat("yyyyMMdd").parse(dateOfBirth)); +				prDateOfBirth.getFirstChild().setNodeValue(dateOfBirth); + +	            identityLink = new IdentityLinkAssertionParser(idlassertion).parseIdentityLink(); + +	            //resign IDL +				IdentityLinkReSigner identitylinkresigner = IdentityLinkReSigner.getInstance(); +				Element resignedilAssertion = identitylinkresigner.resignIdentityLink(identityLink.getSamlAssertion(), config.getStorkFakeIdLResigningKey()); +				identityLink = new IdentityLinkAssertionParser(resignedilAssertion).parseIdentityLink(); +				 +			} else { +				//contact SZR Gateway +				Logger.debug("Starting connecting SZR Gateway"); +			 +				//TODO:!!!!!! +				 +			} +			 +			Logger.debug("SZR communication was successfull"); + +			if (identityLink == null) { +				Logger.error("SZR Gateway did not return an identity link."); +				throw new MOAIDException("stork.10", null); +			} +			 +			MOAReversionLogger.getInstance().logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_PEPS_IDL_RECEIVED);			 +			moasession.setForeigner(true); +			moasession.setIdentityLink(identityLink); +			moasession.setBkuURL("Not applicable (eIDASAuthentication)"); +			 +			//store MOA-session to database +			AuthenticationSessionStoreage.storeSession(moasession); +			 +		} catch (ParseException | MOAIDException | MOADatabaseException | ParserConfigurationException | SAXException | IOException e) { +			throw new TaskExecutionException("IdentityLink generation for foreign person FAILED.", e); +			 +		} catch (eIDASAttributeException e) { +			throw new TaskExecutionException("Minimum required eIDAS attributeset not found.", e); +				 +		}	 + +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java new file mode 100644 index 000000000..18432fd1c --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java @@ -0,0 +1,210 @@ +/* + * 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.eidas.tasks; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Collection; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; + +import eu.eidas.auth.commons.EIDASAuthnRequest; +import eu.eidas.auth.commons.EIDASUtil; +import eu.eidas.auth.commons.EidasLoaCompareType; +import eu.eidas.auth.commons.EidasLoaLevels; +import eu.eidas.auth.commons.IPersonalAttributeList; +import eu.eidas.auth.commons.PersonalAttribute; +import eu.eidas.auth.commons.PersonalAttributeList; +import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.auth.engine.core.eidas.SPType; +import eu.eidas.engine.exceptions.EIDASSAMLEngineException; +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +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.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +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.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.config.stork.CPEPS; +import at.gv.egovernment.moa.id.config.stork.StorkAttribute; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.VelocityProvider; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +public class GenerateAuthnRequestTask 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{ +			String moasessionid = (String) executionContext.get(MOAIDAuthConstants.PARAM_SESSIONID);	    	 +			String pendingRequestID = (String) executionContext.get("pendingRequestID"); + +			//load pending request +			IRequest pendingReq = RequestStorage.getPendingRequest(pendingRequestID);				 +			if (pendingReq == null) { +				Logger.info("No PendingRequest with Id: '{}' Maybe, a transaction timeout occure.", new Object[] {pendingRequestID}); +				throw new MOAIDException("auth.28", new Object[]{pendingRequestID}); +			 +			} + +			//load MOASession object, configuration and OA-configuration +			AuthenticationSession moasession = AuthenticationSessionStoreage.getSession(moasessionid); +			IOAAuthParameters oaConfig = pendingReq.getOnlineApplicationConfiguration(); +			AuthConfiguration moaconfig = AuthConfigurationProviderFactory.getInstance(); + +			// get target country +			String citizenCountryCode = (String) executionContext.get(MOAIDAuthConstants.PARAM_CCC); + +			if (StringUtils.isEmpty(citizenCountryCode)) { +				// illegal state; task should not have been executed without a selected country +				throw new AuthenticationException("stork.22", new Object[] { moasessionid }); +			} + +			CPEPS cpeps = moaconfig.getStorkConfig().getCPEPS(citizenCountryCode); +			if(null == cpeps) { +				Logger.error("PEPS unknown for country", new Object[] {citizenCountryCode}); +				throw new AuthenticationException("Unknown PEPS for citizen country '{}'", new Object[] {citizenCountryCode}); +			} +			Logger.debug("Found eIDaS Node/C-PEPS configuration for citizen of country: " + citizenCountryCode); +			String destination = cpeps.getPepsURL().toString().split(";")[1].trim(); // FIXME convenience for metadata url and assertion destination +			String metadataUrl = cpeps.getPepsURL().toString().split(";")[0].trim(); + +			// assemble requested attributes +			Collection<StorkAttribute> attributesFromConfig = oaConfig.getRequestedSTORKAttributes(); + +			// - prepare attribute list +			IPersonalAttributeList pAttList = new PersonalAttributeList(); + +			// - fill container +			for (StorkAttribute current : attributesFromConfig) { +				PersonalAttribute newAttribute = new PersonalAttribute(); +				newAttribute.setName(current.getName()); + +				boolean globallyMandatory = false; +				for (StorkAttribute currentGlobalAttribute : moaconfig.getStorkConfig().getStorkAttributes()) +					if (current.getName().equals(currentGlobalAttribute.getName())) { +						globallyMandatory = BooleanUtils.isTrue(currentGlobalAttribute.getMandatory()); +						break; +					} + +				newAttribute.setIsRequired(current.getMandatory() || globallyMandatory); +				pAttList.add(newAttribute); +			} + +			EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + +			//build eIDAS AuthnRequest +			EIDASAuthnRequest authnRequest = new EIDASAuthnRequest(); +			authnRequest.setProviderName(moaconfig.getPublicURLPrefix()); +			authnRequest.setPersonalAttributeList(pAttList); +			 +			authnRequest.setIssuer(moaconfig.getPublicURLPrefix() + Constants.eIDAS_HTTP_ENDPOINT_METADATA); +			 +			authnRequest.setDestination(destination);  +			authnRequest.setEidasNameidFormat(EIDASAuthnRequest.NAMEID_FORMAT_UNSPECIFIED); +			authnRequest.setEidasLoA(EidasLoaLevels.LOW.stringValue()); +			authnRequest.setEidasLoACompareType(EidasLoaCompareType.MINIMUM.stringValue()); +			authnRequest.setSPType(SPType.DEFAULT_VALUE); + +			engine.initRequestedAttributes(pAttList); +			authnRequest = engine.generateEIDASAuthnRequest(authnRequest); +			 +			//encode AuthnRequest +			byte[] token = authnRequest.getTokenSaml();		 +			String SAMLRequest = EIDASUtil.encodeSAMLToken(token); +			 +			 +			//send +	        try { +	            VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine(); +	            Template template = velocityEngine.getTemplate("/resources/templates/eidas_postbinding_template.vm"); +	            VelocityContext context = new VelocityContext(); + +	            String actionType = "SAMLRequest"; +	            context.put(actionType, SAMLRequest); +	            Logger.debug("Encoded " + actionType + " original: " + SAMLRequest); + +	            context.put("RelayState", moasessionid); +	             +	            Logger.debug("Using assertion consumer url as action: " + destination); +	            context.put("action", destination); + +	            Logger.debug("Starting template merge"); +	            StringWriter writer = new StringWriter(); + +	            Logger.debug("Doing template merge"); +	            template.merge(context, writer); +	            Logger.debug("Template merge done"); + +	            Logger.debug("Sending html content: " + writer.getBuffer().toString()); + +	            response.setContentType("text/html;charset=UTF-8"); +	            response.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8")); + +	        } catch (IOException e) { +	            Logger.error("Velocity IO error: " + e.getMessage()); +	            throw new MOAIDException("stork.15", null); // TODO +	        } catch (Exception e) { +	            Logger.error("Velocity general error: " + e.getMessage()); +	            throw new MOAIDException("stork.15", null); // TODO +	        } + +		}catch (EIDASSAMLEngineException e){ +			Logger.error("eIDAS AuthnRequest generation FAILED.", e); +			throw new TaskExecutionException("eIDAS AuthnRequest generation FAILED.",  +					new EIDASEngineException("Could not generate token for Saml Request", e)); +			 +		} catch (EIDASEngineException | MOAIDException | MOADatabaseException e) { +			throw new TaskExecutionException("eIDAS AuthnRequest generation FAILED.", e); +			 +		}	 + +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java new file mode 100644 index 000000000..693807d63 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java @@ -0,0 +1,109 @@ +package at.gv.egovernment.moa.id.auth.modules.eidas.tasks; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import eu.eidas.auth.commons.EIDASAuthnResponse; +import eu.eidas.auth.commons.EIDASUtil; +import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.engine.exceptions.EIDASSAMLEngineException; + +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.AuthenticationSessionStorageConstants; +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.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +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.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; + +public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { + +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException { + +		try{ +			String moasessionid = (String) executionContext.get(MOAIDAuthConstants.PARAM_SESSIONID);	    	 +			String pendingRequestID = (String) executionContext.get("pendingRequestID"); + +			//load pending request +			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}); +			 +			} +    	 +			//load MOASession object and OA-configuration +			AuthenticationSession moasession = AuthenticationSessionStoreage.getSession(moasessionid); +			IOAAuthParameters oaConfig = pendingReq.getOnlineApplicationConfiguration(); +			 +			//get SAML Response and decode it +			String base64SamlToken = request.getParameter("SAMLResponse"); +			if (MiscUtil.isEmpty(base64SamlToken)) { +				Logger.warn("No eIDAS SAMLReponse found in http request."); +				throw new MOAIDException("HTTP request includes no eIDAS SAML-Response element.", null); +				 +			}						 +			byte[] decSamlToken = EIDASUtil.decodeSAMLToken(base64SamlToken);		 +			 +			//get eIDAS SAML-engine +			EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); +			 +			//validate SAML token +			EIDASAuthnResponse samlResp = engine.validateEIDASAuthnResponse(decSamlToken,  +					request.getRemoteHost(), Constants.CONFIG_PROPS_SKEWTIME); +			 +			boolean encryptedResponse=engine.isEncryptedSamlResponse(decSamlToken); +			if (encryptedResponse) { +				Logger.info("Received encrypted eIDAS SAML-Response."); +				//TODO: check if additional decryption operation is required +				 +			} +						 +			//MOA-ID specific response validation +			//TODO: implement MOA-ID specific response validation +			 +			//update MOA-Session data with received information			 +			Logger.debug("Store eIDAS response information into MOA-session."); +			moasession.setQAALevel(samlResp.getAssuranceLevel()); +			moasession.setCcc(samlResp.getCountry()); +						 +			moasession.setGenericDataToSession( +					AuthenticationSessionStorageConstants.eIDAS_ATTRIBUTELIST,  +					new MOAPersonalAttributeList(samlResp.getPersonalAttributeList())); +						 +			moasession.setGenericDataToSession( +					AuthenticationSessionStorageConstants.eIDAS_RESPONSE,  +					decSamlToken); + +			//set general information to MOA-Session +			moasession.setAuthURL(AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix() + "/"); +			 +			//store MOA-session to database +			AuthenticationSessionStoreage.storeSession(moasession); +			 +		}catch (EIDASSAMLEngineException e) { +			Logger.error("eIDAS AuthnRequest generation FAILED.", e); +			throw new TaskExecutionException("eIDAS Response processing FAILED.",  +					new EIDASEngineException("Could not validate eIDAS response", e)); +			 +		} catch (EIDASEngineException | MOAIDException | MOADatabaseException e) { +			throw new TaskExecutionException("eIDAS Response processing FAILED.", e); +			 +		}	 +		 +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/EidasMetaDataServlet.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/EidasMetaDataServlet.java new file mode 100644 index 000000000..470e3b0fc --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/EidasMetaDataServlet.java @@ -0,0 +1,96 @@ +/******************************************************************************* + *  Copyright 2015 e-SENS project + * + *  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://ec.europa.eu/idabc/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. + *******************************************************************************/ +package at.gv.egovernment.moa.id.auth.modules.eidas.utils; +import iaik.security.ecc.provider.ECCProvider; +import iaik.security.provider.IAIK; + +import java.io.IOException; +import java.security.Security; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.auth.engine.metadata.MetadataConfigParams; +import eu.eidas.auth.engine.metadata.MetadataGenerator; +import eu.eidas.engine.exceptions.SAMLEngineException; + + +/** + * First version to provide some valid metadata to an asking eIDaS node + */ +@WebServlet("/eidas/metadata") +public class EidasMetaDataServlet extends HttpServlet { +    private static final long serialVersionUID = -2129228304760706063L; +    private Logger logger = org.slf4j.LoggerFactory.getLogger(EidasMetaDataServlet.class);  +    /** +     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse +     *      response) +     */ +    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { +        try { +            logger.debug("EidasMetaDataServlet GET"); +             +            AuthConfiguration config = AuthConfigurationProviderFactory.getInstance(); +            String pubURLPrefix = config.getPublicURLPrefix(); +             +            String metadata_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_METADATA; +             +            String sp_return_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_SP_POST;             +            String metaData = generateMetadata(metadata_url, sp_return_url); + +            logger.trace(metaData); + +            response.setContentType("text/xml"); +            response.getWriter().print(metaData); +            response.flushBuffer(); +        } catch (Exception e) { +            e.printStackTrace(); +        }  +    } + +    public String generateMetadata(String metadata_url, String sp_return_url) throws SAMLEngineException, EIDASEngineException{ +        String metadata="invalid metadata"; + +		EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); +         +        MetadataGenerator generator = new MetadataGenerator(); +        MetadataConfigParams mcp=new MetadataConfigParams(); +        generator.setConfigParams(mcp); +        generator.initialize(engine); +        mcp.setEntityID(metadata_url); + +        generator.addSPRole(); +        String returnUrl = sp_return_url; +        mcp.setAssertionConsumerUrl(returnUrl); + +        generator.addIDPRole(); +        mcp.setAssuranceLevel("http://eidas.europa.eu/LoA/substantial"); // TODO make configurable + +        metadata = generator.generateMetadata(); +        return metadata; +    } +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAOrderedAttributeIterator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAOrderedAttributeIterator.java new file mode 100644 index 000000000..573163af0 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAOrderedAttributeIterator.java @@ -0,0 +1,66 @@ +/* + * 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.eidas.utils; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import at.gv.egovernment.moa.logging.Logger; + +import eu.eidas.auth.commons.PersonalAttribute; +import eu.eidas.auth.commons.PersonalAttributeList; + + +/** + * @author tlenz + * + */ +public class MOAOrderedAttributeIterator  implements Iterator<PersonalAttribute> { +	 +    private MOAPersonalAttributeList pal; +    private Iterator<String> keyIterator; + +    public MOAOrderedAttributeIterator(MOAPersonalAttributeList palArg) { +        this.pal = palArg; +        keyIterator = palArg.getInsertOrder().iterator(); +    } + +    @Override +    public boolean hasNext() { +        return keyIterator.hasNext(); +    } + +    @Override +    public PersonalAttribute next() { +        if (!hasNext()) { +            throw new NoSuchElementException(); +        } +        return pal.get(keyIterator.next()); +    } + +    @Override +    public void remove() { +        Logger.error("Not implemented"); +    } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAPersonalAttributeList.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAPersonalAttributeList.java new file mode 100644 index 000000000..5cc100b70 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAPersonalAttributeList.java @@ -0,0 +1,343 @@ +/* + * 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.eidas.utils; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.lang.StringUtils; + +import at.gv.egovernment.moa.logging.Logger; + +import eu.eidas.auth.commons.AttributeConstants; +import eu.eidas.auth.commons.AttributeUtil; +import eu.eidas.auth.commons.EIDASErrors; +import eu.eidas.auth.commons.EIDASParameters; +import eu.eidas.auth.commons.EIDASUtil; +import eu.eidas.auth.commons.EIDASValues; +import eu.eidas.auth.commons.IPersonalAttributeList; +import eu.eidas.auth.commons.PersonalAttribute; +import eu.eidas.auth.commons.exceptions.InternalErrorEIDASException; + +/** + * @author tlenz + * + */ +public final class MOAPersonalAttributeList extends +	ConcurrentHashMap<String, PersonalAttribute> implements IPersonalAttributeList { +	 +	 /** +	 *  +	 */ +	private static final long serialVersionUID = -4488124133022713089L; + +    public MOAPersonalAttributeList(IPersonalAttributeList eIDASAttributeList) { +    	super(); +    	Iterator<PersonalAttribute> element = eIDASAttributeList.iterator(); +    	while(element.hasNext()) +    		add(element.next());    		 +    	 +    } +	 +	/** +     * Hash with the latest fetched attribute name alias. +     */ +    private Map<String, Integer> latestAttrAlias = +            new HashMap<String, Integer>(); + +    /** +     * Hash with mapping number of alias or the attribute name. +     */ +    private Map<String, Integer> attrAliasNumber = +            new HashMap<String, Integer>(); +    private List<String> insertOrder = new ArrayList<String>(); + +    /** +     * Obtain the insertOrder Collection +     * +     * @return defensive copy of the collection +     */ +    List<String> getInsertOrder() { +        return Collections.unmodifiableList(this.insertOrder); +    } + +    /** +     * Default constructor. +     */ +    public MOAPersonalAttributeList() { +        super(); +         +    } +     +    /** +     * Constructor with initial capacity for the PersonalAttributeList size. +     * +     * @param capacity The initial capacity for the PersonalAttributeList. +     */ +    public MOAPersonalAttributeList(final int capacity) { +        super(capacity); +    } + +    /** +     * {@inheritDoc} +     */ +    public Iterator<PersonalAttribute> iterator() { +        return new MOAOrderedAttributeIterator(this); +    } + +    /** +     * {@inheritDoc} +     */ +    public PersonalAttribute get(final Object key) { +        String attrName = (String) key; + +        if (this.latestAttrAlias == null) +        	this.latestAttrAlias = new HashMap<String, Integer>(); +         +        if (this.attrAliasNumber == null) +        	this.attrAliasNumber = new HashMap<String, Integer>(); +         +        if (this.latestAttrAlias.containsKey(key)) { +            attrName = attrName + this.latestAttrAlias.get(key); +        } else { +            if (this.attrAliasNumber.containsKey(key)) { +                this.latestAttrAlias.put(attrName, this.attrAliasNumber.get(key)); +            } +        } +        return super.get(attrName); +    } + +    /** +     * {@inheritDoc} +     */ +    public void add(final PersonalAttribute value) { +        if (value != null) { +            this.put(value.getName(), value); +        } +    } + +    /** +     * {@inheritDoc} +     */ +    public PersonalAttribute put(final String key, final PersonalAttribute val) { +        if (StringUtils.isNotEmpty(key) && val != null) { +            // Validate if attribute name already exists! +            String attrAlias = key; +            if (this.containsKey(attrAlias)) { +            	if (this.attrAliasNumber == null) +            		this.attrAliasNumber = new HashMap<String, Integer>(); +                if (!val.isEmptyValue() && StringUtils.isNumeric(val.getValue().get(0))) { +                    final String attrValue = val.getValue().get(0); +                    attrAlias = key + attrValue; +                    this.attrAliasNumber.put(key, Integer.valueOf(attrValue)); +                } else { +                    final PersonalAttribute attr = super.get(key); +                    if (!attr.isEmptyValue() +                            && StringUtils.isNumeric(attr.getValue().get(0))) { +                        attrAlias = key + attr.getValue().get(0); +                        super.put(key, (PersonalAttribute) attr); +                        this.attrAliasNumber.put(key, null); +                    } +                } +            } else { +            	if (insertOrder == null) +            		insertOrder = new ArrayList<String>(); +            	 +                insertOrder.add(key); +            } +            return super.put(attrAlias, val); +        } else { +            return null; +        } +    } + +    @Override +    public PersonalAttribute remove(Object key) { +        insertOrder.remove(key); +        return super.remove(key); +    } + +    /** +     * {@inheritDoc} +     */ +    public void populate(final String attrList) { +        final StringTokenizer strToken = +                new StringTokenizer(attrList, EIDASValues.ATTRIBUTE_SEP.toString()); + +        while (strToken.hasMoreTokens()) { +            final PersonalAttribute persAttr = new PersonalAttribute(); +            String[] tuples = +                    strToken.nextToken().split(EIDASValues.ATTRIBUTE_TUPLE_SEP.toString(), +                            AttributeConstants.NUMBER_TUPLES.intValue()); + +            // Convert to the new format if needed! +            tuples = convertFormat(tuples); + +            if (AttributeUtil.hasValidTuples(tuples)) { +                final int attrValueIndex = +                        AttributeConstants.ATTR_VALUE_INDEX.intValue(); +                final String tmpAttrValue = +                        tuples[attrValueIndex].substring(1, +                                tuples[attrValueIndex].length() - 1); +                final String[] vals = +                        tmpAttrValue.split(EIDASValues.ATTRIBUTE_VALUE_SEP.toString()); + +                persAttr.setName(tuples[AttributeConstants.ATTR_NAME_INDEX.intValue()]); +                persAttr.setIsRequired(Boolean +                        .valueOf(tuples[AttributeConstants.ATTR_TYPE_INDEX.intValue()])); +                // check if it is a complex value +                if (tuples[AttributeConstants.ATTR_NAME_INDEX.intValue()] +                        .equals(EIDASParameters.COMPLEX_ADDRESS_VALUE.toString())) { +                    persAttr.setComplexValue(createComplexValue(vals)); +                } else { +                    persAttr.setValue(createValues(vals)); +                } + +                if (tuples.length == AttributeConstants.NUMBER_TUPLES.intValue()) { +                    persAttr.setStatus(tuples[AttributeConstants.ATTR_STATUS_INDEX +                            .intValue()]); +                } +                this.put(tuples[AttributeConstants.ATTR_NAME_INDEX.intValue()], +                        persAttr); + +            } else { +                Logger.info("BUSINESS EXCEPTION : Invalid personal attribute list tuples"); +            } + +        } +    } + +  /** +  * Returns a copy of this <tt>IPersonalAttributeList</tt> instance. +  * +  * @return The copy of this IPersonalAttributeList. +  */ +  public Object clone() { +      try { +          MOAPersonalAttributeList theClone= (MOAPersonalAttributeList)super.clone(); +          theClone.insertOrder=new ArrayList<String>(insertOrder); +          return theClone; +           +      } catch (CloneNotSupportedException e) { +          throw new InternalErrorEIDASException( +                  EIDASUtil.getConfig(EIDASErrors.INTERNAL_ERROR.errorCode()), +                  EIDASUtil.getConfig(EIDASErrors.INTERNAL_ERROR.errorMessage()), e); +      } +  } + +  /** +   * Creates a string in the following format. +   * +   * attrName:attrType:[attrValue1,attrValue2=attrComplexValue]:attrStatus; +   * +   * @return {@inheritDoc} +   */ +  @Override +  public String toString() { +      final StringBuilder strBuilder = new StringBuilder(); +      final Iterator<String> iteratorInsertOrder = insertOrder.iterator(); +      while (iteratorInsertOrder.hasNext()) { +          String key = iteratorInsertOrder.next(); +          final PersonalAttribute attr = get(key); +          strBuilder.append(attr.toString()); +          if (isNumberAlias(key)) { +              strBuilder.append(get(key).toString()); +          } +      } +      return strBuilder.toString(); +  } + +    /** +     * Validates and creates the attribute's complex values. +     * +     * @param values The complex values. +     * @return The {@link Map} with the complex values. +     * @see Map +     */ +    private Map<String, String> createComplexValue(final String[] values) { +        final Map<String, String> complexValue = new HashMap<String, String>(); +        for (final String val : values) { +            final String[] tVal = val.split("="); +            if (StringUtils.isNotEmpty(val) && tVal.length == 2) { +                complexValue.put(tVal[0], AttributeUtil.unescape(tVal[1])); +            } +        } +        return complexValue; +    } + +    /** +     * Validates and creates the attribute values. +     * +     * @param vals The attribute values. +     * @return The {@link List} with the attribute values. +     * @see List +     */ +    private List<String> createValues(final String[] vals) { +        final List<String> values = new ArrayList<String>(); +        for (final String val : vals) { +            if (StringUtils.isNotEmpty(val)) { +                values.add(AttributeUtil.unescape(val)); +            } +        } +        return values; +    } + +    ////////////////// +    /** +     * Converts the attribute tuple (attrName:attrType...) to the new format. +     * +     * @param tuples The attribute tuples to convert. +     * @return The attribute tuples in the new format. +     */ +    private String[] convertFormat(final String[] tuples) { +        final String[] newFormatTuples = +                new String[AttributeConstants.NUMBER_TUPLES.intValue()]; +        if (tuples != null) { +            System.arraycopy(tuples, 0, newFormatTuples, 0, tuples.length); + +            for (int i = tuples.length; i < newFormatTuples.length; i++) { +                if (i == AttributeConstants.ATTR_VALUE_INDEX.intValue()) { +                    newFormatTuples[i] = "[]"; +                } else { +                    newFormatTuples[i] = ""; +                } +            } +        } +        return newFormatTuples; +    } + +    public boolean isNumberAlias(String key) { +        return this.attrAliasNumber.containsKey(key); +    } +	 +	 + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java new file mode 100644 index 000000000..8e46f0ef1 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java @@ -0,0 +1,71 @@ +/* + * 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.eidas.utils; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.config.MOAIDCertificateManagerConfigurationImpl; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASMetadataProviderDecorator; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; +import at.gv.egovernment.moa.logging.Logger; +import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.engine.exceptions.EIDASSAMLEngineException; +import eu.eidas.samlengineconfig.CertificateConfigurationManager; + +/** + * @author tlenz + * + */ +public class SAMLEngineUtils { + +	private static EIDASSAMLEngine eIDASEngine = null; +	 +	public static synchronized EIDASSAMLEngine createSAMLEngine() throws EIDASEngineException{ +		 +		if (eIDASEngine == null) { +			try { +				//get eIDAS SAMLengine configuration from MOA-ID configuration +				CertificateConfigurationManager configManager = new MOAIDCertificateManagerConfigurationImpl(); +				 +				//initial eIDAS SAMLengine +				EIDASSAMLEngine engine = EIDASSAMLEngine.createSAMLEngine(Constants.eIDAS_SAML_ENGINE_NAME, +							configManager); +	 +				//set Metadata managment to eIDAS SAMLengine +				engine.setMetadataProcessor( +						new MOAeIDASMetadataProviderDecorator( +								MOAeIDASChainingMetadataProvider.getInstance())); +				 +				eIDASEngine = engine; +				 +			} catch (EIDASSAMLEngineException e) { +				Logger.error("eIDAS SAMLengine initialization FAILED!", e); +				throw new EIDASEngineException("eIDAS SAMLengine initialization FAILED!", e); +				 +			} +		} +		 +		return eIDASEngine; +	} +	 +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/AuthenticationRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/AuthenticationRequest.java new file mode 100644 index 000000000..1012be1b7 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/AuthenticationRequest.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * 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.protocols.eidas; + +import java.io.StringWriter; +import java.text.SimpleDateFormat; +import java.util.Map.Entry; + +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.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASMetadataProviderDecorator; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.data.IAuthData; +import at.gv.egovernment.moa.id.data.SLOInformationInterface; +import at.gv.egovernment.moa.id.moduls.IAction; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.util.VelocityProvider; +import at.gv.egovernment.moa.logging.Logger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import eu.eidas.auth.commons.EIDASAuthnResponse; +import eu.eidas.auth.commons.EIDASStatusCode; +import eu.eidas.auth.commons.EIDASUtil; +import eu.eidas.auth.commons.PersonalAttribute; +import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.auth.engine.metadata.MetadataUtil; + + +/** + * Second request step - after authentication of the user is done and moasession obtained, + * process request and forward the user further to PEPS and/or other entities + * + * @author bsuzic + */ + +public class AuthenticationRequest implements IAction { + +	@Override +	public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { +		EIDASData eidasRequest; +		if(req instanceof EIDASData) +			eidasRequest = (EIDASData) req; +		else +			throw new MOAIDException("got wrong IRequest type. is: {}, should be: {}", new String[] {req.getClass().toString(), EIDASData.class.toString()}); +		 +		 +		// gather attributes +		MOAPersonalAttributeList resultingAttributeList = (MOAPersonalAttributeList) eidasRequest.getEidasRequestedAttributes().clone(); +		 +		for(Entry<String, PersonalAttribute> current : resultingAttributeList.entrySet()) { +			String newValue = ""; +			 +			// TODO make use of proper builder +			switch(current.getKey()) { +			case Constants.eIDAS_ATTR_DATEOFBIRTH: newValue = new SimpleDateFormat("YYYY-MM-dd").format(authData.getDateOfBirth()); break; +			case Constants.eIDAS_ATTR_CURRENTFAMILYNAME: newValue = authData.getFamilyName();break; +			case Constants.eIDAS_ATTR_CURRENTGIVENNAME: newValue = authData.getGivenName();break; +			case Constants.eIDAS_ATTR_PERSONALIDENTIFIER: newValue = new BPKBuilder().buildStorkeIdentifier(authData.getIdentificationType(), authData.getIdentificationValue(), +                    eidasRequest.getTarget()); break; +			} +			 +			if("".equals(newValue)) +				current.getValue().setStatus(EIDASStatusCode.STATUS_NOT_AVAILABLE.toString()); +			else { +				current.getValue().getValue().clear(); +				current.getValue().getValue().add(newValue); +				current.getValue().setStatus(EIDASStatusCode.STATUS_AVAILABLE.toString()); +			} +		} +		 +		// construct eIDaS response +		EIDASAuthnResponse response = new EIDASAuthnResponse(); +		response.setPersonalAttributeList(resultingAttributeList); +		 +		// - create metadata url +        AuthConfiguration config = AuthConfigurationProviderFactory.getInstance(); +        String pubURLPrefix = config.getPublicURLPrefix(); +        String metadata_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_METADATA; +		response.setIssuer(metadata_url); + +		response.setAssuranceLevel(authData.getEIDASQAALevel()); +		 +		String token = null; +		try { +			EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); +			 +			// check if we have the destination available, supply it if not +			if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) { +				String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata( +						new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()),  +						engine,  +						eidasRequest.getEidasRequest()); +				eidasRequest.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl); +			} +			 +			response = engine.generateEIDASAuthnResponse(eidasRequest.getEidasRequest(), response, eidasRequest.getRemoteAddress(), true); + +			 +			token = EIDASUtil.encodeSAMLToken(response.getTokenSaml()); +		} catch(Exception e) { +			e.printStackTrace(); +		} +		 +		// send the response +        try { +            VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine(); +            Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html"); +            VelocityContext context = new VelocityContext(); +             +            context.put("SAMLResponse", token); +            Logger.debug("SAMLResponse original: " + token); + +            Logger.debug("Putting assertion consumer url as action: " + eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()); +            context.put("action", eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()); +            Logger.trace("Starting template merge"); +            StringWriter writer = new StringWriter(); + +            Logger.trace("Doing template merge"); +            template.merge(context, writer); +            Logger.trace("Template merge done"); + +            Logger.trace("Sending html content: " + writer.getBuffer().toString()); +            Logger.trace("Sending html content2  : " + new String(writer.getBuffer())); + +            httpResp.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8")); + +        } catch (Exception e) { +            Logger.error("Velocity error: " + e.getMessage()); +        } +		 +		return null; +	} + +	@Override +	public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) { +		return true; +	} + +	@Override +	public String getDefaultActionName() { +		// TODO Auto-generated method stub +		return null; +	} + + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java new file mode 100644 index 000000000..0bedf0432 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java @@ -0,0 +1,84 @@ +package at.gv.egovernment.moa.id.protocols.eidas; + +import java.util.List; + +import org.opensaml.saml2.core.Attribute; + +import eu.eidas.auth.commons.EIDASAuthnRequest; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; +import at.gv.egovernment.moa.id.moduls.RequestImpl; + +public class EIDASData extends RequestImpl { + +	/** The Constant serialVersionUID. */ +	private static final long serialVersionUID = 8765755670214923910L; +	 +	/** The attributes requested by the eIDaS. */ +	private MOAPersonalAttributeList attributes; + +	/** The incoming eIDaS SAML2 AuthnRequest. */ +	private EIDASAuthnRequest authnRequest; + +	/** The ip address of the requester. */ +	private String remoteIPAddress; + +	@Override +	public List<Attribute> getRequestedAttributes() { +		// TODO Auto-generated method stub +		return null; +	} +	 +	/** +	 * Gets the eidas requested attributes. +	 * +	 * @return the requested attributes +	 */ +	public MOAPersonalAttributeList getEidasRequestedAttributes() { +		return (MOAPersonalAttributeList) attributes.clone(); +	} + +	/** +	 * Sets the eidas requested attributes. +	 * +	 * @param personalAttributeList the requested attributes +	 */ +	public void setEidasRequestedAttributes(MOAPersonalAttributeList personalAttributeList) { +		attributes = personalAttributeList; +	} + +	/** +	 * Gets the eidas request. +	 * +	 * @return the eidas request +	 */ +	public EIDASAuthnRequest getEidasRequest() { +		return authnRequest; +	} +	 +	/** +	 * Sets the eidas request. +	 * +	 * @param request the new eidas request +	 */ +	public void setEidasRequest(EIDASAuthnRequest request) { +		authnRequest = request;   +	} + +	/** +	 * Gets the remote address. +	 * +	 * @return the remote address +	 */ +	public String getRemoteAddress() { +		return remoteIPAddress; +	} +	 +	/** +	 * Sets the remote address. +	 * +	 * @param remoteIP the new remote address +	 */ +	public void setRemoteAddress(String remoteIP) { +		remoteIPAddress = remoteIP; +	} +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java new file mode 100644 index 000000000..a94e136b4 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * 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.protocols.eidas; + +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +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.modules.eidas.utils.MOAPersonalAttributeList; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.moduls.IAction; +import at.gv.egovernment.moa.id.moduls.IModulInfo; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; +import eu.eidas.auth.commons.EIDASAuthnRequest; +import eu.eidas.auth.commons.EIDASUtil; +import eu.eidas.auth.engine.EIDASSAMLEngine; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import java.util.HashMap; + +/** + * Stork 2 Protocol Support + * + * @author bsuzic + */ +public class EIDASProtocol extends MOAIDAuthConstants implements IModulInfo { + +    public static final String NAME = EIDASProtocol.class.getName(); +    public static final String PATH = "eidas"; + +    public static final String AUTHENTICATIONREQUEST = "AuthenticationRequest"; + +    private static HashMap<String, IAction> actions = new HashMap<String, IAction>(); + +    static { +        actions.put(AUTHENTICATIONREQUEST, new AuthenticationRequest()); +    } + +    public String getName() { +        return NAME; +    } + +    public String getPath() { +        return PATH; +    } + +    public IAction getAction(String action) { +        return actions.get(action); +    } + +    public EIDASProtocol() { +        super(); +    } + +    /* +        First request step - send it to BKU selection for user authentication. After the user credentials +        and other info are obtained, in the second step the request will be processed and the user redirected +         */ +    public IRequest preProcess(HttpServletRequest request, HttpServletResponse response, String action, +			String sessionId, String transactionId) throws MOAIDException { + +        Logger.info("received an eIDaS request"); + +		//get SAML Response and decode it +		String base64SamlToken = request.getParameter("SAMLRequest"); +		if (MiscUtil.isEmpty(base64SamlToken)) { +			Logger.warn("No eIDAS SAMLRequest found in http request."); +			throw new MOAIDException("HTTP request includes no eIDAS SAML-Request element.", null); +		}						 +		byte[] decSamlToken = EIDASUtil.decodeSAMLToken(base64SamlToken);	 + +		try { +			//get eIDAS SAML-engine +			EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + +			//validate SAML token +			EIDASAuthnRequest samlReq = engine.validateEIDASAuthnRequest(decSamlToken); + +			// memorize important stuff +			EIDASData result = new EIDASData(); + +			// - memorize remote ip +			result.setRemoteAddress(request.getRemoteAddr()); +			 +			// - memorize country code of target country +			result.setTarget(samlReq.getCountry()); +			 +			// - memorize requested attributes +			result.setEidasRequestedAttributes(new MOAPersonalAttributeList(samlReq.getPersonalAttributeList())); + +			// - memorize whole request +			samlReq.setPersonalAttributeList(result.getEidasRequestedAttributes()); // circumvent non-serializable eidas personal attribute list +			result.setEidasRequest(samlReq); +			 +			// - memorize OA url +			result.setOAURL(samlReq.getIssuer()); + +			// - memorize OA config +			OAAuthParameter oaConfig = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(result.getOAURL()); +			if (oaConfig == null) +				throw new AuthenticationException("stork.12", new Object[]{result.getOAURL()}); +			result.setOnlineApplicationConfiguration(oaConfig); + +			return result; +		} catch(Exception e) { +			Logger.error("error in preprocessing step", e); +			throw new MOAIDException("error in preprocessing step", null); +		} +    } + +    public IAction canHandleRequest(HttpServletRequest request, HttpServletResponse response) { +        return null; +    } + +    public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, IRequest protocolRequest) throws Throwable { +        return false; +    } + +    public boolean validate(HttpServletRequest request, HttpServletResponse response, IRequest pending) { +        return false; +    } +} + + diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo b/id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo new file mode 100644 index 000000000..31d15951c --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo @@ -0,0 +1 @@ +at.gv.egovernment.moa.id.protocols.eidas.EIDASProtocol
\ No newline at end of file diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas/eIDAS.Authentication.process.xml b/id/server/modules/moa-id-module-eIDAS/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas/eIDAS.Authentication.process.xml new file mode 100644 index 000000000..f24ff1c28 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas/eIDAS.Authentication.process.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<pd:ProcessDefinition id="eIDASAuthentication" xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1"> + + +	<pd:Task id="createAuthnRequest" class="at.gv.egovernment.moa.id.auth.modules.eidas.tasks.GenerateAuthnRequestTask" /> +	<pd:Task id="receiveAuthnResponse" class="at.gv.egovernment.moa.id.auth.modules.eidas.tasks.ReceiveAuthnResponseTask" async="true" /> +	<pd:Task id="finalizeAuthentication" class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.FinalizeAuthenticationTask" /> +	<pd:Task id="generateIdentityLink" class="at.gv.egovernment.moa.id.auth.modules.eidas.tasks.CreateIdentityLinkTask" /> + +	<pd:StartEvent id="start" />	 +	<pd:Transition from="start" to="createAuthnRequest" />	 +	<pd:Transition from="createAuthnRequest" to="receiveAuthnResponse" /> +	<pd:Transition from="receiveAuthnResponse" to="generateIdentityLink" /> +	<pd:Transition from="generateIdentityLink" to="finalizeAuthentication" />		 +	<pd:Transition from="finalizeAuthentication"    to="end" />	 +	<pd:EndEvent id="end" /> + +</pd:ProcessDefinition> diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas/eIDAS.authmodule.beans.xml b/id/server/modules/moa-id-module-eIDAS/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas/eIDAS.authmodule.beans.xml new file mode 100644 index 000000000..0e1b60fe7 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas/eIDAS.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="eIDASAuthModule" class="at.gv.egovernment.moa.id.auth.modules.eidas.eIDASAuthenticationModulImpl"> +		<property name="priority" value="1" /> +	</bean> + +</beans> diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/resources/templates/eidas_postbinding_template.vm b/id/server/modules/moa-id-module-eIDAS/src/main/resources/resources/templates/eidas_postbinding_template.vm new file mode 100644 index 000000000..8beb601c6 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/resources/templates/eidas_postbinding_template.vm @@ -0,0 +1,38 @@ +## +## Velocity Template for SAML 2 HTTP-POST binding +## +## Velocity context may contain the following properties +## action - String - the action URL for the form +## RelayState - String - the relay state for the message +## SAMLRequest - String - the Base64 encoded SAML Request +## SAMLResponse - String - the Base64 encoded SAML Response +## Contains target attribute to delegate PEPS authentication out of iFrame + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> + +    <body onload="document.forms[0].submit()"> +        <noscript> +            <p> +                <strong>Note:</strong> Since your browser does not support JavaScript, +                you must press the Continue button once to proceed. +            </p> +        </noscript> +         +        <form action="${action}" method="post" target="_top"> +            <div> +                #if($RelayState)<input type="hidden" name="RelayState" value="${RelayState}"/>#end +                 +                #if($SAMLRequest)<input type="hidden" name="SAMLRequest" value="${SAMLRequest}"/>#end +                 +                #if($SAMLResponse)<input type="hidden" name="SAMLResponse" value="${SAMLResponse}"/>#end +                 +            </div> +            <noscript> +                <div> +                    <input type="submit" value="Continue"/> +                </div> +            </noscript> +        </form> +         +    </body> +</html>
\ No newline at end of file diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/resources/xmldata/fakeIdL_IdL_template.xml b/id/server/modules/moa-id-module-eIDAS/src/main/resources/resources/xmldata/fakeIdL_IdL_template.xml new file mode 100644 index 000000000..09084a34f --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/resources/xmldata/fakeIdL_IdL_template.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ecdsa="http://www.w3.org/2001/04/xmldsig-more#" xmlns:pr="http://reference.e-government.gv.at/namespace/persondata/20020228#" xmlns:si="http://www.w3.org/2001/XMLSchema-instance" AssertionID="szr.bmi.gv.at-AssertionID13456264458587874" IssueInstant="2012-08-22T11:07:25+01:00" Issuer="http://portal.bmi.gv.at/ref/szr/issuer" MajorVersion="1" MinorVersion="0" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> +	<saml:AttributeStatement> +		<saml:Subject> +			<saml:SubjectConfirmation> +				<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:sender-vouches</saml:ConfirmationMethod> +				<saml:SubjectConfirmationData> +					<pr:Person si:type="pr:PhysicalPersonType"><pr:Identification><pr:Value>wJO/bvDJjUysG0yARn7I6w==</pr:Value><pr:Type>urn:publicid:gv.at:baseid</pr:Type></pr:Identification><pr:Name><pr:GivenName>XXXRúùd</pr:GivenName><pr:FamilyName primary="undefined">XXXVàn Nisteĺrooy</pr:FamilyName></pr:Name><pr:DateOfBirth>1969-02-13</pr:DateOfBirth></pr:Person> +				</saml:SubjectConfirmationData> +			</saml:SubjectConfirmation> +		</saml:Subject> +	<saml:Attribute AttributeName="CitizenPublicKey" AttributeNamespace="urn:publicid:gv.at:namespaces:identitylink:1.2"><saml:AttributeValue><ecdsa:ECDSAKeyValue><ecdsa:DomainParameters><ecdsa:NamedCurve URN="urn:oid:1.2.840.10045.3.1.7"/></ecdsa:DomainParameters><ecdsa:PublicKey><ecdsa:X Value="22280299907126338788314199678167217078072953115254374209747379168424021905237" si:type="ecdsa:PrimeFieldElemType"/><ecdsa:Y Value="40387096985250872237992703378062984723606079359080588656963239072881568409170" si:type="ecdsa:PrimeFieldElemType"/></ecdsa:PublicKey></ecdsa:ECDSAKeyValue></saml:AttributeValue></saml:Attribute><saml:Attribute AttributeName="CitizenPublicKey" AttributeNamespace="urn:publicid:gv.at:namespaces:identitylink:1.2"><saml:AttributeValue><dsig:RSAKeyValue><dsig:Modulus>4Y4FL09VhczsfYQgFPuycP8quJNZBAAu1R1rFXNodI2711B6BTMjAGQn6xuFWfd3/nyFav/MLTr/ +t2VazvANS4TRFxJAcWyIx7xbxCdzZr6gJ+FCmq4g5JPrQvt50v3JX+wKSYft1gHBOWlDn90Ia4Gm +P8MVuze21T+VVKM6ZklmS6d5PT1er/uYQFydGErmJ17xlSQG6Fi5xuftopBDyJxG1tL1KIebpLFg +gaM2EyuB1HxH8/+Mfqa4UgeqIH65</dsig:Modulus><dsig:Exponent>AQAB</dsig:Exponent></dsig:RSAKeyValue></saml:AttributeValue></saml:Attribute></saml:AttributeStatement> +	<dsig:Signature> +		<dsig:SignedInfo> +			<dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> +			<dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> +			<dsig:Reference URI=""> +				<dsig:Transforms> +					<dsig:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"> +						<dsig:XPath>not(ancestor-or-self::pr:Identification)</dsig:XPath> +					</dsig:Transform> +					<dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> +				</dsig:Transforms> +				<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> +				<dsig:DigestValue>KEQEPY2O3Z3IRaISSSoRZVPzsHE=</dsig:DigestValue> +			</dsig:Reference> +			<dsig:Reference Type="http://www.w3.org/2000/09/xmldsig#Manifest" URI="#manifest"> +				<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> +				<dsig:DigestValue>gzGhjH1kdmPcPbgen0xojNIoJLk=</dsig:DigestValue> +			</dsig:Reference> +		</dsig:SignedInfo> +		<dsig:SignatureValue> +    06wqWHgplwpu3N5HMhzb6QC5NkXMO1z4N4oc1L6eDqwZlvFJ9X1XGW//QqviKO9oog3il7IzdfJwnjygR4trgGCIqx+JYCDHJCrG9l8zlxlSW0ZqfsygGXthutcQ1aeUpfO6jYuhnWOUywa8BgzukRtWT+AOJBQZPRYTb8IBmey+uAwlhFLni94eMOd81l+efCvkWi3jRajwsG8ZOaNxSZT3aEV5vj+32Aqtx2MPEVzQWtIA7GqZi+EzcdSdHQvHhg7UB+8kqbU70ENAJbEMTANFZYvLOJ0Om9KfDtPf/+R2TvTc360fNo9RnPl04pHPhCIjcGZhFZorBpUhXFwd2Q== +  </dsig:SignatureValue><dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>MIIF3TCCBMWgAwIBAgIDByniMA0GCSqGSIb3DQEBBQUAMIGfMQswCQYDVQQGEwJBVDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMSIwIAYDVQQLDBlhLXNpZ24tY29ycG9yYXRlLWxpZ2h0LTAyMSIwIAYDVQQDDBlhLXNpZ24tY29ycG9yYXRlLWxpZ2h0LTAyMB4XDTEwMDcyODExMzY0M1oXDTE1MDcyODExMzY0M1owgbYxCzAJBgNVBAYTAkFUMR4wHAYDVQQKDBVEYXRlbnNjaHV0emtvbW1pc3Npb24xIjAgBgNVBAsMGVN0YW1temFobHJlZ2lzdGVyYmVob2VyZGUxLjAsBgNVBAMMJVNpZ25hdHVyc2VydmljZSBEYXRlbnNjaHV0emtvbW1pc3Npb24xFTATBgNVBAUTDDMyNTkyODMyMzk5ODEcMBoGCSqGSIb3DQEJARYNZHNrQGRzay5ndi5hdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN+dBSEBGj2jUXIK1Mp3lVxc/Za+pJMiyKrX3G1ZxgX/ikx7D9scsPYMt473LlAWl9cmCbHbJK+PV2XNNdURLMUCIX+4vUNs2MHeDTQtX8BXjJFpwJYSoaRJQ39FVS/1r5sWcra9Hhdm7w5Gtx/2ukyDX0kdkxawkhP4EQEzi/SI+Fugn+WqgQ1nAdlbxb/dcBw5w1h9b3lmuwUf4z3ooQWUD2DgA/kKd1KejNR43mLUsmvSzevPxT9zs78pOR1OacB7IszTVJPXeOEaaNZHnnB/UeO3g8LEV/3OkXcUgcMkbIIiaBHlll71Pq0COj9kqjXoe7OrRjLY5i3KwOpa6TMCAwEAAaOCAgcwggIDMBMGA1UdIwQMMAqACEkcWDpP6A0DMH8GCCsGAQUFBwEBBHMwcTAnBggrBgEFBQcwAYYbaHR0cDovL29jc3AuYS10cnVzdC5hdC9vY3NwMEYGCCsGAQUFBzAChjpodHRwOi8vd3d3LmEtdHJ1c3QuYXQvY2VydHMvYS1zaWduLWNvcnBvcmF0ZS1saWdodC0wMmEuY3J0MFQGA1UdIARNMEswSQYGKigAEQESMD8wPQYIKwYBBQUHAgEWMWh0dHA6Ly93d3cuYS10cnVzdC5hdC9kb2NzL2NwL2Etc2lnbi1BbXRzc2lnbmF0dXIwgZ4GA1UdHwSBljCBkzCBkKCBjaCBioaBh2xkYXA6Ly9sZGFwLmEtdHJ1c3QuYXQvb3U9YS1zaWduLWNvcnBvcmF0ZS1saWdodC0wMixvPUEtVHJ1c3QsYz1BVD9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0P2Jhc2U/b2JqZWN0Y2xhc3M9ZWlkQ2VydGlmaWNhdGlvbkF1dGhvcml0eTARBgNVHQ4ECgQITAgOnhr0tbowDgYDVR0PAQH/BAQDAgSwMCAGA1UdEQQZMBeBFW1hcmN1cy5oaWxkQGRzay5ndi5hdDAJBgNVHRMEAjAAMA4GByooAAoBBwEEAwEB/zAUBgcqKAAKAQEBBAkMB0JTQi1EU0swDQYJKoZIhvcNAQEFBQADggEBAHTklnvPCH/bJSOlIPbLUEkSGuFHsektSZ8Vr22x/Yv7EzsxoQrJIiz2mQ2gQqFuExdWYxvsowjiSbiis9iUf1c0zscvDS3mIZxGs4M89XHsjHnIyb+Fuwnamw65QrFvM1tNB1ZMjxJ3x+YmHLHdtT3BEBcr3/NCRHd2S0HoBspNz9HVgJaZY1llR7poKBvnAc4g1i+QTvyVb00PtKxR9Lw/9ABInX/1pzpxqrPy7Ib2OP8z6dd3WHmIsCiSHUaj0Dxwwln6fYJjhxZ141SnbovlCLYtrsZLXoi9ljIqX4xO0PwMI2RfNc9cXxTRrRS6rEOvX7PpvgXiDXhp592Yyp4=</dsig:X509Certificate></dsig:X509Data></dsig:KeyInfo> +		<dsig:Object> +			<dsig:Manifest Id="manifest"> +				<dsig:Reference URI=""> +					<dsig:Transforms> +						<dsig:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"> +							<dsig:XPath>not(ancestor-or-self::dsig:Signature)</dsig:XPath> +						</dsig:Transform> +					</dsig:Transforms> +					<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> +					<dsig:DigestValue>8e7RjLnA4Mgltq5ruIJzheKGxu0=</dsig:DigestValue> +				</dsig:Reference> +			</dsig:Manifest> +		</dsig:Object> +	</dsig:Signature> +</saml:Assertion>
\ No newline at end of file diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java index d4e73690f..95d45a865 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java @@ -27,7 +27,10 @@ import java.util.List;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse; +import eu.stork.peps.auth.commons.IPersonalAttributeList; +  import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;  import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;  import at.gv.egovernment.moa.id.auth.servlet.RedirectServlet; @@ -71,8 +74,11 @@ public class GetArtifactAction implements IAction {  			SAML1AuthenticationServer saml1server = SAML1AuthenticationServer.getInstace();  			// add other stork attributes to MOA assertion if available -			if(null != authData.getStorkAttributes()) { -				List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = SAML1AuthenticationServer.addAdditionalSTORKAttributes(authData.getStorkAttributes()); +			IPersonalAttributeList storkAttributes = authData.getGenericData( +					AuthenticationSessionStorageConstants.STORK_ATTRIBUTELIST,  +					IPersonalAttributeList.class); +			if(null != storkAttributes) { +				List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = SAML1AuthenticationServer.addAdditionalSTORKAttributes(storkAttributes);  				authData.getExtendedSAMLAttributesOA().addAll(moaExtendedSAMLAttibutes);  				Logger.info("MOA assertion assembled and SAML Artifact generated.");  			} diff --git a/id/server/modules/module-stork/pom.xml b/id/server/modules/module-stork/pom.xml index b52c10391..2fec7f519 100644 --- a/id/server/modules/module-stork/pom.xml +++ b/id/server/modules/module-stork/pom.xml @@ -61,6 +61,50 @@  			<scope>test</scope>  		</dependency> +		<dependency> +			<groupId>eu.stork</groupId> +			<artifactId>oasis-dss-api</artifactId> +			<version>1.0.0-RELEASE</version> +			<exclusions> +				<exclusion> +					<groupId>org.apache.commons</groupId> +					<artifactId>commons-io</artifactId> +				</exclusion> +			</exclusions> +		</dependency> +		 +		<!--         <dependency> +            <groupId>eu.stork</groupId> +            <artifactId>Commons</artifactId> +            <version>1.4.0</version> +        </dependency> --> +        <dependency> +            <groupId>eu.stork</groupId> +            <artifactId>SamlEngine</artifactId> +            <version>1.5.1</version> +        </dependency> + +		<dependency> +			<groupId>eu.stork</groupId> +			<artifactId>DocumentService</artifactId> +			<version>0.0.1-SNAPSHOT</version> +			<classifier>classes</classifier> +			<exclusions> +				<exclusion> +					<artifactId>axis</artifactId> +					<groupId>org.apache.axis</groupId> +				</exclusion> +				<exclusion> +					<artifactId>bcprov-jdk16</artifactId> +					<groupId>org.bouncycastle</groupId> +				</exclusion> +				<exclusion> +					<artifactId>jaxws-tools</artifactId> +					<groupId>com.sun.xml.ws</groupId> +				</exclusion> +			</exclusions> +		</dependency> +  	</dependencies>  </project> diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthModuleImpl.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthModuleImpl.java index 41384690e..ecb568635 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthModuleImpl.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthModuleImpl.java @@ -28,7 +28,11 @@ public class STORKAuthModuleImpl implements AuthModule {  	@Override
  	public String selectProcess(ExecutionContext context) {
 -		return StringUtils.isNotBlank((String) context.get("ccc")) ? "STORKAuthentication" : null;
 +		if (StringUtils.isNotBlank((String) context.get("ccc")) || 
 +				StringUtils.isNotBlank((String) context.get("CCC"))) 
 +			return "STORKAuthentication";
 +		else
 +			return null;
  	}
  	@Override
 diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/AbstractPepsConnectorWithLocalSigningTask.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/AbstractPepsConnectorWithLocalSigningTask.java index 939390847..ee4961d5e 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/AbstractPepsConnectorWithLocalSigningTask.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/AbstractPepsConnectorWithLocalSigningTask.java @@ -21,6 +21,7 @@ import org.apache.commons.io.IOUtils;  import org.xml.sax.SAXException;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
 +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;
  import at.gv.egovernment.moa.id.auth.data.IdentityLink;
  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
  import at.gv.egovernment.moa.id.auth.exception.BKUException;
 @@ -113,7 +114,9 @@ public abstract class AbstractPepsConnectorWithLocalSigningTask extends Abstract  		moaSession.setIdentityLink(identityLink);
  		Logger.debug("Adding addtional STORK attributes to MOA session");
 -		moaSession.setStorkAttributes(personalAttributeList);
 +		moaSession.setGenericDataToSession(
 +				AuthenticationSessionStorageConstants.STORK_ATTRIBUTELIST, 
 +				personalAttributeList);
  		// We don't have BKUURL, setting from null to "Not applicable"
  		moaSession.setBkuURL("Not applicable (STORK Authentication)");
 diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java index 138776976..c0422e06e 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java @@ -26,11 +26,27 @@ import org.opensaml.common.IdentifierGenerator;  import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
  import org.w3c.dom.DOMException;
 -import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
 -import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
 +import eu.stork.oasisdss.api.AdditionalProfiles;
 +import eu.stork.oasisdss.api.ApiUtils;
 +import eu.stork.oasisdss.api.Profiles;
 +import eu.stork.oasisdss.api.QualityLevels;
 +import eu.stork.oasisdss.api.SignatureTypes;
 +import eu.stork.oasisdss.api.exceptions.ApiUtilsException;
 +import eu.stork.oasisdss.profile.AnyType;
 +import eu.stork.oasisdss.profile.DocumentType;
 +import eu.stork.oasisdss.profile.SignRequest;
 +import eu.stork.peps.auth.commons.PEPSUtil;
 +import eu.stork.peps.auth.commons.PersonalAttribute;
 +import eu.stork.peps.auth.commons.PersonalAttributeList;
 +import eu.stork.peps.auth.commons.STORKAuthnRequest;
 +import eu.stork.peps.auth.engine.STORKSAMLEngine;
 +import eu.stork.peps.auth.engine.core.CitizenCountryCode;
 +import eu.stork.peps.exceptions.STORKSAMLEngineException;
  import at.gv.egovernment.moa.id.auth.BaseAuthenticationServer;
 +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
  import at.gv.egovernment.moa.id.auth.builder.CreateXMLSignatureRequestBuilder;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
 +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;
  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.WrongParametersException;
 @@ -124,7 +140,10 @@ public class CreateStorkAuthRequestFormTask extends AbstractAuthServletTask {  			AuthenticationSession moasession = BaseAuthenticationServer.getSession(sessionID);			
  			IRequest pendingReq = RequestStorage.getPendingRequest(pendingRequestID);
 -			if (StringUtils.isEmpty(ccc)) {
 +			// bugfix: the new task system fails to initialize the CCC - set it here
 +			moasession.setCcc((String) executionContext.get(MOAIDAuthConstants.PARAM_CCC));
 +
 +			if (StringUtils.isEmpty(moasession.getCcc())) {
  				// illegal state; task should not have been executed without a selected country
  				throw new AuthenticationException("stork.22", new Object[] { sessionID });
 @@ -265,7 +284,7 @@ public class CreateStorkAuthRequestFormTask extends AbstractAuthServletTask {  			//attributeList.add(newAttribute);
  			//store SignRequest for later...
 -			moasession.setSignedDoc(signedDoc);
 +			moasession.setGenericDataToSession("STORK_signDoc", signedDoc);
  			acsURL = issuerValue + AbstractPepsConnectorWithLocalSigningTask.PEPSCONNECTOR_SERVLET_URL_PATTERN;
  			// TODO[branch]: STORK AuthReq acsURL "/PEPSConnectorWithLocalSigning"
 @@ -340,7 +359,9 @@ public class CreateStorkAuthRequestFormTask extends AbstractAuthServletTask {  		Logger.debug("STORK AuthnRequest successfully internally validated.");
  		//send
 -		moasession.setStorkAuthnRequest(authnRequest);
 +		moasession.setGenericDataToSession(
 +				AuthenticationSessionStorageConstants.STORK_REQUEST, 
 +				authnRequest);
  		// do PEPS-conform logging for easier evaluation
  		try {
 diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java index 7b9fa3f12..f872241ae 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java @@ -22,6 +22,7 @@ import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;  import at.gv.egovernment.moa.id.auth.BaseAuthenticationServer;
  import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
 +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;
  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.modules.TaskExecutionException;
 @@ -142,7 +143,10 @@ public class PepsConnectorHandleLocalSignResponseTask extends AbstractPepsConnec  			moaSession.setXMLVerifySignatureResponse(tmp);
  			executionContext.put("identityLinkAvailable", false);
  			try {
 -				IPersonalAttributeList personalAttributeList = moaSession.getAuthnResponseGetPersonalAttributeList();
 +				IPersonalAttributeList personalAttributeList = 
 +						moaSession.getGenericDataFromSession(
 +								AuthenticationSessionStorageConstants.STORK_ATTRIBUTELIST, 
 +								IPersonalAttributeList.class);
  				// Add SignResponse TODO Add signature (extracted from signResponse)?
  				List<String> values = new ArrayList<String>();
  				values.add(signResponseString);
 @@ -151,7 +155,8 @@ public class PepsConnectorHandleLocalSignResponseTask extends AbstractPepsConnec  				PersonalAttribute signedDocAttribute = new PersonalAttribute("signedDoc", false, values, "Available");
  				personalAttributeList.add(signedDocAttribute);
 -				String authnContextClassRef = moaSession.getAuthnContextClassRef();
 +				String authnContextClassRef = moaSession.getGenericDataFromSession(
 +						"STORK_authContextClass", String.class);
  				SZRGInsertion(moaSession, personalAttributeList, authnContextClassRef, citizenSignature);
  				executionContext.put("identityLinkAvailable", true);
  			} catch (STORKException e) {
 @@ -187,8 +192,9 @@ public class PepsConnectorHandleLocalSignResponseTask extends AbstractPepsConnec  			}
  			Logger.debug("Add full STORK AuthnResponse to MOA session");
 -			moaSession.setStorkAuthnResponse(request.getParameter("SAMLResponse"));// TODO ask Florian/Thomas
 -																					// authnResponse?
 +			moaSession.setGenericDataToSession(
 +					AuthenticationSessionStorageConstants.STORK_RESPONSE, 
 +					request.getParameter("SAMLResponse"));
  			MOAReversionLogger.getInstance().logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED);
 diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java index e84c33d5d..0ac26f45f 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java @@ -2,18 +2,15 @@ package at.gv.egovernment.moa.id.auth.modules.stork.tasks;  import iaik.x509.X509Certificate;
 -import java.io.IOException;
  import java.io.StringWriter;
  import java.util.ArrayList;
  import java.util.Collection;
 -import java.util.List;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.xml.transform.Source;
  import javax.xml.transform.stream.StreamSource;
 -import org.apache.commons.codec.binary.Base64;
  import org.apache.commons.io.IOUtils;
  import org.apache.commons.lang.StringEscapeUtils;
  import org.apache.velocity.Template;
 @@ -24,6 +21,7 @@ import org.opensaml.saml2.core.StatusCode;  import at.gv.egovernment.moa.id.auth.BaseAuthenticationServer;
  import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
 +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;
  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.modules.TaskExecutionException;
 @@ -207,7 +205,10 @@ public class PepsConnectorHandleResponseWithoutSignatureTask extends AbstractPep  			Logger.debug("MOA session is still valid");
 -			STORKAuthnRequest storkAuthnRequest = moaSession.getStorkAuthnRequest();
 +			STORKAuthnRequest storkAuthnRequest = 
 +					moaSession.getGenericDataFromSession(
 +							AuthenticationSessionStorageConstants.STORK_REQUEST, 
 +							STORKAuthnRequest.class);
  			if (storkAuthnRequest == null) {
  				Logger.error("Could not find any preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
 @@ -266,11 +267,15 @@ public class PepsConnectorHandleResponseWithoutSignatureTask extends AbstractPep  				} else {
  					// store SAMLResponse
 -					moaSession.setSAMLResponse(request.getParameter("SAMLResponse"));
 +					moaSession.setGenericDataToSession(
 +							AuthenticationSessionStorageConstants.STORK_RESPONSE, 
 +							request.getParameter("SAMLResponse"));
  					// store authnResponse
  					// moaSession.setAuthnResponse(authnResponse);//not serializable
 -					moaSession.setAuthnResponseGetPersonalAttributeList(attributeList);
 +					moaSession.setGenericDataToSession(
 +							AuthenticationSessionStorageConstants.STORK_ATTRIBUTELIST, 
 +							attributeList);
  					String authnContextClassRef = null;
  					try {
 @@ -280,12 +285,12 @@ public class PepsConnectorHandleResponseWithoutSignatureTask extends AbstractPep  						Logger.warn("STORK QAA-Level is not found in AuthnResponse. Set QAA Level to requested level");
  					}
 -					moaSession.setAuthnContextClassRef(authnContextClassRef);
 -					moaSession.setReturnURL(request.getRequestURL());
 +					moaSession.setGenericDataToSession("STORK_authContextClass", authnContextClassRef);
 +					moaSession.setGenericDataToSession("STORK_returnURL", request.getRequestURL());
  					// load signedDoc
 -					String signRequest = moaSession.getSignedDoc();
 -
 +					String signRequest = moaSession.getGenericDataFromSession("STORK_signDoc", String.class);
 +					
  					// session is implicit stored in changeSessionID!!!!
  					String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 @@ -383,9 +388,11 @@ public class PepsConnectorHandleResponseWithoutSignatureTask extends AbstractPep  			}
  			Logger.debug("Add full STORK AuthnResponse to MOA session");
 -			moaSession.setStorkAuthnResponse(request.getParameter("SAMLResponse"));// TODO ask Florian/Thomas
 -																					// authnResponse?
 -
 +			moaSession.setGenericDataToSession(
 +					AuthenticationSessionStorageConstants.STORK_RESPONSE, 
 +					request.getParameter("SAMLResponse"));
 +			
 +			
  			// session is implicit stored in changeSessionID!!!!
  			String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java index b505605ab..8322d1a02 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java @@ -2,7 +2,6 @@ package at.gv.egovernment.moa.id.auth.modules.stork.tasks;  import iaik.x509.X509Certificate;
 -import java.io.IOException;
  import java.io.InputStream;
  import java.io.StringWriter;
  import java.net.URL;
 @@ -11,7 +10,6 @@ import java.util.ArrayList;  import java.util.Arrays;
  import java.util.Date;
  import java.util.List;
 -import java.util.Properties;
  import javax.activation.DataSource;
  import javax.servlet.http.HttpServletRequest;
 @@ -39,6 +37,7 @@ import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;  import at.gv.egovernment.moa.id.auth.BaseAuthenticationServer;
  import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
 +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;
  import at.gv.egovernment.moa.id.auth.data.IdentityLink;
  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
  import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
 @@ -243,7 +242,10 @@ public class PepsConnectorTask extends AbstractAuthServletTask {  			Logger.debug("MOA session is still valid");
 -			STORKAuthnRequest storkAuthnRequest = moaSession.getStorkAuthnRequest();
 +			STORKAuthnRequest storkAuthnRequest = 
 +					moaSession.getGenericDataFromSession(
 +							AuthenticationSessionStorageConstants.STORK_REQUEST, 
 +							STORKAuthnRequest.class);
  			if (storkAuthnRequest == null) {
  				Logger.error("Could not find any preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
 @@ -575,10 +577,15 @@ public class PepsConnectorTask extends AbstractAuthServletTask {  			moaSession.setIdentityLink(identityLink);
  			Logger.debug("Adding addtional STORK attributes to MOA session");
 -			moaSession.setStorkAttributes(attributeList);
 -
 +			moaSession.setGenericDataToSession(
 +					AuthenticationSessionStorageConstants.STORK_ATTRIBUTELIST, 
 +					attributeList);
 +			
  			Logger.debug("Add full STORK AuthnResponse to MOA session");
 -			moaSession.setStorkAuthnResponse(request.getParameter("SAMLResponse"));
 +			moaSession.setGenericDataToSession(
 +					AuthenticationSessionStorageConstants.STORK_RESPONSE, 
 +					request.getParameter("SAMLResponse"));
 +
  			// We don't have BKUURL, setting from null to "Not applicable"
  			moaSession.setBkuURL("Not applicable (STORK Authentication)");
 diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/STORKAttributHelper.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/STORKAttributHelper.java index 9a0598cf6..fb9172f6e 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/STORKAttributHelper.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/STORKAttributHelper.java @@ -24,8 +24,7 @@ package at.gv.egovernment.moa.id.protocols.builder.attributes;  import eu.stork.peps.auth.commons.IPersonalAttributeList;  import eu.stork.peps.auth.commons.PersonalAttribute; -import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; -import at.gv.egovernment.moa.id.auth.stork.STORKConstants; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;  import at.gv.egovernment.moa.id.data.IAuthData;  import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.UnavailableAttributeException;  import at.gv.egovernment.moa.logging.Logger; @@ -43,7 +42,10 @@ public class STORKAttributHelper {  			throw new UnavailableAttributeException(attributName);  		} else { -			IPersonalAttributeList storkAttributes = authSession.getStorkAttributes(); +			IPersonalAttributeList storkAttributes =  +					authSession.getGenericData( +							AuthenticationSessionStorageConstants.STORK_ATTRIBUTELIST,  +							IPersonalAttributeList.class);  			if ( storkAttributes == null ) {  				throw new UnavailableAttributeException(attributName); diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java index 2c7e5b539..f9f38e2d5 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/MOAAttributeProvider.java @@ -23,6 +23,7 @@  package at.gv.egovernment.moa.id.protocols.stork2;  import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;  import at.gv.egovernment.moa.id.auth.exception.BuildException;  import at.gv.egovernment.moa.id.data.AuthenticationRole;  import at.gv.egovernment.moa.id.data.IAuthData; @@ -30,6 +31,7 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;  import at.gv.egovernment.moa.id.util.PVPtoSTORKMapper;  import at.gv.egovernment.moa.logging.Logger;  import at.gv.egovernment.moa.util.MiscUtil; +import eu.stork.peps.auth.commons.IPersonalAttributeList;  import eu.stork.peps.auth.commons.PersonalAttribute;  import eu.stork.peps.auth.commons.PersonalAttributeList;  import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.AttributeStatusType; @@ -83,12 +85,17 @@ public class MOAAttributeProvider {      public void populateAttribute(PersonalAttributeList attributeList, PersonalAttribute requestedAttribute ) {          String storkAttribute = requestedAttribute.getName(); - +         +        IPersonalAttributeList storkAttributes =  +        		authData.getGenericData( +						AuthenticationSessionStorageConstants.STORK_ATTRIBUTELIST,  +						IPersonalAttributeList.class); +                  // TODO: check if authData gets populated with stork attributtes during previous steps; it seems it is not -        if (null != authData && null != authData.getStorkAttributes() && authData.getStorkAttributes().containsKey(requestedAttribute.getName())) { +        if (null != authData && null != storkAttributes && storkAttributes.containsKey(requestedAttribute.getName())) {              Logger.debug("Trying to get value for attribute directly from STORK2 response [" + storkAttribute + "]");              try { -                PersonalAttribute tmp = authData.getStorkAttributes().get(requestedAttribute.getName()); +                PersonalAttribute tmp = storkAttributes.get(requestedAttribute.getName());                  attributeList.add((PersonalAttribute) tmp.clone());              } catch(Exception e) {                  Logger.error("Could not retrieve attribute from STORK2 response: " + storkAttribute); diff --git a/id/server/modules/pom.xml b/id/server/modules/pom.xml index c164252c7..69cd7c217 100644 --- a/id/server/modules/pom.xml +++ b/id/server/modules/pom.xml @@ -25,6 +25,7 @@  		<module>moa-id-modules-saml1</module>  		<module>moa-id-module-openID</module>  		<module>moa-id-modul-citizencard_authentication</module> +		<module>moa-id-module-eIDAS</module>  	</modules>  	<dependencies> | 
