aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java')
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java613
1 files changed, 613 insertions, 0 deletions
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
new file mode 100644
index 000000000..c614e6490
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java
@@ -0,0 +1,613 @@
+/*
+ * 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.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.joda.time.DateTime;
+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.core.Attribute;
+import org.opensaml.saml2.core.AttributeValue;
+import org.opensaml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml2.metadata.Company;
+import org.opensaml.saml2.metadata.ContactPerson;
+import org.opensaml.saml2.metadata.ContactPersonTypeEnumeration;
+import org.opensaml.saml2.metadata.EmailAddress;
+import org.opensaml.saml2.metadata.EncryptionMethod;
+import org.opensaml.saml2.metadata.EntitiesDescriptor;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.GivenName;
+import org.opensaml.saml2.metadata.IDPSSODescriptor;
+import org.opensaml.saml2.metadata.KeyDescriptor;
+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.OrganizationURL;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml2.metadata.SSODescriptor;
+import org.opensaml.saml2.metadata.SingleSignOnService;
+import org.opensaml.saml2.metadata.SurName;
+import org.opensaml.saml2.metadata.TelephoneNumber;
+import org.opensaml.samlext.saml2mdattr.EntityAttributes;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.XMLObjectBuilderFactory;
+import org.opensaml.xml.schema.XSString;
+import org.opensaml.xml.schema.impl.XSStringBuilder;
+import org.opensaml.xml.security.SecurityException;
+import org.opensaml.xml.security.credential.Credential;
+import org.opensaml.xml.security.credential.UsageType;
+import org.opensaml.xml.security.keyinfo.KeyInfoGenerator;
+import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory;
+import org.opensaml.xml.signature.KeyInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Ordering;
+
+import at.gv.egovernment.moa.id.auth.modules.eidas.Constants;
+import eu.eidas.auth.commons.EIDASUtil;
+import eu.eidas.auth.commons.EidasStringUtil;
+import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.protocol.impl.SamlNameIdFormat;
+import eu.eidas.auth.commons.xml.opensaml.OpenSamlHelper;
+import eu.eidas.auth.engine.ProtocolEngineI;
+import eu.eidas.auth.engine.core.SAMLExtensionFormat;
+import eu.eidas.auth.engine.core.eidas.DigestMethod;
+import eu.eidas.auth.engine.core.eidas.EidasConstants;
+import eu.eidas.auth.engine.core.eidas.SPType;
+import eu.eidas.auth.engine.core.eidas.SigningMethod;
+import eu.eidas.auth.engine.metadata.Contact;
+import eu.eidas.auth.engine.metadata.EntityDescriptorContainer;
+import eu.eidas.auth.engine.metadata.MetadataConfigParams;
+import eu.eidas.auth.engine.metadata.MetadataGenerator;
+import eu.eidas.auth.engine.metadata.MetadataSignerI;
+import eu.eidas.auth.engine.xml.opensaml.BuilderFactoryUtil;
+import eu.eidas.auth.engine.xml.opensaml.CertificateUtil;
+import eu.eidas.encryption.exception.UnmarshallException;
+import eu.eidas.engine.exceptions.EIDASSAMLEngineException;
+import eu.eidas.engine.exceptions.SAMLEngineException;
+
+/**
+ * @author tlenz
+ *
+ */
+public class MOAeIDASMetadataGenerator extends MetadataGenerator {
+ private static final Logger LOGGER = LoggerFactory.getLogger(MetadataGenerator.class.getName());
+
+ MetadataConfigParams params;
+
+ XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
+
+ SPSSODescriptor spSSODescriptor = null;
+
+ IDPSSODescriptor idpSSODescriptor = null;
+
+ private String ssoLocation;
+
+ /**
+ * @return a String representation of the entityDescriptr built based on the attributes previously set
+ */
+ public String generateMetadata() throws EIDASSAMLEngineException {
+ EntityDescriptor entityDescriptor;
+ try {
+ entityDescriptor = (EntityDescriptor) builderFactory.getBuilder(EntityDescriptor.DEFAULT_ELEMENT_NAME)
+ .buildObject(EntityDescriptor.DEFAULT_ELEMENT_NAME);
+
+ entityDescriptor.setEntityID(params.getEntityID());
+ entityDescriptor.setOrganization(buildOrganization());
+ entityDescriptor.getContactPersons().add(buildContact(ContactPersonTypeEnumeration.SUPPORT));
+ entityDescriptor.getContactPersons().add(buildContact(ContactPersonTypeEnumeration.TECHNICAL));
+ entityDescriptor.setValidUntil(getExpireDate());
+
+ X509KeyInfoGeneratorFactory keyInfoGeneratorFactory = new X509KeyInfoGeneratorFactory();
+ keyInfoGeneratorFactory.setEmitEntityCertificate(true);
+ Extensions e = generateExtensions();
+ if (!e.getUnknownXMLObjects().isEmpty()) {
+ entityDescriptor.setExtensions(e);
+ }
+ if (spSSODescriptor != null) {
+ generateSPSSODescriptor(entityDescriptor, keyInfoGeneratorFactory);
+ }
+ if (idpSSODescriptor != null) {
+ generateIDPSSODescriptor(entityDescriptor, keyInfoGeneratorFactory);
+ }
+ if (params.getSpEngine() != null) {
+ ProtocolEngineI spEngine = params.getSpEngine();
+ ((MetadataSignerI) spEngine.getSigner()).signMetadata(entityDescriptor);
+ } else if (params.getIdpEngine() != null) {
+ ProtocolEngineI idpEngine = params.getIdpEngine();
+ ((MetadataSignerI) idpEngine.getSigner()).signMetadata(entityDescriptor);
+ }
+ return EidasStringUtil.toString(OpenSamlHelper.marshall(entityDescriptor, false));
+ } catch (Exception ex) {
+ LOGGER.info("ERROR : SAMLException ", ex.getMessage());
+ LOGGER.debug("ERROR : SAMLException ", ex);
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ private void generateSPSSODescriptor(final EntityDescriptor entityDescriptor,
+ final X509KeyInfoGeneratorFactory keyInfoGeneratorFactory)
+ throws org.opensaml.xml.security.SecurityException, IllegalAccessException, NoSuchFieldException,
+ SAMLEngineException, EIDASSAMLEngineException {
+ //the node has SP role
+ spSSODescriptor.setWantAssertionsSigned(params.isWantAssertionsSigned());
+ spSSODescriptor.setAuthnRequestsSigned(true);
+ spSSODescriptor.setID(idpSSODescriptor == null ? params.getEntityID()
+ : ("SP" + params.getEntityID()));
+ if (params.getSPSignature() != null) {
+ spSSODescriptor.setSignature(params.getSPSignature());
+ }
+ if (params.getSpSigningCredential() != null) {
+ spSSODescriptor.getKeyDescriptors()
+ .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getSpSigningCredential(), UsageType.SIGNING));
+
+ } else if (params.getSigningCredential() != null) {
+ spSSODescriptor.getKeyDescriptors()
+ .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getSigningCredential(), UsageType.SIGNING));
+ }
+
+ if (params.getSpEncryptionCredential() != null) {
+ spSSODescriptor.getKeyDescriptors()
+ .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getSpEncryptionCredential(),
+ UsageType.ENCRYPTION));
+ } else if (params.getEncryptionCredential() != null) {
+ spSSODescriptor.getKeyDescriptors()
+ .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getEncryptionCredential(), UsageType.ENCRYPTION));
+ }
+ spSSODescriptor.addSupportedProtocol(params.getSpSamlProtocol());
+ if (!StringUtils.isEmpty(params.getAssertionConsumerUrl())) {
+ addAssertionConsumerService();
+ }
+ fillNameIDFormat(spSSODescriptor);
+ if (params.getSpEngine() != null) {
+ ProtocolEngineI spEngine = params.getSpEngine();
+ ((MetadataSignerI) spEngine.getSigner()).signMetadata(spSSODescriptor);
+ }
+ entityDescriptor.getRoleDescriptors().add(spSSODescriptor);
+
+ }
+
+ private void fillNameIDFormat(SSODescriptor ssoDescriptor) throws EIDASSAMLEngineException {
+ NameIDFormat persistentFormat =
+ (NameIDFormat) BuilderFactoryUtil.buildXmlObject(NameIDFormat.DEFAULT_ELEMENT_NAME);
+ persistentFormat.setFormat(SamlNameIdFormat.PERSISTENT.getNameIdFormat());
+ ssoDescriptor.getNameIDFormats().add(persistentFormat);
+ NameIDFormat transientFormat =
+ (NameIDFormat) BuilderFactoryUtil.buildXmlObject(NameIDFormat.DEFAULT_ELEMENT_NAME);
+ transientFormat.setFormat(SamlNameIdFormat.TRANSIENT.getNameIdFormat());
+ ssoDescriptor.getNameIDFormats().add(transientFormat);
+ NameIDFormat unspecifiedFormat =
+ (NameIDFormat) BuilderFactoryUtil.buildXmlObject(NameIDFormat.DEFAULT_ELEMENT_NAME);
+ unspecifiedFormat.setFormat(SamlNameIdFormat.UNSPECIFIED.getNameIdFormat());
+ ssoDescriptor.getNameIDFormats().add(unspecifiedFormat);
+ }
+
+ private void generateIDPSSODescriptor(final EntityDescriptor entityDescriptor,
+ final X509KeyInfoGeneratorFactory keyInfoGeneratorFactory)
+ throws org.opensaml.xml.security.SecurityException, IllegalAccessException, NoSuchFieldException,
+ SAMLEngineException, EIDASSAMLEngineException {
+ //the node has IDP role
+ idpSSODescriptor.setWantAuthnRequestsSigned(true);
+ idpSSODescriptor.setID(spSSODescriptor == null ? params.getEntityID()
+ : ("IDP" + params.getEntityID()));
+ if (params.getIDPSignature() != null) {
+ idpSSODescriptor.setSignature(params.getIDPSignature());
+ }
+ if (params.getIdpSigningCredential() != null) {
+ idpSSODescriptor.getKeyDescriptors()
+ .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getIdpSigningCredential(), UsageType.SIGNING));
+ } else if (params.getSigningCredential() != null) {
+ idpSSODescriptor.getKeyDescriptors()
+ .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getSigningCredential(), UsageType.SIGNING));
+ }
+ if (params.getIdpEncryptionCredential() != null) {
+ idpSSODescriptor.getKeyDescriptors()
+ .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getIdpEncryptionCredential(),
+ UsageType.ENCRYPTION));
+ } else if (params.getEncryptionCredential() != null) {
+ idpSSODescriptor.getKeyDescriptors()
+ .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getEncryptionCredential(), UsageType.ENCRYPTION));
+ }
+ idpSSODescriptor.addSupportedProtocol(params.getIdpSamlProtocol());
+ fillNameIDFormat(idpSSODescriptor);
+ if (params.getIdpEngine() != null) {
+ if (params.getIdpEngine().getProtocolProcessor() != null
+ && params.getIdpEngine().getProtocolProcessor().getFormat() == SAMLExtensionFormat.EIDAS10) {
+
+ /*TODO: Only a work-around to add eIDAS attributes, which could be provided from MOA-ID, to IDP metadata
+ * If we restrict the eIDAS Engine attribute definitions then also additional incoming attributes can not processed any more.
+ *
+ * INFO: Maybe, this code can be removed in a future version of the eIDAS engine
+ */
+ generateSupportedAttributes(idpSSODescriptor, getAllSupportedAttributes());
+ }
+ ProtocolEngineI idpEngine = params.getIdpEngine();
+ ((MetadataSignerI) idpEngine.getSigner()).signMetadata(idpSSODescriptor);
+ }
+
+ idpSSODescriptor.getSingleSignOnServices().addAll(buildSingleSignOnServicesBindingLocations());
+
+ entityDescriptor.getRoleDescriptors().add(idpSSODescriptor);
+
+ }
+
+ /*TODO: Only a work-around to add eIDAS attributes, which could be provided from MOA-ID, to IDP metadata
+ * If we restrict the eIDAS Engine attribute definitions then also additional incoming attributes can not processed any more.
+ */
+ public ImmutableSortedSet<AttributeDefinition<?>> getAllSupportedAttributes() {
+ ImmutableSortedSet.Builder<AttributeDefinition<?>> builder =
+ new ImmutableSortedSet.Builder<>(Ordering.<AttributeDefinition<?>>natural());
+ builder.addAll(Constants.MOA_IDP_ATTR_REGISTRY.getAttributes());
+ return builder.build();
+ }
+
+ private ArrayList<SingleSignOnService> buildSingleSignOnServicesBindingLocations()
+ throws NoSuchFieldException, IllegalAccessException {
+ ArrayList<SingleSignOnService> singleSignOnServices = new ArrayList<SingleSignOnService>();
+
+ HashMap<String, String> bindingLocations = params.getProtocolBindingLocation();
+ for (String binding : bindingLocations.keySet()) {
+ SingleSignOnService ssos = BuilderFactoryUtil.buildXmlObject(SingleSignOnService.class);
+ ssos.setBinding(binding);
+ ssos.setLocation(bindingLocations.get(binding));
+ singleSignOnServices.add(ssos);
+ }
+
+ return singleSignOnServices;
+ }
+
+ /**
+ * @param metadata
+ * @return an EntityDescriptor parsed from the given String or null
+ */
+ // TODO (commented by donydgr) Move to a eu.eidas.auth.engine.metadata.MetadataUtil ? Throw an exception if the metadata is invalid instead of returning null ?
+ public static EntityDescriptorContainer deserializeEntityDescriptor(String metadata) {
+ EntityDescriptorContainer result = new EntityDescriptorContainer();
+ try {
+ byte[] metaDataBytes = EidasStringUtil.getBytes(metadata);
+ XMLObject obj = OpenSamlHelper.unmarshall(metaDataBytes);
+ if (obj instanceof EntityDescriptor) {
+ result.addEntityDescriptor((EntityDescriptor) obj, metaDataBytes);
+ } else if (obj instanceof EntitiesDescriptor) {
+ EntitiesDescriptor ed = (EntitiesDescriptor) obj;
+ result.setEntitiesDescriptor(ed);
+ result.getEntityDescriptors().addAll(((EntitiesDescriptor) obj).getEntityDescriptors());
+ result.setSerializedEntitesDescriptor(metaDataBytes);
+ }
+ } catch (UnmarshallException ue) {
+ LOGGER.info("ERROR : unmarshalling error", ue.getMessage());
+ LOGGER.debug("ERROR : unmarshalling error", ue);
+ }
+ return result;
+ }
+
+ private KeyDescriptor getKeyDescriptor(X509KeyInfoGeneratorFactory keyInfoGeneratorFactory,
+ Credential credential,
+ UsageType usage)
+ throws NoSuchFieldException, IllegalAccessException, SecurityException, EIDASSAMLEngineException {
+ KeyDescriptor keyDescriptor = null;
+ if (credential != null) {
+ keyDescriptor = BuilderFactoryUtil.buildXmlObject(KeyDescriptor.class);
+ KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance();
+
+ KeyInfo keyInfo = keyInfoGenerator.generate(credential);
+ keyDescriptor.setUse(usage);
+ keyDescriptor.setKeyInfo(keyInfo);
+ if (usage == UsageType.ENCRYPTION && params.getEncryptionAlgorithms() != null) {
+ Set<String> encryptionAlgos = EIDASUtil.parseSemicolonSeparatedList(params.getEncryptionAlgorithms());
+ for (String encryptionAlgo : encryptionAlgos) {
+ EncryptionMethod em =
+ (EncryptionMethod) BuilderFactoryUtil.buildXmlObject(EncryptionMethod.DEFAULT_ELEMENT_NAME);
+ em.setAlgorithm(encryptionAlgo);
+ keyDescriptor.getEncryptionMethods().add(em);
+ }
+ }
+
+ }
+ return keyDescriptor;
+ }
+
+ private Organization buildOrganization() {
+ Organization organization = null;
+ try {
+ organization = BuilderFactoryUtil.buildXmlObject(Organization.class);
+ OrganizationDisplayName odn = BuilderFactoryUtil.buildXmlObject(OrganizationDisplayName.class);
+ odn.setName(new LocalizedString(params.getCountryName(), "en"));
+ organization.getDisplayNames().add(odn);
+ OrganizationURL url = BuilderFactoryUtil.buildXmlObject(OrganizationURL.class);
+ url.setURL(new LocalizedString(params.getNodeUrl(), "en"));
+ organization.getURLs().add(url);
+ } catch (IllegalAccessException iae) {
+ LOGGER.info("ERROR : error generating the Organization: {}", iae.getMessage());
+ LOGGER.debug("ERROR : error generating the Organization: {}", iae);
+ } catch (NoSuchFieldException nfe) {
+ LOGGER.info("ERROR : error generating the Organization: {}", nfe.getMessage());
+ LOGGER.debug("ERROR : error generating the Organization: {}", nfe);
+ }
+ return organization;
+ }
+
+ private ContactPerson buildContact(ContactPersonTypeEnumeration contactType) {
+ ContactPerson contact = null;
+ try {
+ Contact currentContact = null;
+ if (contactType == ContactPersonTypeEnumeration.SUPPORT) {
+ currentContact = params.getSupportContact();
+ } else if (contactType == ContactPersonTypeEnumeration.TECHNICAL) {
+ currentContact = params.getTechnicalContact();
+ } else {
+ LOGGER.error("ERROR: unsupported contact type");
+ }
+ contact = BuilderFactoryUtil.buildXmlObject(ContactPerson.class);
+ if (currentContact == null) {
+ LOGGER.error("ERROR: cannot retrieve contact from the configuration");
+ return contact;
+ }
+
+ EmailAddress emailAddressObj = BuilderFactoryUtil.buildXmlObject(EmailAddress.class);
+ Company company = BuilderFactoryUtil.buildXmlObject(Company.class);
+ GivenName givenName = BuilderFactoryUtil.buildXmlObject(GivenName.class);
+ SurName surName = BuilderFactoryUtil.buildXmlObject(SurName.class);
+ TelephoneNumber phoneNumber = BuilderFactoryUtil.buildXmlObject(TelephoneNumber.class);
+ contact.setType(contactType);
+ emailAddressObj.setAddress(currentContact.getEmail());
+ company.setName(currentContact.getCompany());
+ givenName.setName(currentContact.getGivenName());
+ surName.setName(currentContact.getSurName());
+ phoneNumber.setNumber(currentContact.getPhone());
+
+ populateContact(contact, currentContact, emailAddressObj, company, givenName, surName, phoneNumber);
+
+ } catch (IllegalAccessException iae) {
+ LOGGER.info("ERROR : error generating the Organization: {}", iae.getMessage());
+ LOGGER.debug("ERROR : error generating the Organization: {}", iae);
+ } catch (NoSuchFieldException nfe) {
+ LOGGER.info("ERROR : error generating the Organization: {}", nfe.getMessage());
+ LOGGER.debug("ERROR : error generating the Organization: {}", nfe);
+ }
+ return contact;
+ }
+
+ private void populateContact(ContactPerson contact,
+ Contact currentContact,
+ EmailAddress emailAddressObj,
+ Company company,
+ GivenName givenName,
+ SurName surName,
+ TelephoneNumber phoneNumber) {
+ if (!StringUtils.isEmpty(currentContact.getEmail())) {
+ contact.getEmailAddresses().add(emailAddressObj);
+ }
+ if (!StringUtils.isEmpty(currentContact.getCompany())) {
+ contact.setCompany(company);
+ }
+ if (!StringUtils.isEmpty(currentContact.getGivenName())) {
+ contact.setGivenName(givenName);
+ }
+ if (!StringUtils.isEmpty(currentContact.getSurName())) {
+ contact.setSurName(surName);
+ }
+ if (!StringUtils.isEmpty(currentContact.getPhone())) {
+ contact.getTelephoneNumbers().add(phoneNumber);
+ }
+
+ }
+
+ /**
+ * @param engine a EIDASSamlEngine from which signing and encryption information is extracted
+ */
+
+ public void initialize(ProtocolEngineI engine) throws EIDASSAMLEngineException {
+
+ X509Certificate decryptionCertificate = engine.getDecryptionCertificate();
+ if (null != decryptionCertificate) {
+ params.setEncryptionCredential(CertificateUtil.toCredential(decryptionCertificate));
+ }
+ params.setSigningCredential(CertificateUtil.toCredential(engine.getSigningCertificate()));
+ params.setIdpEngine(engine);
+ params.setSpEngine(engine);
+ }
+
+ /**
+ * @param spEngine a EIDASSamlEngine for the
+ */
+
+ public void initialize(ProtocolEngineI spEngine, ProtocolEngineI idpEngine) throws EIDASSAMLEngineException {
+ if (idpEngine != null) {
+ idpEngine.getProtocolProcessor().configure();
+ params.setIdpSigningCredential(CertificateUtil.toCredential(idpEngine.getSigningCertificate()));
+
+ final X509Certificate idpEngineDecryptionCertificate = idpEngine.getDecryptionCertificate();
+ if (idpEngineDecryptionCertificate != null) {
+ params.setIdpEncryptionCredential(CertificateUtil.toCredential(idpEngineDecryptionCertificate));
+ }
+
+ }
+ if (spEngine != null) {
+ spEngine.getProtocolProcessor().configure();
+ params.setSpSigningCredential(CertificateUtil.toCredential(spEngine.getSigningCertificate()));
+
+ final X509Certificate spEngineDecryptionCertificate = spEngine.getDecryptionCertificate();
+ if (spEngineDecryptionCertificate != null) {
+ params.setSpEncryptionCredential(CertificateUtil.toCredential(spEngineDecryptionCertificate));
+ }
+ }
+
+ params.setIdpEngine(idpEngine);
+ params.setSpEngine(spEngine);
+ }
+
+ public void addSPRole() throws EIDASSAMLEngineException {
+ try {
+ if (spSSODescriptor == null) {
+ spSSODescriptor = BuilderFactoryUtil.buildXmlObject(SPSSODescriptor.class);
+ }
+ } catch (IllegalAccessException iae) {
+ throw new EIDASSAMLEngineException(iae);
+ } catch (NoSuchFieldException nsfe) {
+ throw new EIDASSAMLEngineException(nsfe);
+ }
+ }
+
+ public void addIDPRole() throws EIDASSAMLEngineException {
+ try {
+ if (idpSSODescriptor == null) {
+ idpSSODescriptor = BuilderFactoryUtil.buildXmlObject(IDPSSODescriptor.class);
+ }
+ } catch (IllegalAccessException iae) {
+ throw new EIDASSAMLEngineException(iae);
+ } catch (NoSuchFieldException nsfe) {
+ throw new EIDASSAMLEngineException(nsfe);
+ }
+ }
+
+ private void generateDigest(Extensions eidasExtensions) throws EIDASSAMLEngineException {
+ if (!StringUtils.isEmpty(params.getDigestMethods())) {
+ Set<String> signatureMethods = EIDASUtil.parseSemicolonSeparatedList(params.getDigestMethods());
+ Set<String> digestMethods = new HashSet<String>();
+ for (String signatureMethod : signatureMethods) {
+ digestMethods.add(CertificateUtil.validateDigestAlgorithm(signatureMethod));
+ }
+ for (String digestMethod : digestMethods) {
+ final DigestMethod dm = (DigestMethod) BuilderFactoryUtil.buildXmlObject(DigestMethod.DEF_ELEMENT_NAME);
+ if (dm != null) {
+ dm.setAlgorithm(digestMethod);
+ eidasExtensions.getUnknownXMLObjects().add(dm);
+ } else {
+ LOGGER.info("BUSINESS EXCEPTION error adding DigestMethod extension");
+ }
+ }
+ }
+
+ }
+
+ private Extensions generateExtensions() throws EIDASSAMLEngineException {
+ Extensions eidasExtensions = BuilderFactoryUtil.generateExtension();
+ if (params.getAssuranceLevel() != null) {
+ generateLoA(eidasExtensions);
+ }
+ if (!StringUtils.isEmpty(params.getSpType())) {
+ final SPType spTypeObj = (SPType) BuilderFactoryUtil.buildXmlObject(SPType.DEF_ELEMENT_NAME);
+ if (spTypeObj != null) {
+ spTypeObj.setSPType(params.getSpType());
+ eidasExtensions.getUnknownXMLObjects().add(spTypeObj);
+ } else {
+ LOGGER.info("BUSINESS EXCEPTION error adding SPType extension");
+ }
+ }
+ generateDigest(eidasExtensions);
+
+ if (!StringUtils.isEmpty(params.getSigningMethods())) {
+ Set<String> signMethods = EIDASUtil.parseSemicolonSeparatedList(params.getDigestMethods());
+ for (String signMethod : signMethods) {
+ final SigningMethod sm =
+ (SigningMethod) BuilderFactoryUtil.buildXmlObject(SigningMethod.DEF_ELEMENT_NAME);
+ if (sm != null) {
+ sm.setAlgorithm(signMethod);
+ eidasExtensions.getUnknownXMLObjects().add(sm);
+ } else {
+ LOGGER.info("BUSINESS EXCEPTION error adding SigningMethod extension");
+ }
+ }
+ }
+ return eidasExtensions;
+ }
+
+ private void generateLoA(Extensions eidasExtensions) throws EIDASSAMLEngineException {
+ EntityAttributes loa =
+ (EntityAttributes) BuilderFactoryUtil.buildXmlObject(EntityAttributes.DEFAULT_ELEMENT_NAME);
+ Attribute loaAttrib = (Attribute) BuilderFactoryUtil.buildXmlObject(Attribute.DEFAULT_ELEMENT_NAME);
+ loaAttrib.setName(EidasConstants.LEVEL_OF_ASSURANCE_NAME);
+ loaAttrib.setNameFormat(Attribute.URI_REFERENCE);
+ XSStringBuilder stringBuilder =
+ (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME);
+ XSString stringValue = stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME);
+ stringValue.setValue(params.getAssuranceLevel());
+ loaAttrib.getAttributeValues().add(stringValue);
+ loa.getAttributes().add(loaAttrib);
+ eidasExtensions.getUnknownXMLObjects().add(loa);
+
+ }
+
+ private static final Set<String> DEFAULT_BINDING = new HashSet<String>() {{
+ this.add(SAMLConstants.SAML2_POST_BINDING_URI);
+ }};
+
+ private void addAssertionConsumerService() throws EIDASSAMLEngineException {
+ int index = 0;
+ Set<String> bindings = params.getProtocolBinding().isEmpty() ? DEFAULT_BINDING : params.getProtocolBinding();
+ for (String binding : bindings) {
+ AssertionConsumerService asc = (AssertionConsumerService) BuilderFactoryUtil.buildXmlObject(
+ AssertionConsumerService.DEFAULT_ELEMENT_NAME);
+ asc.setLocation(params.getAssertionConsumerUrl());
+ asc.setBinding(checkBinding(binding));
+ asc.setIndex(index);
+ if (index == 0) {
+ asc.setIsDefault(true);
+ }
+ index++;
+ spSSODescriptor.getAssertionConsumerServices().add(asc);
+ }
+ }
+
+ private String checkBinding(String binding) {
+ if (binding != null && (binding.equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI) || binding.equals(
+ SAMLConstants.SAML2_POST_BINDING_URI))) {
+ return binding;
+ }
+ return SAMLConstants.SAML2_POST_BINDING_URI;
+ }
+
+ private DateTime getExpireDate() {
+ DateTime expiryDate = DateTime.now();
+ expiryDate =
+ expiryDate.withFieldAdded(DurationFieldType.seconds(), (int) (getConfigParams().getValidityDuration()));
+ return expiryDate;
+ }
+
+ private void generateSupportedAttributes(IDPSSODescriptor idpssoDescriptor,
+ ImmutableSortedSet<AttributeDefinition<?>> attributeDefinitions)
+ throws EIDASSAMLEngineException {
+ List<Attribute> attributes = idpssoDescriptor.getAttributes();
+ for (AttributeDefinition<?> attributeDefinition : attributeDefinitions) {
+ Attribute a = (Attribute) BuilderFactoryUtil.buildXmlObject(Attribute.DEFAULT_ELEMENT_NAME);
+ a.setName(attributeDefinition.getNameUri().toASCIIString());
+ a.setFriendlyName(attributeDefinition.getFriendlyName());
+ a.setNameFormat(Attribute.URI_REFERENCE);
+ attributes.add(a);
+ }
+ }
+
+}