diff options
Diffstat (limited to 'id')
25 files changed, 919 insertions, 126 deletions
| 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 aefc0801a..09568ce68 100644 --- a/id/server/data/deploy/conf/moa-id/moa-id.properties +++ b/id/server/data/deploy/conf/moa-id/moa-id.properties @@ -52,7 +52,7 @@ stork.documentservice.url=  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 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/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/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 ad3268b90..1d8ea4cd4 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 @@ -89,6 +89,11 @@ public interface AuthConfiguration extends ConfigurationProvider{  	public boolean isAdvancedLoggingActive(); +	/** +	 * Returns the PublicURLPrefix. NOTE: returns {@code null} if no PublicURLPrefix is set. +	 *  +	 * @return the PublicURLPrefix without trailing slash or {@code null} +	 */  	public String getPublicURLPrefix();  	public boolean isPVP2AssertionEncryptionActive(); 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/pvp2x/binding/PostBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java index 5402e3dce..65400444d 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; @@ -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.exceptions.PVP2Exception;  import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage; @@ -74,6 +76,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"); @@ -109,6 +114,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 81863f48f..9a505a7b0 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; @@ -73,6 +75,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(); @@ -103,6 +108,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 a2583c706..fee508d33 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; @@ -48,6 +49,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.BindingNotSupportedException;  import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception; @@ -130,6 +132,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..f4c099878 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 @@ -60,7 +60,7 @@ 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; @@ -422,8 +422,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 +435,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 +470,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/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 d0da0003f..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 @@ -102,7 +102,7 @@ public class PVPtoSTORKMapper {  	public String mapeIDASQAAToSTORKQAA(String qaaLevel) {  		if (mapping != null) {  			String input = qaaLevel.substring(eIDAS_QAA_PREFIX.length());			 -			String mappedQAA = mapping.getProperty(MAPPING_EIDAS_PREFIX + input); +			String mappedQAA = mapping.getProperty(input);  			if (MiscUtil.isNotEmpty(mappedQAA)) {  				Logger.info("Map eIDAS-QAA " + qaaLevel + " to STORK-QAA " + mappedQAA);  				return mappedQAA; 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 index 9f347b4ee..1d4556459 100644 --- 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 @@ -28,8 +28,8 @@ package at.gv.egovernment.moa.id.auth.modules.eidas;   */  public class Constants { -	//public static final String eIDAS_SAML_ENGINE_NAME = "MOA_eIDASEninge";  	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"; @@ -45,20 +45,30 @@ public class Constants {  	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_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"; +			+ CONIG_PROPS_EIDAS_SAMLENGINE_ENCRYPT + ".config.file";	 +	public static final String CONIG_PROPS_EIDAS_METADATA_VALIDATION_TRUSTSTORE = CONIG_PROPS_EIDAS_PREFIX + ".metadata.validation.truststore"; -	public static final long CONFIG_PROPS_SKEWTIME = 2 * 60 * 1000;  //2 minutes skew time for response validation +	//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 +	//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/eIDASSignalServlet.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASSignalServlet.java index 556947572..49f0451cb 100644 --- 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 @@ -22,30 +22,19 @@   */  package at.gv.egovernment.moa.id.auth.modules.eidas; -import java.io.ByteArrayInputStream; -  import javax.servlet.annotation.WebServlet;  import javax.servlet.http.HttpServletRequest; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathFactory;  import org.apache.commons.lang.StringEscapeUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.util.xml.SimpleNamespaceContext; -import org.w3c.dom.Document; -import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;  import at.gv.egovernment.moa.id.auth.servlet.ProcessEngineSignalServlet;  import at.gv.egovernment.moa.logging.Logger; -import at.gv.egovernment.moa.util.Base64Utils;  /**   * @author tlenz   *   */ -@WebServlet(urlPatterns = { "/eidas/post",  "/eidas/redirect"}, loadOnStartup = 1) +@WebServlet(urlPatterns = { "/eidas/sp/post",  "/eidas/sp/redirect"}, loadOnStartup = 1)  public class eIDASSignalServlet extends ProcessEngineSignalServlet {  	private static final long serialVersionUID = 8215688005533754459L; @@ -53,7 +42,7 @@ public class eIDASSignalServlet extends ProcessEngineSignalServlet {  	public eIDASSignalServlet() {  		super();  		Logger.debug("Registering servlet " + getClass().getName() +  -				" with mappings '/eidas/post' and '/eidas/redirect'."); +				" with mappings '/eidas/sp/post' and '/eidas/sp/redirect'.");  	} 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..f1b14015b --- /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,290 @@ +package at.gv.egovernment.moa.id.auth.modules.eidas.engine; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +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.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.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 { + +	private static MOAeIDASChainingMetadataProvider instance = null; +	private static Object mutex = new Object(); +	 +	private MetadataProvider internalProvider; +	 +	 +	public static MOAeIDASChainingMetadataProvider getInstance() { +		if (instance == null) { +			synchronized (mutex) { +				if (instance == null) { +					instance = new MOAeIDASChainingMetadataProvider(); +				} +			} +		} +		return instance; +	} +	 +	 +	private MOAeIDASChainingMetadataProvider() { +		internalProvider = new ChainingMetadataProvider(); +		 +	} +	     +	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)) +					return internalProvider.getEntityDescriptor(entityID); +									 +			} else { +				if (!entityDesc.isValid()) +					if (refreshMetadataProvider(entityID)) +						return internalProvider.getEntityDescriptor(entityID); +									 +			} +			 +			 +		} catch (MetadataProviderException e) { +			Logger.debug("Can not find eIDAS metadata for entityID: " + entityID  +					+ " Start refreshing process ..."); +			if (refreshMetadataProvider(entityID)) +				return internalProvider.getEntityDescriptor(entityID); +			 +		} +		 +		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/engine/MOAeIDASSimpleMetadataProvider.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASSimpleMetadataProvider.java deleted file mode 100644 index 2aec81db5..000000000 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASSimpleMetadataProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -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.SPSSODescriptor; - -import at.gv.egovernment.moa.logging.Logger; -import eu.eidas.auth.engine.EIDASSAMLEngine; -import eu.eidas.auth.engine.metadata.SimpleMetadataProcessor; -import eu.eidas.engine.exceptions.SAMLEngineException; - -public class MOAeIDASSimpleMetadataProvider extends SimpleMetadataProcessor { - -	@Override -	public EntityDescriptor getEntityDescriptor(String url) { -        EntityDescriptor entityDescriptor=getEntityDescriptorHelper(url); -         -        if(Logger.isDebugEnabled()){ -            Logger.debug("got entityDescriptor: " + entityDescriptor); -        } -        return entityDescriptor; -	} - -	@Override -	public SPSSODescriptor getSPSSODescriptor(String url) throws SAMLEngineException { -		return getFirstRoleDescriptor(getEntityDescriptor(url), SPSSODescriptor.class); -		 -	} - -	@Override -	public IDPSSODescriptor getIDPSSODescriptor(String url) throws SAMLEngineException { -		return getFirstRoleDescriptor(getEntityDescriptor(url), IDPSSODescriptor.class); -		 -	} - -    @Override -    public void checkValidMetadataSignature(String url, EIDASSAMLEngine engine) throws SAMLEngineException { -        //TODO: implement Metadata signature validation -        Logger.warn("MetadataProcessor in demo SP does not actually check the signature of metadata"); -    -    } -    @Override -    public void checkValidMetadataSignature(String url, KeyStore store) throws SAMLEngineException { -        //not implemented -    	 -    } -	 -} 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 index 57588287d..963fe70c1 100644 --- 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 @@ -142,7 +142,11 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {  			EIDASAuthnRequest authnRequest = new EIDASAuthnRequest();  			authnRequest.setProviderName(moaconfig.getPublicURLPrefix());  			authnRequest.setPersonalAttributeList(pAttList); +			  			authnRequest.setIssuer(moaconfig.getPublicURLPrefix() + "/eidas/metadata"); +			//TODO: only for development and reverse proxy  +			authnRequest.setIssuer("http://localhost:12343/moa-id-auth/eidas/metadata"); +			  			authnRequest.setDestination(destination);   			authnRequest.setEidasNameidFormat(EIDASAuthnRequest.NAMEID_FORMAT_UNSPECIFIED);  			authnRequest.setEidasLoA(EidasLoaLevels.LOW.stringValue()); 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 index 6a573d0f2..d1bc02766 100644 --- 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 @@ -29,7 +29,10 @@ 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; @@ -49,13 +52,21 @@ public class EidasMetaDataServlet extends HttpServlet {       */      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {          try { -            logger.info("EidasMetaDataServlet GET"); +            logger.debug("EidasMetaDataServlet GET"); -            String metadata_url = "http://localhost:12344/moa-id-auth/eidas/metadata"; -            String sp_return_url = "http://localhost:12344/moa-id-auth/eidas/metadata"; +            AuthConfiguration config = AuthConfigurationProviderFactory.getInstance(); +            String pubURLPrefix = config.getPublicURLPrefix(); +             +             +            String metadata_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_METADATA; +             +            //TODO: only for development and reverse proxy  +            metadata_url = "http://localhost:12343/moa-id-auth/eidas/metadata"; +             +            String sp_return_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_SP_POST;                          String metaData = generateMetadata(metadata_url, sp_return_url); -            logger.debug(metaData); +            logger.trace(metaData);              response.setContentType("text/xml");              response.getWriter().print(metaData); @@ -69,13 +80,13 @@ public class EidasMetaDataServlet extends HttpServlet {          String metadata="invalid metadata";  		// FIXME workaround!? -		Security.removeProvider("IAIK"); -		Security.removeProvider("IAIK_ECC"); +//		Security.removeProvider("IAIK"); +//		Security.removeProvider("IAIK_ECC");  		EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); -		IAIK.addAsProvider(); -		ECCProvider.addAsProvider(true); +//		IAIK.addAsProvider(); +//		ECCProvider.addAsProvider(true);          MetadataGenerator generator = new MetadataGenerator();          MetadataConfigParams mcp=new MetadataConfigParams(); 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 index 2c2435ff6..8e46f0ef1 100644 --- 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 @@ -24,7 +24,8 @@ 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.MOAeIDASSimpleMetadataProvider; +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; @@ -37,28 +38,34 @@ import eu.eidas.samlengineconfig.CertificateConfigurationManager;   */  public class SAMLEngineUtils { -	public static EIDASSAMLEngine createSAMLEngine() throws EIDASEngineException{ +	private static EIDASSAMLEngine eIDASEngine = null; +	 +	public static synchronized EIDASSAMLEngine createSAMLEngine() throws EIDASEngineException{ -		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 -			//TODO: implement final Metadata processor (this is only a first solution!!!) -			engine.setMetadataProcessor(new MOAeIDASSimpleMetadataProvider()); -			 -			return engine; -			 -		} catch (EIDASSAMLEngineException e) { -			Logger.error("eIDAS SAMLengine initialization FAILED!", e); -			throw new EIDASEngineException("eIDAS SAMLengine initialization FAILED!", e); -			 +		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;  	}  } | 
