aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-eIDAS/src
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/modules/moa-id-module-eIDAS/src')
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java52
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAExtendedSWSigner.java11
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOASWSigner.java8
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java6
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java21
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAProtocolEngine.java105
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java180
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java18
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/validation/MoaEidasConditionsValidator.java4
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java4
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java3
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java50
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java1356
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/NewMoaEidasMetadata.java602
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java39
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/eIDASAttributeBuilder.java174
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java4
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java10
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java83
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/IeIDASAttribute.java33
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrDateOfBirth.java37
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrFamilyName.java61
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrGivenName.java61
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrLegalName.java37
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrLegalPersonIdentifier.java37
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrNaturalPersonalIdentifier.java116
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java149
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder6
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.IeIDASAttribute6
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/resources/schema/eIDAS_saml_extensions.xsd31
30 files changed, 2269 insertions, 1035 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 369d77863..c0101b553 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
@@ -25,10 +25,6 @@ package at.gv.egovernment.moa.id.auth.modules.eidas;
import org.apache.xml.security.signature.XMLSignature;
import org.opensaml.xml.encryption.EncryptionConstants;
import org.opensaml.xml.signature.SignatureConstants;
-//import eu.eidas.auth.engine.core.validator.eidas.EIDASAttributes;
-
-import eu.eidas.auth.commons.attribute.AttributeRegistries;
-import eu.eidas.auth.commons.attribute.AttributeRegistry;
/**
* @author tlenz
@@ -61,17 +57,23 @@ public class Constants {
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_SAMLENGINE_ATTIONAL_ATTRIBUTE_DEFINITIONS =
+ CONIG_PROPS_EIDAS_SAMLENGINE_PREFIX + ".attributes.addition.config";
public static final String CONIG_PROPS_EIDAS_METADATA_VALIDATION_TRUSTSTORE = CONIG_PROPS_EIDAS_PREFIX + ".metadata.validation.truststore";
+
public static final String CONIG_PROPS_EIDAS_NODE_COUNTRYCODE = CONIG_PROPS_EIDAS_NODE + ".countrycode";
public static final String CONIG_PROPS_EIDAS_NODE_COUNTRY = CONIG_PROPS_EIDAS_NODE + ".country";
- public static final String CONIG_PROPS_EIDAS_NODE_LoA = CONIG_PROPS_EIDAS_NODE + ".LoA";
+ public static final String CONIG_PROPS_EIDAS_NODE_LoA = CONIG_PROPS_EIDAS_NODE + ".LoA";
+
+ public static final String CONIG_PROPS_EIDAS_METADATA_URLS_LIST_PREFIX = CONIG_PROPS_EIDAS_PREFIX + ".metadata.url";
+
//timeouts and clock skews
- public static final int CONFIG_PROPS_SKEWTIME = 2 * 60 * 1000; //2 minutes skew time for response validation
- public static final int CONFIG_PROPS_METADATA_SOCKED_TIMEOUT = 20 * 1000; //20 seconds metadata socked timeout
+ public static final long CONFIG_PROPS_SKEWTIME_BEFORE = -2 * 60 * 1000; //5 minutes skew time for response validation
+ public static final long CONFIG_PROPS_SKEWTIME_AFTER = 2 * 60 * 1000; //5 minutes skew time for response validation
public static final long CONFIG_PROPS_METADATA_GARBAGE_TIMEOUT = 7 * 24 * 60 * 60 * 1000; //remove unused eIDAS metadata after 7 days
//eIDAS request parameters
@@ -88,8 +90,6 @@ public class Constants {
//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_IDP_COLLEAGUEREQUEST = "/eidas/ColleagueRequest";
public static final String eIDAS_HTTP_ENDPOINT_METADATA = "/eidas/metadata";
@@ -99,38 +99,6 @@ public class Constants {
public static final int eIDAS_REVERSIONSLOG_IDP_AUTHREQUEST = 3401;
public static final int eIDAS_REVERSIONSLOG_IDP_AUTHRESPONSE = 3402;
- //metadata constants
-// public final static Map<String, EidasAttributesTypes> METADATA_POSSIBLE_ATTRIBUTES = Collections.unmodifiableMap(
-// new HashMap<String, EidasAttributesTypes>(){
-// private static final long serialVersionUID = 1L;
-// {
-// put(EIDASAttributes.ATTRIBUTE_GIVENNAME, EidasAttributesTypes.NATURAL_PERSON_MANDATORY);
-// put(EIDASAttributes.ATTRIBUTE_FIRSTNAME, EidasAttributesTypes.NATURAL_PERSON_MANDATORY);
-// put(EIDASAttributes.ATTRIBUTE_DATEOFBIRTH, EidasAttributesTypes.NATURAL_PERSON_MANDATORY);
-// put(EIDASAttributes.ATTRIBUTE_PERSONIDENTIFIER, EidasAttributesTypes.NATURAL_PERSON_MANDATORY);
-//
-// //TODO: add additional attributes for eIDAS with mandates
-// //put(EIDASAttributes.ATTRIBUTE_LEGALIDENTIFIER, EidasAttributesTypes.LEGAL_PERSON_MANDATORY);
-// //put(EIDASAttributes.ATTRIBUTE_LEGALNAME, EidasAttributesTypes.LEGAL_PERSON_MANDATORY);
-// }
-// }
-// );
-
- public static final AttributeRegistry NAT_ATTR =
- AttributeRegistries.of( eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.PERSON_IDENTIFIER,
- eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_FAMILY_NAME,
- eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_GIVEN_NAME,
- eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.DATE_OF_BIRTH
- );
-
- public static final AttributeRegistry LEGAL_ATTR =
- AttributeRegistries.of( eu.eidas.auth.engine.core.eidas.spec.LegalPersonSpec.Definitions.LEGAL_PERSON_IDENTIFIER,
- eu.eidas.auth.engine.core.eidas.spec.LegalPersonSpec.Definitions.LEGAL_NAME
- );
-
- public static final AttributeRegistry MOA_IDP_ATTR_REGISTRY =
- AttributeRegistries.copyOf(NAT_ATTR, LEGAL_ATTR);
-
public static final String METADATA_ALLOWED_ALG_DIGIST =
SignatureConstants.ALGO_ID_DIGEST_SHA256 + ";" +
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAExtendedSWSigner.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAExtendedSWSigner.java
index e08d302f6..6a48e5030 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAExtendedSWSigner.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAExtendedSWSigner.java
@@ -98,8 +98,11 @@ public class MOAExtendedSWSigner implements ProtocolSignerI, MetadataSignerI {
private final ImmutableList<X509Credential> trustedCredentials;
private final String signatureAlgorithm;
- public MOAExtendedSWSigner(Map<String, String> properties) throws SamlEngineConfigurationException {
- this(new KeyStoreSignatureConfigurator().getSignatureConfiguration(properties));
+
+ //TODO: check if it is required any more
+
+ public MOAExtendedSWSigner(Map<String, String> properties, String defaultConfigPath) throws SamlEngineConfigurationException {
+ this(new KeyStoreSignatureConfigurator().getSignatureConfiguration(properties, null));
}
@@ -109,7 +112,7 @@ public class MOAExtendedSWSigner implements ProtocolSignerI, MetadataSignerI {
*/
public MOAExtendedSWSigner(CertificateConfigurationManager configManager) throws SamlEngineConfigurationException {
this(new KeyStoreSignatureConfigurator().getSignatureConfiguration(
- ConfigurationAdapter.adapt(configManager).getInstances().get(Constants.eIDAS_SAML_ENGINE_NAME).getConfigurationEntries().get(ConfigurationKey.SIGNATURE_CONFIGURATION.getKey()).getParameters()));
+ ConfigurationAdapter.adapt(configManager).getInstances().get(Constants.eIDAS_SAML_ENGINE_NAME).getConfigurationEntries().get(ConfigurationKey.SIGNATURE_CONFIGURATION.getKey()).getParameters(), null));
}
@@ -226,7 +229,7 @@ public class MOAExtendedSWSigner implements ProtocolSignerI, MetadataSignerI {
checkCertificateIssuer(credential.getEntityCertificate());
Signature signature;
try {
- Logger.debug("Creating an OpenSAML signature object");
+ Logger.trace("Creating an OpenSAML signature object");
signature = (Signature) Configuration.getBuilderFactory().getBuilder(Signature.DEFAULT_ELEMENT_NAME)
.buildObject(Signature.DEFAULT_ELEMENT_NAME);
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 5cf5e83ec..3cc9787df 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
@@ -79,8 +79,8 @@ public class MOASWSigner extends KeyStoreProtocolSigner {
//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);
+ public MOASWSigner(Map<String, String> properties, String defaultConfigPath) throws SamlEngineConfigurationException {
+ super(properties, null);
props = properties;
}
@@ -90,7 +90,7 @@ public class MOASWSigner extends KeyStoreProtocolSigner {
* @throws SamlEngineConfigurationException
*/
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());
+ super(props = ConfigurationAdapter.adapt(configManager).getInstances().get(Constants.eIDAS_SAML_ENGINE_NAME).getConfigurationEntries().get(ConfigurationKey.SIGNATURE_CONFIGURATION.getKey()).getParameters(), null);
}
@@ -100,7 +100,7 @@ public class MOASWSigner extends KeyStoreProtocolSigner {
if (sigAlgWhiteList == null) {
sigAlgWhiteList = MOAWhiteListConfigurator.getAllowedAlgorithms(DEFAULT_ALGORITHM_WHITE_LIST,
ALLOWED_ALGORITHMS_FOR_VERIFYING,
- (new KeyStoreSignatureConfigurator().getSignatureConfiguration(props)).getSignatureAlgorithmWhiteList());
+ (new KeyStoreSignatureConfigurator().getSignatureConfiguration(props, null)).getSignatureAlgorithmWhiteList());
}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java
index de4f3fc9c..d5cbb2cfd 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java
@@ -33,15 +33,15 @@ public class ModifiedEncryptionSW extends KeyStoreSamlEngineEncryption {
private static ReloadableProperties initActivationConf(Map<String, String> properties) {
String activationConfigurationFile = EncryptionKey.ENCRYPTION_ACTIVATION.getAsString(properties);
Logger.debug("File containing encryption configuration: \"" + activationConfigurationFile + "\"");
- return new ReloadableProperties(activationConfigurationFile);
+ return new ReloadableProperties(activationConfigurationFile, null);
}
/**
* @param properties
* @throws SamlEngineConfigurationException
*/
- public ModifiedEncryptionSW(Map<String, String> properties) throws SamlEngineConfigurationException {
- super(properties);
+ public ModifiedEncryptionSW(Map<String, String> properties, String defaultConfigPath) throws SamlEngineConfigurationException {
+ super(properties, null);
this.properties = ImmutableMap.copyOf(properties);
encryptionActivationProperties = initActivationConf(properties);
}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java
index c24c5efca..28d74075e 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java
@@ -22,7 +22,9 @@
*/
package at.gv.egovernment.moa.id.auth.modules.eidas.engine;
+import eu.eidas.auth.commons.attribute.AttributeRegistry;
import eu.eidas.auth.engine.core.eidas.EidasProtocolProcessor;
+import eu.eidas.auth.engine.core.eidas.spec.EidasSpec;
import eu.eidas.auth.engine.metadata.MetadataFetcherI;
import eu.eidas.auth.engine.metadata.MetadataSignerI;
@@ -38,11 +40,14 @@ public class MOAEidasProtocolProcesser extends EidasProtocolProcessor {
private final MetadataSignerI metadataSigner;
/**
- * @param metadataFetcher
- * @param metadataSigner
+ * Build a MOA specific eIDAS-engine protocol processor
+ *
+ * @param metadataFetcher eIDAS-engine Metadata fetcher implementation
+ * @param metadataSigner eIDAS-engine Signer implementation
+ * @param addAttrDefinitions additinal eIDAS attributes
*/
- public MOAEidasProtocolProcesser(MetadataFetcherI metadataFetcher, MetadataSignerI metadataSigner) {
- super(metadataFetcher, metadataSigner);
+ public MOAEidasProtocolProcesser(MetadataFetcherI metadataFetcher, MetadataSignerI metadataSigner, AttributeRegistry addAttrDefinitions) {
+ super(EidasSpec.REGISTRY, addAttrDefinitions, metadataFetcher, metadataSigner);
this.metadataFetcher = metadataFetcher;
this.metadataSigner = metadataSigner;
@@ -53,5 +58,11 @@ public class MOAEidasProtocolProcesser extends EidasProtocolProcessor {
public String getResponseValidatorId() {
return OWN_EIDAS_RESPONSE_VALIDATOR_SUITE_ID;
}
-
+
+
+ public MetadataFetcherI getMetadataFetcher() {
+ return this.metadataFetcher;
+ }
+
+
}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAProtocolEngine.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAProtocolEngine.java
index d8fcd1694..f347022b8 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAProtocolEngine.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAProtocolEngine.java
@@ -1,16 +1,17 @@
package at.gv.egovernment.moa.id.auth.modules.eidas.engine;
-import java.security.cert.X509Certificate;
-
-import org.apache.commons.lang3.StringUtils;
+import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.core.Response;
+import org.w3c.dom.Document;
import at.gv.egovernment.moa.logging.Logger;
-import eu.eidas.auth.commons.EidasErrorKey;
-import eu.eidas.auth.commons.protocol.IAuthenticationRequest;
+import at.gv.egovernment.moa.util.MiscUtil;
+import eu.eidas.auth.engine.Correlated;
import eu.eidas.auth.engine.ProtocolEngine;
import eu.eidas.auth.engine.configuration.ProtocolConfigurationAccessor;
-import eu.eidas.auth.engine.xml.opensaml.SAMLEngineUtils;
+import eu.eidas.auth.engine.core.ProtocolProcessorI;
+import eu.eidas.auth.engine.metadata.MetadataFetcherI;
+import eu.eidas.auth.engine.xml.opensaml.XmlSchemaUtil;
import eu.eidas.engine.exceptions.EIDASSAMLEngineException;
public class MOAProtocolEngine extends ProtocolEngine {
@@ -20,6 +21,98 @@ public class MOAProtocolEngine extends ProtocolEngine {
}
+ /**
+ * Add SAML2 metadata refresh functionality if first validation failed
+ *
+ */
+ @Override
+ public Correlated unmarshallResponse(byte[] responseBytes) throws EIDASSAMLEngineException {
+ try {
+ return super.unmarshallResponse(responseBytes);
+
+ } catch (EIDASSAMLEngineException e) {
+ if (responseBytes != null ) {
+ Logger.info("eIDAS Response validation FAILED. Starting metadata reloading process ...");
+ Document document = XmlSchemaUtil.validateSamlSchema(responseBytes);
+ Response response = (Response) unmarshall(document);
+ String entityID = response.getIssuer().getValue();
+
+ if (MiscUtil.isEmpty(entityID)) {
+ Logger.debug("eIDAS Response contains no EntityID.");
+ throw e;
+
+ }
+
+ if (startInternalMetadataRefesh(entityID)) {
+ Logger.debug("Metadata refresh success. Revalidate eIDAS Response ...");
+ return super.unmarshallResponse(responseBytes);
+
+ }
+ Logger.info("eIDAS metadata refresh not possible or not successful.");
+
+ }
+ throw e;
+
+ }
+ }
+
+ /**
+ * Add SAML2 metadata refresh functionality if first validation failed
+ *
+ */
+ @Override
+ public AuthnRequest unmarshallRequest(byte[] requestBytes) throws EIDASSAMLEngineException {
+ try {
+ return super.unmarshallRequest(requestBytes);
+
+
+ } catch (EIDASSAMLEngineException e) {
+ if (null != requestBytes) {
+ Logger.info("eIDAS Request validation FAILED. Starting metadata reloading process ...");
+ Document document = XmlSchemaUtil.validateSamlSchema(requestBytes);
+ AuthnRequest request = (AuthnRequest) unmarshall(document);
+ String entityID = request.getIssuer().getValue();
+
+ if (MiscUtil.isEmpty(entityID)) {
+ Logger.debug("eIDAS Authn. Request contains no EntityID.");
+ throw e;
+
+ }
+
+ if (startInternalMetadataRefesh(entityID)) {
+ Logger.debug("Metadata refresh success. Revalidate eIDAS Authn. Request ...");
+ return super.unmarshallRequest(requestBytes);
+
+ }
+
+ Logger.info("eIDAS metadata refresh not possible or not successful.");
+ }
+
+ throw e;
+
+ }
+ }
+
+ /**
+ * Refresh SAML2 metadata if the internal metadata provider supports this functionality
+ *
+ * @param entityID
+ * @return true if refresh was success, otherwise false
+ */
+ private boolean startInternalMetadataRefesh(String entityID) {
+ //check if eIDAS SAML-Engine implementation supports metadata refresh
+ ProtocolProcessorI protocolProcessor = this.getProtocolProcessor();
+ if (protocolProcessor instanceof MOAEidasProtocolProcesser) {
+ MetadataFetcherI metadataFetcher =
+ ((MOAEidasProtocolProcesser)protocolProcessor).getMetadataFetcher();
+ if (metadataFetcher instanceof MOAeIDASMetadataProviderDecorator)
+ return ((MOAeIDASMetadataProviderDecorator)metadataFetcher).refreshMetadata(entityID);
+
+ }
+
+ return false;
+ }
+
// @Override
// protected X509Certificate getEncryptionCertificate(String requestIssuer,
// String destinationCountryCode) throws EIDASSAMLEngineException {
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
index ffa74b92b..490dc9dcf 100644
--- 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
@@ -9,15 +9,13 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Timer;
-import javax.net.ssl.SSLHandshakeException;
import javax.xml.namespace.QName;
-import org.apache.commons.httpclient.MOAHttpClient;
-import org.apache.commons.httpclient.params.HttpClientParams;
import org.opensaml.saml2.metadata.EntitiesDescriptor;
import org.opensaml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml2.metadata.RoleDescriptor;
import org.opensaml.saml2.metadata.provider.ChainingMetadataProvider;
+import org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider;
import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider;
import org.opensaml.saml2.metadata.provider.MetadataFilter;
import org.opensaml.saml2.metadata.provider.MetadataProvider;
@@ -28,25 +26,22 @@ import org.springframework.stereotype.Service;
import at.gv.egovernment.moa.id.auth.IDestroyableObject;
import at.gv.egovernment.moa.id.auth.IGarbageCollectorProcessing;
+import at.gv.egovernment.moa.id.auth.IPostStartupInitializable;
import at.gv.egovernment.moa.id.auth.modules.eidas.Constants;
-import at.gv.egovernment.moa.id.commons.api.AuthConfiguration;
-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.AuthConfigurationProviderFactory;
-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.metadata.IMOARefreshableMetadataProvider;
+import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.SimpleMOAMetadataProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.MOASPMetadataSignatureFilter;
import at.gv.egovernment.moa.id.saml2.MetadataFilterChain;
import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.FileUtils;
import at.gv.egovernment.moa.util.MiscUtil;
import eu.eidas.auth.engine.AbstractProtocolEngine;
@Service("eIDASMetadataProvider")
-public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvider,
- IGarbageCollectorProcessing, IDestroyableObject {
+public class MOAeIDASChainingMetadataProvider extends SimpleMOAMetadataProvider implements ObservableMetadataProvider,
+ IGarbageCollectorProcessing, IDestroyableObject, IMOARefreshableMetadataProvider, IPostStartupInitializable{
-// private static MOAeIDASChainingMetadataProvider instance = null;
- private static Object mutex = new Object();
+ private Timer timer = null;
private MetadataProvider internalProvider;
private Map<String, Date> lastAccess = null;
@@ -70,12 +65,41 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi
lastAccess = new HashMap<String, Date>();
}
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.IPostStartupInitializable#executeAfterStartup()
+ */
+ @Override
+ public void executeAfterStartup() {
+ initializeEidasMetadataFromFileSystem();
+
+ }
+
+ protected void initializeEidasMetadataFromFileSystem() {
+ Map<String, String> metadataToLoad = authConfig.getBasicMOAIDConfigurationWithPrefix(Constants.CONIG_PROPS_EIDAS_METADATA_URLS_LIST_PREFIX);
+ if (!metadataToLoad.isEmpty()) {
+ Logger.info("Load static configurated eIDAS metadata ... ");
+ for (String metaatalocation : metadataToLoad.values()) {
+ String absMetadataLocation = FileUtils.makeAbsoluteURL(metaatalocation, authConfig.getRootConfigFileDir());
+ Logger.info(" Load eIDAS metadata from: " + absMetadataLocation);
+ refreshMetadataProvider(absMetadataLocation);
+
+ }
+
+ Logger.info("Load static configurated eIDAS metadata finished ");
+ }
+ }
+
/* (non-Javadoc)
* @see at.gv.egovernment.moa.id.auth.IDestroyableObject#fullyDestroy()
*/
@Override
public void fullyDestroy() {
+
+ if (timer != null)
+ timer.cancel();
+
Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders();
if (loadedproviders != null) {
for (Entry<String, HTTPMetadataProvider> el : loadedproviders.entrySet()) {
@@ -140,8 +164,8 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi
+ " after timeout.");
} else
- Logger.warn("eIDAS metadata for EntityID: " + expired
- + " is marked as unsed, but no loaded metadata provider is found.");
+ Logger.info("eIDAS metadata for EntityID: " + expired
+ + " is marked as expired, but no currently loaded HTTPMetadataProvider metadata provider is found.");
}
}
@@ -187,108 +211,50 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi
}
}
-
-
- 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 {
- //FIX: change hostname validation default flag to true when httpClient is updated to > 4.4
- MOAHttpProtocolSocketFactory protoSocketFactory = new MOAHttpProtocolSocketFactory(
- Constants.SSLSOCKETFACTORYNAME,
- authConfig.getTrustedCACertificates(),
- null,
- AuthConfiguration.DEFAULT_X509_CHAININGMODE,
- authConfig.isTrustmanagerrevoationchecking(),
- authConfig.getRevocationMethodOrder(),
- authConfig.getBasicMOAIDConfigurationBoolean(
- AuthConfiguration.PROP_KEY_SSL_HOSTNAME_VALIDATION, false));
-
- httpClient.setCustomSSLTrustStore(metadataURL, protoSocketFactory);
-
- } catch (MOAHttpProtocolSocketFactoryException e) {
- Logger.warn("MOA SSL-TrustStore can not initialized. Use default Java TrustStore.");
-
- }
- }
-
+
+ private MetadataProvider createNewHTTPMetaDataProvider(String metadataURL) {
+ if (timer == null)
timer = new Timer(true);
- httpProvider = new HTTPMetadataProvider(timer, httpClient,
- metadataURL);
- httpProvider.setParserPool(AbstractProtocolEngine.getSecuredParserPool());
- 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 MOASPMetadataSignatureFilter(
- 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;
+ //add Metadata filters
+ MetadataFilterChain filter = new MetadataFilterChain();
+ filter.addFilter(new MOASPMetadataSignatureFilter(
+ authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_METADATA_VALIDATION_TRUSTSTORE)));
+
+ return createNewMoaMetadataProvider(metadataURL, filter,
+ "eIDAS metadata-provider",
+ timer, AbstractProtocolEngine.getSecuredParserPool());
+
}
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);
-
- }
+
+ } else if (provider instanceof FilesystemMetadataProvider) {
+ String entityID = "'!!NO-ENTITYID!!'";
+ try {
+ if (provider.getMetadata() instanceof EntityDescriptor)
+ entityID = ((EntityDescriptor)provider.getMetadata()).getEntityID();
+
+ Logger.debug("Skip eIDAS metadata: " + entityID + " because it is loaded from local Filesystem");
+
+ } catch (MetadataProviderException e) {
+ Logger.info("Collect currently loaded eIDAS metadata provider has an internel process error: " + e.getMessage());
+
+ }
+
+ } else
+ Logger.info("Skip " + provider.getClass().getName() + " from list of currently loaded "
+ + "eIDAS metadata provider");
+
}
return loadedproviders;
@@ -309,7 +275,7 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi
} else {
//load new Metadata Provider
ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider;
- HTTPMetadataProvider newMetadataProvider = createNewHTTPMetaDataProvider(metadataURL);
+ MetadataProvider newMetadataProvider = createNewHTTPMetaDataProvider(metadataURL);
if (newMetadataProvider != null) {
chainProvider.addMetadataProvider(newMetadataProvider);
@@ -319,7 +285,8 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi
+ metadataURL + " is added.");
return true;
- }
+ } else
+ Logger.warn("Can not load eIDAS metadata from URL: " + metadataURL);
}
} else
@@ -435,4 +402,5 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi
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
index c5e56502b..9adc221e5 100644
--- 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
@@ -31,6 +31,7 @@ import org.opensaml.saml2.metadata.SPSSODescriptor;
import org.opensaml.saml2.metadata.provider.MetadataProvider;
import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IMOARefreshableMetadataProvider;
import eu.eidas.auth.engine.ProtocolEngineI;
import eu.eidas.auth.engine.metadata.MetadataFetcherI;
import eu.eidas.auth.engine.metadata.MetadataSignerI;
@@ -54,6 +55,23 @@ public class MOAeIDASMetadataProviderDecorator implements MetadataFetcherI {
}
+ /**
+ * Refresh the SAML2 metadata of a specific Entity
+ * <br>
+ * <b>Info:</b> A refresh is only possible if the internal metadata provider implements
+ * the 'RefeshableMetadataProvider' interface
+ *
+ * @param entityId EntityID that should be refreshed
+ * @return true if refresh was successful, otherwise false
+ */
+ public boolean refreshMetadata(String entityId) {
+ if (this.metadataprovider instanceof IMOARefreshableMetadataProvider )
+ return ((IMOARefreshableMetadataProvider)this.metadataprovider).refreshMetadataProvider(entityId);
+ else
+ return false;
+
+ }
+
/* (non-Javadoc)
* @see eu.eidas.auth.engine.metadata.MetadataFetcherI#getEntityDescriptor(java.lang.String, eu.eidas.auth.engine.metadata.MetadataSignerI)
*/
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/validation/MoaEidasConditionsValidator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/validation/MoaEidasConditionsValidator.java
index d9453322f..9895ca79f 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/validation/MoaEidasConditionsValidator.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/validation/MoaEidasConditionsValidator.java
@@ -56,7 +56,7 @@ public class MoaEidasConditionsValidator extends ConditionsSpecValidator {
throw new ValidationException("NotBefore is required.");
}
- if (conditions.getNotBefore().minusMillis(Constants.CONFIG_PROPS_SKEWTIME).isAfterNow()) {
+ if (conditions.getNotBefore().plusMillis((int)Constants.CONFIG_PROPS_SKEWTIME_BEFORE).isAfterNow()) {
throw new ValidationException("Current time is before NotBefore condition");
}
@@ -64,7 +64,7 @@ public class MoaEidasConditionsValidator extends ConditionsSpecValidator {
throw new ValidationException("NotOnOrAfter is required.");
}
- if (conditions.getNotOnOrAfter().isBeforeNow()) {
+ if (conditions.getNotOnOrAfter().plusMillis((int)Constants.CONFIG_PROPS_SKEWTIME_AFTER).isBeforeNow()) {
throw new ValidationException("Current time is after NotOnOrAfter condition");
}
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 7155040c6..6f1d75bfe 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
@@ -228,9 +228,9 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask {
//set correct SPType for this online application
if (oaConfig.getBusinessService())
- authnRequestBuilder.spType(SpType.PRIVATE);
+ authnRequestBuilder.spType(SpType.PRIVATE.getValue());
else
- authnRequestBuilder.spType(SpType.PUBLIC);
+ authnRequestBuilder.spType(SpType.PUBLIC.getValue());
//set service provider (eIDAS node) countryCode
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java
index 45ba3d64e..17e112c4c 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java
@@ -57,7 +57,8 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask {
//validate SAML token
IAuthenticationResponse samlResp = engine.unmarshallResponseAndValidate(decSamlToken,
request.getRemoteHost(),
- Constants.CONFIG_PROPS_SKEWTIME,
+ Constants.CONFIG_PROPS_SKEWTIME_BEFORE,
+ Constants.CONFIG_PROPS_SKEWTIME_AFTER,
pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA);
if (samlResp.isEncrypted()) {
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java
index 47cdb4ade..dbe11c12e 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java
@@ -23,10 +23,16 @@
package at.gv.egovernment.moa.id.auth.modules.eidas.utils;
import at.gv.egovernment.moa.id.auth.modules.eidas.config.MOAIDCertificateManagerConfigurationImpl;
+import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAProtocolEngine;
import at.gv.egovernment.moa.logging.Logger;
import eu.eidas.auth.engine.ProtocolEngineFactory;
+import eu.eidas.auth.engine.ProtocolEngineI;
+import eu.eidas.auth.engine.SamlEngineClock;
+import eu.eidas.auth.engine.configuration.FixedProtocolConfigurationAccessor;
+import eu.eidas.auth.engine.configuration.ProtocolEngineConfiguration;
import eu.eidas.auth.engine.configuration.SamlEngineConfigurationException;
import eu.eidas.auth.engine.configuration.dom.ProtocolEngineConfigurationFactory;
+import eu.eidas.auth.engine.core.ProtocolProcessorI;
import eu.eidas.samlengineconfig.CertificateConfigurationManager;
/**
@@ -95,22 +101,32 @@ public class MOAProtocolEngineFactory extends ProtocolEngineFactory {
}
-// public static ProtocolEngineI createProtocolEngine(String instanceName,
-// ProtocolEngineConfigurationFactory protocolEngineConfigurationFactory,
-// ProtocolProcessorI protocolProcessor, SamlEngineClock samlEngineClock)
-// throws SamlEngineConfigurationException {
-//
-// ProtocolEngineConfiguration preConfiguration = protocolEngineConfigurationFactory
-// .getConfiguration(instanceName);
-//
-// protocolProcessor.configure();
-//
-// ProtocolEngineConfiguration configuration = ProtocolEngineConfiguration.builder(preConfiguration)
-// .protocolProcessor(protocolProcessor).clock(samlEngineClock).build();
-//
-// ProtocolEngineI samlEngine = new MOAProtocolEngine(new FixedProtocolConfigurationAccessor(configuration));
-//
-// return samlEngine;
-// }
+ public static ProtocolEngineI ownCreateProtocolEngine(String instanceName,
+ CertificateConfigurationManager configManager, ProtocolProcessorI protocolProcessor,
+ SamlEngineClock samlEngineClock) throws SamlEngineConfigurationException {
+ ProtocolEngineConfigurationFactory protocolEngineConfigurationFactory = new ProtocolEngineConfigurationFactory(
+ configManager);
+
+ return createProtocolEngine(instanceName, protocolEngineConfigurationFactory, protocolProcessor,
+ samlEngineClock);
+ }
+
+ public static ProtocolEngineI createProtocolEngine(String instanceName,
+ ProtocolEngineConfigurationFactory protocolEngineConfigurationFactory,
+ ProtocolProcessorI protocolProcessor, SamlEngineClock samlEngineClock)
+ throws SamlEngineConfigurationException {
+
+ ProtocolEngineConfiguration preConfiguration = protocolEngineConfigurationFactory
+ .getConfiguration(instanceName);
+
+ protocolProcessor.configure();
+
+ ProtocolEngineConfiguration configuration = ProtocolEngineConfiguration.builder(preConfiguration)
+ .protocolProcessor(protocolProcessor).clock(samlEngineClock).build();
+
+ ProtocolEngineI samlEngine = new MOAProtocolEngine(new FixedProtocolConfigurationAccessor(configuration));
+
+ return samlEngine;
+ }
}
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 8faaf1874..9683db503 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
@@ -1,675 +1,681 @@
-/*
- * 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.common.impl.ExtensionsBuilder;
-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.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.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 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;
-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());
-
- /**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();
- 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);
-
-
- /**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());
- }
- 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);
-
- /**FIXME:
- * Double signing of SPSSODescribtor is not required
- */
-// 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);
-
- /**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());
- }
- 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());
- }
-
-
- /**FIXME:
- * Double signing of IDPSSODescribtor is not required
- */
-// 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);
-
- /**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);
- 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 null;
- }
-
- 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.setSpEncryptionCredential(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) {
-
- //BUGFIX: eIDAS implementation does not allow MGF1 signature schemes
- digestMethods.add(signatureMethod);
- //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 {
- /**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);
- }
- 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.getSigningMethods());
- 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);
- }
- }
-
- public MetadataConfigParams getConfigParams() {
- return params;
- }
-
- public void setConfigParams(MetadataConfigParams params) {
- this.params = params;
- }
-
-}
+///*
+// * 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.common.impl.ExtensionsBuilder;
+//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.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.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.commons.db.dao.config.deprecated.Contact;
+//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;
+//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.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());
+//
+// /**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();
+// 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);
+//
+//
+// /**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());
+// }
+// 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();
+// }
+//
+// //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);
+//
+// /**FIXME:
+// * Double signing of SPSSODescribtor is not required
+// */
+//// if (params.getSpEngine() != null) {
+//// ProtocolEngineI spEngine = params.getSpEngine();
+//// ((MetadataSignerI) spEngine.getSigner()).signMetadata(spSSODescriptor);
+//// }
+//
+// entityDescriptor.getRoleDescriptors().add(spSSODescriptor);
+//
+// }
+//
+// private void fillIDPNameIDFormat(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);
+//
+// /**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());
+// }
+// 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());
+//
+// //Austrian eIDAS node IDP can provided persistent, transient, and unspecified identifiers
+// fillIDPNameIDFormat(idpSSODescriptor);
+//
+//
+// if (params.getIdpEngine() != null) {
+// if (params.getIdpEngine().getProtocolProcessor() != null
+// && params.getIdpEngine().getProtocolProcessor().getFormat() == SAMLExtensionFormat.EIDAS10) {
+//
+// generateSupportedAttributes(idpSSODescriptor, getAllSupportedAttributes());
+// }
+//
+//
+// /**FIXME:
+// * Double signing of IDPSSODescribtor is not required
+// */
+//// ProtocolEngineI idpEngine = params.getIdpEngine();
+//// ((MetadataSignerI) idpEngine.getSigner()).signMetadata(idpSSODescriptor);
+// }
+//
+// idpSSODescriptor.getSingleSignOnServices().addAll(buildSingleSignOnServicesBindingLocations());
+//
+// entityDescriptor.getRoleDescriptors().add(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<AttributeDefinition<?>> getAllSupportedAttributes() {
+// ImmutableSortedSet.Builder<AttributeDefinition<?>> builder =
+// new ImmutableSortedSet.Builder<>(Ordering.<AttributeDefinition<?>>natural());
+//
+// for (String attr : eIDASAttributeBuilder.getAllProvideableeIDASAttributes()) {
+// AttributeDefinition<?> supAttr = params.getIdpEngine().getProtocolProcessor().getAttributeDefinitionNullable(attr);
+// builder.add(supAttr);
+// }
+//
+// 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);
+//
+// /**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);
+// 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 null;
+// }
+//
+// 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.setSpEncryptionCredential(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) {
+//
+// //BUGFIX: eIDAS implementation does not allow MGF1 signature schemes
+// digestMethods.add(signatureMethod);
+// //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 {
+// /**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);
+// }
+// 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.getSigningMethods());
+// 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);
+// }
+// }
+//
+// public MetadataConfigParams getConfigParams() {
+// return params;
+// }
+//
+// public void setConfigParams(MetadataConfigParams params) {
+// this.params = params;
+// }
+//
+//}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/NewMoaEidasMetadata.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/NewMoaEidasMetadata.java
new file mode 100644
index 000000000..bb52d2ffe
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/NewMoaEidasMetadata.java
@@ -0,0 +1,602 @@
+/*
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Ordering;
+
+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<br>
+ * <ul>
+ * <li>Does not add an encryption certificated to IDPSSODescriptor</li>
+ * <li>Only set provideable eIDAS attributes to IDPSSODescriptor</li>
+ * <li>SPSSODescriptor only requests 'persistent' subject nameIDs</li>
+ * </ul>
+ *
+ */
+public class NewMoaEidasMetadata {
+ private static final Logger LOGGER = LoggerFactory.getLogger(EidasMetadata.class.getName());
+ private final String metadata;
+ private final String entityId;
+ private static final Set<String> 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<String> signatureMethods = EIDASUtil.parseSemicolonSeparatedList(this.params.getSigningMethods());
+ Set<String> 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 {
+ NewMoaEidasMetadata.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 {
+ NewMoaEidasMetadata.LOGGER.info("BUSINESS EXCEPTION error adding SPType extension");
+ }
+ }
+ generateDigest(eidasExtensions);
+
+ if (!(StringUtils.isEmpty(this.params.getSigningMethods()))) {
+ Set<String> 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 {
+ NewMoaEidasMetadata.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<String> 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<AttributeDefinition<?>> 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<AttributeDefinition<?>> getAllSupportedAttributes() {
+ ImmutableSortedSet.Builder<AttributeDefinition<?>> builder =
+ new ImmutableSortedSet.Builder<>(Ordering.<AttributeDefinition<?>>natural());
+
+ for (String attr : eIDASAttributeBuilder.getAllProvideableeIDASAttributes()) {
+ AttributeDefinition<?> supAttr = params.getIdpEngine().getProtocolProcessor().getAttributeDefinitionNullable(attr);
+ builder.add(supAttr);
+ }
+
+ return builder.build();
+ }
+
+ private ArrayList<SingleSignOnService> buildSingleSignOnServicesBindingLocations()
+ throws NoSuchFieldException, IllegalAccessException {
+ ArrayList singleSignOnServices = new ArrayList();
+
+ HashMap<String, String> 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<String> 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) {
+ NewMoaEidasMetadata.LOGGER.info("ERROR : error generating the OrganizationData: {}", iae.getMessage());
+ NewMoaEidasMetadata.LOGGER.debug("ERROR : error generating the OrganizationData: {}", iae);
+ } catch (NoSuchFieldException nfe) {
+ NewMoaEidasMetadata.LOGGER.info("ERROR : error generating the OrganizationData: {}", nfe.getMessage());
+ NewMoaEidasMetadata.LOGGER.debug("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 {
+ NewMoaEidasMetadata.LOGGER.error("ERROR: unsupported contact type");
+ }
+ contact = (ContactPerson) BuilderFactoryUtil.buildXmlObject(ContactPerson.class);
+ if (currentContact == null) {
+ NewMoaEidasMetadata.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) {
+ NewMoaEidasMetadata.LOGGER.info("ERROR : error generating the OrganizationData: {}", iae.getMessage());
+ NewMoaEidasMetadata.LOGGER.debug("ERROR : error generating the OrganizationData: {}", iae);
+ } catch (NoSuchFieldException nfe) {
+ NewMoaEidasMetadata.LOGGER.info("ERROR : error generating the OrganizationData: {}", nfe.getMessage());
+ NewMoaEidasMetadata.LOGGER.debug("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) {
+ NewMoaEidasMetadata.LOGGER.info("ERROR : SAMLException ", ex.getMessage());
+ NewMoaEidasMetadata.LOGGER.debug("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();
+ }
+ }
+}
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 70135c06f..02a5df098 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
@@ -23,9 +23,12 @@
package at.gv.egovernment.moa.id.auth.modules.eidas.utils;
import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.HashMap;
import java.util.Map;
+import org.opensaml.common.xml.SAMLSchemaBuilder;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.XMLConfigurator;
@@ -36,8 +39,13 @@ import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAEidasProtocolProces
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.id.config.auth.AuthConfigurationProviderFactory;
import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.FileUtils;
+import at.gv.egovernment.moa.util.MiscUtil;
import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.AttributeRegistries;
+import eu.eidas.auth.commons.attribute.AttributeRegistry;
import eu.eidas.auth.engine.ProtocolEngineI;
import eu.eidas.auth.engine.SamlEngineSystemClock;
import eu.eidas.auth.engine.metadata.MetadataFetcherI;
@@ -62,6 +70,7 @@ public class SAMLEngineUtils {
if (eIDASEngine == null) {
try {
+
//get eIDAS SAMLengine configuration from MOA-ID configuration
CertificateConfigurationManager configManager = new MOAIDCertificateManagerConfigurationImpl();
@@ -70,12 +79,25 @@ public class SAMLEngineUtils {
//set metadata signer
metadataSigner = new MOAExtendedSWSigner(configManager);
-
+
+ //load additional eIDAS attribute definitions
+ String additionalAttributeConfigFile =
+ AuthConfigurationProviderFactory.getInstance().getBasicMOAIDConfiguration(
+ Constants.CONIG_PROPS_EIDAS_SAMLENGINE_ATTIONAL_ATTRIBUTE_DEFINITIONS);
+ AttributeRegistry addAttrDefinitions = AttributeRegistries.empty();
+ if (MiscUtil.isNotEmpty(additionalAttributeConfigFile)) {
+ URL addAttrConfigUrl = new URL(FileUtils.makeAbsoluteURL(
+ additionalAttributeConfigFile,
+ AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir()));
+ addAttrDefinitions = AttributeRegistries.fromFile(addAttrConfigUrl.getPath(), null);
+
+ }
+
//build eIDAS SAML eninge
- ProtocolEngineI engine = MOAProtocolEngineFactory.createProtocolEngine(
+ ProtocolEngineI engine = MOAProtocolEngineFactory.ownCreateProtocolEngine(
Constants.eIDAS_SAML_ENGINE_NAME,
configManager,
- new MOAEidasProtocolProcesser(metadataFetcher, metadataSigner),
+ new MOAEidasProtocolProcesser(metadataFetcher, metadataSigner, addAttrDefinitions),
new SamlEngineSystemClock());
//build a map with all actually supported attributes
@@ -86,6 +108,9 @@ public class SAMLEngineUtils {
//overwrite eIDAS response validator suite because Condition-Valitator has not time jitter
initOpenSAMLConfig("own-saml-eidasnode-config.xml");
+ //add eIDAS specific SAML2 extensions to eIDAS Schema validatior
+ SAMLSchemaBuilder.addExtensionSchema(
+ at.gv.egovernment.moa.util.Constants.SAML2_eIDAS_EXTENSIONS_SCHEMA_LOCATION);
eIDASEngine = engine;
@@ -93,6 +118,14 @@ public class SAMLEngineUtils {
Logger.error("eIDAS SAMLengine initialization FAILED!", e);
throw new EIDASEngineException("eIDAS.00", new Object[]{e.getMessage()}, e);
+ } catch (at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException e) {
+ Logger.error("eIDAS SAMLengine initialization FAILED!", e);
+ throw new EIDASEngineException("eIDAS.00", new Object[]{e.getMessage()}, e);
+
+ } catch (MalformedURLException e) {
+ Logger.error("eIDAS SAMLengine initialization FAILED!", e);
+ throw new EIDASEngineException("eIDAS.00", new Object[]{e.getMessage()}, e);
+
}
}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/eIDASAttributeBuilder.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/eIDASAttributeBuilder.java
new file mode 100644
index 000000000..22b94178e
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/eIDASAttributeBuilder.java
@@ -0,0 +1,174 @@
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ServiceLoader;
+
+import com.google.common.collect.ImmutableSet;
+
+import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.Pair;
+import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.IeIDASAttribute;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.AttributeDefinition.Builder;
+import eu.eidas.auth.commons.attribute.AttributeValue;
+import eu.eidas.auth.commons.attribute.AttributeValueMarshaller;
+import eu.eidas.auth.commons.attribute.AttributeValueMarshallingException;
+
+/**
+ * @author tlenz
+ *
+ */
+public class eIDASAttributeBuilder extends PVPAttributeBuilder {
+ private static IAttributeGenerator<String> generator = new SimpleEidasAttributeGenerator();
+
+ private static List<String> listOfSupportedeIDASAttributes;
+ private static ServiceLoader<IeIDASAttribute> eIDASAttributLoader =
+ ServiceLoader.load(IeIDASAttribute.class);
+
+ static {
+ List<String> supportAttrList = new ArrayList<String>();
+
+ Logger.info("Select eIDAS attributes that are corrently providable:");
+ if (eIDASAttributLoader != null ) {
+ Iterator<IeIDASAttribute> moduleLoaderInterator = eIDASAttributLoader.iterator();
+ while (moduleLoaderInterator.hasNext()) {
+ try {
+ IeIDASAttribute modul = moduleLoaderInterator.next();
+ Logger.info("Loading eIDAS attribut-builder Modul Information: " + modul.getName());
+ supportAttrList.add(modul.getName());
+
+ } catch(Throwable e) {
+ Logger.error("Check configuration! " + "Some attribute-builder modul" +
+ " is not a valid IAttributeBuilder", e);
+ }
+ }
+ }
+
+ listOfSupportedeIDASAttributes = Collections.unmodifiableList(supportAttrList);
+ Logger.info("Selection of providable eIDAS attributes done");
+
+ }
+
+ /**
+ * Get all eIDAS attribute names that can be generated by the Austrian eIDAS node.
+ * This list is dynamically generated from loaded eIDAS attribute builders that are found in Java Classpath
+ *
+ * @return {@link List} of {@link String} of eIDAS attribute names
+ */
+ public static List<String> getAllProvideableeIDASAttributes() {
+ return listOfSupportedeIDASAttributes;
+ }
+
+ /**
+ * This method build an eIDAS response attribute, by using a loaded eIDAS attribute builder.
+ *
+ * @param attr eIDAS attribute that should be generated
+ * @param onlineApplicationConfiguration SP configuration
+ * @param authData Authentication data that contains user information for attribute generation
+ * @return eIDAS attribute response {@link Pair} or null if the attribute generation FAILES
+ */
+ public static Pair<AttributeDefinition<?>,ImmutableSet<AttributeValue<?>>> buildAttribute(AttributeDefinition<?> attr, IOAAuthParameters onlineApplicationConfiguration,
+ IAuthData authData) {
+
+ String attrName = attr.getNameUri().toString();
+ Logger.trace("Build eIDAS attribute: "+ attrName);
+
+
+ IAttributeBuilder attrBuilder = getAttributeBuilder(attrName);
+ if (attrBuilder != null) {
+ try {
+ String attrValue = attrBuilder.build(onlineApplicationConfiguration, authData, generator);
+ if (MiscUtil.isNotEmpty(attrValue)) {
+ //set uniqueIdentifier attribute, because eIDAS SAMLEngine use this flag to select the
+ // Subject->NameID value from this attribute
+ Builder<?> eIDASAttrBuilder = AttributeDefinition.builder(attr);
+ eIDASAttrBuilder.uniqueIdentifier(evaluateUniqueID(attrName, authData.isUseMandate()));
+ AttributeDefinition<?> returnAttr = eIDASAttrBuilder.build();
+
+ //unmarshal attribute value into eIDAS attribute
+ AttributeValueMarshaller<?> attributeValueMarshaller = returnAttr.getAttributeValueMarshaller();
+ ImmutableSet.Builder<AttributeValue<?>> builder = ImmutableSet.builder();
+
+ AttributeValue<?> attributeValue = null;
+ try {
+ attributeValue = attributeValueMarshaller.unmarshal(attrValue, false);
+ builder.add(attributeValue);
+
+ } catch (AttributeValueMarshallingException e) {
+ throw new IllegalStateException(e);
+
+ }
+
+ return Pair.newInstance(returnAttr, builder.build());
+
+ }
+
+ } catch (AttributeException e) {
+ Logger.debug("Attribute can not generate requested attribute:" + attr.getNameUri().toString() + " Reason:" + e.getMessage());
+
+ }
+
+ } else
+ Logger.warn("NO attribute builder FOUND for eIDAS attr: " + attrName);
+
+ return null;
+ }
+
+ /**
+ * This method use the information from authenticated session and
+ * evaluate the uniqueID flag according to eIDAS specification
+ *
+ * @param attrName eIDAS attribute name that is evaluated
+ * @param useMandate flag that indicates if the current authenticated session includes a mandate
+ * @return true if eIDAS attribute holds the unique ID, otherwise false
+ */
+ private static boolean evaluateUniqueID(String attrName, boolean useMandate) {
+ //if no mandate is used the natural person identifier is the unique ID
+ if (!useMandate &&
+ attrName.equals(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.PERSON_IDENTIFIER.getNameUri().toString()))
+ return true;
+
+ //if mandates are used the the legal person identifier or the natural person identifier of the mandator is the unique ID
+ else if (useMandate &&
+ attrName.equals(eu.eidas.auth.engine.core.eidas.spec.LegalPersonSpec.Definitions.LEGAL_PERSON_IDENTIFIER.getNameUri().toString()))
+ return true;
+
+ //TODO: implement flag selector for mandates and natural persons
+
+
+ return false;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java
index 7647b4cab..694efab80 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java
@@ -15,6 +15,8 @@ import eu.eidas.auth.commons.protocol.IAuthenticationRequest;
@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
public class EIDASData extends RequestImpl {
+ public static final String REQ_PARAM_eIDAS_AUTHN_TRANSIENT_ID = "transiendIDRequested";
+
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 8765755670214923910L;
@@ -28,7 +30,7 @@ public class EIDASData extends RequestImpl {
private String remoteIPAddress;
private String remoteRelayState;
-
+
@Override
public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) {
// TODO Auto-generated method stub
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java
index 388d65963..940b91b44 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java
@@ -67,6 +67,7 @@ import eu.eidas.auth.commons.protocol.eidas.IEidasAuthenticationRequest;
import eu.eidas.auth.commons.protocol.eidas.impl.EidasAuthenticationRequest;
import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse;
import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse.Builder;
+import eu.eidas.auth.commons.protocol.impl.SamlNameIdFormat;
import eu.eidas.auth.engine.ProtocolEngineI;
import eu.eidas.auth.engine.metadata.MetadataUtil;
import eu.eidas.engine.exceptions.EIDASSAMLEngineException;
@@ -307,6 +308,13 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController {
pendingReq.setGenericDataToSession(RequestImpl.eIDAS_GENERIC_REQ_DATA_LEVELOFASSURENCE,
eIDASSamlReq.getEidasLevelOfAssurance().stringValue());
+ //set flag if transiend identifier is requested
+ if (MiscUtil.isNotEmpty(eIDASSamlReq.getNameIdFormat())
+ && eIDASSamlReq.getNameIdFormat().equals(SamlNameIdFormat.TRANSIENT.getNameIdFormat()))
+ pendingReq.setGenericDataToSession(EIDASData.REQ_PARAM_eIDAS_AUTHN_TRANSIENT_ID, true);
+ else
+ pendingReq.setGenericDataToSession(EIDASData.REQ_PARAM_eIDAS_AUTHN_TRANSIENT_ID, false);
+
// - memorize requested attributes
pendingReq.setEidasRequestedAttributes(eIDASSamlReq.getRequestedAttributes());
@@ -322,7 +330,7 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController {
// - memorize service-provider type from eIDAS request
String spType = null;
if (eIDASSamlReq.getSpType() != null)
- spType = eIDASSamlReq.getSpType().getValue();
+ spType = eIDASSamlReq.getSpType();
if (MiscUtil.isEmpty(spType))
spType = MetadataUtil.getSPTypeFromMetadata(eIDASNodeEntityDesc);
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java
index df96bef12..cc9b09107 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java
@@ -31,7 +31,7 @@ import org.springframework.stereotype.Service;
import at.gv.egovernment.moa.id.auth.modules.eidas.Constants;
import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider;
import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException;
-import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAeIDASMetadataGenerator;
+import at.gv.egovernment.moa.id.auth.modules.eidas.utils.NewMoaEidasMetadata;
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.AuthConfiguration;
@@ -44,8 +44,10 @@ import at.gv.egovernment.moa.id.moduls.IAction;
import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
import at.gv.egovernment.moa.logging.Logger;
import eu.eidas.auth.engine.ProtocolEngineI;
-import eu.eidas.auth.engine.metadata.Contact;
+import eu.eidas.auth.engine.metadata.ContactData;
import eu.eidas.auth.engine.metadata.MetadataConfigParams;
+import eu.eidas.auth.engine.metadata.MetadataConfigParams.Builder;
+import eu.eidas.auth.engine.metadata.OrganizationData;
import eu.eidas.engine.exceptions.EIDASSAMLEngineException;
@@ -119,22 +121,21 @@ public class EidasMetaDataRequest implements IAction {
ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider);
- MOAeIDASMetadataGenerator generator = new MOAeIDASMetadataGenerator();
- MetadataConfigParams mcp=new MetadataConfigParams();
- generator.setConfigParams(mcp);
- generator.initialize(engine);
-
- mcp.setEntityID(metadata_url);
- mcp.setAssertionConsumerUrl(sp_return_url);
- mcp.getProtocolBindingLocation().put(
+ //configura metadata builder
+ Builder metadataConfigBuilder = MetadataConfigParams.builder();
+ metadataConfigBuilder.entityID(metadata_url);
+ metadataConfigBuilder.assertionConsumerUrl(sp_return_url);
+
+ metadataConfigBuilder.addProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);
+ metadataConfigBuilder.addProtocolBindingLocation(
SAMLConstants.SAML2_POST_BINDING_URI,
pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST);
//TODO: make it configurable
- mcp.setAuthnRequestsSigned(true);
- mcp.setWantAssertionsSigned(true);
- mcp.setAssuranceLevel(
+ metadataConfigBuilder.authnRequestsSigned(true);
+ metadataConfigBuilder.wantAssertionsSigned(true);
+ metadataConfigBuilder.assuranceLevel(
authConfig.getBasicMOAIDConfiguration(
Constants.CONIG_PROPS_EIDAS_NODE_LoA,
MOAIDAuthConstants.eIDAS_LOA_HIGH));
@@ -142,47 +143,71 @@ public class EidasMetaDataRequest implements IAction {
//must be set in request, because it could be different for every online-application
//mcp.setSpType(SPType.DEFAULT_VALUE);
- mcp.setDigestMethods(Constants.METADATA_ALLOWED_ALG_DIGIST);
- mcp.setSigningMethods(Constants.METADATA_ALLOWED_ALG_SIGN);
- mcp.setEncryptionAlgorithms(Constants.METADATA_ALLOWED_ALG_ENCRYPT);
+ metadataConfigBuilder.digestMethods(Constants.METADATA_ALLOWED_ALG_DIGIST);
+ metadataConfigBuilder.signingMethods(Constants.METADATA_ALLOWED_ALG_SIGN);
+ metadataConfigBuilder.encryptionAlgorithms(Constants.METADATA_ALLOWED_ALG_ENCRYPT);
//add organisation information from PVP metadata information
Organization pvpOrganisation = null;
try {
pvpOrganisation = PVPConfiguration.getInstance().getIDPOrganisation();
- Contact technicalContact = new Contact();
+ eu.eidas.auth.engine.metadata.ContactData.Builder technicalContact = ContactData.builder();
List<ContactPerson> contacts = PVPConfiguration.getInstance().getIDPContacts();
if (contacts != null && contacts.size() >= 1) {
ContactPerson contact = contacts.get(0);
- technicalContact.setGivenName(contact.getGivenName().getName());
- technicalContact.setSurName(contact.getSurName().getName());
+ technicalContact.givenName(contact.getGivenName().getName());
+ technicalContact.surName(contact.getSurName().getName());
if (!contact.getEmailAddresses().isEmpty())
- technicalContact.setEmail(contact.getEmailAddresses().get(0).getAddress());
+ technicalContact.email(contact.getEmailAddresses().get(0).getAddress());
if (!contact.getTelephoneNumbers().isEmpty())
- technicalContact.setPhone(contact.getTelephoneNumbers().get(0).getNumber());
+ technicalContact.phone(contact.getTelephoneNumbers().get(0).getNumber());
- mcp.setTechnicalContact(technicalContact );
+
}
if (pvpOrganisation != null) {
- mcp.setNodeUrl(pvpOrganisation.getURLs().get(0).getURL().getLocalString());
- mcp.setCountryName(authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRY, "Austria"));
- technicalContact.setCompany(pvpOrganisation.getDisplayNames().get(0).getName().getLocalString());
+ eu.eidas.auth.engine.metadata.OrganizationData.Builder organizationConfig = OrganizationData.builder();
+ organizationConfig.url(pvpOrganisation.getURLs().get(0).getURL().getLocalString());
+ organizationConfig.name(authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRY, "Austria"));
+ //TODO: add display name and maybe update name
+
+
+ metadataConfigBuilder.organization(organizationConfig.build());
+
+ technicalContact.company(pvpOrganisation.getDisplayNames().get(0).getName().getLocalString());
}
+
+ metadataConfigBuilder.technicalContact(technicalContact.build());
+
+ //TODO: add correct support contact
+ metadataConfigBuilder.supportContact(ContactData.builder(technicalContact.build()).build());
+
} catch (ConfigurationException | NullPointerException e) {
Logger.warn("Can not load Organisation or Contact from Configuration", e);
}
-
- generator.addSPRole();
- generator.addIDPRole();
+
+ metadataConfigBuilder.idpEngine(engine);
+ metadataConfigBuilder.spEngine(engine);
+
+ //TODO:
+// MOAeIDASMetadataGenerator generator = new MOAeIDASMetadataGenerator();
+// generator.initialize(engine);
+// generator.addSPRole();
+// generator.addIDPRole();
+// metadata = generator.generateMetadata();
+
+ //use own implementation that solves some problems in original implementation
+ NewMoaEidasMetadata.Generator generator = NewMoaEidasMetadata.generator();
+ generator.configParams(metadataConfigBuilder.build());
+ NewMoaEidasMetadata eidasMetadata = generator.build();
+ metadata = eidasMetadata.getMetadata();
- metadata = generator.generateMetadata();
return metadata;
}
}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/IeIDASAttribute.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/IeIDASAttribute.java
new file mode 100644
index 000000000..15060fb52
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/IeIDASAttribute.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.protocols.eidas.attributes.builder;
+
+import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface IeIDASAttribute extends IAttributeBuilder{
+
+}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrDateOfBirth.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrDateOfBirth.java
new file mode 100644
index 000000000..64e5ae770
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrDateOfBirth.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.protocols.eidas.attributes.builder;
+
+import at.gv.egovernment.moa.id.protocols.builder.attributes.BirthdateAttributeBuilder;
+
+/**
+ * @author tlenz
+ *
+ */
+public class eIDASAttrDateOfBirth extends BirthdateAttributeBuilder implements IeIDASAttribute {
+
+ @Override
+ public String getName() {
+ return eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.DATE_OF_BIRTH.getNameUri().toString();
+ }
+}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrFamilyName.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrFamilyName.java
new file mode 100644
index 000000000..4195eeeef
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrFamilyName.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.protocols.eidas.attributes.builder;
+
+import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+/**
+ * @author tlenz
+ *
+ */
+public class eIDASAttrFamilyName implements IeIDASAttribute{
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder#getName()
+ */
+ @Override
+ public String getName() {
+ return eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_FAMILY_NAME.getNameUri().toString();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder#build(at.gv.egovernment.moa.id.commons.api.IOAAuthParameters, at.gv.egovernment.moa.id.data.IAuthData, at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator)
+ */
+ @Override
+ public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g)
+ throws AttributeException {
+ return g.buildStringAttribute(null, getName(), authData.getFamilyName());
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder#buildEmpty(at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator)
+ */
+ @Override
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return null;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrGivenName.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrGivenName.java
new file mode 100644
index 000000000..2a654ac44
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrGivenName.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.protocols.eidas.attributes.builder;
+
+import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+
+/**
+ * @author tlenz
+ *
+ */
+public class eIDASAttrGivenName implements IeIDASAttribute{
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder#getName()
+ */
+ @Override
+ public String getName() {
+ return eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_GIVEN_NAME.getNameUri().toString();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder#build(at.gv.egovernment.moa.id.commons.api.IOAAuthParameters, at.gv.egovernment.moa.id.data.IAuthData, at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator)
+ */
+ @Override
+ public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g)
+ throws AttributeException {
+ return g.buildStringAttribute(null, getName(), authData.getGivenName());
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder#buildEmpty(at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator)
+ */
+ @Override
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return null;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrLegalName.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrLegalName.java
new file mode 100644
index 000000000..51a2bd69b
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrLegalName.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.protocols.eidas.attributes.builder;
+
+import at.gv.egovernment.moa.id.protocols.builder.attributes.MandateLegalPersonFullNameAttributeBuilder;
+
+/**
+ * @author tlenz
+ *
+ */
+public class eIDASAttrLegalName extends MandateLegalPersonFullNameAttributeBuilder implements IeIDASAttribute {
+
+ @Override
+ public String getName() {
+ return eu.eidas.auth.engine.core.eidas.spec.LegalPersonSpec.Definitions.LEGAL_NAME.getNameUri().toString();
+ }
+}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrLegalPersonIdentifier.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrLegalPersonIdentifier.java
new file mode 100644
index 000000000..c008048cb
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrLegalPersonIdentifier.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.protocols.eidas.attributes.builder;
+
+import at.gv.egovernment.moa.id.protocols.builder.attributes.MandateLegalPersonSourcePinAttributeBuilder;
+
+/**
+ * @author tlenz
+ *
+ */
+public class eIDASAttrLegalPersonIdentifier extends MandateLegalPersonSourcePinAttributeBuilder implements IeIDASAttribute {
+
+ @Override
+ public String getName() {
+ return eu.eidas.auth.engine.core.eidas.spec.LegalPersonSpec.Definitions.LEGAL_PERSON_IDENTIFIER.getNameUri().toString();
+ }
+}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrNaturalPersonalIdentifier.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrNaturalPersonalIdentifier.java
new file mode 100644
index 000000000..cb659c2b1
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/attributes/builder/eIDASAttrNaturalPersonalIdentifier.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.protocols.eidas.attributes.builder;
+
+import java.security.MessageDigest;
+
+import at.gv.egovernment.moa.id.auth.modules.eidas.utils.eIDASAttributeProcessingUtils;
+import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.Trible;
+import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.eidas.EIDASData;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+import at.gv.egovernment.moa.id.util.Random;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+/**
+ * @author tlenz
+ *
+ */
+public class eIDASAttrNaturalPersonalIdentifier implements IeIDASAttribute{
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder#getName()
+ */
+ @Override
+ public String getName() {
+ return eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.PERSON_IDENTIFIER.getNameUri().toString();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder#build(at.gv.egovernment.moa.id.commons.api.IOAAuthParameters, at.gv.egovernment.moa.id.data.IAuthData, at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator)
+ */
+ @Override
+ public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g)
+ throws AttributeException {
+ String personalID = authData.getBPK();
+
+ //generate eIDAS conform 'PersonalIdentifier' attribute
+ if (!eIDASAttributeProcessingUtils.validateEidasPersonalIdentifier(personalID)) {
+ Logger.debug("preCalculated PersonalIdentifier does not include eIDAS conform prefixes ... add prefix now");
+ if (MiscUtil.isEmpty(authData.getBPKType())
+ || !authData.getBPKType().startsWith(at.gv.egovernment.moa.util.Constants.URN_PREFIX_EIDAS)) {
+ Logger.error("BPKType is empty or does not start with eIDAS bPKType prefix! bPKType:" + authData.getBPKType());
+ throw new AttributeException("Suspect bPKType for eIDAS identifier generation");
+
+ }
+
+ String prefix = authData.getBPKType().substring(at.gv.egovernment.moa.util.Constants.URN_PREFIX_EIDAS.length() + 1);
+ personalID = prefix.replaceAll("\\+", "/") + "/" + personalID;
+
+ }
+
+ //generate a transient unique identifier if it is requested
+ Boolean isTransiendIDRequested =
+ authData.getGenericData(EIDASData.REQ_PARAM_eIDAS_AUTHN_TRANSIENT_ID, Boolean.class);
+ if (isTransiendIDRequested != null && isTransiendIDRequested)
+ personalID = generateTransientNameID(personalID);
+
+ return g.buildStringAttribute(null, getName(), personalID);
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder#buildEmpty(at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator)
+ */
+ @Override
+ public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) {
+ return null;
+ }
+
+ private String generateTransientNameID(String nameID) {
+ //extract source-country and destination country from persistent identifier
+ Trible<String, String, String> split = eIDASAttributeProcessingUtils.parseEidasPersonalIdentifier(nameID);
+ if (split == null) {
+ Logger.error("eIDAS 'PersonalIdentifier' has a wrong format. There had to be a ERROR in implementation!!!!");
+ throw new IllegalStateException("eIDAS 'PersonalIdentifier' has a wrong format. There had to be a ERROR in implementation!!!!");
+
+ }
+
+ //build correct formated transient identifier
+ String random = Random.nextLongRandom();
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+ byte[] hash = md.digest((split.getThird() + random).getBytes("ISO-8859-1"));
+ return split.getFirst() + "/" + split.getSecond() + "/" + Base64Utils.encode(hash);
+
+ } catch (Exception e) {
+ Logger.error("Can not generate transient personal identifier!", e);
+ return null;
+
+ }
+
+ }
+}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java
index 2fe52bb4f..d0cda38c7 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java
@@ -23,8 +23,6 @@
package at.gv.egovernment.moa.id.protocols.eidas;
import java.io.StringWriter;
-import java.security.MessageDigest;
-import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -43,33 +41,23 @@ import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider;
import at.gv.egovernment.moa.id.auth.modules.eidas.Constants;
import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider;
import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SimpleEidasAttributeGenerator;
-import at.gv.egovernment.moa.id.auth.modules.eidas.utils.eIDASAttributeProcessingUtils;
+import at.gv.egovernment.moa.id.auth.modules.eidas.utils.eIDASAttributeBuilder;
import at.gv.egovernment.moa.id.commons.MOAIDConstants;
import at.gv.egovernment.moa.id.commons.api.IRequest;
import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.Pair;
import at.gv.egovernment.moa.id.data.SLOInformationImpl;
import at.gv.egovernment.moa.id.data.SLOInformationInterface;
-import at.gv.egovernment.moa.id.data.Trible;
import at.gv.egovernment.moa.id.moduls.IAction;
import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator;
-import at.gv.egovernment.moa.id.protocols.builder.attributes.MandateLegalPersonFullNameAttributeBuilder;
-import at.gv.egovernment.moa.id.protocols.builder.attributes.MandateLegalPersonSourcePinAttributeBuilder;
-import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
-import at.gv.egovernment.moa.id.util.Random;
import at.gv.egovernment.moa.logging.Logger;
-import at.gv.egovernment.moa.util.Base64Utils;
-import at.gv.egovernment.moa.util.MiscUtil;
import eu.eidas.auth.commons.EidasStringUtil;
import eu.eidas.auth.commons.attribute.AttributeDefinition;
-import eu.eidas.auth.commons.attribute.AttributeDefinition.Builder;
import eu.eidas.auth.commons.attribute.AttributeValue;
-import eu.eidas.auth.commons.attribute.AttributeValueMarshaller;
-import eu.eidas.auth.commons.attribute.AttributeValueMarshallingException;
import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
import eu.eidas.auth.commons.protocol.IResponseMessage;
import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse;
-import eu.eidas.auth.commons.protocol.impl.SamlNameIdFormat;
import eu.eidas.auth.engine.ProtocolEngineI;
import eu.eidas.auth.engine.xml.opensaml.SAMLEngineUtils;
@@ -97,104 +85,31 @@ public class eIDASAuthenticationRequest implements IAction {
else
throw new MOAIDException("got wrong IRequest type. is: {}, should be: {}", new String[] {req.getClass().toString(), EIDASData.class.toString()});
-
+
String subjectNameID = null;
-
+
//gather attributes
ImmutableAttributeMap reqAttributeList = (ImmutableAttributeMap) eidasRequest.getEidasRequestedAttributes();
ImmutableAttributeMap.Builder attrMapBuilder = ImmutableAttributeMap.builder();
-
- //TODO: if we support more then this minimum required attributes -> redesign to a smoother attribute builder selector
+
+ //generate eIDAS attributes
for(AttributeDefinition<?> attr : reqAttributeList.getDefinitions()) {
- String newValue = "";
- boolean isUniqueID = false;
- try {
- switch(attr.getFriendlyName()) {
- case Constants.eIDAS_ATTR_DATEOFBIRTH:
- newValue = new SimpleDateFormat("YYYY-MM-dd").format(authData.getDateOfBirth());
- break;
- case Constants.eIDAS_ATTR_CURRENTFAMILYNAME:
- newValue = authData.getFamilyName();
- break;
- case Constants.eIDAS_ATTR_CURRENTGIVENNAME:
- newValue = authData.getGivenName();
- break;
- case Constants.eIDAS_ATTR_PERSONALIDENTIFIER:
- newValue = authData.getBPK();
- isUniqueID = true;
+ Pair<AttributeDefinition<?>, ImmutableSet<AttributeValue<?>>> eIDASAttr = eIDASAttributeBuilder.buildAttribute(
+ attr, req.getOnlineApplicationConfiguration(), authData);
- //generate eIDAS conform 'PersonalIdentifier' attribute
- if (!eIDASAttributeProcessingUtils.validateEidasPersonalIdentifier(newValue)) {
- Logger.debug("preCalculated PersonalIdentifier does not include eIDAS conform prefixes ... add prefix now");
- if (MiscUtil.isEmpty(authData.getBPKType())
- || !authData.getBPKType().startsWith(at.gv.egovernment.moa.util.Constants.URN_PREFIX_EIDAS)) {
- Logger.error("BPKType is empty or does not start with eIDAS bPKType prefix! bPKType:" + authData.getBPKType());
- throw new MOAIDException("builder.08", new Object[]{"Suspect bPKType for eIDAS identifier generation"});
-
- }
-
- String prefix = authData.getBPKType().substring(at.gv.egovernment.moa.util.Constants.URN_PREFIX_EIDAS.length() + 1);
- newValue = prefix.replaceAll("\\+", "/") + "/" + newValue;
-
- }
-
- //generate a transient unique identifier if it is requested
- String reqNameIDFormat = eidasRequest.getEidasRequest().getNameIdFormat();
- if (MiscUtil.isNotEmpty(reqNameIDFormat)
- && reqNameIDFormat.equals(SamlNameIdFormat.TRANSIENT.getNameIdFormat()))
- newValue = generateTransientNameID(newValue);
-
-
- subjectNameID = newValue;
- break;
- case Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER:
- newValue = new MandateLegalPersonSourcePinAttributeBuilder().build(
- req.getOnlineApplicationConfiguration(), authData, generator);
- break;
- case Constants.eIDAS_ATTR_LEGALNAME:
- newValue = new MandateLegalPersonFullNameAttributeBuilder().build(
- req.getOnlineApplicationConfiguration(), authData, generator);
- break;
-
- }
-
- } catch (AttributeException e) {
- Logger.debug("Attribute can not generate requested attribute:" + attr.getFriendlyName() + " Reason:" + e.getMessage());
-
- }
-
- if(MiscUtil.isEmpty(newValue)) {
+ if(eIDASAttr == null) {
if (attr.isRequired()) {
Logger.info("eIDAS Attr:" + attr.getNameUri() + " is marked as 'Required' but not available.");
throw new MOAIDException("eIDAS.15", new Object[]{attr.getFriendlyName()});
} else
Logger.info("eIDAS Attr:" + attr.getNameUri() + " is not available.");
-
} else {
- //set uniqueIdentifier attribute, because eIDAS SAMLEngine use this flag to select the
- // Subject->NameID value from this attribute
- Builder<?> attrBuilder = AttributeDefinition.builder(attr);
- attrBuilder.uniqueIdentifier(isUniqueID);
- AttributeDefinition<?> returnAttr = attrBuilder.build();
-
- //unmarshal attribute value into eIDAS attribute
- AttributeValueMarshaller<?> attributeValueMarshaller = returnAttr.getAttributeValueMarshaller();
- ImmutableSet.Builder<AttributeValue<?>> builder = ImmutableSet.builder();
-
- AttributeValue<?> attributeValue = null;
- try {
- attributeValue = attributeValueMarshaller.unmarshal(newValue, false);
- builder.add(attributeValue);
-
- } catch (AttributeValueMarshallingException e) {
- throw new IllegalStateException(e);
-
- }
-
- //add attribute to Map
- attrMapBuilder.put((AttributeDefinition)returnAttr, (ImmutableSet) builder.build());
+ //add attribute to Map
+ attrMapBuilder.put(
+ (AttributeDefinition)eIDASAttr.getFirst(),
+ (ImmutableSet)eIDASAttr.getSecond());
}
}
@@ -231,19 +146,7 @@ public class eIDASAuthenticationRequest implements IAction {
eIDASRespMsg = engine.generateResponseMessage(eidasRequest.getEidasRequest(),
response, true, eidasRequest.getRemoteAddress());
-
-// if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) {
-// String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata(
-// new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider),
-// engine,
-// eidasRequest.getEidasRequest());
-// eidasRequest.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl);
-//
-// }
-
-// response = engine.generateEIDASAuthnResponse(eidasRequest.getEidasRequest(), response, eidasRequest.getRemoteAddress(), true);
-
-
+
token = EidasStringUtil.encodeToBase64(eIDASRespMsg.getMessageBytes());
} catch(Exception e) {
@@ -319,28 +222,6 @@ public class eIDASAuthenticationRequest implements IAction {
}
- private String generateTransientNameID(String nameID) {
- //extract source-country and destination country from persistent identifier
- Trible<String, String, String> split = eIDASAttributeProcessingUtils.parseEidasPersonalIdentifier(nameID);
- if (split == null) {
- Logger.error("eIDAS 'PersonalIdentifier' has a wrong format. There had to be a ERROR in implementation!!!!");
- throw new IllegalStateException("eIDAS 'PersonalIdentifier' has a wrong format. There had to be a ERROR in implementation!!!!");
-
- }
-
- //build correct formated transient identifier
- String random = Random.nextLongRandom();
- try {
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest((split.getThird() + random).getBytes("ISO-8859-1"));
- return split.getFirst() + "/" + split.getSecond() + "/" + Base64Utils.encode(hash);
-
- } catch (Exception e) {
- Logger.error("Can not generate transient personal identifier!", e);
- return null;
-
- }
-
- }
+
}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder b/id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder
new file mode 100644
index 000000000..62e7c20ab
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder
@@ -0,0 +1,6 @@
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrDateOfBirth
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrFamilyName
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrGivenName
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrNaturalPersonalIdentifier
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrLegalPersonIdentifier
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrLegalName
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.IeIDASAttribute b/id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.IeIDASAttribute
new file mode 100644
index 000000000..62e7c20ab
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.IeIDASAttribute
@@ -0,0 +1,6 @@
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrDateOfBirth
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrFamilyName
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrGivenName
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrNaturalPersonalIdentifier
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrLegalPersonIdentifier
+at.gv.egovernment.moa.id.protocols.eidas.attributes.builder.eIDASAttrLegalName
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/schema/eIDAS_saml_extensions.xsd b/id/server/modules/moa-id-module-eIDAS/src/main/resources/schema/eIDAS_saml_extensions.xsd
new file mode 100644
index 000000000..76b82a267
--- /dev/null
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/schema/eIDAS_saml_extensions.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:eidas="http://eidas.europa.eu/saml-extensions" targetNamespace="http://eidas.europa.eu/saml-extensions" elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+ <xsd:element name="SPType" type="eidas:SPTypeType"/>
+ <xsd:simpleType name="SPTypeType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="public"/>
+ <xsd:enumeration value="private"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:element name="RequestedAttributes" type="eidas:RequestedAttributesType"/>
+ <xsd:complexType name="RequestedAttributesType">
+ <xsd:sequence>
+ <xsd:element minOccurs="0" maxOccurs="unbounded" ref="eidas:RequestedAttribute"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="RequestedAttribute" type="eidas:RequestedAttributeType"/>
+ <xsd:complexType name="RequestedAttributeType">
+ <xsd:sequence>
+ <xsd:element name="AttributeValue" minOccurs="0" maxOccurs="unbounded" type="xsd:anyType"/>
+ </xsd:sequence>
+ <xsd:attribute name="Name" type="xsd:string" use="required"/>
+ <xsd:attribute name="NameFormat" type="xsd:anyURI" use="required" />
+ <xsd:attribute name="isRequired" type="xsd:boolean" use="required"/>
+ <xsd:attribute name="FriendlyName" type="xsd:string" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax" />
+ </xsd:complexType>
+
+</xsd:schema>