aboutsummaryrefslogtreecommitdiff
path: root/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base')
-rw-r--r--id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/SAMLEngine.java.svn-base409
-rw-r--r--id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/SAMLEngineUtils.java.svn-base833
-rw-r--r--id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/STORKSAMLEngine.java.svn-base2983
-rw-r--r--id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/X509PrincipalUtil.java.svn-base69
-rw-r--r--id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/package-info.java.svn-base19
5 files changed, 4313 insertions, 0 deletions
diff --git a/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/SAMLEngine.java.svn-base b/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/SAMLEngine.java.svn-base
new file mode 100644
index 000000000..f8f50fc74
--- /dev/null
+++ b/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/SAMLEngine.java.svn-base
@@ -0,0 +1,409 @@
+/*
+ * 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/european-union-public-licence-eupl-v.1.1
+ *
+ * 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.
+ */
+
+package eu.stork.peps.auth.engine;
+
+import java.io.ByteArrayInputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.opensaml.Configuration;
+import org.opensaml.DefaultBootstrap;
+import org.opensaml.common.SAMLObject;
+import org.opensaml.common.SignableSAMLObject;
+import org.opensaml.xml.ConfigurationException;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.io.Marshaller;
+import org.opensaml.xml.io.MarshallerFactory;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.io.Unmarshaller;
+import org.opensaml.xml.io.UnmarshallerFactory;
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.parse.BasicParserPool;
+import org.opensaml.xml.parse.XMLParserException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import eu.stork.peps.auth.engine.core.SAMLEngineSignI;
+import eu.stork.peps.auth.engine.core.STORKSAMLCore;
+import eu.stork.peps.auth.engine.core.impl.SignModuleFactory;
+import eu.stork.peps.configuration.ConfigurationCreator;
+import eu.stork.peps.configuration.ConfigurationReader;
+import eu.stork.peps.configuration.InstanceEngine;
+import eu.stork.peps.exceptions.SAMLEngineException;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+import eu.stork.peps.exceptions.STORKSAMLEngineRuntimeException;
+
+/**
+ * Class that wraps the operations over SAML tokens, both generation and
+ * validation of SAML requests and SAML responses. Compliant with "OASIS Secure
+ * Assertion Markup Language (SAML) 2.0, May 2005", but taking into account
+ * STORK specific requirements.
+ *
+ * @author fjquevedo
+ * @author iinigo
+ */
+
+public class SAMLEngine {
+
+ /** The Document Builder Factory. */
+ private static javax.xml.parsers.DocumentBuilderFactory dbf = null;
+
+ /** The instance of every engine SAML. */
+ private static Map<String, InstanceEngine> instanceConfigs;
+
+ /** The instances of SAML engine. */
+ private static Map<String, Map<String, Object>> instances;
+
+ /** The logger. */
+ private static final Logger LOG = LoggerFactory.getLogger(SAMLEngine.class
+ .getName());
+
+ /** The Constant MODULE_SIGN_CONF. */
+ private static final String MODULE_SIGN_CONF = "SignatureConf";
+
+ /** The Constant SAML_ENGINE_SIGN_CLASS. */
+ private static final String SAML_ENGINE_SIGN_CLASS = "class";
+
+ /** The Constant SAML_ENGINE_CONF. */
+ private static final String SAML_ENGINE_CONF = "SamlEngineConf";
+
+ /** The Constant SAML_ENGINE_FILE_CONF. */
+ private static final String SAML_ENGINE_FILE_CONF = "fileConfiguration";
+
+ /** The codification of characters. */
+ private static final String CHARACTER_ENCODING = "UTF-8";
+
+ /** The SAML core. */
+ private STORKSAMLCore samlCore;
+
+ /** The Module of Signature. */
+ private SAMLEngineSignI signer;
+
+
+ /** Initializes the SAML engine. */
+ /** Configure Document Builder Factory. */
+
+ static {
+ startUp();
+ loadDocumentFactory();
+ }
+
+ /**
+ * Load document factory.
+ */
+ private static void loadDocumentFactory() {
+
+ try {
+ dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
+ dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ dbf.setNamespaceAware(true);
+ dbf.setIgnoringComments(true);
+ } catch (ParserConfigurationException e) {
+ LOG.error("Error parser configuration.");
+ throw new STORKSAMLEngineRuntimeException(e);
+ }
+
+ }
+
+ /**
+ * Method that initializes the basic services for the SAML Engine, like the
+ * OpenSAML library and the BouncyCastle provider.
+ */
+ private static void startUp() {
+
+ LOG.info("SAMLEngine: Initialize OpenSAML");
+
+ try {
+ DefaultBootstrap.bootstrap();
+ } catch (ConfigurationException e) {
+ LOG.error("Problem initializing the OpenSAML library.");
+ throw new STORKSAMLEngineRuntimeException(e);
+ }
+
+ LOG.debug("Read all file configurations. (instances of SAMLEngine)");
+ try {
+ instanceConfigs = ConfigurationReader.readConfiguration();
+ } catch (SAMLEngineException e) {
+ LOG.error("Error read configuration file.");
+ throw new STORKSAMLEngineRuntimeException(e);
+ }
+
+ LOG.debug("Create all instaces of saml engine. (instances of SAMLEngine)");
+ try {
+ instances = ConfigurationCreator
+ .createConfiguration(instanceConfigs);
+ } catch (STORKSAMLEngineException e) {
+ LOG.error("Error initializing instances from Stork SAML engine.");
+ throw new STORKSAMLEngineRuntimeException(e);
+ }
+ }
+
+ /**
+ * Instantiates a new SAML engine.
+ */
+ private SAMLEngine() {
+
+ }
+
+ /**
+ * Instantiates a new SAML engine.
+ *
+ * @param nameInstance the name instance
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ protected SAMLEngine(final String nameInstance)
+ throws STORKSAMLEngineException {
+ LOG.info("Loading Specific Configuration.");
+
+ LOG.debug("Create intance of saml messages.");
+
+ Map<String, Object> instance = instances.get(nameInstance);
+
+ if (instance == null || instance.isEmpty()) {
+ LOG.error("Instance: " + nameInstance + " not exist.");
+ throw new STORKSAMLEngineException("Instance: " + nameInstance
+ + " not exist.");
+ }
+
+ Properties properties = (Properties) instance.get(SAML_ENGINE_CONF);
+
+ if (properties == null) {
+ LOG.error("SamlEngine.xml: not exist.");
+ throw new STORKSAMLEngineException("SamlEngine.xml: not exist.");
+ }
+
+ samlCore = new STORKSAMLCore(properties);
+
+ final HashMap<String, String> propertiesSign = (HashMap<String, String>) instance
+ .get(MODULE_SIGN_CONF);
+
+ LOG.debug("Loading Module of sign.");
+ signer = SignModuleFactory.getInstance(propertiesSign
+ .get(SAML_ENGINE_SIGN_CLASS));
+
+ try {
+ LOG.info("Initialize module of sign.");
+ signer.init(propertiesSign.get(SAML_ENGINE_FILE_CONF));
+ LOG.info("Load cryptographic service provider of module of sign.");
+ signer.loadCryptServiceProvider();
+ } catch (SAMLEngineException e) {
+ LOG.error("Error create signature module: "
+ + propertiesSign.get(SAML_ENGINE_FILE_CONF));
+ LOG.info("Exception" + e);
+ throw new STORKSAMLEngineException(e);
+ }
+ }
+
+ /**
+ * Gets the Signer properties.
+ *
+ * @return the SAML Sign properties
+ */
+ protected SAMLEngineSignI getSigner() {
+ return signer;
+ }
+
+ /**
+ * Gets the SAML core properties.
+ *
+ * @return the SAML core properties
+ */
+ protected final STORKSAMLCore getSamlCoreProperties() {
+ return samlCore;
+ }
+
+ /**
+ * Method that transform the received SAML object into a byte array
+ * representation.
+ *
+ * @param samlToken the SAML token.
+ *
+ * @return the byte[] of the SAML token.
+ *
+ * @throws SAMLEngineException the SAML engine exception
+ */
+ private byte[] marshall(final XMLObject samlToken)
+ throws SAMLEngineException {
+
+ try {
+ javax.xml.parsers.DocumentBuilder docBuilder = null;
+
+ final MarshallerFactory marshallerFactory = Configuration
+ .getMarshallerFactory();
+
+ final Marshaller marshaller = marshallerFactory
+ .getMarshaller(samlToken);
+
+ docBuilder = dbf.newDocumentBuilder();
+
+ final Document doc = docBuilder.newDocument();
+
+ marshaller.marshall(samlToken, doc);
+
+ // Obtain a byte array representation of the marshalled SAML object
+ final DOMSource domSource = new DOMSource(doc);
+ final StringWriter writer = new StringWriter();
+ final StreamResult result = new StreamResult(writer);
+ final TransformerFactory transFactory = TransformerFactory
+ .newInstance();
+ Transformer transformer;
+
+ transformer = transFactory.newTransformer();
+ transformer.transform(domSource, result);
+ LOG.debug("SAML request \n"+ writer.toString());
+ return writer.toString().getBytes(CHARACTER_ENCODING);
+
+ } catch (ParserConfigurationException e) {
+ LOG.error("ParserConfigurationException.");
+ throw new SAMLEngineException(e);
+ } catch (MarshallingException e) {
+ LOG.error("MarshallingException.");
+ throw new SAMLEngineException(e);
+ } catch (TransformerConfigurationException e) {
+ LOG.error("TransformerConfigurationException.");
+ throw new SAMLEngineException(e);
+ } catch (TransformerException e) {
+ LOG.error("TransformerException.");
+ throw new SAMLEngineException(e);
+ } catch (UnsupportedEncodingException e) {
+ LOG.error("UnsupportedEncodingException: " + CHARACTER_ENCODING);
+ throw new SAMLEngineException(e);
+ }
+ }
+
+ /**
+ * Method that signs a SAML Token.
+ *
+ * @param tokenSaml the token SAML
+ *
+ * @return the SAML object sign
+ *
+ * @throws SAMLEngineException the SAML engine exception
+ */
+ private SignableSAMLObject sign(final SignableSAMLObject tokenSaml)
+ throws SAMLEngineException {
+ LOG.debug("Sign SamlToken.");
+ signer.sign(tokenSaml);
+ return tokenSaml;
+ }
+
+ /**
+ * Sign and transform to byte array.
+ *
+ * @param samlToken the SAML token
+ *
+ * @return the byte[] of the SAML token
+ *
+ * @throws SAMLEngineException the SAML engine exception
+ */
+ protected final byte[] signAndMarshall(final SignableSAMLObject samlToken)
+ throws SAMLEngineException {
+ LOG.debug("Marshall Saml Token.");
+ SignableSAMLObject signElement = sign(samlToken);
+ return marshall(signElement);
+ }
+
+ /**
+ * Method that unmarshalls a SAML Object from a byte array representation to
+ * an XML Object.
+ *
+ * @param samlToken Byte array representation of a SAML Object
+ *
+ * @return XML Object (superclass of SAMLObject)
+ *
+ * @throws SAMLEngineException the SAML engine exception
+ */
+ protected final XMLObject unmarshall(final byte[] samlToken)
+ throws SAMLEngineException {
+ try {
+ // Get parser pool manager
+ final BasicParserPool ppMgr = new BasicParserPool();
+ // Note: this is necessary due to an unresolved Xerces deferred DOM
+ // issue/bug
+ final HashMap<String, Boolean> features = new HashMap<String, Boolean>();
+ features.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
+ ppMgr.setBuilderFeatures(features);
+
+ ppMgr.setNamespaceAware(true);
+
+ // Parse SAMLToken
+ Document document = ppMgr.parse(new ByteArrayInputStream(samlToken));
+ if (document != null){
+ final Element root = document.getDocumentElement();
+ // Get appropriate unmarshaller
+ final UnmarshallerFactory unmarshallerFact = Configuration.getUnmarshallerFactory();
+ // Unmarshall using the SAML Token root element
+ if (unmarshallerFact != null && root != null){
+ final Unmarshaller unmarshaller = unmarshallerFact.getUnmarshaller(root);
+ try {
+ return unmarshaller.unmarshall(root);
+ } catch (NullPointerException e){
+ LOG.error("Error element tag incomplet or null.");
+ throw new SAMLEngineException("NullPointerException", e);
+ }
+ } else {
+ LOG.error("Error element tag incomplet or null.");
+ throw new SAMLEngineException("NullPointerException : unmarshallerFact or root is null");
+ }
+ } else {
+ LOG.error("Error element tag incomplet or null.");
+ throw new SAMLEngineException("NullPointerException : document is null");
+ }
+ } catch (XMLParserException e) {
+ LOG.error("XML Parsing Error.", e);
+ throw new SAMLEngineException(e);
+ } catch (UnmarshallingException e) {
+ LOG.error("TransformerException.", e);
+ throw new SAMLEngineException(e);
+ } catch (NullPointerException e) {
+ LOG.error("Error element tag incomplet or null.", e);
+ throw new SAMLEngineException(e);
+ }
+ }
+
+ /**
+ * Method that validates an XML Signature contained in a SAML Token.
+ *
+ * @param samlToken the SAML token
+ *
+ * @return the SAML object
+ *
+ * @throws SAMLEngineException the SAML engine exception
+ */
+ protected final SAMLObject validateSignature(
+ final SignableSAMLObject samlToken) throws SAMLEngineException {
+
+ LOG.info("Validate Signature");
+ signer.validateSignature(samlToken);
+
+ return samlToken;
+ }
+}
diff --git a/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/SAMLEngineUtils.java.svn-base b/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/SAMLEngineUtils.java.svn-base
new file mode 100644
index 000000000..60f7c3091
--- /dev/null
+++ b/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/SAMLEngineUtils.java.svn-base
@@ -0,0 +1,833 @@
+/*
+ * 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/european-union-public-licence-eupl-v.1.1
+ *
+ * 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.
+ */
+
+package eu.stork.peps.auth.engine;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.lang.StringUtils;
+import org.joda.time.DateTime;
+import org.opensaml.Configuration;
+import org.opensaml.common.SAMLVersion;
+import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
+import org.opensaml.saml2.common.Extensions;
+import org.opensaml.saml2.common.impl.ExtensionsBuilder;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.AttributeQuery;
+import org.opensaml.saml2.core.AttributeValue;
+import org.opensaml.saml2.core.AuthnContext;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.AuthnStatement;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.Status;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.core.StatusMessage;
+import org.opensaml.saml2.core.Subject;
+import org.opensaml.saml2.core.SubjectConfirmation;
+import org.opensaml.saml2.core.SubjectConfirmationData;
+import org.opensaml.saml2.core.SubjectLocality;
+import org.opensaml.saml2.core.impl.AssertionBuilder;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.schema.XSAny;
+import org.opensaml.xml.schema.XSString;
+import org.opensaml.xml.signature.KeyInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import eu.stork.peps.auth.engine.core.QAAAttribute;
+import eu.stork.peps.auth.engine.core.RequestedAttribute;
+import eu.stork.peps.auth.engine.core.SAMLCore;
+import eu.stork.peps.auth.engine.core.SPApplication;
+import eu.stork.peps.auth.engine.core.SPCountry;
+import eu.stork.peps.auth.engine.core.SPInstitution;
+import eu.stork.peps.auth.engine.core.SPSector;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+import eu.stork.peps.exceptions.STORKSAMLEngineRuntimeException;
+
+/**
+ * The Class SAMLEngineUtils.
+ *
+ * @author fjquevedo
+ * @author iinigo
+ */
+public final class SAMLEngineUtils {
+
+ /** The Constant UTF_8. */
+ public static final String UTF_8 = "UTF-8";
+
+ /** The Constant SHA_512. */
+ public static final String SHA_512 = "SHA-512";
+
+
+ /** The generator. */
+ private static SecureRandomIdentifierGenerator generator;
+
+ /** The Constant LOG. */
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SAMLEngineUtils.class.getName());
+
+ /**
+ * Method that generates a random value according to NCName grammar.
+ *
+ * NCName ::= NCNameStartChar NCNameChar* NCNameChar ::= NameChar - ':'
+ * NCNameStartChar ::= Letter | '_' NameStartChar ::= ":" | [A-Z] | "_" |
+ * [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] |
+ * [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] |
+ * [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
+ * NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] |
+ * [#x203F-#x2040] Name ::= NameStartChar (NameChar)* Letter ::= BaseChar |
+ * Ideographic BaseChar ::= [#x0041-#x005A] | [#x0061-#x007A] |
+ * [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x00FF] | [#x0100-#x0131] |
+ * [#x0134-#x013E] | [#x0141-#x0148] | [#x014A-#x017E] | [#x0180-#x01C3] |
+ * [#x01CD-#x01F0] | [#x01F4-#x01F5] | [#x01FA-#x0217] | [#x0250-#x02A8] |
+ * [#x02BB-#x02C1] | #x0386 | [#x0388-#x038A] | #x038C | [#x038E-#x03A1] |
+ * [#x03A3-#x03CE] | [#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 |
+ * [#x03E2-#x03F3] | [#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] |
+ * [#x045E-#x0481] | [#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] |
+ * [#x04D0-#x04EB] | [#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] |
+ * #x0559 | [#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] |
+ * [#x0621-#x063A] | [#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] |
+ * [#x06C0-#x06CE] | [#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] |
+ * [#x0905-#x0939] | #x093D | [#x0958-#x0961] | [#x0985-#x098C] |
+ * [#x098F-#x0990] | [#x0993-#x09A8] | [#x09AA-#x09B0] | #x09B2 |
+ * [#x09B6-#x09B9] | [#x09DC-#x09DD] | [#x09DF-#x09E1] | [#x09F0-#x09F1] |
+ * [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | [#x0A13-#x0A28] | [#x0A2A-#x0A30] |
+ * [#x0A32-#x0A33] | [#x0A35-#x0A36] | [#x0A38-#x0A39] | [#x0A59-#x0A5C] |
+ * #x0A5E | [#x0A72-#x0A74] | [#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] |
+ * [#x0A93-#x0AA8] | [#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] |
+ * #x0ABD | #x0AE0 | [#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] |
+ * [#x0B2A-#x0B30] | [#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D |
+ * [#x0B5C-#x0B5D] | [#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] |
+ * [#x0B92-#x0B95] | [#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] |
+ * [#x0BA3-#x0BA4] | [#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] |
+ * [#x0C05-#x0C0C] | [#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] |
+ * [#x0C35-#x0C39] | [#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] |
+ * [#x0C92-#x0CA8] | [#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE |
+ * [#x0CE0-#x0CE1] | [#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] |
+ * [#x0D2A-#x0D39] | [#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 |
+ * [#x0E32-#x0E33] | [#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 |
+ * [#x0E87-#x0E88] | #x0E8A | #x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] |
+ * [#x0EA1-#x0EA3] | #x0EA5 | #x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] |
+ * #x0EB0 | [#x0EB2-#x0EB3] | #x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] |
+ * [#x0F49-#x0F69] | [#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 |
+ * [#x1102-#x1103] | [#x1105-#x1107] | #x1109 | [#x110B-#x110C] |
+ * [#x110E-#x1112] | #x113C | #x113E | #x1140 | #x114C | #x114E | #x1150 |
+ * [#x1154-#x1155] | #x1159 | [#x115F-#x1161] | #x1163 | #x1165 | #x1167 |
+ * #x1169 | [#x116D-#x116E] | [#x1172-#x1173] | #x1175 | #x119E | #x11A8 |
+ * #x11AB | [#x11AE-#x11AF] | [#x11B7-#x11B8] | #x11BA | [#x11BC-#x11C2] |
+ * #x11EB | #x11F0 | #x11F9 | [#x1E00-#x1E9B] | [#x1EA0-#x1EF9] |
+ * [#x1F00-#x1F15] | [#x1F18-#x1F1D] | [#x1F20-#x1F45] | [#x1F48-#x1F4D] |
+ * [#x1F50-#x1F57] | #x1F59 | #x1F5B | #x1F5D | [#x1F5F-#x1F7D] |
+ * [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | [#x1FC2-#x1FC4] |
+ * [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | [#x1FE0-#x1FEC] |
+ * [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | [#x212A-#x212B] | #x212E |
+ * [#x2180-#x2182] | [#x3041-#x3094] | [#x30A1-#x30FA] | [#x3105-#x312C] |
+ * [#xAC00-#xD7A3] Ideographic ::= [#x4E00-#x9FA5] | #x3007 |
+ * [#x3021-#x3029]
+ *
+ * @return Random ID value
+ */
+
+ //Initialization of a generator of identifiers for all token SAML.
+
+ static {
+ loadRandomIdentifierGenerator();
+ }
+
+
+ /**
+ * Load random identifier generator.
+ *
+ *@throws STORKSAMLEngineRuntimeException the STORKSAML engine runtime exception
+ */
+ private static void loadRandomIdentifierGenerator() {
+
+ try {
+ generator = new SecureRandomIdentifierGenerator();
+ } catch (NoSuchAlgorithmException ex) {
+ LOG.error("Error init SecureRandomIdentifierGenerator", ex);
+ throw new STORKSAMLEngineRuntimeException(ex);
+ }
+
+ }
+
+ /**
+ * Creates the SAML object.
+ *
+ * @param qname the QName
+ *
+ * @return the XML object
+ */
+ public static XMLObject createSamlObject(final QName qname) {
+ return Configuration.getBuilderFactory().getBuilder(qname).buildObject(
+ qname);
+ }
+
+ /**
+ * Creates the SAML object.
+ *
+ * @param qname the quality name
+ * @param qname1 the qname1
+ *
+ * @return the xML object
+ */
+ public static XMLObject createSamlObject(final QName qname,
+ final QName qname1) {
+ return Configuration.getBuilderFactory().getBuilder(qname1)
+ .buildObject(qname, qname1);
+ }
+
+ /**
+ * Encode value with an specific algorithm.
+ *
+ * @param value the value
+ * @param alg the algorithm
+ *
+ * @return the string
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public static String encode(final String value, final String alg)
+ throws STORKSAMLEngineException {
+ LOG.debug("Encode value with " + alg + " algorithm.");
+ byte[] buffer;
+
+ final StringBuffer hash = new StringBuffer("");
+ try {
+ buffer = value.getBytes(UTF_8);
+ MessageDigest msgDig;
+ msgDig = MessageDigest.getInstance(alg);
+
+
+ msgDig.update(buffer);
+ final byte[] digest = msgDig.digest();
+
+ final int signedByte = 0xff;
+ for (byte aux : digest) {
+ final int byt = aux & signedByte;
+ if (Integer.toHexString(byt).length() == 1) {
+ hash.append('0');
+ }
+ hash.append(Integer.toHexString(byt));
+ }
+
+ } catch (UnsupportedEncodingException e1) {
+ LOG.error("UnsupportedEncodingException: " + UTF_8);
+ throw new STORKSAMLEngineException(e1);
+ } catch (NoSuchAlgorithmException e) {
+ LOG.error("NoSuchAlgorithmException: " + alg);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ return hash.toString();
+ }
+
+ /**
+ * Generate assertion.
+ *
+ * @param version the version
+ * @param identifier the identifier
+ * @param issueInstant the issue instant
+ * @param issuer the issuer
+ *
+ * @return the assertion
+ */
+ public static Assertion generateAssertion(final SAMLVersion version,
+ final String identifier, final DateTime issueInstant,
+ final Issuer issuer) {
+ final AssertionBuilder assertionBuilder = new AssertionBuilder();
+ final Assertion assertion = assertionBuilder.buildObject();
+ assertion.setVersion(version);
+ assertion.setID(identifier);
+ assertion.setIssueInstant(issueInstant);
+
+ // <saml:Issuer>
+ assertion.setIssuer(issuer);
+ return assertion;
+ }
+
+ /**
+ * Generate authentication statement.
+ *
+ * @param authnInstant the authentication instant
+ * @param authnContext the authentication context
+ *
+ * @return the authentication statement
+ */
+ public static AuthnStatement generateAthnStatement(final DateTime authnInstant,
+ final AuthnContext authnContext) {
+ // <saml:AuthnStatement>
+ final AuthnStatement authnStatement = (AuthnStatement) SAMLEngineUtils
+ .createSamlObject(AuthnStatement.DEFAULT_ELEMENT_NAME);
+
+ authnStatement.setAuthnInstant(authnInstant);
+ authnStatement.setAuthnContext(authnContext);
+
+ return authnStatement;
+ }
+
+
+
+
+
+ /**
+ * Generate attribute from a list of values.
+ *
+ * @param name the name of the attribute.
+ * @param status the status of the parameter: "Available", "NotAvailable" or
+ * "Withheld".
+ * @param values the value of the attribute.
+ * @param isHashing the is hashing with "SHA-512" algorithm.
+ * @return the attribute
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public static Attribute generateAttrComplex(final String name,
+ final String status, final Map<String, String> values,
+ final boolean isHashing) throws STORKSAMLEngineException {
+ LOG.debug("Generate attribute complex: " + name);
+ final Attribute attribute = (Attribute) SAMLEngineUtils
+ .createSamlObject(Attribute.DEFAULT_ELEMENT_NAME);
+
+ attribute.setName(name);
+ attribute.setNameFormat(Attribute.URI_REFERENCE);
+
+ attribute.getUnknownAttributes().put(
+ new QName(SAMLCore.STORK10_NS.getValue(), "AttributeStatus",
+ SAMLCore.STORK10_PREFIX.getValue()), status);
+
+ if (!values.isEmpty()) {
+ LOG.debug("Add attribute values.");
+
+ // Create an attribute that contains all XSAny elements.
+ final XSAny attrValue = (XSAny) SAMLEngineUtils.createSamlObject(
+ AttributeValue.DEFAULT_ELEMENT_NAME, XSAny.TYPE_NAME);
+
+ final Iterator<Entry<String, String>> iterator = values.entrySet()
+ .iterator();
+ while (iterator.hasNext()) {
+ final Map.Entry<String, String> pairs = iterator.next();
+
+ final String value = pairs.getValue();
+
+ if (StringUtils.isNotBlank(value)) {
+ // Create the attribute statement
+ final XSAny attrValueSimple = (XSAny) SAMLEngineUtils
+ .createSamlObject(new QName(SAMLCore.STORK10_NS.getValue(),
+ pairs.getKey().toString(),
+ SAMLCore.STORK10_PREFIX.getValue()), XSAny.TYPE_NAME);
+
+ // if it's necessary encode the information.
+ if (isHashing) {
+ attrValueSimple
+ .setTextContent(encode(value, SHA_512));
+ } else {
+ attrValueSimple.setTextContent(value);
+ }
+
+ attrValue.getUnknownXMLObjects().add(attrValueSimple);
+ attribute.getAttributeValues().add(attrValue);
+ }
+ }
+
+ }
+ return attribute;
+ }
+
+ /**
+ * Generate extension.
+ *
+ * @return the extensions
+ */
+ public static Extensions generateExtension() {
+ final ExtensionsBuilder extensionsBuilder = new ExtensionsBuilder();
+ return extensionsBuilder.buildObject(
+ "urn:oasis:names:tc:SAML:2.0:protocol", "Extensions", "saml2p");
+ }
+
+
+
+
+ /**
+ * Generate issuer.
+ *
+ * @return the issuer
+ */
+ public static Issuer generateIssuer() {
+ return (Issuer) SAMLEngineUtils
+ .createSamlObject(Issuer.DEFAULT_ELEMENT_NAME);
+ }
+
+ /**
+ * Generate key info.
+ *
+ * @return the key info
+ */
+ public static KeyInfo generateKeyInfo() {
+ return (KeyInfo) SAMLEngineUtils
+ .createSamlObject(KeyInfo.DEFAULT_ELEMENT_NAME);
+ }
+
+ /**
+ * Generate name id.
+ *
+ * @return the name id
+ */
+ public static NameID generateNameID() {
+ return (NameID) SAMLEngineUtils
+ .createSamlObject(NameID.DEFAULT_ELEMENT_NAME);
+ }
+
+ /**
+ * Generate name id.
+ *
+ * @param nameQualifier the name qualifier
+ * @param format the format
+ * @param spNameQualifier the sP name qualifier
+ *
+ * @return the name id
+ */
+ public static NameID generateNameID(final String nameQualifier,
+ final String format, final String spNameQualifier) {
+ // <saml:NameID>
+ final NameID nameId = (NameID) Configuration.getBuilderFactory()
+ .getBuilder(NameID.DEFAULT_ELEMENT_NAME).buildObject(
+ NameID.DEFAULT_ELEMENT_NAME);
+
+ // optional
+ nameId.setNameQualifier(nameQualifier);
+
+ // optional
+ nameId.setFormat(format);
+
+ // optional
+ nameId.setSPNameQualifier(spNameQualifier);
+
+ return nameId;
+ }
+
+ /**
+ * Generate NCName.
+ *
+ * @return the string
+ */
+ public static String generateNCName() {
+ return generator.generateIdentifier();
+ }
+
+
+ /**
+ * Generate the quality authentication assurance level.
+ *
+ * @param qaal the level of quality authentication assurance.
+ *
+ * @return the quality authentication assurance attribute
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public static QAAAttribute generateQAAAttribute(final int qaal)
+ throws STORKSAMLEngineException {
+ LOG.debug("Generate QAAAttribute.");
+
+ final QAAAttribute qaaAttribute = (QAAAttribute) SAMLEngineUtils
+ .createSamlObject(QAAAttribute.DEF_ELEMENT_NAME);
+ qaaAttribute.setQaaLevel(String.valueOf(qaal));
+ return qaaAttribute;
+ }
+
+ /**
+ * Generate requested attribute.
+ *
+ * @param name the name
+ * @param friendlyName the friendly name
+ * @param isRequired the is required
+ * @param value the value
+ *
+ * @return the requested attribute
+ */
+ public static RequestedAttribute generateReqAuthnAttributeSimple(
+ final String name, final String friendlyName,
+ final String isRequired, final List<String> value) {
+ LOG.debug("Generate the requested attribute.");
+
+ final RequestedAttribute requested = (RequestedAttribute) SAMLEngineUtils
+ .createSamlObject(RequestedAttribute.DEF_ELEMENT_NAME);
+ requested.setName(name);
+ requested.setNameFormat(RequestedAttribute.URI_REFERENCE);
+
+ requested.setFriendlyName(friendlyName);
+
+ requested.setIsRequired(isRequired);
+
+ // The value is optional in an authentication request.
+ if (!value.isEmpty()) {
+ for (int nextValue = 0; nextValue < value.size(); nextValue++) {
+ final String valor = value.get(nextValue);
+ if (StringUtils.isNotBlank(valor)) {
+
+ if(!name.equals("http://www.stork.gov.eu/1.0/signedDoc")){
+
+ // Create the attribute statement
+ final XSAny attrValue = (XSAny) SAMLEngineUtils
+ .createSamlObject(
+ new QName(SAMLCore.STORK10_NS.getValue(),
+ "AttributeValue",
+ SAMLCore.STORK10_PREFIX.getValue()),
+ XSAny.TYPE_NAME);
+
+ attrValue.setTextContent(valor.trim());
+ requested.getAttributeValues().add(attrValue);
+
+ }else{
+
+ DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
+ domFactory.setNamespaceAware(true);
+ Document document = null;
+ DocumentBuilder builder;
+
+ // Parse the signedDoc value into an XML DOM Document
+ try {
+ builder = domFactory.newDocumentBuilder();
+ InputStream is;
+ is = new ByteArrayInputStream(valor.trim().getBytes("UTF-8"));
+ document = builder.parse(is);
+ is.close();
+ } catch (SAXException e1) {
+ LOG.error("SAX Error while parsing signModule attribute", e1);
+ throw new STORKSAMLEngineRuntimeException(e1);
+ } catch (ParserConfigurationException e2) {
+ LOG.error("Parser Configuration Error while parsing signModule attribute", e2);
+ throw new STORKSAMLEngineRuntimeException(e2);
+ } catch (UnsupportedEncodingException e3) {
+ LOG.error("Unsupported encoding Error while parsing signModule attribute", e3);
+ throw new STORKSAMLEngineRuntimeException(e3);
+ } catch (IOException e4) {
+ LOG.error("IO Error while parsing signModule attribute", e4);
+ throw new STORKSAMLEngineRuntimeException(e4);
+ }
+
+ // Create the XML statement(this will be overwritten with the previous DOM structure)
+ final XSAny xmlValue = (XSAny) SAMLEngineUtils
+ .createSamlObject(
+ new QName(SAMLCore.STORK10_NS.getValue(),
+ "XMLValue",
+ SAMLCore.STORK10_PREFIX.getValue()),
+ XSAny.TYPE_NAME);
+
+ //Set the signedDoc XML content to this element
+ xmlValue.setDOM(document.getDocumentElement());
+
+ // Create the attribute statement
+ final XSAny attrValue = (XSAny) SAMLEngineUtils
+ .createSamlObject(
+ new QName(SAMLCore.STORK10_NS.getValue(),
+ "AttributeValue",
+ SAMLCore.STORK10_PREFIX.getValue()),
+ XSAny.TYPE_NAME);
+
+ //Add previous signedDocXML to the AttributeValue Element
+ attrValue.getUnknownXMLObjects().add(xmlValue);
+
+ requested.getAttributeValues().add(attrValue);
+ }
+
+
+ }
+ }
+ }
+
+ return requested;
+ }
+
+ /**
+ * Generate response.
+ *
+ * @param version the version
+ * @param identifier the identifier
+ * @param issueInstant the issue instant
+ * @param status the status
+ *
+ * @return the response
+ */
+ public static Response generateResponse(final SAMLVersion version,
+ final String identifier, final DateTime issueInstant,
+ final Status status) {
+ final Response response = (Response) SAMLEngineUtils
+ .createSamlObject(Response.DEFAULT_ELEMENT_NAME);
+ response.setID(identifier);
+ response.setIssueInstant(issueInstant);
+ response.setStatus(status);
+ return response;
+ }
+
+ /**
+ * Method that generates a SAML Authentication Request basing on the
+ * provided information.
+ *
+ * @param identifier the identifier
+ * @param version the version
+ * @param issueInstant the issue instant
+ *
+ * @return the authentication request
+ */
+ public static AuthnRequest generateSAMLAuthnRequest(final String identifier,
+ final SAMLVersion version, final DateTime issueInstant) {
+ LOG.debug("Generate basic authentication request.");
+ final AuthnRequest authnRequest = (AuthnRequest) SAMLEngineUtils
+ .createSamlObject(AuthnRequest.DEFAULT_ELEMENT_NAME);
+
+ authnRequest.setID(identifier);
+ authnRequest.setVersion(version);
+ authnRequest.setIssueInstant(issueInstant);
+ return authnRequest;
+ }
+
+ public static AttributeQuery generateSAMLAttrQueryRequest(final String identifier,
+ final SAMLVersion version, final DateTime issueInstant) {
+ LOG.debug("Generate attribute query request.");
+ final AttributeQuery attrQueryRequest = (AttributeQuery) SAMLEngineUtils
+ .createSamlObject(AttributeQuery.DEFAULT_ELEMENT_NAME);
+
+ attrQueryRequest.setID(identifier);
+ attrQueryRequest.setVersion(version);
+ attrQueryRequest.setIssueInstant(issueInstant);
+ return attrQueryRequest;
+ }
+
+ /**
+ * Generate service provider application.
+ *
+ * @param spApplication the service provider application
+ *
+ * @return the sP application
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public static SPApplication generateSPApplication(final String spApplication)
+ throws STORKSAMLEngineException {
+ LOG.debug("Generate SPApplication.");
+
+ final SPApplication applicationAttr = (SPApplication) SAMLEngineUtils
+ .createSamlObject(SPApplication.DEF_ELEMENT_NAME);
+ applicationAttr.setSPApplication(spApplication);
+ return applicationAttr;
+ }
+
+ /**
+ * Generate service provider country.
+ *
+ * @param spCountry the service provider country
+ *
+ * @return the service provider country
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public static SPCountry generateSPCountry(final String spCountry)
+ throws STORKSAMLEngineException {
+ LOG.debug("Generate SPApplication.");
+
+ final SPCountry countryAttribute = (SPCountry) SAMLEngineUtils
+ .createSamlObject(SPCountry.DEF_ELEMENT_NAME);
+ countryAttribute.setSPCountry(spCountry);
+ return countryAttribute;
+ }
+
+ /**
+ * Generate service provider institution.
+ *
+ * @param spInstitution the service provider institution
+ *
+ * @return the service provider institution
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public static SPInstitution generateSPInstitution(final String spInstitution)
+ throws STORKSAMLEngineException {
+ LOG.debug("Generate SPInstitution.");
+
+ final SPInstitution institutionAttr = (SPInstitution) SAMLEngineUtils
+ .createSamlObject(SPInstitution.DEF_ELEMENT_NAME);
+ institutionAttr.setSPInstitution(spInstitution);
+ return institutionAttr;
+ }
+
+ /**
+ * Generate service provider sector.
+ *
+ * @param spSector the service provider sector
+ *
+ * @return the service provider sector
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public static SPSector generateSPSector(final String spSector)
+ throws STORKSAMLEngineException {
+ LOG.debug("Generate SPSector.");
+
+ final SPSector sectorAttribute = (SPSector) SAMLEngineUtils
+ .createSamlObject(SPSector.DEF_ELEMENT_NAME);
+ sectorAttribute.setSPSector(spSector);
+ return sectorAttribute;
+ }
+
+ /**
+ * Generate status.
+ *
+ * @param statusCode the status code
+ *
+ * @return the status
+ */
+ public static Status generateStatus(final StatusCode statusCode) {
+ final Status status = (Status) SAMLEngineUtils
+ .createSamlObject(Status.DEFAULT_ELEMENT_NAME);
+ status.setStatusCode(statusCode);
+ return status;
+ }
+
+ /**
+ * Generate status code.
+ *
+ * @param value the value
+ *
+ * @return the status code
+ */
+ public static StatusCode generateStatusCode(final String value) {
+ final StatusCode statusCode = (StatusCode) SAMLEngineUtils
+ .createSamlObject(StatusCode.DEFAULT_ELEMENT_NAME);
+ statusCode.setValue(value);
+ return statusCode;
+ }
+
+
+ /**
+ * Generate status message.
+ *
+ * @param message the message
+ *
+ * @return the status message
+ */
+ public static StatusMessage generateStatusMessage(final String message) {
+ final StatusMessage statusMessage = (StatusMessage) SAMLEngineUtils
+ .createSamlObject(StatusMessage.DEFAULT_ELEMENT_NAME);
+ statusMessage.setMessage(message);
+ return statusMessage;
+ }
+
+ /**
+ * Generate subject.
+ *
+ * @return the subject
+ */
+ public static Subject generateSubject() {
+ return (Subject) SAMLEngineUtils
+ .createSamlObject(Subject.DEFAULT_ELEMENT_NAME);
+ }
+
+ /**
+ * Generate subject confirmation.
+ *
+ * @param method the method
+ * @param data the data
+ *
+ * @return the subject confirmation
+ */
+ public static SubjectConfirmation generateSubjectConfirmation(
+ final String method, final SubjectConfirmationData data) {
+ final SubjectConfirmation subjectConf = (SubjectConfirmation) Configuration
+ .getBuilderFactory().getBuilder(
+ SubjectConfirmation.DEFAULT_ELEMENT_NAME).buildObject(
+ SubjectConfirmation.DEFAULT_ELEMENT_NAME);
+
+ subjectConf.setMethod(method);
+
+ subjectConf.setSubjectConfirmationData(data);
+
+ return subjectConf;
+ }
+
+
+ /**
+ * Generate subject confirmation data.
+ *
+ * @param notOnOrAfter the not on or after
+ * @param recipient the recipient
+ * @param inResponseTo the in response to
+ *
+ * @return the subject confirmation data
+ */
+ public static SubjectConfirmationData generateSubjectConfirmationData(
+ final DateTime notOnOrAfter, final String recipient,
+ final String inResponseTo) {
+ final SubjectConfirmationData subjectConfData = (SubjectConfirmationData) SAMLEngineUtils
+ .createSamlObject(SubjectConfirmationData.DEFAULT_ELEMENT_NAME);
+ subjectConfData.setNotOnOrAfter(notOnOrAfter);
+ subjectConfData.setRecipient(recipient);
+ subjectConfData.setInResponseTo(inResponseTo);
+ return subjectConfData;
+ }
+
+
+ /**
+ * Generate subject locality.
+ *
+ * @param address the address
+ *
+ * @return the subject locality
+ */
+ public static SubjectLocality generateSubjectLocality(final String address) {
+ final SubjectLocality subjectLocality = (SubjectLocality) SAMLEngineUtils
+ .createSamlObject(SubjectLocality.DEFAULT_ELEMENT_NAME);
+ subjectLocality.setAddress(address);
+ return subjectLocality;
+ }
+
+
+
+
+ /**
+ * Method that returns the current time.
+ *
+ * @return the current time
+ */
+ public static DateTime getCurrentTime() {
+ return new DateTime();
+ }
+
+
+ /**
+ * Instantiates a new SAML engine utilities.
+ */
+ private SAMLEngineUtils() {
+ }
+
+}
diff --git a/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/STORKSAMLEngine.java.svn-base b/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/STORKSAMLEngine.java.svn-base
new file mode 100644
index 000000000..3cac2f637
--- /dev/null
+++ b/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/STORKSAMLEngine.java.svn-base
@@ -0,0 +1,2983 @@
+/*
+ * 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/european-union-public-licence-eupl-v.1.1
+ *
+ * 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.
+ */
+
+package eu.stork.peps.auth.engine;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.lang.StringUtils;
+import org.bouncycastle.jce.X509Principal;
+import org.joda.time.DateTime;
+import org.opensaml.Configuration;
+import org.opensaml.common.SAMLVersion;
+import org.opensaml.common.SignableSAMLObject;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.common.Extensions;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.AttributeQuery;
+import org.opensaml.saml2.core.AttributeStatement;
+import org.opensaml.saml2.core.AttributeValue;
+import org.opensaml.saml2.core.Audience;
+import org.opensaml.saml2.core.AudienceRestriction;
+import org.opensaml.saml2.core.AuthnContext;
+import org.opensaml.saml2.core.AuthnContextDecl;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.AuthnStatement;
+import org.opensaml.saml2.core.Conditions;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.OneTimeUse;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.Status;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.core.StatusMessage;
+import org.opensaml.saml2.core.Subject;
+import org.opensaml.saml2.core.SubjectConfirmation;
+import org.opensaml.saml2.core.SubjectConfirmationData;
+import org.opensaml.saml2.core.SubjectLocality;
+import org.opensaml.saml2.core.impl.SubjectConfirmationBuilder;
+import org.opensaml.xml.Namespace;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.schema.XSAny;
+import org.opensaml.xml.schema.impl.XSAnyBuilder;
+import org.opensaml.xml.schema.impl.XSAnyImpl;
+import org.opensaml.xml.schema.impl.XSAnyMarshaller;
+import org.opensaml.xml.schema.impl.XSAnyUnmarshaller;
+import org.opensaml.xml.schema.impl.XSStringImpl;
+import org.opensaml.xml.signature.KeyInfo;
+import org.opensaml.xml.util.Base64;
+import org.opensaml.xml.validation.ValidationException;
+import org.opensaml.xml.validation.Validator;
+import org.opensaml.xml.validation.ValidatorSuite;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+import eu.stork.peps.auth.commons.STORKAttrQueryRequest;
+import eu.stork.peps.auth.commons.STORKAttrQueryResponse;
+import eu.stork.peps.auth.commons.STORKAuthnRequest;
+import eu.stork.peps.auth.commons.STORKAuthnResponse;
+import eu.stork.peps.auth.engine.core.AuthenticationAttributes;
+import eu.stork.peps.auth.engine.core.CitizenCountryCode;
+import eu.stork.peps.auth.engine.core.EIDCrossBorderShare;
+import eu.stork.peps.auth.engine.core.EIDCrossSectorShare;
+import eu.stork.peps.auth.engine.core.EIDSectorShare;
+import eu.stork.peps.auth.engine.core.QAAAttribute;
+import eu.stork.peps.auth.engine.core.RequestedAttribute;
+import eu.stork.peps.auth.engine.core.RequestedAttributes;
+import eu.stork.peps.auth.engine.core.SAMLCore;
+import eu.stork.peps.auth.engine.core.SPApplication;
+import eu.stork.peps.auth.engine.core.SPCountry;
+import eu.stork.peps.auth.engine.core.SPID;
+import eu.stork.peps.auth.engine.core.SPInformation;
+import eu.stork.peps.auth.engine.core.SPInstitution;
+import eu.stork.peps.auth.engine.core.SPSector;
+import eu.stork.peps.auth.engine.core.VIDPAuthenticationAttributes;
+import eu.stork.peps.auth.engine.core.impl.AuthenticationAttributesBuilder;
+import eu.stork.peps.auth.engine.core.impl.AuthenticationAttributesMarshaller;
+import eu.stork.peps.auth.engine.core.impl.AuthenticationAttributesUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.CitizenCountryCodeBuilder;
+import eu.stork.peps.auth.engine.core.impl.CitizenCountryCodeMarshaller;
+import eu.stork.peps.auth.engine.core.impl.CitizenCountryCodeUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.EIDCrossBorderShareBuilder;
+import eu.stork.peps.auth.engine.core.impl.EIDCrossBorderShareMarshaller;
+import eu.stork.peps.auth.engine.core.impl.EIDCrossBorderShareUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.EIDCrossSectorShareBuilder;
+import eu.stork.peps.auth.engine.core.impl.EIDCrossSectorShareMarshaller;
+import eu.stork.peps.auth.engine.core.impl.EIDCrossSectorShareUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.EIDSectorShareBuilder;
+import eu.stork.peps.auth.engine.core.impl.EIDSectorShareMarshaller;
+import eu.stork.peps.auth.engine.core.impl.EIDSectorShareUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.QAAAttributeBuilder;
+import eu.stork.peps.auth.engine.core.impl.QAAAttributeMarshaller;
+import eu.stork.peps.auth.engine.core.impl.QAAAttributeUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.RequestedAttributeBuilder;
+import eu.stork.peps.auth.engine.core.impl.RequestedAttributeMarshaller;
+import eu.stork.peps.auth.engine.core.impl.RequestedAttributeUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.RequestedAttributesBuilder;
+import eu.stork.peps.auth.engine.core.impl.RequestedAttributesMarshaller;
+import eu.stork.peps.auth.engine.core.impl.RequestedAttributesUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPApplicationBuilder;
+import eu.stork.peps.auth.engine.core.impl.SPApplicationMarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPApplicationUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPCountryBuilder;
+import eu.stork.peps.auth.engine.core.impl.SPCountryMarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPCountryUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPIDBuilder;
+import eu.stork.peps.auth.engine.core.impl.SPIDMarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPIDUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPInformationBuilder;
+import eu.stork.peps.auth.engine.core.impl.SPInformationMarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPInformationUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPInstitutionBuilder;
+import eu.stork.peps.auth.engine.core.impl.SPInstitutionMarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPInstitutionUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPSectorBuilder;
+import eu.stork.peps.auth.engine.core.impl.SPSectorMarshaller;
+import eu.stork.peps.auth.engine.core.impl.SPSectorUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.VIDPAuthenticationAttributesBuilder;
+import eu.stork.peps.auth.engine.core.impl.VIDPAuthenticationAttributesMarshaller;
+import eu.stork.peps.auth.engine.core.impl.VIDPAuthenticationAttributesUnmarshaller;
+import eu.stork.peps.auth.engine.core.validator.ExtensionsSchemaValidator;
+import eu.stork.peps.auth.engine.core.validator.QAAAttributeSchemaValidator;
+import eu.stork.peps.exceptions.SAMLEngineException;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+import eu.stork.peps.exceptions.STORKSAMLEngineRuntimeException;
+
+/**
+ * Class that wraps the operations over SAML tokens, both generation and
+ * validation of SAML STORK requests and SAML STORK responses. Complaint with
+ * "OASIS Secure Assertion Markup Language (SAML) 2.0, May 2005", but taking
+ * into account STORK specific requirements.
+ *
+ * @author fjquevedo
+ * @author iinigo
+ */
+public final class STORKSAMLEngine extends SAMLEngine {
+
+ /** The Constant LOG. */
+ private static final Logger LOG = LoggerFactory
+ .getLogger(STORKSAMLEngine.class.getName());
+
+ private static final String ATTRIBUTE_EMPTY_LITERAL = "Attribute name is null or empty.";
+ /**
+ * Gets the single instance of STORKSAMLEngine.
+ *
+ * @param nameInstance the name instance
+ *
+ * @return single instance of STORKSAMLEngine
+ */
+ public static synchronized STORKSAMLEngine getInstance(
+ final String nameInstance) {
+ STORKSAMLEngine engine = null;
+ LOG.info("Get instance: " + nameInstance);
+ try {
+ engine = new STORKSAMLEngine(nameInstance.trim());
+ } catch (Exception e) {
+ LOG.error("Error get instance: " + nameInstance);
+ }
+ return engine;
+ }
+
+ /**
+ * Instantiate a new STORKSAML engine.
+ *
+ * @param nameInstance the name instance
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private STORKSAMLEngine(final String nameInstance)
+ throws STORKSAMLEngineException {
+ // Initialization OpenSAML.
+ super(nameInstance);
+ LOG.info("Register STORK objects provider.");
+ Configuration.registerObjectProvider(QAAAttribute.DEF_ELEMENT_NAME,
+ new QAAAttributeBuilder(), new QAAAttributeMarshaller(),
+ new QAAAttributeUnmarshaller());
+
+ Configuration.registerObjectProvider(EIDSectorShare.DEF_ELEMENT_NAME,
+ new EIDSectorShareBuilder(), new EIDSectorShareMarshaller(),
+ new EIDSectorShareUnmarshaller());
+
+ Configuration.registerObjectProvider(
+ EIDCrossSectorShare.DEF_ELEMENT_NAME,
+ new EIDCrossSectorShareBuilder(),
+ new EIDCrossSectorShareMarshaller(),
+ new EIDCrossSectorShareUnmarshaller());
+
+ Configuration.registerObjectProvider(
+ EIDCrossBorderShare.DEF_ELEMENT_NAME,
+ new EIDCrossBorderShareBuilder(),
+ new EIDCrossBorderShareMarshaller(),
+ new EIDCrossBorderShareUnmarshaller());
+
+ Configuration.registerObjectProvider(SPSector.DEF_ELEMENT_NAME,
+ new SPSectorBuilder(), new SPSectorMarshaller(),
+ new SPSectorUnmarshaller());
+
+ Configuration.registerObjectProvider(SPInstitution.DEF_ELEMENT_NAME,
+ new SPInstitutionBuilder(), new SPInstitutionMarshaller(),
+ new SPInstitutionUnmarshaller());
+
+ Configuration.registerObjectProvider(SPApplication.DEF_ELEMENT_NAME,
+ new SPApplicationBuilder(), new SPApplicationMarshaller(),
+ new SPApplicationUnmarshaller());
+
+ Configuration.registerObjectProvider(SPCountry.DEF_ELEMENT_NAME,
+ new SPCountryBuilder(), new SPCountryMarshaller(),
+ new SPCountryUnmarshaller());
+
+ Configuration.registerObjectProvider(XSAny.TYPE_NAME,
+ new XSAnyBuilder(), new XSAnyMarshaller(),
+ new XSAnyUnmarshaller());
+
+ Configuration.registerObjectProvider(
+ RequestedAttribute.DEF_ELEMENT_NAME,
+ new RequestedAttributeBuilder(),
+ new RequestedAttributeMarshaller(),
+ new RequestedAttributeUnmarshaller());
+
+ Configuration.registerObjectProvider(
+ RequestedAttributes.DEF_ELEMENT_NAME,
+ new RequestedAttributesBuilder(),
+ new RequestedAttributesMarshaller(),
+ new RequestedAttributesUnmarshaller());
+
+ Configuration.registerObjectProvider(
+ AuthenticationAttributes.DEF_ELEMENT_NAME,
+ new AuthenticationAttributesBuilder(),
+ new AuthenticationAttributesMarshaller(),
+ new AuthenticationAttributesUnmarshaller());
+
+ Configuration.registerObjectProvider(
+ VIDPAuthenticationAttributes.DEF_ELEMENT_NAME,
+ new VIDPAuthenticationAttributesBuilder(),
+ new VIDPAuthenticationAttributesMarshaller(),
+ new VIDPAuthenticationAttributesUnmarshaller());
+
+ Configuration.registerObjectProvider(
+ CitizenCountryCode.DEF_ELEMENT_NAME,
+ new CitizenCountryCodeBuilder(),
+ new CitizenCountryCodeMarshaller(),
+ new CitizenCountryCodeUnmarshaller());
+
+ Configuration.registerObjectProvider(
+ SPID.DEF_ELEMENT_NAME,
+ new SPIDBuilder(),
+ new SPIDMarshaller(),
+ new SPIDUnmarshaller());
+
+ Configuration.registerObjectProvider(
+ SPInformation.DEF_ELEMENT_NAME,
+ new SPInformationBuilder(),
+ new SPInformationMarshaller(),
+ new SPInformationUnmarshaller());
+
+ LOG.info("Register STORK object validators.");
+ final ValidatorSuite validatorSuite = new ValidatorSuite(
+ QAAAttribute.DEF_LOCAL_NAME);
+
+ validatorSuite.registerValidator(QAAAttribute.DEF_ELEMENT_NAME,
+ new QAAAttributeSchemaValidator());
+ final Extensions extensions = SAMLEngineUtils.generateExtension();
+ validatorSuite.registerValidator(extensions.getElementQName(),
+ new ExtensionsSchemaValidator());
+
+ Configuration.registerValidatorSuite(
+ "stork:QualityAuthenticationAssuranceLevel", validatorSuite);
+
+ }
+
+ /**
+ * Generate authentication response base.
+ *
+ * @param status the status
+ * @param assertConsumerURL the assert consumer URL.
+ * @param inResponseTo the in response to
+ *
+ * @return the response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private Response genAuthnRespBase(final Status status,
+ final String assertConsumerURL, final String inResponseTo)
+ throws STORKSAMLEngineException {
+ LOG.debug("Generate Authentication Response base.");
+ final Response response = SAMLEngineUtils.generateResponse(
+ SAMLVersion.VERSION_20, SAMLEngineUtils.generateNCName(),
+ SAMLEngineUtils.getCurrentTime(), status);
+
+ // Set name Spaces
+ this.setNameSpaces(response);
+
+ // Mandatory STORK
+ LOG.debug("Generate Issuer");
+ final Issuer issuer = SAMLEngineUtils.generateIssuer();
+ issuer.setValue(super.getSamlCoreProperties().getResponder());
+
+ // Format Entity Optional STORK
+ issuer.setFormat(super.getSamlCoreProperties().getFormatEntity());
+
+ response.setIssuer(issuer);
+
+ // destination Mandatory Stork
+ response.setDestination(assertConsumerURL.trim());
+
+ // inResponseTo Mandatory Stork
+ response.setInResponseTo(inResponseTo.trim());
+
+ // Optional STORK
+ response.setConsent(super.getSamlCoreProperties()
+ .getConsentAuthnResponse());
+
+ return response;
+ }
+
+ /**
+ * Generate attribute query response base.
+ *
+ * @param status the status
+ * @param destinationURL the assert consumer URL.
+ * @param inResponseTo the in response to
+ *
+ * @return the response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private Response genAttrQueryRespBase(final Status status,
+ final String destinationURL, final String inResponseTo)
+ throws STORKSAMLEngineException {
+ LOG.debug("Generate Attribute query Response base.");
+ final Response response = SAMLEngineUtils.generateResponse(
+ SAMLVersion.VERSION_20, SAMLEngineUtils.generateNCName(),
+ SAMLEngineUtils.getCurrentTime(), status);
+
+ // Set name Spaces
+ this.setNameSpaces(response);
+
+ // Mandatory STORK
+ LOG.debug("Generate Issuer");
+ final Issuer issuer = SAMLEngineUtils.generateIssuer();
+ issuer.setValue(super.getSamlCoreProperties().getResponder());
+
+ // Format Entity Optional STORK
+ issuer.setFormat(super.getSamlCoreProperties().getFormatEntity());
+
+ response.setIssuer(issuer);
+
+ // destination Mandatory Stork
+ response.setDestination(destinationURL.trim());
+
+ // inResponseTo Mandatory Stork
+ response.setInResponseTo(inResponseTo.trim());
+
+ // Optional STORK
+ response.setConsent(super.getSamlCoreProperties()
+ .getConsentAuthnResponse());
+
+ return response;
+ }
+
+ /**
+ * Generate assertion.
+ *
+ * @param ipAddress the IP address.
+ * @param assertConsumerURL the assert consumer URL.
+ * @param inResponseTo the in response to
+ * @param issuer the issuer
+ * @param notOnOrAfter the not on or after
+ *
+ * @return the assertion
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private Assertion generateAssertion(final String ipAddress,
+ final String assertConsumerURL, final String inResponseTo,
+ final String issuer, final DateTime notOnOrAfter)
+ throws STORKSAMLEngineException {
+ LOG.info("Generate Assertion.");
+
+ // Mandatory STORK
+ LOG.debug("Generate Issuer to Assertion");
+ final Issuer issuerAssertion = SAMLEngineUtils.generateIssuer();
+ issuerAssertion.setValue(super.getSamlCoreProperties().getResponder());
+
+ // Format Entity Optional STORK
+ issuerAssertion.setFormat(super.getSamlCoreProperties()
+ .getFormatEntity());
+
+ final Assertion assertion = SAMLEngineUtils.generateAssertion(
+ SAMLVersion.VERSION_20, SAMLEngineUtils.generateNCName(),
+ SAMLEngineUtils.getCurrentTime(), issuerAssertion);
+
+ final Subject subject = SAMLEngineUtils.generateSubject();
+
+ // Mandatory STORK verified
+ // String format = NameID.UNSPECIFIED
+ // specification: 'SAML:2.0' exist
+ // opensaml: "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
+ // opensaml "urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified"
+ final String format = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified";
+
+ final String nameQualifier = "";
+
+ LOG.debug("Generate NameID");
+ final NameID nameId = SAMLEngineUtils.generateNameID(super
+ .getSamlCoreProperties().getResponder(), format, nameQualifier);
+ nameId.setValue(format);
+ subject.setNameID(nameId);
+
+ // Mandatory if urn:oasis:names:tc:SAML:2.0:cm:bearer.
+ // Optional in other case.
+ LOG.debug("Generate SubjectConfirmationData.");
+ final SubjectConfirmationData dataBearer = SAMLEngineUtils
+ .generateSubjectConfirmationData(SAMLEngineUtils
+ .getCurrentTime(), assertConsumerURL, inResponseTo);
+
+ // Mandatory if urn:oasis:names:tc:SAML:2.0:cm:bearer.
+ // Optional in other case.
+ LOG.debug("Generate SubjectConfirmation");
+ final SubjectConfirmation subjectConf = SAMLEngineUtils
+ .generateSubjectConfirmation(SubjectConfirmation.METHOD_BEARER,
+ dataBearer);
+
+ final ArrayList<SubjectConfirmation> listSubjectConf = new ArrayList<SubjectConfirmation>();
+ listSubjectConf.add(subjectConf);
+
+ for (final Iterator<SubjectConfirmation> iter = listSubjectConf
+ .iterator(); iter.hasNext();) {
+ final SubjectConfirmation element = iter.next();
+
+ if (SubjectConfirmation.METHOD_BEARER.equals(element.getMethod())) {
+ // ipAddress Mandatory if method is Bearer.
+
+ if (StringUtils.isBlank(ipAddress)) {
+ throw new STORKSAMLEngineException(
+ "ipAddress is null or empty");
+ }
+ element.getSubjectConfirmationData().setAddress(
+ ipAddress.trim());
+ }
+
+ element.getSubjectConfirmationData()
+ .setRecipient(assertConsumerURL);
+ element.getSubjectConfirmationData().setNotOnOrAfter(notOnOrAfter);
+ }
+
+ // The SAML 2.0 specification allows multiple SubjectConfirmations
+ subject.getSubjectConfirmations().addAll(listSubjectConf);
+
+ // Mandatory Stork
+ assertion.setSubject(subject);
+
+ // Conditions that MUST be evaluated when assessing the validity of
+ // and/or when using the assertion.
+ final Conditions conditions = this.generateConditions(SAMLEngineUtils
+ .getCurrentTime(), notOnOrAfter, issuer);
+
+ assertion.setConditions(conditions);
+
+ LOG.debug("Generate stork Authentication Statement.");
+ final AuthnStatement storkAuthnStat = this
+ .generateStorkAuthStatement(ipAddress);
+ assertion.getAuthnStatements().add(storkAuthnStat);
+
+ return assertion;
+ }
+
+ private String getAttributeName(final PersonalAttribute attribute) throws STORKSAMLEngineException {
+ if (StringUtils.isBlank(attribute.getName())) {
+ LOG.error(ATTRIBUTE_EMPTY_LITERAL);
+ throw new STORKSAMLEngineException(ATTRIBUTE_EMPTY_LITERAL);
+ }
+
+ final String attributeName = super.getSamlCoreProperties()
+ .getProperty(attribute.getName());
+
+ if (StringUtils.isBlank(attributeName)) {
+ LOG.error("Attribute name: {} it is not known.", attribute
+ .getName());
+ throw new STORKSAMLEngineException("Attribute name: "
+ + attribute.getName() + " it is not known.");
+ }
+ return attributeName;
+ }
+ /**
+ * Generate attribute statement.
+ *
+ * @param personalAttrList the personal attribute list
+ * @param isHashing the is hashing
+ *
+ * @return the attribute statement
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ * @throws IOException
+ */
+ private AttributeStatement generateAttributeStatement(
+ final IPersonalAttributeList personalAttrList,
+ final boolean isHashing) throws STORKSAMLEngineException {
+ LOG.debug("Generate attribute statement");
+
+ final AttributeStatement attrStatement = (AttributeStatement) SAMLEngineUtils
+ .createSamlObject(AttributeStatement.DEFAULT_ELEMENT_NAME);
+
+ for (PersonalAttribute attribute : personalAttrList) {
+
+ String attributeName = getAttributeName(attribute);
+
+ // Verification that only one value it's permitted, simple or
+ // complex, not both.
+
+ final boolean simpleNull = (attribute.getValue() == null);
+ final boolean simpleEmpty = (simpleNull || (!simpleNull && attribute
+ .getValue().isEmpty()));
+
+ final boolean complexNull = (attribute.getComplexValue() == null);
+ final boolean complexEmpty = (complexNull || (!complexNull && attribute
+ .getComplexValue().isEmpty()));
+
+ if ((!simpleEmpty && !complexEmpty)) {
+ throw new STORKSAMLEngineException(
+ "Attribute name: "
+ + attribute.getName()
+ + " must be contain one value, simple or complex value.");
+ } else {
+
+ if (!simpleEmpty) {
+ attrStatement.getAttributes().add(
+ this.generateAttrSimple(attributeName, attribute
+ .getStatus(), attribute.getValue(),
+ isHashing));
+ } else if (!complexEmpty) {
+ attrStatement.getAttributes().add(
+ SAMLEngineUtils.generateAttrComplex(attributeName,
+ attribute.getStatus(), attribute
+ .getComplexValue(), isHashing));
+ } else if (!simpleNull) {
+ attrStatement.getAttributes().add(
+ this.generateAttrSimple(attributeName, attribute
+ .getStatus(), new ArrayList<String>(),
+ isHashing));
+ } else {
+ // Add attribute complex.
+ attrStatement.getAttributes().add(
+ SAMLEngineUtils.generateAttrComplex(attributeName,
+ attribute.getStatus(),
+ new HashMap<String, String>(), isHashing));
+ }
+ }
+ }
+ return attrStatement;
+ }
+ private XSAny createAttributeValueForSignedDoc(final String value, final boolean isHashing) throws STORKSAMLEngineException {
+ DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
+ domFactory.setNamespaceAware(true);
+ Document document = null;
+ DocumentBuilder builder;
+
+ // Parse the signedDoc value into an XML DOM Document
+ try {
+ builder = domFactory.newDocumentBuilder();
+ InputStream is;
+ is = new ByteArrayInputStream(value.trim().getBytes("UTF-8"));
+ document = builder.parse(is);
+ is.close();
+ } catch (SAXException e1) {
+ LOG.error("SAX Error while parsing signModule attribute", e1);
+ throw new STORKSAMLEngineRuntimeException(e1);
+ } catch (ParserConfigurationException e2) {
+ LOG.error("Parser Configuration Error while parsing signModule attribute", e2);
+ throw new STORKSAMLEngineRuntimeException(e2);
+ } catch (UnsupportedEncodingException e3) {
+ LOG.error("Unsupported encoding Error while parsing signModule attribute", e3);
+ throw new STORKSAMLEngineRuntimeException(e3);
+ } catch (IOException e4) {
+ LOG.error("IO Error while parsing signModule attribute", e4);
+ throw new STORKSAMLEngineRuntimeException(e4);
+ }
+
+ // Create the attribute statement
+ final XSAny xmlValue = (XSAny) SAMLEngineUtils
+ .createSamlObject(
+ AttributeValue.DEFAULT_ELEMENT_NAME,
+ XSAny.TYPE_NAME);
+
+ //Set the signedDoc XML content to this element
+ xmlValue.setDOM(document.getDocumentElement());
+
+ // Create the attribute statement
+ final XSAny attrValue = (XSAny) SAMLEngineUtils
+ .createSamlObject(
+ AttributeValue.DEFAULT_ELEMENT_NAME,
+ XSAny.TYPE_NAME);
+
+ //Add previous signedDocXML to the AttributeValue Element
+
+ // if it's necessary encode the information.
+ if (!isHashing) {
+ attrValue.getUnknownXMLObjects().add(xmlValue);
+ }
+ return attrValue;
+ }
+
+ private XSAny createAttributeValueForNonSignedDoc(final String value, final boolean isHashing) throws STORKSAMLEngineException {
+ // Create the attribute statement
+ final XSAny attrValue = (XSAny) SAMLEngineUtils
+ .createSamlObject(
+ AttributeValue.DEFAULT_ELEMENT_NAME,
+ XSAny.TYPE_NAME);
+ // if it's necessary encode the information.
+ if (isHashing) {
+ attrValue.setTextContent(SAMLEngineUtils.encode(value, SAMLEngineUtils.SHA_512));
+ } else {
+ attrValue.setTextContent(value);
+ }
+ return attrValue;
+ }
+
+ /**
+ * Generate attribute from a list of values.
+ *
+ * @param name the name of the attribute.
+ * @param values the value of the attribute.
+ * @param isHashing the is hashing with "SHA-512" algorithm.
+ * @param status the status of the parameter: "Available", "NotAvailable" or
+ * "Withheld".
+ *
+ * @return the attribute
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private Attribute generateAttrSimple(final String name,
+ final String status, final List<String> values,
+ final boolean isHashing) throws STORKSAMLEngineException {
+ LOG.debug("Generate attribute simple: " + name);
+ final Attribute attribute = (Attribute) SAMLEngineUtils
+ .createSamlObject(Attribute.DEFAULT_ELEMENT_NAME);
+
+ attribute.setName(name);
+ attribute.setNameFormat(Attribute.URI_REFERENCE);
+
+ attribute.getUnknownAttributes().put(
+ new QName(SAMLCore.STORK10_NS.getValue(), "AttributeStatus",
+ SAMLCore.STORK10_PREFIX.getValue()), status);
+
+ if (values != null) {
+ LOG.debug("Add attribute values.");
+ for (int i = 0; i < values.size(); i++) {
+ final String value = values.get(i);
+ if (StringUtils.isNotBlank(value)) {
+ XSAny attrValue = null;
+ if (!name.equals("http://www.stork.gov.eu/1.0/signedDoc")) {
+ // Create the attribute statement
+ attrValue = createAttributeValueForNonSignedDoc(value, isHashing);
+
+ } else {
+ attrValue = createAttributeValueForSignedDoc(value, isHashing);
+ attribute.getAttributeValues().add(attrValue);
+ }
+ attribute.getAttributeValues().add(attrValue);
+ }
+ }
+ }
+ return attribute;
+ }
+
+ /**
+ * Generate conditions that MUST be evaluated when assessing the validity of
+ * and/or when using the assertion.
+ *
+ * @param notBefore the not before
+ * @param notOnOrAfter the not on or after
+ * @param audienceURI the audience URI.
+ *
+ * @return the conditions
+ */
+ private Conditions generateConditions(final DateTime notBefore,
+ final DateTime notOnOrAfter, final String audienceURI) {
+ LOG.debug("Generate conditions.");
+ final Conditions conditions = (Conditions) SAMLEngineUtils
+ .createSamlObject(Conditions.DEFAULT_ELEMENT_NAME);
+ conditions.setNotBefore(notBefore);
+ conditions.setNotOnOrAfter(notOnOrAfter);
+
+ final AudienceRestriction restrictions = (AudienceRestriction) SAMLEngineUtils
+ .createSamlObject(AudienceRestriction.DEFAULT_ELEMENT_NAME);
+
+ final Audience audience = (Audience) SAMLEngineUtils
+ .createSamlObject(Audience.DEFAULT_ELEMENT_NAME);
+ audience.setAudienceURI(audienceURI);
+
+ restrictions.getAudiences().add(audience);
+ conditions.getAudienceRestrictions().add(restrictions);
+
+ if (super.getSamlCoreProperties().isOneTimeUse()) {
+ final OneTimeUse oneTimeUse = (OneTimeUse) SAMLEngineUtils
+ .createSamlObject(OneTimeUse.DEFAULT_ELEMENT_NAME);
+ conditions.getConditions().add(oneTimeUse);
+ }
+ return conditions;
+ }
+
+ /**
+ * Generate personal attribute list.
+ *
+ * @param assertion the assertion
+ *
+ * @return the personal attribute list
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private IPersonalAttributeList generatePersonalAttributeList(
+ final Assertion assertion) throws STORKSAMLEngineException {
+ LOG.debug("Generate personal attribute list from XMLObject.");
+ final List<XMLObject> listExtensions = assertion.getOrderedChildren();
+
+ boolean find = false;
+ AttributeStatement requestedAttr = null;
+
+ // Search the attribute statement.
+ for (int i = 0; i < listExtensions.size() && !find; i++) {
+ final XMLObject xml = listExtensions.get(i);
+ if (xml instanceof AttributeStatement) {
+ requestedAttr = (AttributeStatement) xml;
+ find = true;
+ }
+ }
+
+ if (!find) {
+ LOG.error("Error: AttributeStatement it's not present.");
+ throw new STORKSAMLEngineException(
+ "AttributeStatement it's not present.");
+ }
+
+ final List<Attribute> reqAttrs = requestedAttr.getAttributes();
+
+ final IPersonalAttributeList personalAttrList = new PersonalAttributeList();
+ String attributeName;
+
+ // Process the attributes.
+ for (int nextAttribute = 0; nextAttribute < reqAttrs.size(); nextAttribute++) {
+ final Attribute attribute = reqAttrs.get(nextAttribute);
+
+ final PersonalAttribute personalAttribute = new PersonalAttribute();
+
+ attributeName = attribute.getName();
+ personalAttribute.setName(attributeName.substring(attributeName
+ .lastIndexOf('/') + 1));
+
+ personalAttribute.setStatus(attribute.getUnknownAttributes().get(
+ new QName(SAMLCore.STORK10_NS.getValue(),
+ "AttributeStatus", SAMLCore.STORK10_PREFIX
+ .getValue())));
+
+ final ArrayList<String> simpleValues = new ArrayList<String>();
+ final HashMap<String, String> multiValues = new HashMap<String, String>();
+
+ final List<XMLObject> values = attribute.getOrderedChildren();
+
+
+ // Process the values.
+ for (int nextValue = 0; nextValue < values.size(); nextValue++) {
+
+ final XMLObject xmlObject = values.get(nextValue);
+
+ if (xmlObject instanceof XSStringImpl) {
+
+ // Process simple value.
+ simpleValues.add(((XSStringImpl) xmlObject).getValue());
+
+ } else if (xmlObject instanceof XSAnyImpl) {
+
+ if (attributeName.equals("http://www.stork.gov.eu/1.0/signedDoc")) {
+
+ final XSAnyImpl xmlString = (XSAnyImpl) values
+ .get(nextValue);
+
+ TransformerFactory transFactory = TransformerFactory
+ .newInstance();
+ Transformer transformer = null;
+ try {
+ transformer = transFactory.newTransformer();
+ transformer.setOutputProperty(
+ OutputKeys.OMIT_XML_DECLARATION, "yes");
+ } catch (TransformerConfigurationException e) {
+ LOG.error("Error transformer configuration exception", e);
+ }
+ StringWriter buffer = new StringWriter();
+ try {
+ if (xmlString != null && xmlString.getUnknownXMLObjects() != null && xmlString.getUnknownXMLObjects().size() > 0 ){
+ transformer.transform(new DOMSource(xmlString
+ .getUnknownXMLObjects().get(0).getDOM()),
+ new StreamResult(buffer));
+ }
+ } catch (TransformerException e) {
+ LOG.error("Error transformer exception", e);
+ }
+ String str = buffer.toString();
+
+ simpleValues.add(str);
+
+ } else if (attributeName
+ .equals("http://www.stork.gov.eu/1.0/canonicalResidenceAddress"))
+ {
+ LOG.info("canonicalResidenceAddress found");
+ // Process complex value.
+ final XSAnyImpl complexValue = (XSAnyImpl) xmlObject;
+
+ for (int nextComplexValue = 0; nextComplexValue < complexValue
+ .getUnknownXMLObjects().size(); nextComplexValue++) {
+
+ final XSAnyImpl simple = (XSAnyImpl) complexValue
+ .getUnknownXMLObjects().get(
+ nextComplexValue);
+
+ multiValues.put(simple.getElementQName()
+ .getLocalPart(), simple.getTextContent());
+ }
+
+ }
+ else if (attributeName
+ .equals("http://www.stork.gov.eu/1.0/newAttribute2"))
+ {
+ LOG.info("newAttribute2 found");
+ // Process complex value.
+ final XSAnyImpl complexValue = (XSAnyImpl) xmlObject;
+
+ for (int nextComplexValue = 0; nextComplexValue < complexValue
+ .getUnknownXMLObjects().size(); nextComplexValue++) {
+
+ final XSAnyImpl simple = (XSAnyImpl) complexValue
+ .getUnknownXMLObjects().get(
+ nextComplexValue);
+
+ multiValues.put(simple.getElementQName()
+ .getLocalPart(), simple.getTextContent());
+ }
+ }
+ else if (attributeName
+ .equals("http://www.stork.gov.eu/1.0/hasDegree"))
+ {
+ LOG.info("hasDegree found");
+ // Process complex value.
+ final XSAnyImpl complexValue = (XSAnyImpl) xmlObject;
+
+ for (int nextComplexValue = 0; nextComplexValue < complexValue
+ .getUnknownXMLObjects().size(); nextComplexValue++) {
+
+ final XSAnyImpl simple = (XSAnyImpl) complexValue
+ .getUnknownXMLObjects().get(
+ nextComplexValue);
+
+ multiValues.put(simple.getElementQName()
+ .getLocalPart(), simple.getTextContent());
+ }
+ }
+ else if(attributeName
+ .equals("http://www.stork.gov.eu/1.0/mandateContent"))
+ {
+ LOG.info("mandateContent found");
+ // Process complex value.
+ final XSAnyImpl complexValue = (XSAnyImpl) xmlObject;
+
+ for (int nextComplexValue = 0; nextComplexValue < complexValue
+ .getUnknownXMLObjects().size(); nextComplexValue++) {
+
+ final XSAnyImpl simple = (XSAnyImpl) complexValue
+ .getUnknownXMLObjects().get(
+ nextComplexValue);
+
+ multiValues.put(simple.getElementQName()
+ .getLocalPart(), simple.getTextContent());
+ }
+ }
+ else {
+ // Process simple value.
+ simpleValues.add(((XSAnyImpl) xmlObject)
+ .getTextContent());
+ }
+
+ } else {
+ LOG.error("Error: attribute value it's unknown.");
+ throw new STORKSAMLEngineException(
+ "Attribute value it's unknown.");
+ }
+ }
+
+ personalAttribute.setValue(simpleValues);
+ personalAttribute.setComplexValue(multiValues);
+ personalAttrList.add(personalAttribute);
+ }
+
+ return personalAttrList;
+ }
+
+ /**
+ * Generate stork authentication request.
+ *
+ * @param request the request that contain all parameters for generate an
+ * authentication request.
+ *
+ * @return the STORK authentication request that has been processed.
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAuthnRequest generateSTORKAuthnRequest(
+ final STORKAuthnRequest request) throws STORKSAMLEngineException {
+ LOG.info("Generate SAMLAuthnRequest.");
+
+ // Validate Parameters mandatories
+ validateParamAuthnReq(request);
+
+ final AuthnRequest authnRequestAux = SAMLEngineUtils
+ .generateSAMLAuthnRequest(SAMLEngineUtils.generateNCName(),
+ SAMLVersion.VERSION_20, SAMLEngineUtils
+ .getCurrentTime());
+
+ // Set name spaces.
+ setNameSpaces(authnRequestAux);
+
+ // Add parameter Mandatory STORK
+ authnRequestAux.setForceAuthn(Boolean.TRUE);
+
+ // Add parameter Mandatory STORK
+ authnRequestAux.setIsPassive(Boolean.FALSE);
+
+ authnRequestAux.setAssertionConsumerServiceURL(request
+ .getAssertionConsumerServiceURL());
+
+ authnRequestAux.setProviderName(request.getProviderName());
+
+ // Add protocol binding
+ authnRequestAux.setProtocolBinding(super.getSamlCoreProperties()
+ .getProtocolBinding());
+
+ // Add parameter optional STORK
+ // Destination is mandatory if the destination is a C-PEPS
+ // The application must to know if the destination is a C-PEPS.
+ if (StringUtils.isNotBlank(request.getDestination())) {
+ authnRequestAux.setDestination(request.getDestination());
+ }
+
+ // Consent is optional. Set from SAMLEngine.xml - consent.
+ authnRequestAux.setConsent(super.getSamlCoreProperties()
+ .getConsentAuthnRequest());
+
+ final Issuer issuer = SAMLEngineUtils.generateIssuer();
+
+ if(request.getIssuer()!=null){
+ issuer.setValue(request.getIssuer());
+ } else {
+ issuer.setValue(super.getSamlCoreProperties().getRequester());
+ }
+
+ // Optional STORK
+ final String formatEntity = super.getSamlCoreProperties()
+ .getFormatEntity();
+ if (StringUtils.isNotBlank(formatEntity)) {
+ issuer.setFormat(formatEntity);
+ }
+
+ authnRequestAux.setIssuer(issuer);
+
+ // Generate stork extensions.
+ final Extensions storkExtensions = this
+ .generateSTORKExtensions(request);
+ // add the extensions to the SAMLAuthnRequest
+ authnRequestAux.setExtensions(storkExtensions);
+
+ // the result contains an authentication request token (byte[]),
+ // identifier of the token, and all parameters from the request.
+ final STORKAuthnRequest authRequest = processExtensions(authnRequestAux
+ .getExtensions());
+
+ try {
+ authRequest.setTokenSaml(super.signAndMarshall(authnRequestAux));
+ } catch (SAMLEngineException e) {
+ LOG.error("Sign and Marshall.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ authRequest.setSamlId(authnRequestAux.getID());
+ authRequest.setDestination(authnRequestAux.getDestination());
+ authRequest.setAssertionConsumerServiceURL(authnRequestAux
+ .getAssertionConsumerServiceURL());
+
+ authRequest.setProviderName(authnRequestAux.getProviderName());
+ authRequest.setIssuer(authnRequestAux.getIssuer().getValue());
+
+ return authRequest;
+ }
+
+ /**
+ * Generate stork authentication response.
+ *
+ * @param request the request
+ * @param responseAuthReq the response authentication request
+ * @param ipAddress the IP address
+ * @param isHashing the is hashing
+ *
+ * @return the sTORK authentication response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAuthnResponse generateSTORKAuthnResponse(
+ final STORKAuthnRequest request,
+ final STORKAuthnResponse responseAuthReq, final String ipAddress,
+ final boolean isHashing) throws STORKSAMLEngineException {
+ LOG.info("generateSTORKAuthnResponse");
+
+ // Validate parameters
+ validateParamResponse(request, responseAuthReq);
+
+ // Mandatory SAML
+ LOG.debug("Generate StatusCode");
+ final StatusCode statusCode = SAMLEngineUtils
+ .generateStatusCode(StatusCode.SUCCESS_URI);
+
+ LOG.debug("Generate Status");
+ final Status status = SAMLEngineUtils.generateStatus(statusCode);
+
+ LOG.debug("Generate StatusMessage");
+ final StatusMessage statusMessage = (StatusMessage) SAMLEngineUtils
+ .generateStatusMessage(StatusCode.SUCCESS_URI);
+
+ status.setStatusMessage(statusMessage);
+
+ LOG.debug("Generate Response");
+
+ // RESPONSE
+ final Response response = genAuthnRespBase(status, request
+ .getAssertionConsumerServiceURL(), request.getSamlId());
+
+ DateTime notOnOrAfter = new DateTime();
+
+ notOnOrAfter = notOnOrAfter.plusSeconds(super.getSamlCoreProperties()
+ .getTimeNotOnOrAfter());
+
+ final Assertion assertion = this.generateAssertion(ipAddress, request
+ .getAssertionConsumerServiceURL(), request.getSamlId(), request
+ .getIssuer(), notOnOrAfter);
+
+ final AttributeStatement attrStatement = this
+ .generateAttributeStatement(responseAuthReq
+ .getPersonalAttributeList(), isHashing);
+
+ assertion.getAttributeStatements().add(attrStatement);
+
+ // Add assertions
+ response.getAssertions().add(assertion);
+
+ final STORKAuthnResponse authresponse = new STORKAuthnResponse();
+
+ try {
+ authresponse.setTokenSaml(super.signAndMarshall(response));
+ authresponse.setSamlId(response.getID());
+ } catch (SAMLEngineException e) {
+ LOG.error("Sign and Marshall.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+ return authresponse;
+ }
+
+ /**
+ * Generate stork authentication response fail.
+ *
+ * @param request the request
+ * @param response the response
+ * @param ipAddress the IP address
+ * @param isHashing the is hashing
+ *
+ * @return the sTORK authentication response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAuthnResponse generateSTORKAuthnResponseFail(
+ final STORKAuthnRequest request, final STORKAuthnResponse response,
+ final String ipAddress, final boolean isHashing)
+ throws STORKSAMLEngineException {
+ LOG.info("generateSTORKAuthnResponseFail");
+
+ validateParamResponseFail(request, response);
+
+ // Mandatory
+ final StatusCode statusCode = SAMLEngineUtils
+ .generateStatusCode(response.getStatusCode());
+
+ // Mandatory SAML
+ LOG.debug("Generate StatusCode.");
+ // Subordinate code it's optional in case not covered into next codes:
+ // - urn:oasis:names:tc:SAML:2.0:status:AuthnFailed
+ // - urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue
+ // - urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy
+ // - urn:oasis:names:tc:SAML:2.0:status:RequestDenied
+ // - http://www.stork.gov.eu/saml20/statusCodes/QAANotSupported
+
+ if (StringUtils.isNotBlank(response.getSubStatusCode())) {
+ final StatusCode newStatusCode = SAMLEngineUtils
+ .generateStatusCode(response.getSubStatusCode());
+ statusCode.setStatusCode(newStatusCode);
+ }
+
+ LOG.debug("Generate Status.");
+ final Status status = SAMLEngineUtils.generateStatus(statusCode);
+
+ if (StringUtils.isNotBlank(response.getMessage())) {
+ final StatusMessage statusMessage = (StatusMessage) SAMLEngineUtils
+ .generateStatusMessage(response.getMessage());
+
+ status.setStatusMessage(statusMessage);
+ }
+
+ LOG.debug("Generate Response.");
+ // RESPONSE
+ final Response responseFail = genAuthnRespBase(status, request
+ .getAssertionConsumerServiceURL(), request.getSamlId());
+
+ DateTime notOnOrAfter = new DateTime();
+
+ notOnOrAfter = notOnOrAfter.plusSeconds(super.getSamlCoreProperties()
+ .getTimeNotOnOrAfter());
+
+ final Assertion assertion = this.generateAssertion(ipAddress, request
+ .getAssertionConsumerServiceURL(), request.getSamlId(), request
+ .getIssuer(), notOnOrAfter);
+
+ responseFail.getAssertions().add(assertion);
+
+ LOG.debug("Sign and Marshall ResponseFail.");
+
+ final STORKAuthnResponse storkResponse = new STORKAuthnResponse();
+
+ try {
+ storkResponse.setTokenSaml(super.signAndMarshall(responseFail));
+ storkResponse.setSamlId(responseFail.getID());
+ } catch (SAMLEngineException e) {
+ LOG.error("SAMLEngineException.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+ return storkResponse;
+ }
+
+ /**
+ * Generate stork attribute query request.
+ *
+ * @param request the request that contain all parameters for generate an
+ * attribute query request.
+ *
+ * @return the STORK attribute query request that has been processed.
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAttrQueryRequest generateSTORKAttrQueryRequest(
+ final STORKAttrQueryRequest request) throws STORKSAMLEngineException {
+ LOG.info("Generate STORKAttrQueryRequest.");
+
+ // Validate Parameters mandatories
+ validateParamAttrQueryReq(request);
+
+ final AttributeQuery attrQueryRequestAux = SAMLEngineUtils
+ .generateSAMLAttrQueryRequest(SAMLEngineUtils.generateNCName(),
+ SAMLVersion.VERSION_20, SAMLEngineUtils
+ .getCurrentTime());
+
+ // Set name spaces.
+ setNameSpaces(attrQueryRequestAux);
+
+
+ // Add parameter optional STORK
+ // Destination is mandatory if the destination is a C-PEPS
+ // The application must to know if the destination is a C-PEPS.
+ if (StringUtils.isNotBlank(request.getDestination())) {
+ attrQueryRequestAux.setDestination(request.getDestination());
+ }
+
+ // Consent is optional. Set from SAMLEngine.xml - consent.
+ attrQueryRequestAux.setConsent(super.getSamlCoreProperties()
+ .getConsentAuthnRequest());
+
+ final Issuer issuer = SAMLEngineUtils.generateIssuer();
+
+ //Set the subject - needed for attribute query validation
+ Subject subject = SAMLEngineUtils.generateSubject();
+ SubjectConfirmationBuilder builder = new SubjectConfirmationBuilder();
+ SubjectConfirmation subjectConfirmation = builder.buildObject();
+ subjectConfirmation.setMethod("urn:oasis:names:tc:SAML:2.0:cm:bearer");
+ subject.getSubjectConfirmations().add(subjectConfirmation);
+ attrQueryRequestAux.setSubject(subject);
+
+ if(request.getIssuer()!=null){
+ issuer.setValue(request.getIssuer());
+ } else {
+ issuer.setValue(super.getSamlCoreProperties().getRequester());
+ }
+
+ // Optional STORK
+ final String formatEntity = super.getSamlCoreProperties()
+ .getFormatEntity();
+ if (StringUtils.isNotBlank(formatEntity)) {
+ issuer.setFormat(formatEntity);
+ }
+
+ attrQueryRequestAux.setIssuer(issuer);
+
+ // Generate stork extensions.
+ final Extensions storkExtensions = this
+ .generateSTORKAttrExtensions(request);
+ // add the extensions to the SAMLAuthnRequest
+ attrQueryRequestAux.setExtensions(storkExtensions);
+
+ // the result contains an authentication request token (byte[]),
+ // identifier of the token, and all parameters from the request.
+ final STORKAttrQueryRequest attrQueryRequest = processAttrExtensions(attrQueryRequestAux
+ .getExtensions());
+
+ try {
+ attrQueryRequest.setTokenSaml(super.signAndMarshall(attrQueryRequestAux));
+ } catch (SAMLEngineException e) {
+ LOG.error("Sign and Marshall.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ attrQueryRequest.setSamlId(attrQueryRequestAux.getID());
+ attrQueryRequest.setDestination(attrQueryRequestAux.getDestination());
+
+ attrQueryRequest.setIssuer(attrQueryRequestAux.getIssuer().getValue());
+
+ return attrQueryRequest;
+ }
+
+ /**
+ * Generate stork attribute query response.
+ *
+ * @param request the request
+ * @param responseAttrQueryReq the response authentication request
+ * @param ipAddress the IP address
+ * @param isHashing the is hashing
+ *
+ * @return the sTORK authentication response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAttrQueryResponse generateSTORKAttrQueryResponse(
+ final STORKAttrQueryRequest request,
+ final STORKAttrQueryResponse responseAttrQueryReq, final String ipAddress,
+ final String destinationUrl, final boolean isHashing) throws STORKSAMLEngineException {
+ LOG.info("generateSTORKAttrQueryResponse");
+
+ // Validate parameters
+ validateParamAttrQueryResponse(request, responseAttrQueryReq);
+
+ // Mandatory SAML
+ LOG.debug("Generate StatusCode");
+ final StatusCode statusCode = SAMLEngineUtils
+ .generateStatusCode(StatusCode.SUCCESS_URI);
+
+ LOG.debug("Generate Status");
+ final Status status = SAMLEngineUtils.generateStatus(statusCode);
+
+ LOG.debug("Generate StatusMessage");
+ final StatusMessage statusMessage = (StatusMessage) SAMLEngineUtils
+ .generateStatusMessage(StatusCode.SUCCESS_URI);
+
+ status.setStatusMessage(statusMessage);
+
+ LOG.debug("Generate Response");
+
+ // RESPONSE
+ final Response response = genAuthnRespBase(status, destinationUrl,
+ request.getSamlId());
+
+ DateTime notOnOrAfter = new DateTime();
+
+ notOnOrAfter = notOnOrAfter.plusSeconds(super.getSamlCoreProperties()
+ .getTimeNotOnOrAfter());
+
+ final Assertion assertion = this.generateAssertion(ipAddress, ""
+ ,request.getSamlId(), request.getIssuer(), notOnOrAfter);
+
+ final AttributeStatement attrStatement = this
+ .generateAttributeStatement(responseAttrQueryReq
+ .getPersonalAttributeList(), isHashing);
+
+ assertion.getAttributeStatements().add(attrStatement);
+
+ // Add assertions
+ response.getAssertions().add(assertion);
+
+ final STORKAttrQueryResponse attrQueryResponse = new STORKAttrQueryResponse();
+
+ try {
+ attrQueryResponse.setTokenSaml(super.signAndMarshall(response));
+ attrQueryResponse.setSamlId(response.getID());
+ } catch (SAMLEngineException e) {
+ LOG.error("Sign and Marshall.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+ return attrQueryResponse;
+ }
+
+ /**
+ * Generate stork attribute query response fail.
+ *
+ * @param request the request
+ * @param response the response
+ * @param ipAddress the IP address
+ * @param isHashing the is hashing
+ *
+ * @return the STORK attribute query response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAttrQueryResponse generateSTORKAttrQueryResponseFail(
+ final STORKAttrQueryRequest request, final STORKAttrQueryResponse response,
+ final String ipAddress, final String destinationUrl, final boolean isHashing)
+ throws STORKSAMLEngineException {
+ LOG.info("generateSTORKAttrQueryResponseFail");
+
+ validateParamAttrQueryResponseFail(request, response);
+
+ // Mandatory
+ final StatusCode statusCode = SAMLEngineUtils
+ .generateStatusCode(response.getStatusCode());
+
+ // Mandatory SAML
+ LOG.debug("Generate StatusCode.");
+ // Subordinate code it's optional in case not covered into next codes:
+ // - urn:oasis:names:tc:SAML:2.0:status:AuthnFailed
+ // - urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue
+ // - urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy
+ // - urn:oasis:names:tc:SAML:2.0:status:RequestDenied
+ // - http://www.stork.gov.eu/saml20/statusCodes/QAANotSupported
+
+ if (StringUtils.isNotBlank(response.getSubStatusCode())) {
+ final StatusCode newStatusCode = SAMLEngineUtils
+ .generateStatusCode(response.getSubStatusCode());
+ statusCode.setStatusCode(newStatusCode);
+ }
+
+ LOG.debug("Generate Status.");
+ final Status status = SAMLEngineUtils.generateStatus(statusCode);
+
+ if (StringUtils.isNotBlank(response.getMessage())) {
+ final StatusMessage statusMessage = (StatusMessage) SAMLEngineUtils
+ .generateStatusMessage(response.getMessage());
+
+ status.setStatusMessage(statusMessage);
+ }
+
+ LOG.debug("Generate Response.");
+ // RESPONSE
+ final Response responseFail = genAuthnRespBase(status, destinationUrl,
+ request.getSamlId());
+
+ DateTime notOnOrAfter = new DateTime();
+
+ notOnOrAfter = notOnOrAfter.plusSeconds(super.getSamlCoreProperties()
+ .getTimeNotOnOrAfter());
+
+ final Assertion assertion = this.generateAssertion(ipAddress, "",
+ request.getSamlId(), request
+ .getIssuer(), notOnOrAfter);
+
+ responseFail.getAssertions().add(assertion);
+
+ LOG.debug("Sign and Marshall ResponseFail.");
+
+ final STORKAttrQueryResponse storkResponse = new STORKAttrQueryResponse();
+
+ try {
+ storkResponse.setTokenSaml(super.signAndMarshall(responseFail));
+ storkResponse.setSamlId(responseFail.getID());
+ } catch (SAMLEngineException e) {
+ LOG.error("SAMLEngineException.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+ return storkResponse;
+ }
+
+ /**
+ * Generate stork authentication statement for the authentication statement.
+ *
+ * @param ipAddress the IP address
+ *
+ * @return the authentication statement
+ */
+ private AuthnStatement generateStorkAuthStatement(final String ipAddress) {
+ LOG.debug("Generate stork authenticate statement.");
+ final SubjectLocality subjectLocality = SAMLEngineUtils
+ .generateSubjectLocality(ipAddress);
+
+ final AuthnContext authnContext = (AuthnContext) SAMLEngineUtils
+ .createSamlObject(AuthnContext.DEFAULT_ELEMENT_NAME);
+
+ final AuthnContextDecl authnContextDecl = (AuthnContextDecl) SAMLEngineUtils
+ .createSamlObject(AuthnContextDecl.DEFAULT_ELEMENT_NAME);
+
+ authnContext.setAuthnContextDecl(authnContextDecl);
+
+ final AuthnStatement authnStatement = SAMLEngineUtils
+ .generateAthnStatement(new DateTime(), authnContext);
+
+ // Optional STORK
+ authnStatement.setSessionIndex(null);
+ authnStatement.setSubjectLocality(subjectLocality);
+
+ return authnStatement;
+ }
+
+ /**
+ * Generate stork extensions.
+ *
+ * @param request the request
+ *
+ * @return the extensions
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private Extensions generateSTORKExtensions(final STORKAuthnRequest request)
+ throws STORKSAMLEngineException {
+ LOG.debug("Generate STORKExtensions");
+
+ final Extensions extensions = SAMLEngineUtils.generateExtension();
+
+ LOG.debug("Generate QAAAttribute");
+ final QAAAttribute qaaAttribute = SAMLEngineUtils
+ .generateQAAAttribute(request.getQaa());
+ extensions.getUnknownXMLObjects().add(qaaAttribute);
+
+
+ if (StringUtils.isNotEmpty(request
+ .getSpSector())) {
+ // Add information about service provider.
+ LOG.debug("Generate SPSector");
+ final SPSector sector = SAMLEngineUtils.generateSPSector(request
+ .getSpSector());
+ extensions.getUnknownXMLObjects().add(sector);
+ }
+
+ //Delete from specification. Kept for compatibility with Provider Name value
+ LOG.debug("Generate SPInstitution");
+ final SPInstitution institution = SAMLEngineUtils
+ .generateSPInstitution(request.getProviderName());
+ extensions.getUnknownXMLObjects().add(institution);
+
+
+ if (StringUtils.isNotEmpty(request.getSpApplication())) {
+ LOG.debug("Generate SPApplication");
+ final SPApplication application = SAMLEngineUtils
+ .generateSPApplication(request.getSpApplication());
+ extensions.getUnknownXMLObjects().add(application);
+ }
+
+ if (StringUtils.isNotEmpty(request.getSpCountry())) {
+ LOG.debug("Generate SPCountry");
+ final SPCountry country = SAMLEngineUtils.generateSPCountry(request
+ .getSpCountry());
+ extensions.getUnknownXMLObjects().add(country);
+ }
+
+ //eIDSectorShare: optional; default value: false.
+ String valueSectorShare = super.getSamlCoreProperties()
+ .iseIDSectorShare();
+
+ if (StringUtils.isNotEmpty(valueSectorShare)) {
+ // Add information about the use of the SAML message.
+ LOG.debug("Generate EIDSectorShare");
+ final EIDSectorShare eIdSectorShare = (EIDSectorShare) SAMLEngineUtils
+ .createSamlObject(EIDSectorShare.DEF_ELEMENT_NAME);
+
+ eIdSectorShare.setEIDSectorShare(String.valueOf(Boolean.valueOf(valueSectorShare)));
+
+ extensions.getUnknownXMLObjects().add(eIdSectorShare);
+ }
+
+ String valueCrossSectorShare = super.getSamlCoreProperties()
+ .iseIDCrossSectorShare();
+
+ if (StringUtils.isNotEmpty(valueCrossSectorShare)) {
+ LOG.debug("Generate EIDCrossSectorShare");
+ final EIDCrossSectorShare eIdCrossSecShare = (EIDCrossSectorShare) SAMLEngineUtils
+ .createSamlObject(EIDCrossSectorShare.DEF_ELEMENT_NAME);
+ eIdCrossSecShare.setEIDCrossSectorShare(String.valueOf(Boolean.valueOf(valueCrossSectorShare)));
+ extensions.getUnknownXMLObjects().add(eIdCrossSecShare);
+ }
+
+
+ String valueCrossBorderShare = super.getSamlCoreProperties()
+ .iseIDCrossBorderShare();
+
+ if (StringUtils.isNotEmpty(valueCrossBorderShare)) {
+ LOG.debug("Generate EIDCrossBorderShare");
+ final EIDCrossBorderShare eIdCrossBordShare = (EIDCrossBorderShare) SAMLEngineUtils
+ .createSamlObject(EIDCrossBorderShare.DEF_ELEMENT_NAME);
+ eIdCrossBordShare.setEIDCrossBorderShare(String.valueOf(Boolean.valueOf(valueCrossBorderShare)));
+ extensions.getUnknownXMLObjects().add(eIdCrossBordShare);
+ }
+
+
+ // Add information about requested attributes.
+ LOG.debug("Generate RequestedAttributes.");
+ final RequestedAttributes reqAttributes = (RequestedAttributes) SAMLEngineUtils
+ .createSamlObject(RequestedAttributes.DEF_ELEMENT_NAME);
+
+ LOG.debug("SAML Engine configuration properties load.");
+ final Iterator<PersonalAttribute> iterator = request
+ .getPersonalAttributeList().iterator();
+
+ while (iterator.hasNext()) {
+
+ final PersonalAttribute attribute = iterator.next();
+
+ if (attribute == null || StringUtils.isBlank(attribute.getName())) {
+ LOG.error(ATTRIBUTE_EMPTY_LITERAL);
+ throw new STORKSAMLEngineException(ATTRIBUTE_EMPTY_LITERAL);
+ }
+
+ // Verified if exits the attribute name.
+ final String attributeName = super.getSamlCoreProperties()
+ .getProperty(attribute.getName());
+
+ if (StringUtils.isBlank(attributeName)) {
+ LOG.debug("Attribute name: {} was not found.", attribute
+ .getName());
+ throw new STORKSAMLEngineException("Attribute name: "
+ + attribute.getName() + " was not found.");
+ }
+
+ // Friendly name it's an optional attribute.
+ String friendlyName = null;
+
+ if (super.getSamlCoreProperties().isFriendlyName()) {
+ friendlyName = attribute.getName();
+ }
+
+
+ String isRequired = null;
+ if (super.getSamlCoreProperties().isRequired()) {
+ isRequired = String.valueOf(attribute.isRequired());
+ }
+
+
+ LOG.debug("Generate requested attribute: " + attributeName);
+ final RequestedAttribute requestedAttr = SAMLEngineUtils
+ .generateReqAuthnAttributeSimple(attributeName,
+ friendlyName, isRequired, attribute
+ .getValue());
+
+ // Add requested attribute.
+ reqAttributes.getAttributes().add(requestedAttr);
+ }
+
+ // Add requested attributes.
+ extensions.getUnknownXMLObjects().add(reqAttributes);
+
+ CitizenCountryCode citizenCountryCode = null;
+ if (request.getCitizenCountryCode() != null && StringUtils.isNotBlank(request.getCitizenCountryCode())){
+ LOG.debug("Generate CitizenCountryCode");
+ citizenCountryCode = (CitizenCountryCode) SAMLEngineUtils
+ .createSamlObject(CitizenCountryCode.DEF_ELEMENT_NAME);
+
+ citizenCountryCode.setCitizenCountryCode(request
+ .getCitizenCountryCode().toUpperCase());
+ }
+
+ SPID spid = null;
+ if(request.getSPID()!=null && StringUtils.isNotBlank(request.getSPID())) {
+ LOG.debug("Generate SPID");
+ spid = (SPID) SAMLEngineUtils
+ .createSamlObject(SPID.DEF_ELEMENT_NAME);
+
+ spid.setSPID(request.getSPID().toUpperCase());
+ }
+
+ AuthenticationAttributes authenticationAttr = (AuthenticationAttributes) SAMLEngineUtils
+ .createSamlObject(AuthenticationAttributes.DEF_ELEMENT_NAME);
+
+ final VIDPAuthenticationAttributes vIDPauthenticationAttr = (VIDPAuthenticationAttributes) SAMLEngineUtils
+ .createSamlObject(VIDPAuthenticationAttributes.DEF_ELEMENT_NAME);
+
+ final SPInformation spInformation = (SPInformation) SAMLEngineUtils
+ .createSamlObject(SPInformation.DEF_ELEMENT_NAME);
+
+ if(citizenCountryCode!=null){
+ vIDPauthenticationAttr.setCitizenCountryCode(citizenCountryCode);
+ }
+
+ if(spid!=null){
+ spInformation.setSPID(spid);
+ }
+
+ vIDPauthenticationAttr.setSPInformation(spInformation);
+
+ authenticationAttr
+ .setVIDPAuthenticationAttributes(vIDPauthenticationAttr);
+ extensions.getUnknownXMLObjects().add(authenticationAttr);
+
+
+ return extensions;
+
+ }
+
+ /**
+ * Generate stork extensions.
+ *
+ * @param request the attribute query request
+ *
+ * @return the extensions
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private Extensions generateSTORKAttrExtensions(final STORKAttrQueryRequest request)
+ throws STORKSAMLEngineException {
+ LOG.debug("Generate STORKExtensions");
+
+ final Extensions extensions = SAMLEngineUtils.generateExtension();
+
+ LOG.debug("Generate QAAAttribute");
+ final QAAAttribute qaaAttribute = SAMLEngineUtils
+ .generateQAAAttribute(request.getQaa());
+ extensions.getUnknownXMLObjects().add(qaaAttribute);
+
+
+ if (StringUtils.isNotEmpty(request
+ .getSpSector())) {
+ // Add information about service provider.
+ LOG.debug("Generate SPSector");
+ final SPSector sector = SAMLEngineUtils.generateSPSector(request
+ .getSpSector());
+ extensions.getUnknownXMLObjects().add(sector);
+ }
+
+
+ if (StringUtils.isNotEmpty(request.getSpApplication())) {
+ LOG.debug("Generate SPApplication");
+ final SPApplication application = SAMLEngineUtils
+ .generateSPApplication(request.getSpApplication());
+ extensions.getUnknownXMLObjects().add(application);
+ }
+
+ if (StringUtils.isNotEmpty(request.getSpCountry())) {
+ LOG.debug("Generate SPCountry");
+ final SPCountry country = SAMLEngineUtils.generateSPCountry(request
+ .getSpCountry());
+ extensions.getUnknownXMLObjects().add(country);
+ }
+
+ final EIDSectorShare eIdSectorShare = (EIDSectorShare) SAMLEngineUtils
+ .createSamlObject(EIDSectorShare.DEF_ELEMENT_NAME);
+
+ eIdSectorShare.setEIDSectorShare(String.valueOf(request.isEIDSectorShare()));
+
+ extensions.getUnknownXMLObjects().add(eIdSectorShare);
+
+ final EIDCrossSectorShare eIdCrossSecShare = (EIDCrossSectorShare) SAMLEngineUtils
+ .createSamlObject(EIDCrossSectorShare.DEF_ELEMENT_NAME);
+ eIdCrossSecShare.setEIDCrossSectorShare(String.valueOf(request.isEIDCrossSectorShare()));
+ extensions.getUnknownXMLObjects().add(eIdCrossSecShare);
+
+ final EIDCrossBorderShare eIdCrossBordShare = (EIDCrossBorderShare) SAMLEngineUtils
+ .createSamlObject(EIDCrossBorderShare.DEF_ELEMENT_NAME);
+ eIdCrossBordShare.setEIDCrossBorderShare(String.valueOf(request.isEIDCrossBorderShare()));
+ extensions.getUnknownXMLObjects().add(eIdCrossBordShare);
+
+
+ // Add information about requested attributes.
+ LOG.debug("Generate RequestedAttributes.");
+ final RequestedAttributes reqAttributes = (RequestedAttributes) SAMLEngineUtils
+ .createSamlObject(RequestedAttributes.DEF_ELEMENT_NAME);
+
+ LOG.debug("SAML Engine configuration properties load.");
+ final Iterator<PersonalAttribute> iterator = request
+ .getPersonalAttributeList().iterator();
+
+ while (iterator.hasNext()) {
+
+ final PersonalAttribute attribute = iterator.next();
+
+ if (attribute == null || StringUtils.isBlank(attribute.getName())) {
+ LOG.error(ATTRIBUTE_EMPTY_LITERAL);
+ throw new STORKSAMLEngineException(ATTRIBUTE_EMPTY_LITERAL);
+ }
+
+ // Verified if exits the attribute name.
+ final String attributeName = super.getSamlCoreProperties()
+ .getProperty(attribute.getName());
+
+ if (StringUtils.isBlank(attributeName)) {
+ LOG.debug("Attribute name: {} was not found.", attribute
+ .getName());
+ throw new STORKSAMLEngineException("Attribute name: "
+ + attribute.getName() + " was not found.");
+ }
+
+ // Friendly name it's an optional attribute.
+ String friendlyName = null;
+
+ if (super.getSamlCoreProperties().isFriendlyName()) {
+ friendlyName = attribute.getName();
+ }
+
+
+ String isRequired = null;
+ if (super.getSamlCoreProperties().isRequired()) {
+ isRequired = String.valueOf(attribute.isRequired());
+ }
+
+
+ LOG.debug("Generate requested attribute: " + attributeName);
+ final RequestedAttribute requestedAttr = SAMLEngineUtils
+ .generateReqAuthnAttributeSimple(attributeName,
+ friendlyName, isRequired, attribute
+ .getValue());
+
+ // Add requested attribute.
+ reqAttributes.getAttributes().add(requestedAttr);
+ }
+
+ // Add requested attributes.
+ extensions.getUnknownXMLObjects().add(reqAttributes);
+
+ CitizenCountryCode citizenCountryCode = null;
+ if (request.getCitizenCountryCode() != null && StringUtils.isNotBlank(request.getCitizenCountryCode())){
+ LOG.debug("Generate CitizenCountryCode");
+ citizenCountryCode = (CitizenCountryCode) SAMLEngineUtils
+ .createSamlObject(CitizenCountryCode.DEF_ELEMENT_NAME);
+
+ citizenCountryCode.setCitizenCountryCode(request
+ .getCitizenCountryCode().toUpperCase());
+ }
+
+ SPID spid = null;
+ if(request.getSPID()!=null && StringUtils.isNotBlank(request.getSPID())) {
+ LOG.debug("Generate SPID");
+ spid = (SPID) SAMLEngineUtils
+ .createSamlObject(SPID.DEF_ELEMENT_NAME);
+
+ spid.setSPID(request.getSPID().toUpperCase());
+ }
+
+
+ return extensions;
+
+ }
+
+ /**
+ * Gets the alias from X.509 Certificate at keystore.
+ *
+ * @param keyInfo the key info
+ * @param storkOwnKeyStore
+ * @param storkOwnKeyStore
+ *
+ * @return the alias
+ */
+ private String getAlias(final KeyInfo keyInfo, KeyStore storkOwnKeyStore) {
+
+ LOG.debug("Recover alias information");
+
+ String alias = null;
+ try {
+ final org.opensaml.xml.signature.X509Certificate xmlCert = keyInfo
+ .getX509Datas().get(0).getX509Certificates().get(0);
+
+ // Transform the KeyInfo to X509Certificate.
+ CertificateFactory certFact;
+ certFact = CertificateFactory.getInstance("X.509");
+
+ final ByteArrayInputStream bis = new ByteArrayInputStream(Base64
+ .decode(xmlCert.getValue()));
+
+ final X509Certificate cert = (X509Certificate) certFact
+ .generateCertificate(bis);
+
+ final String tokenSerialNumber = cert.getSerialNumber().toString(16);
+ final X509Principal tokenIssuerDN = new X509Principal(cert.getIssuerDN().getName());
+
+
+ String aliasCert;
+ X509Certificate certificate;
+ boolean find = false;
+
+ for (final Enumeration<String> e = storkOwnKeyStore.aliases(); e
+ .hasMoreElements()
+ && !find; ) {
+ aliasCert = e.nextElement();
+ certificate = (X509Certificate) storkOwnKeyStore
+ .getCertificate(aliasCert);
+
+ final String serialNum = certificate.getSerialNumber()
+ .toString(16);
+
+ X509Principal issuerDN = new X509Principal(certificate
+ .getIssuerDN().getName());
+
+ if(serialNum.equalsIgnoreCase(tokenSerialNumber)
+ && X509PrincipalUtil.equals2(issuerDN, tokenIssuerDN)){
+ alias = aliasCert;
+ find = true;
+ }
+
+ }
+
+ } catch (KeyStoreException e) {
+ LOG.error("Procces getAlias from certificate associated into the signing keystore..", e);
+ } catch (CertificateException e) {
+ LOG.error("Procces getAlias from certificate associated into the signing keystore..", e);
+ } catch (RuntimeException e) {
+ LOG.error("Procces getAlias from certificate associated into the signing keystore..", e);
+ }
+ return alias;
+ }
+
+ /**
+ * Gets the country from X.509 Certificate.
+ *
+ * @param keyInfo the key info
+ *
+ * @return the country
+ */
+ private String getCountry(final KeyInfo keyInfo) {
+ LOG.debug("Recover country information.");
+
+ String result = "";
+ try {
+ final org.opensaml.xml.signature.X509Certificate xmlCert = keyInfo
+ .getX509Datas().get(0).getX509Certificates().get(0);
+
+ // Transform the KeyInfo to X509Certificate.
+ CertificateFactory certFact;
+ certFact = CertificateFactory.getInstance("X.509");
+
+ final ByteArrayInputStream bis = new ByteArrayInputStream(Base64
+ .decode(xmlCert.getValue()));
+
+ final X509Certificate cert = (X509Certificate) certFact
+ .generateCertificate(bis);
+
+ String distName = cert.getSubjectDN().toString();
+
+ distName = StringUtils.deleteWhitespace(StringUtils
+ .upperCase(distName));
+
+ final String countryCode = "C=";
+ final int init = distName.indexOf(countryCode);
+
+ if (init > StringUtils.INDEX_NOT_FOUND) { // Exist country code.
+ int end = distName.indexOf(',', init);
+
+ if (end <= StringUtils.INDEX_NOT_FOUND) {
+ end = distName.length();
+ }
+
+ if (init < end && end > StringUtils.INDEX_NOT_FOUND) {
+ result = distName.substring(init + countryCode.length(),
+ end);
+ //It must be a two characters value
+ if(result.length()>2){
+ result = result.substring(0, 2);
+ }
+ }
+ }
+
+ } catch (CertificateException e) {
+ LOG.error("Procces getCountry from certificate.");
+ }
+ return result.trim();
+ }
+
+ /**
+ * Process all elements XMLObjects from the extensions.
+ *
+ * @param extensions the extensions from the authentication request.
+ *
+ * @return the STORK authentication request
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private STORKAuthnRequest processExtensions(final Extensions extensions)
+ throws STORKSAMLEngineException {
+ LOG.debug("Procces the extensions.");
+
+ final STORKAuthnRequest request = new STORKAuthnRequest();
+
+ final QAAAttribute qaa = (QAAAttribute) extensions
+ .getUnknownXMLObjects(QAAAttribute.DEF_ELEMENT_NAME).get(0);
+ request.setQaa(Integer.parseInt(qaa.getQaaLevel()));
+
+ List optionalElements = extensions.getUnknownXMLObjects(
+ SPSector.DEF_ELEMENT_NAME);
+
+ if (!optionalElements.isEmpty()) {
+ final SPSector sector = (SPSector) extensions.getUnknownXMLObjects(
+ SPSector.DEF_ELEMENT_NAME).get(0);
+ request.setSpSector(sector.getSPSector());
+ }
+
+ optionalElements = extensions.getUnknownXMLObjects(SPApplication.DEF_ELEMENT_NAME);
+
+ if (!optionalElements.isEmpty()) {
+ final SPApplication application = (SPApplication) extensions
+ .getUnknownXMLObjects(SPApplication.DEF_ELEMENT_NAME).get(0);
+ request.setSpApplication(application.getSPApplication());
+ }
+
+ optionalElements = extensions.getUnknownXMLObjects(SPCountry.DEF_ELEMENT_NAME);
+
+ if (!optionalElements.isEmpty()) {
+ final SPCountry application = (SPCountry) extensions
+ .getUnknownXMLObjects(SPCountry.DEF_ELEMENT_NAME).get(0);
+ request.setSpCountry(application.getSPCountry());
+ }
+
+
+ List listCrossBorderShare = extensions
+ .getUnknownXMLObjects(EIDCrossBorderShare.DEF_ELEMENT_NAME);
+
+ if (!listCrossBorderShare .isEmpty()) {
+ final EIDCrossBorderShare crossBorderShare = (EIDCrossBorderShare) listCrossBorderShare.get(0);
+ request.setEIDCrossBorderShare(Boolean.parseBoolean(crossBorderShare
+ .getEIDCrossBorderShare()));
+ }
+
+
+ List listCrosSectorShare = extensions
+ .getUnknownXMLObjects(EIDCrossSectorShare.DEF_ELEMENT_NAME);
+
+ if (!listCrosSectorShare.isEmpty()) {
+ final EIDCrossSectorShare crossSectorShare = (EIDCrossSectorShare) listCrosSectorShare.get(0);
+ request.setEIDCrossSectorShare(Boolean.parseBoolean(crossSectorShare
+ .getEIDCrossSectorShare()));
+ }
+
+ List listSectorShareExtension = extensions
+ .getUnknownXMLObjects(EIDSectorShare.DEF_ELEMENT_NAME);
+ if (!listSectorShareExtension.isEmpty()) {
+ final EIDSectorShare sectorShare = (EIDSectorShare) listSectorShareExtension.get(0);
+ request.setEIDSectorShare(Boolean.parseBoolean(sectorShare.getEIDSectorShare()));
+ }
+
+
+
+ List<XMLObject> authAttrs = extensions
+ .getUnknownXMLObjects(AuthenticationAttributes.DEF_ELEMENT_NAME);
+
+ if (authAttrs != null && !authAttrs.isEmpty()) {
+
+ final AuthenticationAttributes authnAttr = (AuthenticationAttributes) authAttrs
+ .get(0);
+
+ VIDPAuthenticationAttributes vidpAuthnAttr = null;
+ if (authnAttr != null && !authAttrs.isEmpty()){
+ vidpAuthnAttr = authnAttr.getVIDPAuthenticationAttributes();
+ }
+
+ CitizenCountryCode citizenCountryCodeElement = null;
+ SPInformation spInformation = null;
+ if (vidpAuthnAttr != null){
+ citizenCountryCodeElement = vidpAuthnAttr.getCitizenCountryCode();
+ spInformation = vidpAuthnAttr.getSPInformation();
+ }
+
+ String citizenCountryCode = null;
+ if(citizenCountryCodeElement!=null){
+ citizenCountryCode = citizenCountryCodeElement.getCitizenCountryCode();
+ }
+
+ if(citizenCountryCode!= null && StringUtils.isNotBlank(citizenCountryCode)){
+ request.setCitizenCountryCode(citizenCountryCode);
+ }
+
+ SPID spidElement = null;
+ if (spInformation != null){
+ spidElement = spInformation.getSPID();
+ }
+
+ String spid = null;
+ if(spidElement!=null){
+ spid = spidElement.getSPID();
+ }
+
+ if (spid != null && StringUtils.isNotBlank(spid)) {
+ request.setSPID(spid);
+ }
+ }
+
+ if (extensions
+ .getUnknownXMLObjects(RequestedAttributes.DEF_ELEMENT_NAME) == null) {
+ LOG.error("Extensions not contains any requested attribute.");
+ throw new STORKSAMLEngineException(
+ "Extensions not contains any requested attribute.");
+ }
+
+ final RequestedAttributes requestedAttr = (RequestedAttributes) extensions
+ .getUnknownXMLObjects(RequestedAttributes.DEF_ELEMENT_NAME)
+ .get(0);
+
+ final List<RequestedAttribute> reqAttrs = requestedAttr.getAttributes();
+
+ final IPersonalAttributeList personalAttrList = new PersonalAttributeList();
+
+ String attributeName;
+ for (int nextAttribute = 0; nextAttribute < reqAttrs.size(); nextAttribute++) {
+ final RequestedAttribute attribute = reqAttrs.get(nextAttribute);
+ final PersonalAttribute personalAttribute = new PersonalAttribute();
+ personalAttribute.setIsRequired(Boolean.valueOf(attribute.isRequired()));
+ personalAttribute.setFriendlyName(attribute.getFriendlyName());
+ attributeName = attribute.getName();
+
+ // recover the last name from the string.
+ personalAttribute.setName(attributeName.substring(attributeName
+ .lastIndexOf('/') + 1));
+
+ final ArrayList<String> valores = new ArrayList<String>();
+ final List<XMLObject> values = attribute.getOrderedChildren();
+
+ for (int nextSimpleValue = 0; nextSimpleValue < values.size(); nextSimpleValue++) {
+
+ // Process attributes simples. An AuthenticationRequest only
+ // must contains simple values.
+
+ final XMLObject xmlObject = values.get(nextSimpleValue);
+
+ if(xmlObject instanceof XSStringImpl){
+
+ final XSStringImpl xmlString = (XSStringImpl) values
+ .get(nextSimpleValue);
+ valores.add(xmlString.getValue());
+
+ }else{
+
+ if (attributeName.equals("http://www.stork.gov.eu/1.0/signedDoc")) {
+
+ final XSAnyImpl xmlString = (XSAnyImpl) values
+ .get(nextSimpleValue);
+
+ TransformerFactory transFactory = TransformerFactory.newInstance();
+ Transformer transformer = null;
+ try {
+ transformer = transFactory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ } catch (TransformerConfigurationException e) {
+ LOG.error("Error transformer configuration exception", e);
+ }
+ StringWriter buffer = new StringWriter();
+ try {
+ if (xmlString != null && xmlString.getUnknownXMLObjects() != null && xmlString.getUnknownXMLObjects().size() > 0 ){
+ transformer.transform(new DOMSource(xmlString.getUnknownXMLObjects().get(0).getDOM()),
+ new StreamResult(buffer));
+ }
+ } catch (TransformerException e) {
+ LOG.error("Error transformer exception", e);
+ }
+ String str = buffer.toString();
+
+ valores.add(str);
+
+ }else{
+
+ final XSAnyImpl xmlString = (XSAnyImpl) values
+ .get(nextSimpleValue);
+ valores.add(xmlString.getTextContent());
+ }
+
+
+
+ }
+ }
+ personalAttribute.setValue(valores);
+ personalAttrList.add(personalAttribute);
+ }
+
+ request.setPersonalAttributeList(personalAttrList);
+
+ return request;
+ }
+
+
+ /**
+ * Process all elements XMLObjects from the extensions.
+ *
+ * @param extensions the extensions from the authentication request.
+ *
+ * @return the STORK authentication request
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private STORKAttrQueryRequest processAttrExtensions(final Extensions extensions)
+ throws STORKSAMLEngineException {
+ LOG.debug("Procces the atribute query extensions.");
+
+ final STORKAttrQueryRequest request = new STORKAttrQueryRequest();
+
+ final QAAAttribute qaa = (QAAAttribute) extensions
+ .getUnknownXMLObjects(QAAAttribute.DEF_ELEMENT_NAME).get(0);
+ request.setQaa(Integer.parseInt(qaa.getQaaLevel()));
+
+ List optionalElements = extensions.getUnknownXMLObjects(
+ SPSector.DEF_ELEMENT_NAME);
+
+ if (!optionalElements.isEmpty()) {
+ final SPSector sector = (SPSector) extensions.getUnknownXMLObjects(
+ SPSector.DEF_ELEMENT_NAME).get(0);
+ request.setSpSector(sector.getSPSector());
+ }
+
+ optionalElements = extensions.getUnknownXMLObjects(SPApplication.DEF_ELEMENT_NAME);
+
+ if (!optionalElements.isEmpty()) {
+ final SPApplication application = (SPApplication) extensions
+ .getUnknownXMLObjects(SPApplication.DEF_ELEMENT_NAME).get(0);
+ request.setSpApplication(application.getSPApplication());
+ }
+
+ optionalElements = extensions.getUnknownXMLObjects(SPCountry.DEF_ELEMENT_NAME);
+
+ if (!optionalElements.isEmpty()) {
+ final SPCountry application = (SPCountry) extensions
+ .getUnknownXMLObjects(SPCountry.DEF_ELEMENT_NAME).get(0);
+ request.setSpCountry(application.getSPCountry());
+ }
+
+
+ List listCrossBorderShare = extensions
+ .getUnknownXMLObjects(EIDCrossBorderShare.DEF_ELEMENT_NAME);
+
+ if (!listCrossBorderShare .isEmpty()) {
+ final EIDCrossBorderShare crossBorderShare = (EIDCrossBorderShare) listCrossBorderShare.get(0);
+ request.setEIDCrossBorderShare(Boolean.parseBoolean(crossBorderShare
+ .getEIDCrossBorderShare()));
+ }
+
+
+ List listCrosSectorShare = extensions
+ .getUnknownXMLObjects(EIDCrossSectorShare.DEF_ELEMENT_NAME);
+
+ if (!listCrosSectorShare.isEmpty()) {
+ final EIDCrossSectorShare crossSectorShare = (EIDCrossSectorShare) listCrosSectorShare.get(0);
+ request.setEIDCrossSectorShare(Boolean.parseBoolean(crossSectorShare
+ .getEIDCrossSectorShare()));
+ }
+
+ List listSectorShareExtension = extensions
+ .getUnknownXMLObjects(EIDSectorShare.DEF_ELEMENT_NAME);
+ if (!listSectorShareExtension.isEmpty()) {
+ final EIDSectorShare sectorShare = (EIDSectorShare) listSectorShareExtension.get(0);
+ request.setEIDSectorShare(Boolean.parseBoolean(sectorShare.getEIDSectorShare()));
+ }
+
+
+
+ List<XMLObject> authAttrs = extensions
+ .getUnknownXMLObjects(AuthenticationAttributes.DEF_ELEMENT_NAME);
+
+ if (authAttrs != null && !authAttrs.isEmpty()) {
+
+ final AuthenticationAttributes authnAttr = (AuthenticationAttributes) authAttrs
+ .get(0);
+
+ VIDPAuthenticationAttributes vidpAuthnAttr = null;
+ if (authnAttr != null && !authAttrs.isEmpty()){
+ vidpAuthnAttr = authnAttr.getVIDPAuthenticationAttributes();
+ }
+
+ CitizenCountryCode citizenCountryCodeElement = null;
+ SPInformation spInformation = null;
+ if (vidpAuthnAttr != null){
+ citizenCountryCodeElement = vidpAuthnAttr.getCitizenCountryCode();
+ spInformation = vidpAuthnAttr.getSPInformation();
+ }
+
+ String citizenCountryCode = null;
+ if(citizenCountryCodeElement!=null){
+ citizenCountryCode = citizenCountryCodeElement.getCitizenCountryCode();
+ }
+
+ if(citizenCountryCode!= null && StringUtils.isNotBlank(citizenCountryCode)){
+ request.setCitizenCountryCode(citizenCountryCode);
+ }
+
+ SPID spidElement = null;
+ if (spInformation != null){
+ spidElement = spInformation.getSPID();
+ }
+
+ String spid = null;
+ if(spidElement!=null){
+ spid = spidElement.getSPID();
+ }
+
+ if (spid != null && StringUtils.isNotBlank(spid)) {
+ request.setSPID(spid);
+ }
+ }
+
+ if (extensions
+ .getUnknownXMLObjects(RequestedAttributes.DEF_ELEMENT_NAME) == null) {
+ LOG.error("Extensions not contains any requested attribute.");
+ throw new STORKSAMLEngineException(
+ "Extensions not contains any requested attribute.");
+ }
+
+ final RequestedAttributes requestedAttr = (RequestedAttributes) extensions
+ .getUnknownXMLObjects(RequestedAttributes.DEF_ELEMENT_NAME)
+ .get(0);
+
+ final List<RequestedAttribute> reqAttrs = requestedAttr.getAttributes();
+
+ final IPersonalAttributeList personalAttrList = new PersonalAttributeList();
+
+ String attributeName;
+ for (int nextAttribute = 0; nextAttribute < reqAttrs.size(); nextAttribute++) {
+ final RequestedAttribute attribute = reqAttrs.get(nextAttribute);
+ final PersonalAttribute personalAttribute = new PersonalAttribute();
+ personalAttribute.setIsRequired(Boolean.valueOf(attribute.isRequired()));
+ personalAttribute.setFriendlyName(attribute.getFriendlyName());
+ attributeName = attribute.getName();
+
+ // recover the last name from the string.
+ personalAttribute.setName(attributeName.substring(attributeName
+ .lastIndexOf('/') + 1));
+
+ final ArrayList<String> valores = new ArrayList<String>();
+ final List<XMLObject> values = attribute.getOrderedChildren();
+
+ for (int nextSimpleValue = 0; nextSimpleValue < values.size(); nextSimpleValue++) {
+
+ // Process attributes simples. An AuthenticationRequest only
+ // must contains simple values.
+
+ final XMLObject xmlObject = values.get(nextSimpleValue);
+
+ if(xmlObject instanceof XSStringImpl){
+
+ final XSStringImpl xmlString = (XSStringImpl) values
+ .get(nextSimpleValue);
+ valores.add(xmlString.getValue());
+
+ }else{
+
+ if (attributeName.equals("http://www.stork.gov.eu/1.0/signedDoc")) {
+
+ final XSAnyImpl xmlString = (XSAnyImpl) values
+ .get(nextSimpleValue);
+
+ TransformerFactory transFactory = TransformerFactory.newInstance();
+ Transformer transformer = null;
+ try {
+ transformer = transFactory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ } catch (TransformerConfigurationException e) {
+ LOG.error("Error transformer configuration exception", e);
+ }
+ StringWriter buffer = new StringWriter();
+ try {
+ if (xmlString != null && xmlString.getUnknownXMLObjects() != null && xmlString.getUnknownXMLObjects().size() > 0 ){
+ transformer.transform(new DOMSource(xmlString.getUnknownXMLObjects().get(0).getDOM()),
+ new StreamResult(buffer));
+ }
+ } catch (TransformerException e) {
+ LOG.error("Error transformer exception", e);
+ }
+ String str = buffer.toString();
+
+ valores.add(str);
+
+ }else{
+
+ final XSAnyImpl xmlString = (XSAnyImpl) values
+ .get(nextSimpleValue);
+ valores.add(xmlString.getTextContent());
+ }
+
+
+
+ }
+ }
+ personalAttribute.setValue(valores);
+ personalAttrList.add(personalAttribute);
+ }
+
+ request.setPersonalAttributeList(personalAttrList);
+
+ return request;
+ }
+
+ /**
+ * Sets the name spaces.
+ *
+ * @param tokenSaml the new name spaces
+ */
+ private void setNameSpaces(final XMLObject tokenSaml) {
+ LOG.debug("Set namespaces.");
+
+ final Namespace saml2 = new Namespace(SAMLConstants.SAML20_NS,
+ SAMLConstants.SAML20_PREFIX);
+ tokenSaml.addNamespace(saml2);
+
+ final Namespace digSig = new Namespace(
+ "http://www.w3.org/2000/09/xmldsig#", "ds");
+ tokenSaml.addNamespace(digSig);
+
+ final Namespace storkp = new Namespace(SAMLCore.STORK10P_NS.getValue(),
+ SAMLCore.STORK10P_PREFIX.getValue());
+ tokenSaml.addNamespace(storkp);
+
+ final Namespace stork = new Namespace(SAMLCore.STORK10_NS.getValue(),
+ SAMLCore.STORK10_PREFIX.getValue());
+
+ tokenSaml.addNamespace(stork);
+ }
+
+ /**
+ * Validate parameters from authentication request.
+ *
+ * @param request the request.
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private void validateParamAuthnReq(final STORKAuthnRequest request)
+ throws STORKSAMLEngineException {
+ LOG.info("Validate parameters from authentication request.");
+
+ // URL to which Authentication Response must be sent.
+ if (StringUtils.isBlank(request.getAssertionConsumerServiceURL())) {
+ throw new STORKSAMLEngineException(
+ "StorkSamlEngine: Assertion Consumer Service URL it's mandatory.");
+ }
+
+ // the name of the original service provider requesting the
+ // authentication.
+ if (StringUtils.isBlank(request.getProviderName())) {
+ throw new STORKSAMLEngineException(
+ "StorkSamlEngine: Service Provider it's mandatory.");
+ }
+
+ // object that contain all attributes requesting.
+ if (request.getPersonalAttributeList() == null
+ || request.getPersonalAttributeList().isEmpty()) {
+ throw new STORKSAMLEngineException(
+ "attributeQueries is null or empty.");
+ }
+
+ // Quality authentication assurance level.
+ if ((request.getQaa() < QAAAttribute.MIN_VALUE)
+ || (request.getQaa() > QAAAttribute.MAX_VALUE)) {
+ throw new STORKSAMLEngineException("Qaal: " + request.getQaa()
+ + ", is invalid.");
+ }
+
+ }
+
+ /**
+ * Validate parameters from authentication request.
+ *
+ * @param request the request.
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private void validateParamAttrQueryReq(final STORKAttrQueryRequest request)
+ throws STORKSAMLEngineException {
+ LOG.info("Validate parameters from attribute query request.");
+
+ // URL to which Authentication Response must be sent.
+ /*if (StringUtils.isBlank(request.getAssertionConsumerServiceURL())) {
+ throw new STORKSAMLEngineException(
+ "StorkSamlEngine: Assertion Consumer Service URL it's mandatory.");
+ }*/
+
+ // the name of the original service provider requesting the
+ // authentication.
+ /*if (StringUtils.isBlank(request.getProviderName())) {
+ throw new STORKSAMLEngineException(
+ "StorkSamlEngine: Service Provider it's mandatory.");
+ }*/
+
+ // object that contain all attributes requesting.
+ if (request.getPersonalAttributeList() == null
+ || request.getPersonalAttributeList().isEmpty()) {
+ throw new STORKSAMLEngineException(
+ "attributeQueries is null or empty.");
+ }
+
+ // Quality authentication assurance level.
+ if ((request.getQaa() < QAAAttribute.MIN_VALUE)
+ || (request.getQaa() > QAAAttribute.MAX_VALUE)) {
+ throw new STORKSAMLEngineException("Qaal: " + request.getQaa()
+ + ", is invalid.");
+ }
+
+ }
+
+
+ /**
+ * Validate parameters from response.
+ *
+ * @param request the request
+ * @param responseAuthReq the response authentication request
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private void validateParamResponse(final STORKAuthnRequest request,
+ final STORKAuthnResponse responseAuthReq)
+ throws STORKSAMLEngineException {
+ LOG.info("Validate parameters response.");
+ if (StringUtils.isBlank(request.getIssuer())) {
+ throw new STORKSAMLEngineException(
+ "Issuer must be not empty or null.");
+ }
+
+ if (responseAuthReq.getPersonalAttributeList() == null
+ || responseAuthReq.getPersonalAttributeList().isEmpty()) {
+ LOG.error("PersonalAttributeList is null or empty.");
+ throw new STORKSAMLEngineException(
+ "PersonalAttributeList is null or empty.");
+ }
+
+ if (StringUtils.isBlank(request.getAssertionConsumerServiceURL())) {
+ throw new STORKSAMLEngineException(
+ "assertionConsumerServiceURL is null or empty.");
+ }
+
+ if (StringUtils.isBlank(request.getSamlId())) {
+ throw new STORKSAMLEngineException("request ID is null or empty.");
+ }
+ }
+
+ /**
+ * Validate parameters from response.
+ *
+ * @param request the request
+ * @param responseAttrQueryReq the response authentication request
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private void validateParamAttrQueryResponse(final STORKAttrQueryRequest request,
+ final STORKAttrQueryResponse responseAttrQueryReq)
+ throws STORKSAMLEngineException {
+ LOG.info("Validate attribute querey parameters response.");
+ if (StringUtils.isBlank(request.getIssuer())) {
+ throw new STORKSAMLEngineException(
+ "Issuer must be not empty or null.");
+ }
+
+ if (responseAttrQueryReq.getPersonalAttributeList() == null
+ || responseAttrQueryReq.getPersonalAttributeList().isEmpty()) {
+ LOG.error("PersonalAttributeList is null or empty.");
+ throw new STORKSAMLEngineException(
+ "PersonalAttributeList is null or empty.");
+ }
+
+ /*if (StringUtils.isBlank(request.getAssertionConsumerServiceURL())) {
+ throw new STORKSAMLEngineException(
+ "assertionConsumerServiceURL is null or empty.");
+ }*/
+
+ if (StringUtils.isBlank(request.getSamlId())) {
+ throw new STORKSAMLEngineException("request ID is null or empty.");
+ }
+ }
+
+ /**
+ * Validate parameter from response fail.
+ *
+ * @param request the request
+ * @param response the response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private void validateParamResponseFail(final STORKAuthnRequest request,
+ final STORKAuthnResponse response) throws STORKSAMLEngineException {
+ LOG.info("Validate parameters response fail.");
+ if (StringUtils.isBlank(response.getStatusCode())) {
+ throw new STORKSAMLEngineException("Code error it's null or empty.");
+ }
+
+ if (StringUtils.isBlank(request.getAssertionConsumerServiceURL())) {
+ throw new STORKSAMLEngineException(
+ "assertionConsumerServiceURL is null or empty.");
+ }
+
+ if (StringUtils.isBlank(request.getSamlId())) {
+ throw new STORKSAMLEngineException("request ID is null or empty.");
+ }
+ }
+
+ /**
+ * Validate parameter from response fail.
+ *
+ * @param request the request
+ * @param response the response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private void validateParamAttrQueryResponseFail(final STORKAttrQueryRequest request,
+ final STORKAttrQueryResponse response) throws STORKSAMLEngineException {
+ LOG.info("Validate parameters response fail.");
+ if (StringUtils.isBlank(response.getStatusCode())) {
+ throw new STORKSAMLEngineException("Code error it's null or empty.");
+ }
+
+ if (StringUtils.isBlank(request.getSamlId())) {
+ throw new STORKSAMLEngineException("request ID is null or empty.");
+ }
+ }
+
+ /**
+ * Validate stork authentication request.
+ *
+ * @param tokenSaml the token SAML
+ *
+ * @return the sTORK authentication request
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAuthnRequest validateSTORKAuthnRequest(final byte[] tokenSaml)
+ throws STORKSAMLEngineException {
+ LOG.info("validateSTORKAuthnRequest");
+
+ final AuthnRequest samlRequest = (AuthnRequest) validateStorkSaml(tokenSaml);
+
+ LOG.debug("Validate Extensions.");
+ final Validator<Extensions> validatorExt = new ExtensionsSchemaValidator();
+ try {
+ validatorExt.validate(samlRequest.getExtensions());
+ } catch (ValidationException e) {
+ LOG.error("ValidationException: validate Extensions.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ LOG.debug("Generate STORKAuthnRequest.");
+ final STORKAuthnRequest authnRequest = processExtensions(samlRequest
+ .getExtensions());
+
+ authnRequest.setCountry(this.getCountry(samlRequest.getSignature()
+ .getKeyInfo()));
+
+ authnRequest.setAlias(this.getAlias(samlRequest.getSignature()
+ .getKeyInfo(), super.getSigner().getTrustStore()));
+
+ authnRequest.setSamlId(samlRequest.getID());
+ authnRequest.setDestination(samlRequest.getDestination());
+ authnRequest.setAssertionConsumerServiceURL(samlRequest
+ .getAssertionConsumerServiceURL());
+
+ authnRequest.setProviderName(samlRequest.getProviderName());
+ authnRequest.setIssuer(samlRequest.getIssuer().getValue());
+
+ //Delete unknown elements from requested ones
+ final Iterator<PersonalAttribute> iterator = authnRequest.getPersonalAttributeList().iterator();
+ IPersonalAttributeList cleanPerAttrList = (PersonalAttributeList) authnRequest.getPersonalAttributeList();
+ while (iterator.hasNext()) {
+
+ final PersonalAttribute attribute = iterator.next();
+
+ // Verify if the attribute name exits.
+ final String attributeName = super.getSamlCoreProperties()
+ .getProperty(attribute.getName());
+
+ if (StringUtils.isBlank(attributeName)) {
+ LOG.info("Attribute name: {} was not found. It will be removed from the request object", attribute.getName());
+ cleanPerAttrList.remove(attribute.getName());
+ }
+
+ }
+ authnRequest.setPersonalAttributeList(cleanPerAttrList);
+
+ return authnRequest;
+
+ }
+
+ /**
+ * Validate stork authentication request.
+ *
+ * @param tokenSaml the token SAML
+ *
+ * @return the sTORK authentication request
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAttrQueryRequest validateSTORKAttrQueryRequest(final byte[] tokenSaml)
+ throws STORKSAMLEngineException {
+ LOG.info("validateSTORKAttrQueryRequest");
+
+ final AttributeQuery samlRequest = (AttributeQuery) validateStorkSaml(tokenSaml);
+
+ LOG.debug("Validate Extensions.");
+ final Validator<Extensions> validatorExt = new ExtensionsSchemaValidator();
+ try {
+ validatorExt.validate(samlRequest.getExtensions());
+ } catch (ValidationException e) {
+ LOG.error("ValidationException: validate Extensions.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ LOG.debug("Generate STORKAttrQueryRequest.");
+ final STORKAttrQueryRequest attrRequest = processAttrExtensions(samlRequest
+ .getExtensions());
+
+ attrRequest.setCountry(this.getCountry(samlRequest.getSignature()
+ .getKeyInfo()));
+
+ attrRequest.setAlias(this.getAlias(samlRequest.getSignature()
+ .getKeyInfo(), super.getSigner().getTrustStore()));
+
+ attrRequest.setSamlId(samlRequest.getID());
+ attrRequest.setDestination(samlRequest.getDestination());
+ /*attrRequest.setAssertionConsumerServiceURL(samlRequest
+ .getAssertionConsumerServiceURL());
+
+ authnRequest.setProviderName(samlRequest.getProviderName());*/
+ attrRequest.setIssuer(samlRequest.getIssuer().getValue());
+
+ //Delete unknown elements from requested ones
+ final Iterator<PersonalAttribute> iterator = attrRequest.getPersonalAttributeList().iterator();
+ IPersonalAttributeList cleanPerAttrList = (PersonalAttributeList) attrRequest.getPersonalAttributeList();
+ while (iterator.hasNext()) {
+
+ final PersonalAttribute attribute = iterator.next();
+
+ // Verify if the attribute name exits.
+ final String attributeName = super.getSamlCoreProperties()
+ .getProperty(attribute.getName());
+
+ if (StringUtils.isBlank(attributeName)) {
+ LOG.info("Attribute name: {} was not found. It will be removed from the request object", attribute.getName());
+ cleanPerAttrList.remove(attribute.getName());
+ }
+
+ }
+ attrRequest.setPersonalAttributeList(cleanPerAttrList);
+
+ return attrRequest;
+
+ }
+
+ /**
+ * Validate stork authentication response.
+ *
+ * @param tokenSaml the token SAML
+ * @param userIP the user IP
+ *
+ * @return the Stork authentication response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAuthnResponse validateSTORKAuthnResponse(
+ final byte[] tokenSaml, final String userIP)
+ throws STORKSAMLEngineException {
+
+ LOG.info("validateSTORKAuthnResponse");
+ final Response samlResponse = (Response) validateStorkSaml(tokenSaml);
+
+ LOG.debug("Create StorkAuthResponse.");
+ final STORKAuthnResponse authnResponse = new STORKAuthnResponse();
+
+ authnResponse.setCountry(this.getCountry(samlResponse.getSignature()
+ .getKeyInfo()));
+
+ LOG.debug("Set ID.");
+ authnResponse.setSamlId(samlResponse.getID());
+ LOG.debug("Set InResponseTo.");
+ authnResponse.setInResponseTo(samlResponse.getInResponseTo());
+ LOG.debug("Set statusCode.");
+ authnResponse.setStatusCode(samlResponse.getStatus().getStatusCode()
+ .getValue());
+
+ // Subordinate code.
+ if (samlResponse.getStatus().getStatusCode().getStatusCode() != null) {
+ authnResponse.setSubStatusCode(samlResponse.getStatus()
+ .getStatusCode().getStatusCode().getValue());
+ }
+
+ if (samlResponse.getStatus().getStatusMessage() != null) {
+ LOG.debug("Set statusMessage.");
+ authnResponse.setMessage(samlResponse.getStatus()
+ .getStatusMessage().getMessage());
+ }
+
+ LOG.debug("validateStorkResponse");
+ final Assertion assertion = (Assertion) validateStorkResponse(
+ samlResponse, userIP);
+
+ if(assertion!=null){
+ final DateTime serverDate = new DateTime();
+
+ if (assertion.getConditions().getNotOnOrAfter().isBefore(serverDate)) {
+ LOG.error("Token date expired (getNotOnOrAfter = "
+ + assertion.getConditions().getNotOnOrAfter()
+ + ", server_date: " + serverDate + ")");
+ throw new STORKSAMLEngineException(
+ "Token date expired (getNotOnOrAfter = "
+ + assertion.getConditions().getNotOnOrAfter()
+ + " ), server_date: " + serverDate);
+ }
+
+ LOG.debug("Set notOnOrAfter.");
+ authnResponse.setNotOnOrAfter(assertion.getConditions()
+ .getNotOnOrAfter());
+
+ LOG.debug("Set notBefore.");
+ authnResponse.setNotBefore(assertion.getConditions().getNotBefore());
+
+ authnResponse.setNotBefore(assertion.getConditions().getNotBefore());
+
+ authnResponse.setAudienceRestriction(((AudienceRestriction) assertion
+ .getConditions().getAudienceRestrictions().get(0))
+ .getAudiences().get(0).getAudienceURI());
+ }
+
+ // Case no error.
+ if (assertion!=null && StatusCode.SUCCESS_URI.equalsIgnoreCase(authnResponse
+ .getStatusCode())) {
+ LOG.debug("Status Success. Set PersonalAttributeList.");
+ authnResponse
+ .setPersonalAttributeList(generatePersonalAttributeList(assertion));
+ authnResponse.setFail(false);
+ } else {
+ LOG.debug("Status Fail.");
+ authnResponse.setFail(true);
+ }
+ LOG.debug("Return result.");
+ return authnResponse;
+
+ }
+
+ /**
+ * Validate stork attribute query response.
+ *
+ * @param tokenSaml the token SAML
+ * @param userIP the user IP
+ *
+ * @return the Stork attribute query response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAttrQueryResponse validateSTORKAttrQueryResponse(
+ final byte[] tokenSaml, final String userIP)
+ throws STORKSAMLEngineException {
+
+ LOG.info("validateSTORKAttrQueryResponse");
+ final Response samlResponse = (Response) validateStorkSaml(tokenSaml);
+
+ LOG.debug("Create StorkAttrQueryResponse.");
+ final STORKAttrQueryResponse attrQueryResponse = new STORKAttrQueryResponse();
+
+ attrQueryResponse.setCountry(this.getCountry(samlResponse.getSignature()
+ .getKeyInfo()));
+
+ LOG.debug("Set ID.");
+ attrQueryResponse.setSamlId(samlResponse.getID());
+ LOG.debug("Set InResponseTo.");
+ attrQueryResponse.setInResponseTo(samlResponse.getInResponseTo());
+ LOG.debug("Set statusCode.");
+ attrQueryResponse.setStatusCode(samlResponse.getStatus().getStatusCode()
+ .getValue());
+
+ // Subordinate code.
+ if (samlResponse.getStatus().getStatusCode().getStatusCode() != null) {
+ attrQueryResponse.setSubStatusCode(samlResponse.getStatus()
+ .getStatusCode().getStatusCode().getValue());
+ }
+
+ if (samlResponse.getStatus().getStatusMessage() != null) {
+ LOG.debug("Set statusMessage.");
+ attrQueryResponse.setMessage(samlResponse.getStatus()
+ .getStatusMessage().getMessage());
+ }
+
+ LOG.debug("validateStorkResponse");
+ final Assertion assertion = (Assertion) validateStorkResponse(
+ samlResponse, userIP);
+
+ if(assertion!=null){
+ final DateTime serverDate = new DateTime();
+
+ if (assertion.getConditions().getNotOnOrAfter().isBefore(serverDate)) {
+ LOG.error("Token date expired (getNotOnOrAfter = "
+ + assertion.getConditions().getNotOnOrAfter()
+ + ", server_date: " + serverDate + ")");
+ throw new STORKSAMLEngineException(
+ "Token date expired (getNotOnOrAfter = "
+ + assertion.getConditions().getNotOnOrAfter()
+ + " ), server_date: " + serverDate);
+ }
+
+ LOG.debug("Set notOnOrAfter.");
+ attrQueryResponse.setNotOnOrAfter(assertion.getConditions()
+ .getNotOnOrAfter());
+
+ LOG.debug("Set notBefore.");
+ attrQueryResponse.setNotBefore(assertion.getConditions().getNotBefore());
+
+ attrQueryResponse.setNotBefore(assertion.getConditions().getNotBefore());
+
+ attrQueryResponse.setAudienceRestriction(((AudienceRestriction) assertion
+ .getConditions().getAudienceRestrictions().get(0))
+ .getAudiences().get(0).getAudienceURI());
+ }
+
+ // Case no error.
+ if (assertion!=null && StatusCode.SUCCESS_URI.equalsIgnoreCase(attrQueryResponse
+ .getStatusCode())) {
+ LOG.debug("Status Success. Set PersonalAttributeList.");
+ attrQueryResponse
+ .setPersonalAttributeList(generatePersonalAttributeList(assertion));
+ attrQueryResponse.setFail(false);
+ } else {
+ LOG.debug("Status Fail.");
+ attrQueryResponse.setFail(true);
+ }
+ LOG.debug("Return result.");
+ return attrQueryResponse;
+
+ }
+
+ /**
+ * Validate stork response.
+ *
+ * @param samlResponse the SAML response
+ * @param userIP the user IP
+ *
+ * @return the assertion
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private Assertion validateStorkResponse(final Response samlResponse,
+ final String userIP) throws STORKSAMLEngineException {
+ // Exist only one Assertion
+
+ if (samlResponse.getAssertions() == null
+ || samlResponse.getAssertions().isEmpty()) {
+ LOG.info("Assertion is null or empty."); //in replace of throw new STORKSAMLEngineException("Assertion is null or empty.")
+ return null;
+ }
+
+ final Assertion assertion = (Assertion) samlResponse.getAssertions()
+ .get(0);
+
+ LOG.debug("Verified method Bearer");
+ for (final Iterator<SubjectConfirmation> iter = assertion.getSubject()
+ .getSubjectConfirmations().iterator(); iter.hasNext();) {
+ final SubjectConfirmation element = iter.next();
+ final boolean isBearer = SubjectConfirmation.METHOD_BEARER
+ .equals(element.getMethod());
+
+ final boolean ipValidate = super.getSamlCoreProperties()
+ .isIpValidation();
+
+ if (ipValidate) {
+ if (isBearer) {
+ if (StringUtils.isBlank(userIP)) {
+ LOG.error("browser_ip is null or empty.");
+ throw new STORKSAMLEngineException(
+ "browser_ip is null or empty.");
+ } else if (StringUtils.isBlank(element
+ .getSubjectConfirmationData().getAddress())) {
+ LOG.error("token_ip attribute is null or empty.");
+ throw new STORKSAMLEngineException(
+ "token_ip attribute is null or empty.");
+ }
+ }
+
+ final boolean ipEqual = element.getSubjectConfirmationData()
+ .getAddress().equals(userIP);
+
+ // Validation ipUser
+ if (!ipEqual && ipValidate) {
+ LOG.error("SubjectConfirmation BEARER: ");
+ throw new STORKSAMLEngineException(
+ "IPs doesn't match : token_ip ("
+ + element.getSubjectConfirmationData()
+ .getAddress() + ") browser_ip ("
+ + userIP + ")");
+ }
+ }
+
+ }
+ return assertion;
+ }
+
+ /**
+ * Validate stork SAML.
+ *
+ * @param tokenSaml the token SAML
+ *
+ * @return the signable SAML object
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private SignableSAMLObject validateStorkSaml(final byte[] tokenSaml)
+ throws STORKSAMLEngineException {
+
+ LOG.info("Validate StorkSaml message.");
+
+ if (tokenSaml == null) {
+ LOG.error("Saml authentication request is null.");
+ throw new STORKSAMLEngineException(
+ "Saml authentication request is null.");
+ }
+
+ LOG.debug("Generate AuthnRequest from request.");
+ SignableSAMLObject samlObject;
+
+ try {
+ samlObject = (SignableSAMLObject) super.unmarshall(tokenSaml);
+ } catch (SAMLEngineException e) {
+ LOG.error("SAMLEngineException unmarshall.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ boolean validateSign = true;
+
+ if (StringUtils.isNotBlank(super.getSamlCoreProperties().getProperty(
+ "validateSignature"))) {
+ validateSign = Boolean.valueOf(super.getSamlCoreProperties()
+ .getProperty("validateSignature"));
+ }
+
+ if (validateSign) {
+ LOG.debug("Validate Signature.");
+ try {
+ super.validateSignature(samlObject);
+ } catch (SAMLEngineException e) {
+ LOG.error("SAMLEngineException validateSignature.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+ }
+
+ LOG.debug("Validate Schema.");
+ final ValidatorSuite validatorSuite = Configuration
+ .getValidatorSuite("saml2-core-schema-validator");
+ try {
+ validatorSuite.validate(samlObject);
+ } catch (ValidationException e) {
+ LOG.error("ValidationException.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ return samlObject;
+ }
+}
diff --git a/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/X509PrincipalUtil.java.svn-base b/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/X509PrincipalUtil.java.svn-base
new file mode 100644
index 000000000..e38cc5f0b
--- /dev/null
+++ b/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/X509PrincipalUtil.java.svn-base
@@ -0,0 +1,69 @@
+package eu.stork.peps.auth.engine;
+
+import org.bouncycastle.asn1.DERObjectIdentifier;
+import org.bouncycastle.jce.X509Principal;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class used to decrease complexity of comparison of 2 X509principal
+ *
+ * @author vanegdi
+ * @version $Revision: 1.00 $, $Date: 2013-05-24 20:53:51 $
+ */
+public final class X509PrincipalUtil{
+
+ private static final DERObjectIdentifier[] DER_OBJECT_IDENTIFIERS_ARRAY= {
+ X509Principal.CN,
+ X509Principal.OU,
+ X509Principal.O,
+ X509Principal.L,
+ X509Principal.ST,
+ X509Principal.C,
+ X509Principal.E
+ };
+
+ private static final Logger LOG = LoggerFactory.getLogger(eu.stork.peps.auth.engine.X509PrincipalUtil.class);
+
+ /**
+ * Compares 2 X509Principals to detect if they equals
+ * @param principal1
+ * @param principal2
+ * @return true if arguments are not null and equals
+ */
+ public static boolean equals(X509Principal principal1, X509Principal principal2) {
+ boolean continueProcess = true;
+ if (principal1 == null || principal2 == null){
+ return false;
+ }
+
+ int cpt = 0;
+ while(continueProcess && cpt < DER_OBJECT_IDENTIFIERS_ARRAY.length){
+ continueProcess = continueProcess && x509ValuesByIdentifierEquals(principal1, principal2, DER_OBJECT_IDENTIFIERS_ARRAY[cpt]);
+ cpt++;
+ }
+ return continueProcess;
+ }
+
+ public static boolean equals2(X509Principal principal1, X509Principal principal2) {
+
+ if (principal1 == null || principal2 == null){
+ return false;
+ }
+
+ if (principal1.getName().equals(principal2.getName()))
+ return true;
+ else
+ return false;
+
+ }
+
+ private static boolean x509ValuesByIdentifierEquals(X509Principal principal1, X509Principal principal2, DERObjectIdentifier identifier){
+ return principal1.getValues(identifier).equals(principal2.getValues(identifier));
+ }
+
+ private X509PrincipalUtil(){
+ // default contructor
+ LOG.error("Fake X509PrincipalUtil : never be called");
+ }
+}
diff --git a/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/package-info.java.svn-base b/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/package-info.java.svn-base
new file mode 100644
index 000000000..d3e353e51
--- /dev/null
+++ b/id/server/stork2-saml-engine/build/classes/main/java/eu/stork/peps/auth/engine/.svn/text-base/package-info.java.svn-base
@@ -0,0 +1,19 @@
+/*
+ * 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/european-union-public-licence-eupl-v.1.1
+ *
+ * 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.
+ */
+
+/**
+ * Provides the classes necessary to create a SAML message.
+ */
+package eu.stork.peps.auth.engine; \ No newline at end of file