/*
* 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.Iterator;
import java.util.List;
import java.util.Map;
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.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.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.OrganizationName;
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.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 com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Ordering;
import at.gv.egovernment.moa.logging.Logger;
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.SPType;
import eu.eidas.auth.engine.core.eidas.SigningMethod;
import eu.eidas.auth.engine.metadata.ContactData;
import eu.eidas.auth.engine.metadata.EidasMetadata;
import eu.eidas.auth.engine.metadata.MetadataConfigParams;
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.engine.exceptions.EIDASSAMLEngineException;
import eu.eidas.engine.exceptions.SAMLEngineException;
import eu.eidas.util.Preconditions;
/**
* @author tlenz
*
* MOA specific implementation of {@link EidasMetadata}
* This version fix some bugs
*
* - Does not add an encryption certificated to IDPSSODescriptor
* - Only set provideable eIDAS attributes to IDPSSODescriptor
* - SPSSODescriptor only requests 'persistent' subject nameIDs
*
*
*/
public class NewMoaEidasMetadata {
private final String metadata;
private final String entityId;
private static final Set DEFAULT_BINDING = new HashSet() {
};
private NewMoaEidasMetadata( Generator generator) throws EIDASSAMLEngineException {
this.entityId = generator.entityId;
this.metadata = generator.metadata;
}
public String getMetadata() {
return this.metadata;
}
public static Generator generator() {
return new Generator();
}
public static Generator generator( Generator copy) {
return new Generator(copy);
}
public static final class Generator {
private XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
private MetadataConfigParams params;
private SPSSODescriptor spSSODescriptor = null;
private IDPSSODescriptor idpSSODescriptor = null;
private String ssoLocation;
private String metadata;
private String entityId;
public Generator() {
}
public Generator( Generator copy) {
Preconditions.checkNotNull(copy, "copy");
this.params = copy.params;
this.spSSODescriptor = copy.spSSODescriptor;
this.idpSSODescriptor = copy.idpSSODescriptor;
this.ssoLocation = copy.ssoLocation;
this.entityId = copy.entityId;
}
public NewMoaEidasMetadata build() throws EIDASSAMLEngineException {
initialize();
this.entityId = this.params.getEntityID();
this.metadata = generateMetadata();
return new NewMoaEidasMetadata(this);
}
public Generator configParams(MetadataConfigParams params) {
this.params = params;
return this;
}
private void generateDigest(Extensions eidasExtensions) throws EIDASSAMLEngineException {
if (!(StringUtils.isEmpty(this.params.getSigningMethods()))) {
Set signatureMethods = EIDASUtil.parseSemicolonSeparatedList(this.params.getSigningMethods());
Set digestMethods = new HashSet();
for (String signatureMethod : signatureMethods) {
digestMethods.add(CertificateUtil.validateDigestAlgorithm(signatureMethod));
}
for (String digestMethod : digestMethods) {
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.generateMetadataExtension();
if (this.params.getAssuranceLevel() != null) {
generateLoA(eidasExtensions);
}
if (!(StringUtils.isEmpty(this.params.getSpType()))) {
SPType spTypeObj = (SPType) BuilderFactoryUtil.buildXmlObject(SPType.DEF_ELEMENT_NAME);
if (spTypeObj != null) {
spTypeObj.setSPType(this.params.getSpType());
eidasExtensions.getUnknownXMLObjects().add(spTypeObj);
} else {
Logger.info("BUSINESS EXCEPTION error adding SPType extension");
}
}
generateDigest(eidasExtensions);
if (!(StringUtils.isEmpty(this.params.getSigningMethods()))) {
Set signMethods = EIDASUtil.parseSemicolonSeparatedList(this.params.getSigningMethods());
for (String signMethod : signMethods) {
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("urn:oasis:names:tc:SAML:attribute:assurance-certification");
loaAttrib.setNameFormat("urn:oasis:names:tc:SAML:2.0:attrname-format:uri");
XSStringBuilder stringBuilder = (XSStringBuilder) Configuration.getBuilderFactory()
.getBuilder(XSString.TYPE_NAME);
XSString stringValue = (XSString) stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME,
XSString.TYPE_NAME);
stringValue.setValue(this.params.getAssuranceLevel());
loaAttrib.getAttributeValues().add(stringValue);
loa.getAttributes().add(loaAttrib);
eidasExtensions.getUnknownXMLObjects().add(loa);
}
private void addAssertionConsumerService() throws EIDASSAMLEngineException {
int index = 0;
Set bindings = (this.params.getProtocolBinding().isEmpty()) ? NewMoaEidasMetadata.DEFAULT_BINDING
: this.params.getProtocolBinding();
for (String binding : bindings) {
AssertionConsumerService asc = (AssertionConsumerService) BuilderFactoryUtil
.buildXmlObject(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
asc.setLocation(this.params.getAssertionConsumerUrl());
asc.setBinding(checkBinding(binding));
asc.setIndex(Integer.valueOf(index));
if (index == 0) {
asc.setIsDefault(Boolean.valueOf(true));
}
++index;
this.spSSODescriptor.getAssertionConsumerServices().add(asc);
}
}
private String checkBinding(String binding) {
if ((binding != null) && (((binding.equals("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"))
|| (binding.equals("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"))))) {
return binding;
}
return "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
}
private DateTime getExpireDate() {
DateTime expiryDate = DateTime.now();
expiryDate = expiryDate.withFieldAdded(DurationFieldType.seconds(),
(int) this.params.getValidityDuration());
return expiryDate;
}
private void generateSupportedAttributes(IDPSSODescriptor idpssoDescriptor,
ImmutableSortedSet> attributeDefinitions) throws EIDASSAMLEngineException {
List 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("urn:oasis:names:tc:SAML:2.0:attrname-format:uri");
attributes.add(a);
}
}
private void generateSPSSODescriptor(EntityDescriptor entityDescriptor,
X509KeyInfoGeneratorFactory keyInfoGeneratorFactory) throws SecurityException, IllegalAccessException,
NoSuchFieldException, SAMLEngineException, EIDASSAMLEngineException {
this.spSSODescriptor.setWantAssertionsSigned(Boolean.valueOf(this.params.isWantAssertionsSigned()));
this.spSSODescriptor.setAuthnRequestsSigned(Boolean.valueOf(true));
if (this.params.getSpSignature() != null) {
this.spSSODescriptor.setSignature(this.params.getSpSignature());
}
if (this.params.getSpSigningCredential() != null) {
this.spSSODescriptor.getKeyDescriptors().add(getKeyDescriptor(keyInfoGeneratorFactory,
this.params.getSpSigningCredential(), UsageType.SIGNING));
}
if (this.params.getSpEncryptionCredential() != null) {
this.spSSODescriptor.getKeyDescriptors().add(getKeyDescriptor(keyInfoGeneratorFactory,
this.params.getSpEncryptionCredential(), UsageType.ENCRYPTION));
}
this.spSSODescriptor.addSupportedProtocol(this.params.getSpSamlProtocol());
if (!(StringUtils.isEmpty(this.params.getAssertionConsumerUrl()))) {
addAssertionConsumerService();
}
//fillNameIDFormat(this.spSSODescriptor);
//FIX: Austrian eIDAS node SP only needs persistent identifiers
NameIDFormat persistentFormat =
(NameIDFormat) BuilderFactoryUtil.buildXmlObject(NameIDFormat.DEFAULT_ELEMENT_NAME);
persistentFormat.setFormat(SamlNameIdFormat.PERSISTENT.getNameIdFormat());
spSSODescriptor.getNameIDFormats().add(persistentFormat);
entityDescriptor.getRoleDescriptors().add(this.spSSODescriptor);
}
private void fillNameIDFormatIDP(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(EntityDescriptor entityDescriptor,
X509KeyInfoGeneratorFactory keyInfoGeneratorFactory) throws SecurityException, IllegalAccessException,
NoSuchFieldException, SAMLEngineException, EIDASSAMLEngineException {
this.idpSSODescriptor.setWantAuthnRequestsSigned(Boolean.valueOf(true));
if (this.params.getIdpSignature() != null) {
this.idpSSODescriptor.setSignature(this.params.getIdpSignature());
}
if (this.params.getIdpSigningCredential() != null) {
this.idpSSODescriptor.getKeyDescriptors().add(getKeyDescriptor(keyInfoGeneratorFactory,
this.params.getIdpSigningCredential(), UsageType.SIGNING));
}
//INFO: IDP requires no encryption certificate
// if (this.params.getIdpEncryptionCredential() != null) {
// this.idpSSODescriptor.getKeyDescriptors().add(getKeyDescriptor(keyInfoGeneratorFactory,
// this.params.getIdpEncryptionCredential(), UsageType.ENCRYPTION));
// }
this.idpSSODescriptor.addSupportedProtocol(this.params.getIdpSamlProtocol());
fillNameIDFormatIDP(this.idpSSODescriptor);
this.idpSSODescriptor.getSingleSignOnServices().addAll(buildSingleSignOnServicesBindingLocations());
if ((this.params.getIdpEngine() != null) && (this.params.getIdpEngine().getProtocolProcessor() != null)
&& (this.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(this.idpSSODescriptor, getAllSupportedAttributes());
}
entityDescriptor.getRoleDescriptors().add(this.idpSSODescriptor);
}
/* FIX: 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> getAllSupportedAttributes() {
ImmutableSortedSet.Builder> builder =
new ImmutableSortedSet.Builder<>(Ordering.>natural());
for (String attr : eIDASAttributeBuilder.getAllProvideableeIDASAttributes()) {
Logger.trace("Build metadata-attr: " + attr);
AttributeDefinition> supAttr = params.getIdpEngine().getProtocolProcessor().getAttributeDefinitionNullable(attr);
if (supAttr == null)
Logger.warn("Suspect eIDAS attribute definition: " + attr);
else
builder.add(supAttr);
}
return builder.build();
}
private ArrayList buildSingleSignOnServicesBindingLocations()
throws NoSuchFieldException, IllegalAccessException {
ArrayList singleSignOnServices = new ArrayList();
HashMap bindingLocations = this.params.getProtocolBindingLocation();
Iterator bindLocs = bindingLocations.entrySet().iterator();
while (bindLocs.hasNext()) {
Map.Entry bindingLoc = (Map.Entry) bindLocs.next();
SingleSignOnService ssos = (SingleSignOnService) BuilderFactoryUtil
.buildXmlObject(SingleSignOnService.class);
ssos.setBinding((String) bindingLoc.getKey());
ssos.setLocation((String) bindingLoc.getValue());
singleSignOnServices.add(ssos);
}
return singleSignOnServices;
}
private KeyDescriptor getKeyDescriptor(X509KeyInfoGeneratorFactory keyInfoGeneratorFactory,
Credential credential, UsageType usage)
throws NoSuchFieldException, IllegalAccessException, SecurityException, EIDASSAMLEngineException {
KeyDescriptor keyDescriptor = null;
if (credential != null) {
keyDescriptor = (KeyDescriptor) BuilderFactoryUtil.buildXmlObject(KeyDescriptor.class);
KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance();
KeyInfo keyInfo = keyInfoGenerator.generate(credential);
keyDescriptor.setUse(usage);
keyDescriptor.setKeyInfo(keyInfo);
if ((usage == UsageType.ENCRYPTION) && (this.params.getEncryptionAlgorithms() != null)) {
Set encryptionAlgos = EIDASUtil.parseSemicolonSeparatedList(this.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;
if (this.params.getOrganization() != null) {
try {
organization = (Organization) BuilderFactoryUtil.buildXmlObject(Organization.class);
OrganizationDisplayName odn = (OrganizationDisplayName) BuilderFactoryUtil
.buildXmlObject(OrganizationDisplayName.class);
odn.setName(new LocalizedString(this.params.getOrganization().getDisplayName(), "en"));
organization.getDisplayNames().add(odn);
OrganizationName on = (OrganizationName) BuilderFactoryUtil.buildXmlObject(OrganizationName.class);
on.setName(new LocalizedString(this.params.getOrganization().getName(), "en"));
organization.getOrganizationNames().add(on);
OrganizationURL url = (OrganizationURL) BuilderFactoryUtil.buildXmlObject(OrganizationURL.class);
url.setURL(new LocalizedString(this.params.getOrganization().getUrl(), "en"));
organization.getURLs().add(url);
} catch (IllegalAccessException iae) {
Logger.info("ERROR : error generating the OrganizationData: " + iae.getMessage());
Logger.warn("ERROR : error generating the OrganizationData:", iae);
} catch (NoSuchFieldException nfe) {
Logger.info("ERROR : error generating the OrganizationData: " + nfe.getMessage());
Logger.warn("ERROR : error generating the OrganizationData:", nfe);
}
}
return organization;
}
private ContactPerson buildContact(ContactPersonTypeEnumeration contactType) {
ContactPerson contact = null;
try {
ContactData currentContact = null;
if (contactType == ContactPersonTypeEnumeration.SUPPORT)
currentContact = this.params.getSupportContact();
else if (contactType == ContactPersonTypeEnumeration.TECHNICAL)
currentContact = this.params.getTechnicalContact();
else {
Logger.error("ERROR: unsupported contact type");
}
contact = (ContactPerson) BuilderFactoryUtil.buildXmlObject(ContactPerson.class);
if (currentContact == null) {
Logger.error("ERROR: cannot retrieve contact from the configuration");
return contact;
}
EmailAddress emailAddressObj = (EmailAddress) BuilderFactoryUtil.buildXmlObject(EmailAddress.class);
Company company = (Company) BuilderFactoryUtil.buildXmlObject(Company.class);
GivenName givenName = (GivenName) BuilderFactoryUtil.buildXmlObject(GivenName.class);
SurName surName = (SurName) BuilderFactoryUtil.buildXmlObject(SurName.class);
TelephoneNumber phoneNumber = (TelephoneNumber) 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 OrganizationData: " + iae.getMessage());
Logger.warn("ERROR : error generating the OrganizationData: ", iae);
} catch (NoSuchFieldException nfe) {
Logger.info("ERROR : error generating the OrganizationData: " + nfe.getMessage());
Logger.warn("ERROR : error generating the OrganizationData: ", nfe);
}
return contact;
}
private void populateContact(ContactPerson contact, ContactData 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);
}
private String generateMetadata() throws EIDASSAMLEngineException {
try {
EntityDescriptor entityDescriptor = (EntityDescriptor) this.builderFactory
.getBuilder(EntityDescriptor.DEFAULT_ELEMENT_NAME)
.buildObject(EntityDescriptor.DEFAULT_ELEMENT_NAME);
entityDescriptor.setEntityID(this.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 (this.spSSODescriptor != null) {
generateSPSSODescriptor(entityDescriptor, keyInfoGeneratorFactory);
}
if (this.idpSSODescriptor != null) {
generateIDPSSODescriptor(entityDescriptor, keyInfoGeneratorFactory);
}
if (this.params.getSpEngine() != null) {
ProtocolEngineI spEngine = this.params.getSpEngine();
((MetadataSignerI) spEngine.getSigner()).signMetadata(entityDescriptor);
} else if (this.params.getIdpEngine() != null) {
ProtocolEngineI idpEngine = this.params.getIdpEngine();
((MetadataSignerI) idpEngine.getSigner()).signMetadata(entityDescriptor);
}
return EidasStringUtil.toString(OpenSamlHelper.marshall(entityDescriptor, false));
} catch (Exception ex) {
Logger.info("ERROR : SAMLException: " + ex.getMessage());
Logger.warn("ERROR : SAMLException ", ex);
throw new IllegalStateException(ex);
}
}
private void initialize() throws EIDASSAMLEngineException {
ProtocolEngineI idpEngine = this.params.getIdpEngine();
ProtocolEngineI spEngine = this.params.getSpEngine();
MetadataConfigParams.Builder initParamBuilder = MetadataConfigParams.builder(this.params);
if (idpEngine != null) {
idpEngine.getProtocolProcessor().configure();
initParamBuilder.idpSigningCredential(CertificateUtil.toCredential(idpEngine.getSigningCertificate()));
X509Certificate idpEngineDecryptionCertificate = idpEngine.getDecryptionCertificate();
if (idpEngineDecryptionCertificate != null) {
initParamBuilder
.idpEncryptionCredential(CertificateUtil.toCredential(idpEngineDecryptionCertificate));
}
if (this.idpSSODescriptor == null) {
try {
this.idpSSODescriptor = ((IDPSSODescriptor) BuilderFactoryUtil
.buildXmlObject(IDPSSODescriptor.class));
} catch (NoSuchFieldException e) {
throw new EIDASSAMLEngineException(e);
} catch (IllegalAccessException e) {
throw new EIDASSAMLEngineException(e);
}
}
}
if (spEngine != null) {
spEngine.getProtocolProcessor().configure();
initParamBuilder.spSigningCredential(CertificateUtil.toCredential(spEngine.getSigningCertificate()));
X509Certificate spEngineDecryptionCertificate = spEngine.getDecryptionCertificate();
if (spEngineDecryptionCertificate != null) {
initParamBuilder
.spEncryptionCredential(CertificateUtil.toCredential(spEngineDecryptionCertificate));
}
if (this.spSSODescriptor == null) {
try {
this.spSSODescriptor = ((SPSSODescriptor) BuilderFactoryUtil
.buildXmlObject(SPSSODescriptor.class));
} catch (NoSuchFieldException e) {
throw new EIDASSAMLEngineException(e);
} catch (IllegalAccessException e) {
throw new EIDASSAMLEngineException(e);
}
}
}
this.params = initParamBuilder.build();
}
}
}