diff options
Diffstat (limited to 'id/server/modules/moa-id-module-eIDAS')
5 files changed, 342 insertions, 58 deletions
| 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 f45b6ffa5..02c9a8f5d 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 @@ -45,7 +45,7 @@ public class Constants {  	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_SIGNING_IMPLENTATION = "at.gv.egovernment.moa.id.auth.modules.eidas.config.MOASWSigner";  	public static final String SAML_ENCRYPTION_IMPLENTATION = "at.gv.egovernment.moa.id.auth.modules.eidas.config.ModifiedEncryptionSW";  	//configuration property keys diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOASWSigner.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOASWSigner.java index 302c12aaa..5cf5e83ec 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOASWSigner.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOASWSigner.java @@ -22,12 +22,22 @@   */  package at.gv.egovernment.moa.id.auth.modules.eidas.config; +import java.util.Locale;  import java.util.Map; +import org.apache.commons.lang.StringUtils; +import org.apache.xml.security.signature.XMLSignature; +import org.opensaml.xml.signature.SignatureConstants; + +import com.google.common.collect.ImmutableSet; +  import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAWhiteListConfigurator; +import at.gv.egovernment.moaspss.logging.Logger;  import eu.eidas.auth.engine.configuration.SamlEngineConfigurationException;  import eu.eidas.auth.engine.configuration.dom.ConfigurationAdapter;  import eu.eidas.auth.engine.configuration.dom.ConfigurationKey; +import eu.eidas.auth.engine.configuration.dom.KeyStoreSignatureConfigurator;  import eu.eidas.auth.engine.core.impl.KeyStoreProtocolSigner;  import eu.eidas.samlengineconfig.CertificateConfigurationManager; @@ -37,20 +47,71 @@ import eu.eidas.samlengineconfig.CertificateConfigurationManager;   */  public class MOASWSigner extends KeyStoreProtocolSigner { +	private static Map<String, String> props; +	private ImmutableSet<String> sigAlgWhiteList = null; +	 +    private static final ImmutableSet<String> ALLOWED_ALGORITHMS_FOR_VERIFYING = +            ImmutableSet.of(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256, +                            SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA384, +                            SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512, +                            // RIPEMD is allowed to verify +                            SignatureConstants.ALGO_ID_SIGNATURE_RSA_RIPEMD160, +                            SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256, +                            SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA384, +                            SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA512, + +                            //Set other algorithms which are not supported by openSAML in default  +                            StringUtils.lowerCase(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1_MGF1, Locale.ENGLISH), +                            StringUtils.lowerCase(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224_MGF1, Locale.ENGLISH), +                            StringUtils.lowerCase(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1, Locale.ENGLISH), +                            StringUtils.lowerCase(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384_MGF1, Locale.ENGLISH), +                            StringUtils.lowerCase(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512_MGF1, Locale.ENGLISH)); + +    private static final ImmutableSet<String> DEFAULT_ALGORITHM_WHITE_LIST = +            ImmutableSet.of(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256, +                            SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA384, +                            SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512, +                            // RIPEMD is not allowed to sign +                            SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256, +                            SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA384, +                            SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA512, +                             +                            //Set other algorithms which are not supported by openSAML in default  +                            StringUtils.lowerCase(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1, Locale.ENGLISH)); +	  	public MOASWSigner(Map<String, String> properties) throws SamlEngineConfigurationException {  		super(properties); -	 +		props = properties; +			  	}  	/**  	 * @param configManager  	 * @throws SamlEngineConfigurationException  	 */ -	public MOASWSigner(CertificateConfigurationManager configManager) throws SamlEngineConfigurationException {  -		super(ConfigurationAdapter.adapt(configManager).getInstances().get(Constants.eIDAS_SAML_ENGINE_NAME).getConfigurationEntries().get(ConfigurationKey.SIGNATURE_CONFIGURATION.getKey()).getParameters()); +	public MOASWSigner(CertificateConfigurationManager configManager) throws SamlEngineConfigurationException { +		super(props = ConfigurationAdapter.adapt(configManager).getInstances().get(Constants.eIDAS_SAML_ENGINE_NAME).getConfigurationEntries().get(ConfigurationKey.SIGNATURE_CONFIGURATION.getKey()).getParameters());  	} +	@Override +    protected ImmutableSet<String> getSignatureAlgorithmWhiteList() { +		try { +			if (sigAlgWhiteList == null) { +				sigAlgWhiteList = MOAWhiteListConfigurator.getAllowedAlgorithms(DEFAULT_ALGORITHM_WHITE_LIST, +						ALLOWED_ALGORITHMS_FOR_VERIFYING, +                           (new KeyStoreSignatureConfigurator().getSignatureConfiguration(props)).getSignatureAlgorithmWhiteList()); +        	 +			} +         +			return sigAlgWhiteList; +			 +		} catch (SamlEngineConfigurationException e) { +			Logger.warn("Can not parse eIDAS signing configuration." , e); +			return DEFAULT_ALGORITHM_WHITE_LIST; +			 +		} +    }  } 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 3522a16fd..a9c4d5d3a 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 @@ -22,10 +22,13 @@   */  package at.gv.egovernment.moa.id.auth.modules.eidas.tasks; +import java.io.ByteArrayOutputStream;  import java.io.StringWriter;  import java.util.ArrayList;  import java.util.Collection;  import java.util.List; +import java.util.zip.Deflater; +import java.util.zip.DeflaterOutputStream;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse; @@ -39,6 +42,7 @@ import org.opensaml.common.xml.SAMLConstants;  import org.opensaml.saml2.metadata.EntityDescriptor;  import org.opensaml.saml2.metadata.SingleSignOnService;  import org.opensaml.saml2.metadata.provider.MetadataProviderException; +import org.opensaml.xml.util.Base64;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.stereotype.Component; @@ -55,10 +59,12 @@ import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineExcepti  import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils;  import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants;  import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.IRequest;  import at.gv.egovernment.moa.id.commons.api.data.CPEPS;  import at.gv.egovernment.moa.id.commons.api.data.StorkAttribute;  import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;  import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;  import at.gv.egovernment.moa.logging.Logger;  import at.gv.egovernment.moa.util.MiscUtil;  import eu.eidas.auth.commons.EidasStringUtil; @@ -111,15 +117,15 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {  			// select SingleSignOnService Endpoint from eIDAS-node metadata  -			String destination = null; +			SingleSignOnService authnReqEndpoint = null;  			String metadataUrl = cpeps.getPepsURL().toString().split(";")[0].trim();  			try {  				EntityDescriptor eIDASNodeMetadata = eIDASMetadataProvider.getEntityDescriptor(metadataUrl);  				if (eIDASNodeMetadata != null) {  					SingleSignOnService ssoDescr = selectSingleSignOnServiceFromMetadata(eIDASNodeMetadata);  					if (ssoDescr != null) { -						destination = ssoDescr.getLocation(); -						Logger.debug("Use destination URL:" + destination + " from eIDAS metadata:" + metadataUrl); +						authnReqEndpoint = ssoDescr; +						Logger.debug("Use destination URL:" + authnReqEndpoint.getLocation() + " from eIDAS metadata:" + metadataUrl);  					} else  						Logger.warn("eIDAS metadata for node:" + metadataUrl + " has no IDPSSODescriptor or no SingleSignOnService information."); @@ -134,13 +140,21 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {  			// load SingleSignOnService Endpoint from configuration, if Metadata contains no information  			// FIXME convenience function for not standard conform metadata  -			if (MiscUtil.isEmpty(destination)) { +			if (authnReqEndpoint == null) { +				String destination = null;  				String[] splitString = cpeps.getPepsURL().toString().split(";");  				if (splitString.length > 1)				  					destination = cpeps.getPepsURL().toString().split(";")[1].trim(); -				if (MiscUtil.isNotEmpty(destination)) +				if (MiscUtil.isNotEmpty(destination)) {  					Logger.debug("Use eIDAS node destination URL:" + destination + " from configuration"); +					 +					//set POST binding as default binding, if Authn. request endpoint from config is used +					authnReqEndpoint = SAML2Utils.createSAMLObject(SingleSignOnService.class); +					authnReqEndpoint.setLocation(destination); +					authnReqEndpoint.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); +					 +				}  				else {  					Logger.error("No eIDAS-node destination URL FOUND. Request eIDAS node not possible."); @@ -193,7 +207,7 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {  			authnRequestBuilder.providerName(pendingReq.getAuthURL());  			String issur = pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA;  			authnRequestBuilder.issuer(issur); -			authnRequestBuilder.destination(destination); +			authnRequestBuilder.destination(authnReqEndpoint.getLocation());  			authnRequestBuilder.nameIdFormat(Constants.eIDAS_REQ_NAMEID_FORMAT);			 @@ -226,45 +240,21 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {  			String SAMLRequest = EidasStringUtil.encodeToBase64(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", pendingReq.getRequestID()); -	             -	            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()); -	             -	             -	            byte[] content = writer.getBuffer().toString().getBytes("UTF-8");	             -	            response.setContentType(MediaType.HTML_UTF_8.toString()); -	            response.setContentLength(content.length); -	            response.getOutputStream().write(content); +			if (SAMLConstants.SAML2_POST_BINDING_URI.equals(authnReqEndpoint.getBinding()))  +				buildPostBindingRequest(pendingReq, authnReqEndpoint, SAMLRequest, authnRequest, response); +			 +			//TODO: redirect Binding is not completely implemented +			//else if (SAMLConstants.SAML2_REDIRECT_BINDING_URI.equals(authnReqEndpoint.getBinding())) +				//buildRedirecttBindingRequest(pendingReq, authnReqEndpoint, token, authnRequest, response); +			 +			else { +				Logger.error("eIDAS-node use an unsupported binding (" +						+ authnReqEndpoint.getBinding() + "). Request eIDAS node not possible."); +				throw new MOAIDException("eIDAS.02", new Object[]{"eIDAS-node use an unsupported binding"}); +				 +			} +				 -	            revisionsLogger.logEvent(oaConfig, pendingReq,  -						MOAIDEventConstants.AUTHPROCESS_PEPS_REQUESTED, -						authnRequest.getRequest().getId()); -	            	         -	        } catch (Exception e) { -	            Logger.error("Velocity general error: " + e.getMessage()); -	            throw new MOAIDException("eIDAS.02", new Object[]{e.getMessage()}, e); -	             -	        }  		}catch (EIDASSAMLEngineException e){  			throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.",  @@ -280,6 +270,102 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {  		}  	} +	/** +	 * Encode the eIDAS request with Redirect binding +	 *  +	 * @param pendingReq +	 * @param authnReqEndpoint +	 * @param token +	 * @param authnRequest +	 * @param response +	 * @throws MOAIDException +	 */ +	private void buildRedirecttBindingRequest(IRequest pendingReq, SingleSignOnService authnReqEndpoint,  +			byte[] token, IRequestMessage authnRequest, HttpServletResponse response)  +			throws MOAIDException { + +		//FIXME: implement correct deflat encoding accodring to SAML2 Redirect Binding specification +		 +		try {		 +			ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); +			Deflater deflater = new Deflater(Deflater.DEFLATED, true); +			DeflaterOutputStream deflaterStream = new DeflaterOutputStream(bytesOut, deflater); +			deflaterStream.write(token); +			deflaterStream.finish(); +			String samlReqBase64 =  Base64.encodeBytes(bytesOut.toByteArray(), Base64.DONT_BREAK_LINES); +			 +			 +			 +		} catch (Exception e) { +			 Logger.error("eIDAS Redirect-Binding request encoding error: " + e.getMessage()); +	         throw new MOAIDException("eIDAS.02", new Object[]{e.getMessage()}, e); +			 +		} +		 +	} +	 +	/** +	 * Encode the eIDAS request with POST binding +	 *  +	 * @param pendingReq +	 * @param authnReqEndpoint +	 * @param SAMLRequest +	 * @param authnRequest +	 * @param response +	 * @throws MOAIDException +	 */ +	private void buildPostBindingRequest(IRequest pendingReq, SingleSignOnService authnReqEndpoint,  +			String SAMLRequest, IRequestMessage authnRequest, HttpServletResponse response)  +			throws MOAIDException { +		//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", pendingReq.getRequestID()); +             +            Logger.debug("Using assertion consumer url as action: " + authnReqEndpoint.getLocation()); +            context.put("action", authnReqEndpoint.getLocation()); + +            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()); +             +             +            byte[] content = writer.getBuffer().toString().getBytes("UTF-8");	             +            response.setContentType(MediaType.HTML_UTF_8.toString()); +            response.setContentLength(content.length); +            response.getOutputStream().write(content); + +            revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,  +					MOAIDEventConstants.AUTHPROCESS_PEPS_REQUESTED, +					authnRequest.getRequest().getId()); +            	         +        } catch (Exception e) { +            Logger.error("Velocity general error: " + e.getMessage()); +            throw new MOAIDException("eIDAS.02", new Object[]{e.getMessage()}, e); +             +        } +		 +	} +	 +	/** +	 * Select a SingleSignOnService endPoint from eIDAS node metadata. +	 * This endPoint receives the Authn. request +	 *  +	 * @param idpEntity +	 * @return +	 */  	private SingleSignOnService selectSingleSignOnServiceFromMetadata(EntityDescriptor idpEntity) {  		//select SingleSignOn Service endpoint from IDP metadata  		SingleSignOnService endpoint = null; @@ -294,7 +380,9 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {  			// use POST binding as default if it exists   			if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI))    				endpoint = sss; -				 +			 +			//TODO: redirect Binding is not completely implemented +			// use Redirect binding as backup	  //			else if ( sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)   //					&& endpoint == null )  //				endpoint = sss; diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAWhiteListConfigurator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAWhiteListConfigurator.java new file mode 100644 index 000000000..7d647ff15 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAWhiteListConfigurator.java @@ -0,0 +1,96 @@ +/* + * 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.Locale; +import java.util.regex.Pattern; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; + +import com.google.common.collect.ImmutableSet; + +import at.gv.egovernment.moa.id.commons.utils.KeyValueUtils; + +/** + * @author tlenz + * + */ +public class MOAWhiteListConfigurator  { +	 private static final Pattern WHITE_LIST_SPLITTER = Pattern.compile("[;,]"); + +	     +	    public static ImmutableSet<String> getAllowedAlgorithms( ImmutableSet<String> defaultWhiteList, +	                                                             ImmutableSet<String> allowedValues, +	                                                            String algorithmWhiteListValue) { +	        if (StringUtils.isBlank(algorithmWhiteListValue)) { +	            return defaultWhiteList; +	        } +	        ImmutableSet.Builder<String> allowed = ImmutableSet.builder(); +	        String[] wlAlgorithms = WHITE_LIST_SPLITTER.split(algorithmWhiteListValue); +	        if (null != wlAlgorithms && wlAlgorithms.length > 0) { +	            return getAllowedAlgorithms(defaultWhiteList, allowedValues, ImmutableSet.<String>copyOf(wlAlgorithms)); +	        } +	        return defaultWhiteList; +	    } + + +	    public static ImmutableSet<String> getAllowedAlgorithms( ImmutableSet<String> defaultWhiteList, +	                                                             ImmutableSet<String> allowedValues, +	                                                            ImmutableSet<String> candidateValues) { +	        if (CollectionUtils.isEmpty(candidateValues)) { +	            return defaultWhiteList; +	        } +	        ImmutableSet.Builder<String> allowed = ImmutableSet.builder(); +	        boolean modified = false; +	        for (String candidateValue : candidateValues) { + +	    	    /**FIX: +	    	     * fix problem with lowerCase and MGF1 signature algorithms   +	    	     *  +	    	     */ +	            candidateValue = StringUtils.trimToNull( +	            		KeyValueUtils.removeAllNewlineFromString(candidateValue)); +	            if (StringUtils.isNotBlank(candidateValue)) { +	            	String candidateAlgorithm = StringUtils.lowerCase(candidateValue, Locale.ENGLISH); +	                if (allowedValues.contains(candidateAlgorithm)) { +	                    allowed.add(candidateValue); +	                    if (!modified && !candidateAlgorithm.equals(candidateValue)) { +	                        modified = true; +	                    } +	                } else { +	                    modified = true; +	                } +	            } +	        } +	        if (!modified) { +	            return candidateValues; +	        } +	        ImmutableSet<String> set = allowed.build(); +	        if (set.isEmpty()) { +	            return defaultWhiteList; +	        } +	        return set; +	    } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java index 09c3dff38..dd14972e3 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java @@ -35,6 +35,7 @@ import org.joda.time.DurationFieldType;  import org.opensaml.Configuration;  import org.opensaml.common.xml.SAMLConstants;  import org.opensaml.saml2.common.Extensions; +import org.opensaml.saml2.common.impl.ExtensionsBuilder;  import org.opensaml.saml2.core.Attribute;  import org.opensaml.saml2.core.AttributeValue;  import org.opensaml.saml2.metadata.AssertionConsumerService; @@ -52,6 +53,7 @@ import org.opensaml.saml2.metadata.LocalizedString;  import org.opensaml.saml2.metadata.NameIDFormat;  import org.opensaml.saml2.metadata.Organization;  import org.opensaml.saml2.metadata.OrganizationDisplayName; +import org.opensaml.saml2.metadata.OrganizationName;  import org.opensaml.saml2.metadata.OrganizationURL;  import org.opensaml.saml2.metadata.SPSSODescriptor;  import org.opensaml.saml2.metadata.SSODescriptor; @@ -76,6 +78,7 @@ import com.google.common.collect.ImmutableSortedSet;  import com.google.common.collect.Ordering;  import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;  import eu.eidas.auth.commons.EIDASUtil;  import eu.eidas.auth.commons.EidasStringUtil;  import eu.eidas.auth.commons.attribute.AttributeDefinition; @@ -126,8 +129,17 @@ public class MOAeIDASMetadataGenerator extends MetadataGenerator {              entityDescriptor.setEntityID(params.getEntityID());              entityDescriptor.setOrganization(buildOrganization()); -            entityDescriptor.getContactPersons().add(buildContact(ContactPersonTypeEnumeration.SUPPORT)); -            entityDescriptor.getContactPersons().add(buildContact(ContactPersonTypeEnumeration.TECHNICAL)); +             +            /**FIXME: +             * HOTFIX: do not add empty contactPerson elements  +             */ +            ContactPerson contactSupport = buildContact(ContactPersonTypeEnumeration.SUPPORT); +            if (contactSupport != null) +            	entityDescriptor.getContactPersons().add(contactSupport);             +            ContactPerson contactTech = buildContact(ContactPersonTypeEnumeration.TECHNICAL); +            if (contactTech != null) +            	entityDescriptor.getContactPersons().add(contactTech); +                          entityDescriptor.setValidUntil(getExpireDate());              X509KeyInfoGeneratorFactory keyInfoGeneratorFactory = new X509KeyInfoGeneratorFactory(); @@ -164,8 +176,15 @@ public class MOAeIDASMetadataGenerator extends MetadataGenerator {          //the node has SP role          spSSODescriptor.setWantAssertionsSigned(params.isWantAssertionsSigned());          spSSODescriptor.setAuthnRequestsSigned(true); -        spSSODescriptor.setID(idpSSODescriptor == null ? params.getEntityID() -                                                       : ("SP" + params.getEntityID())); +         +         +        /**FIXME:  +         * 		 "SP" + params.getEntityID()) is not a valid XML ID attribute value +         */ +        //spSSODescriptor.setID(idpSSODescriptor == null ? params.getEntityID() : ("SP" + params.getEntityID()));         +        spSSODescriptor.setID(SAML2Utils.getSecureIdentifier()); +         +                  if (params.getSPSignature() != null) {              spSSODescriptor.setSignature(params.getSPSignature());          } @@ -220,8 +239,13 @@ public class MOAeIDASMetadataGenerator extends MetadataGenerator {                     SAMLEngineException, EIDASSAMLEngineException {          //the node has IDP role          idpSSODescriptor.setWantAuthnRequestsSigned(true); -        idpSSODescriptor.setID(spSSODescriptor == null ? params.getEntityID() -                                                       : ("IDP" + params.getEntityID())); +         +        /**FIXME:  +         * 		 "IDP" + params.getEntityID()) is not a valid XML ID attribute value +         */ +        //idpSSODescriptor.setID(spSSODescriptor == null ? params.getEntityID() : ("IDP" + params.getEntityID()));         +        idpSSODescriptor.setID(SAML2Utils.getSecureIdentifier()); +                  if (params.getIDPSignature() != null) {              idpSSODescriptor.setSignature(params.getIDPSignature());          } @@ -341,8 +365,16 @@ public class MOAeIDASMetadataGenerator extends MetadataGenerator {      private Organization buildOrganization() {          Organization organization = null; -        try { +        try {        	              organization = BuilderFactoryUtil.buildXmlObject(Organization.class); +             +            /**FIXME: +             *   set correct OrganizationName value if it is not fixed in next eIDAS node version +             */ +            OrganizationName orgName = BuilderFactoryUtil.buildXmlObject(OrganizationName.class); +            orgName.setName(new LocalizedString(params.getNodeUrl(), "en")); +            organization.getOrganizationNames().add(orgName); +                          OrganizationDisplayName odn = BuilderFactoryUtil.buildXmlObject(OrganizationDisplayName.class);              odn.setName(new LocalizedString(params.getCountryName(), "en"));              organization.getDisplayNames().add(odn); @@ -373,7 +405,7 @@ public class MOAeIDASMetadataGenerator extends MetadataGenerator {              contact = BuilderFactoryUtil.buildXmlObject(ContactPerson.class);              if (currentContact == null) {                  LOGGER.error("ERROR: cannot retrieve contact from the configuration"); -                return contact; +                return null;              }              EmailAddress emailAddressObj = BuilderFactoryUtil.buildXmlObject(EmailAddress.class); @@ -514,7 +546,14 @@ public class MOAeIDASMetadataGenerator extends MetadataGenerator {      }      private Extensions generateExtensions() throws EIDASSAMLEngineException { -        Extensions eidasExtensions = BuilderFactoryUtil.generateExtension(); +        /**FIXME: BuilderFactoryUtil.generateExtension() generates extensions from SAML2 request namespace +    	*         but SAML2 metadata namespace is required +    	**/ +    	//Extensions eidasExtensions = BuilderFactoryUtil.generateExtension(); +    	 +    	ExtensionsBuilder extensionsBuilder = new ExtensionsBuilder(); +    	Extensions eidasExtensions = extensionsBuilder.buildObject("urn:oasis:names:tc:SAML:2.0:metadata", "Extensions", "md"); +    	          if (params.getAssuranceLevel() != null) {              generateLoA(eidasExtensions);          } | 
