summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2020-01-31 20:41:54 +0100
committerThomas Lenz <thomas.lenz@egiz.gv.at>2020-01-31 20:41:54 +0100
commitd41afe91ee59daf6b5f5037cecac52900fe2ccb2 (patch)
tree3a19e1818d276d701574758ce6166b2f3a7e2030 /eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml
parent0cf9926282ba4aa46bad3f4e8020cec72683492f (diff)
downloadEAAF-Components-d41afe91ee59daf6b5f5037cecac52900fe2ccb2.tar.gz
EAAF-Components-d41afe91ee59daf6b5f5037cecac52900fe2ccb2.tar.bz2
EAAF-Components-d41afe91ee59daf6b5f5037cecac52900fe2ccb2.zip
a lot of more OpenSAML3 refactoring staff
This version is also NOT stable!
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafHttpPostDecoder.java77
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafHttpRedirectDeflateDecoder.java71
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafKeyStoreX509CredentialAdapter.java58
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HttpPostEncoderWithOwnTemplate.java56
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/StringRedirectDeflateEncoder.java33
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSaml2Bootstrap.java88
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSecurityConfigurationBootstrap.java218
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafOpenSaml3xInitializer.java156
8 files changed, 524 insertions, 233 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafHttpPostDecoder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafHttpPostDecoder.java
new file mode 100644
index 00000000..dc60019a
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafHttpPostDecoder.java
@@ -0,0 +1,77 @@
+package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.servlet.http.HttpServletRequest;
+
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.opensaml.saml.saml2.binding.decoding.impl.HTTPPostDecoder;
+
+import com.google.common.base.Strings;
+import lombok.extern.slf4j.Slf4j;
+import net.shibboleth.utilities.java.support.codec.Base64Support;
+
+/**
+ * SAML2 Post-Binding decoder with same EAAF specific hardening regarding http
+ * request-parameter processing.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class EaafHttpPostDecoder extends HTTPPostDecoder {
+
+ @Override
+ protected InputStream getBase64DecodedMessage(final HttpServletRequest request)
+ throws MessageDecodingException {
+
+ log.debug("Getting Base64 encoded message from request");
+ String encodedMessage = getLastParameterFromRequest(request, "SAMLRequest");
+ if (Strings.isNullOrEmpty(encodedMessage)) {
+ encodedMessage = getLastParameterFromRequest(request, "SAMLResponse");
+ }
+
+
+
+ if (Strings.isNullOrEmpty(encodedMessage)) {
+ log.info("Request did not contain either a SAMLRequest or "
+ + "SAMLResponse paramter. Invalid request for SAML 2 HTTP POST binding.");
+ throw new MessageDecodingException("No SAML message present in request");
+ }
+
+ log.trace("Base64 decoding SAML message:\n{}", encodedMessage);
+ final byte[] decodedBytes = Base64Support.decode(encodedMessage);
+ if (decodedBytes == null) {
+ log.info("Unable to Base64 decode SAML message");
+ throw new MessageDecodingException("Unable to Base64 decode SAML message");
+ }
+
+ log.trace("Decoded SAML message:\n{}", new String(decodedBytes));
+ return new ByteArrayInputStream(decodedBytes);
+ }
+
+ /**
+ * Always read the last parameter with this name from request to get a strict deterministic behavior.
+ * <br><br>
+ * <b><i>If more than one parameters with the same name exists,
+ * this method always select the last parameter value.</i></b>
+ *
+ * @param request Incoming http request
+ * @param paramName Name of the http parameter
+ * @return the last parameter value with this name, or <code>null</code> if the parameter not exists
+ */
+ @Nullable
+ private String getLastParameterFromRequest(@Nonnull HttpServletRequest request, @Nonnull String paramName) {
+ final String[] values = request.getParameterValues(paramName);
+ if (values != null && values.length > 0) {
+ return values[values.length - 1];
+
+ }
+
+ return null;
+
+ }
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafHttpRedirectDeflateDecoder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafHttpRedirectDeflateDecoder.java
new file mode 100644
index 00000000..e9140f26
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafHttpRedirectDeflateDecoder.java
@@ -0,0 +1,71 @@
+package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml;
+
+import java.io.InputStream;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.opensaml.saml.common.SAMLObject;
+import org.opensaml.saml.common.binding.SAMLBindingSupport;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.saml2.binding.decoding.impl.HTTPRedirectDeflateDecoder;
+
+import com.google.common.base.Strings;
+import lombok.extern.slf4j.Slf4j;
+import net.shibboleth.utilities.java.support.net.URISupport;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+/**
+ * SAML2 Redirect-Binding deflate decoder with same EAAF specific hardening
+ * regarding http request-parameter processing.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class EaafHttpRedirectDeflateDecoder extends HTTPRedirectDeflateDecoder {
+
+ @Override
+ protected void doDecode() throws MessageDecodingException {
+ final MessageContext<SAMLObject> messageContext = new MessageContext<>();
+ final HttpServletRequest request = getHttpServletRequest();
+
+ if (!"GET".equalsIgnoreCase(request.getMethod())) {
+ throw new MessageDecodingException("This message decoder only supports the HTTP GET method");
+ }
+
+ final String samlEncoding = StringSupport.trimOrNull(request.getParameter("SAMLEncoding"));
+ if (samlEncoding != null && !SAMLConstants.SAML2_BINDING_URL_ENCODING_DEFLATE_URI.equals(samlEncoding)) {
+ throw new MessageDecodingException("Request indicated an unsupported SAMLEncoding: " + samlEncoding);
+
+ }
+
+ final String relayState = request.getParameter("RelayState");
+ log.debug("Decoded RelayState: {}", relayState);
+ SAMLBindingSupport.setRelayState(messageContext, relayState);
+
+ final InputStream samlMessageIns;
+
+ // implement parameter extraction as same as in
+ // SAML2HTTPRedirectDeflateSignatureSecurityHandler.java
+ final String queryString = getHttpServletRequest().getQueryString();
+ if (!Strings.isNullOrEmpty(URISupport.getRawQueryStringParameter(queryString, "SAMLRequest"))) {
+ samlMessageIns = decodeMessage(URISupport.getRawQueryStringParameter(queryString, "SAMLRequest"));
+ } else if (!Strings.isNullOrEmpty(URISupport.getRawQueryStringParameter(queryString, "SAMLResponse"))) {
+ samlMessageIns = decodeMessage(URISupport.getRawQueryStringParameter(queryString, "SAMLResponse"));
+ } else {
+ throw new MessageDecodingException(
+ "No SAMLRequest or SAMLResponse query path parameter, invalid SAML 2 HTTP Redirect message");
+ }
+
+ final SAMLObject samlMessage = (SAMLObject) unmarshallMessage(samlMessageIns);
+ messageContext.setMessage(samlMessage);
+ log.debug("Decoded SAML message");
+
+ populateBindingContext(messageContext);
+
+ setMessageContext(messageContext);
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafKeyStoreX509CredentialAdapter.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafKeyStoreX509CredentialAdapter.java
index 92d8f4b9..7c433c1c 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafKeyStoreX509CredentialAdapter.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/EaafKeyStoreX509CredentialAdapter.java
@@ -21,7 +21,19 @@ package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml;
import java.security.KeyStore;
-import org.opensaml.xml.security.x509.X509Credential;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import at.gv.egiz.eaaf.modules.pvp2.PvpConstants;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+
+import org.opensaml.security.x509.X509Credential;
+import org.opensaml.security.x509.impl.KeyStoreX509CredentialAdapter;
+
+import lombok.extern.slf4j.Slf4j;
/**
* OpenSAML2 KeyStore adapter.
@@ -29,8 +41,11 @@ import org.opensaml.xml.security.x509.X509Credential;
* @author tlenz
*
*/
-public class EaafKeyStoreX509CredentialAdapter
- extends org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter {
+@Slf4j
+public class EaafKeyStoreX509CredentialAdapter extends KeyStoreX509CredentialAdapter
+ implements EaafX509Credential {
+
+ private String signatureAlgorithmtToUse;
/**
* Get an OpenSAML2 keystore.
@@ -38,10 +53,31 @@ public class EaafKeyStoreX509CredentialAdapter
* @param store Java KeyStore
* @param alias Key alias
* @param password key Password
+ * @param keyStoreFriendlyName Friendlyname of this keystore for logging purposes
+ * @throws CredentialsNotAvailableException In case of an initialization exception
*/
- public EaafKeyStoreX509CredentialAdapter(final KeyStore store, final String alias,
- final char[] password) {
+ public EaafKeyStoreX509CredentialAdapter(@Nonnull final KeyStore store, @Nonnull final String alias,
+ @Nullable final char[] password, @Nonnull String keyStoreFriendlyName) throws CredentialsNotAvailableException {
super(store, alias, password);
+
+ if (getPrivateKey() == null && getSecretKey() == null) {
+ log.error("KeyStore: {} Key with alias: {} not found or contains no PrivateKey.",
+ keyStoreFriendlyName, alias);
+ throw new CredentialsNotAvailableException("internal.pvp.00",
+ new Object[] { keyStoreFriendlyName, alias});
+
+ }
+
+ try {
+ setSignatureAlgorithmForSigning(Saml2Utils.getSignatureAlgorithm(this,
+ PvpConstants.DEFAULT_SIGNING_METHODE_RSA,
+ PvpConstants.DEFAULT_SIGNING_METHODE_EC));
+
+ } catch (final SamlSigningException e) {
+ throw new CredentialsNotAvailableException("internal.pvp.01", new Object[] {keyStoreFriendlyName, alias}, e);
+
+ }
+
}
@Override
@@ -49,4 +85,16 @@ public class EaafKeyStoreX509CredentialAdapter
return X509Credential.class;
}
+ @Override
+ public String getSignatureAlgorithmForSigning() {
+ return this.signatureAlgorithmtToUse;
+
+ }
+
+ @Override
+ public void setSignatureAlgorithmForSigning(String sigAlg) {
+ this.signatureAlgorithmtToUse = sigAlg;
+
+ }
+
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HttpPostEncoderWithOwnTemplate.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HttpPostEncoderWithOwnTemplate.java
index 404b4e8e..3650e617 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HttpPostEncoderWithOwnTemplate.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/HttpPostEncoderWithOwnTemplate.java
@@ -19,6 +19,7 @@
package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -26,18 +27,21 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.VelocityEngine;
-import org.opensaml.common.binding.SAMLMessageContext;
-import org.opensaml.saml2.binding.encoding.HTTPPostEncoder;
-import org.opensaml.ws.message.encoder.MessageEncodingException;
-import org.opensaml.ws.transport.http.HTTPOutTransport;
-import org.opensaml.ws.transport.http.HTTPTransportUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import javax.servlet.http.HttpServletResponse;
import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiBuilderConfiguration;
import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiFormBuilder;
+import at.gv.egiz.eaaf.core.impl.gui.velocity.VelocityProvider;
+
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.encoder.MessageEncodingException;
+import org.opensaml.saml.common.SAMLObject;
+import org.opensaml.saml.saml2.binding.encoding.impl.HTTPPostEncoder;
+
+import lombok.extern.slf4j.Slf4j;
+import net.shibboleth.utilities.java.support.net.HttpServletSupport;
/**
* OpenSAML2 Post-Binding encoder that uses dynamic loaded templates.
@@ -45,10 +49,9 @@ import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiFormBuilder;
* @author tlenz
*
*/
+@Slf4j
public class HttpPostEncoderWithOwnTemplate extends HTTPPostEncoder {
- private static final Logger log = LoggerFactory.getLogger(HttpPostEncoderWithOwnTemplate.class);
- private final VelocityEngine velocityEngine;
private final IVelocityGuiBuilderConfiguration guiConfig;
private final IVelocityGuiFormBuilder guiBuilder;
@@ -57,29 +60,28 @@ public class HttpPostEncoderWithOwnTemplate extends HTTPPostEncoder {
*
* @param guiConfig GUI configuration
* @param guiBuilder GUI builder implementation
- * @param engine velocity engine
+ * @throws Exception In case of a {@link Velocity} initialization error
*/
public HttpPostEncoderWithOwnTemplate(final IVelocityGuiBuilderConfiguration guiConfig,
- final IVelocityGuiFormBuilder guiBuilder, final VelocityEngine engine) {
- super(engine, null);
- this.velocityEngine = engine;
+ final IVelocityGuiFormBuilder guiBuilder) throws Exception {
this.guiConfig = guiConfig;
this.guiBuilder = guiBuilder;
+ setVelocityEngine(VelocityProvider.getClassPathVelocityEngine());
+
}
/**
- * Base64 and POST encodes the outbound message and writes it to the outbound
+ * Base64 and POST encodes the out-bound message and writes it to the out-bound
* transport.
*
* @param messageContext current message context
- * @param endpointUrl endpoint URL to which to encode message
*
* @throws MessageEncodingException thrown if there is a problem encoding the
* message
*/
@Override
- protected void postEncode(final SAMLMessageContext messageContext, final String endpointUrl)
+ protected void postEncode(final MessageContext<SAMLObject> messageContext, final String endpointUrl)
throws MessageEncodingException {
log.debug("Invoking Velocity template to create POST body");
InputStream is = null;
@@ -91,19 +93,16 @@ public class HttpPostEncoderWithOwnTemplate extends HTTPPostEncoder {
// load template
is = guiBuilder.getTemplateInputStream(guiConfig);
- // populate velocity context with SAML2 parameters
populateVelocityContext(context, messageContext, endpointUrl);
- // populate transport parameter
- final HTTPOutTransport outTransport =
- (HTTPOutTransport) messageContext.getOutboundMessageTransport();
- HTTPTransportUtils.addNoCacheHeaders(outTransport);
- HTTPTransportUtils.setUTF8Encoding(outTransport);
- HTTPTransportUtils.setContentType(outTransport, "text/html");
+ final HttpServletResponse response = getHttpServletResponse();
- // evaluate template and write content to response
- final Writer out = new OutputStreamWriter(outTransport.getOutgoingStream(), "UTF-8");
- velocityEngine.evaluate(context, out, "SAML2_POST_BINDING",
+ HttpServletSupport.addNoCacheHeaders(response);
+ HttpServletSupport.setUTF8Encoding(response);
+ HttpServletSupport.setContentType(response, "text/html");
+
+ final Writer out = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
+ getVelocityEngine().evaluate(context, out, "SAML2_POST_BINDING",
new BufferedReader(new InputStreamReader(is, "UTF-8")));
out.flush();
@@ -123,4 +122,5 @@ public class HttpPostEncoderWithOwnTemplate extends HTTPPostEncoder {
}
}
+
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/StringRedirectDeflateEncoder.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/StringRedirectDeflateEncoder.java
index 8838daec..bd450518 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/StringRedirectDeflateEncoder.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/StringRedirectDeflateEncoder.java
@@ -19,15 +19,13 @@
package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml;
-import org.opensaml.common.binding.SAMLMessageContext;
-import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder;
-import org.opensaml.ws.message.MessageContext;
-import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.encoder.MessageEncodingException;
+import org.opensaml.saml.common.SAMLObject;
+import org.opensaml.saml.saml2.binding.encoding.impl.HTTPRedirectDeflateEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafDefaultSaml2Bootstrap;
-
/**
* Create deflate encoded SAML2 redirect-binding informations.
*
@@ -40,27 +38,18 @@ public class StringRedirectDeflateEncoder extends HTTPRedirectDeflateEncoder {
private String redirectUrl = null;
@Override
- public void encode(final MessageContext messageContext) throws MessageEncodingException {
- if (!(messageContext instanceof SAMLMessageContext)) {
- log.error("Invalid message context type, this encoder only support SAMLMessageContext");
- throw new MessageEncodingException(
- "Invalid message context type, this encoder only support SAMLMessageContext");
- }
-
- // load default PVP security configurations
- EaafDefaultSaml2Bootstrap.initializeDefaultPvpConfiguration();
-
- final SAMLMessageContext samlMsgCtx = (SAMLMessageContext) messageContext;
+ protected void doEncode() throws MessageEncodingException {
+ final MessageContext<SAMLObject> messageContext = getMessageContext();
+ final SAMLObject outboundMessage = messageContext.getMessage();
- final String endpointUrl = getEndpointURL(samlMsgCtx).buildURL();
+ final String endpointUrl = getEndpointURL(messageContext).toString();
- setResponseDestination(samlMsgCtx.getOutboundSAMLMessage(), endpointUrl);
+ removeSignature(outboundMessage);
- removeSignature(samlMsgCtx);
+ final String encodedMessage = deflateAndBase64Encode(outboundMessage);
- final String encodedMessage = deflateAndBase64Encode(samlMsgCtx.getOutboundSAMLMessage());
+ redirectUrl = buildRedirectURL(messageContext, endpointUrl, encodedMessage);
- redirectUrl = buildRedirectURL(samlMsgCtx, endpointUrl, encodedMessage);
}
/**
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSaml2Bootstrap.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSaml2Bootstrap.java
deleted file mode 100644
index 9625b591..00000000
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSaml2Bootstrap.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
- * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 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:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the Licence
- * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the Licence for the specific language governing permissions and limitations under
- * the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text file for details on the
- * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
- * works that you distribute must include a readable copy of the "NOTICE" text file.
-*/
-
-package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize;
-
-import org.opensaml.DefaultBootstrap;
-import org.opensaml.xml.ConfigurationException;
-
-import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
-import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributeBuilder;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributeMarshaller;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributeUnmarshaller;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributesBuilder;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributesMarshaller;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributesUnmarshaller;
-
-/**
- * EAAF specific OpenSAML Initializer.
- *
- * @author tlenz
- *
- */
-public class EaafDefaultSaml2Bootstrap extends DefaultBootstrap {
-
- /**
- * OpenSAML2 bootstrap.
- *
- * @throws ConfigurationException In case of an error
- */
- public static synchronized void bootstrap() throws ConfigurationException {
-
- initializeXMLSecurity();
-
- initializeXMLTooling();
-
- initializeArtifactBuilderFactories();
-
- initializeGlobalSecurityConfiguration();
-
- initializeParserPool();
-
- initializeESAPI();
-
- initializeExtenstions();
-
- }
-
- private static void initializeExtenstions() {
- org.opensaml.xml.Configuration.registerObjectProvider(
- EaafRequestedAttribute.DEFAULT_ELEMENT_NAME, new EaafRequestedAttributeBuilder(),
- new EaafRequestedAttributeMarshaller(), new EaafRequestedAttributeUnmarshaller());
-
- org.opensaml.xml.Configuration.registerObjectProvider(
- EaafRequestedAttributes.DEFAULT_ELEMENT_NAME, new EaafRequestedAttributesBuilder(),
- new EaafRequestedAttributesMarshaller(), new EaafRequestedAttributesUnmarshaller());
-
- }
-
- public static void initializeDefaultPvpConfiguration() {
- initializeGlobalSecurityConfiguration();
-
- }
-
- /**
- * Initializes the default global security configuration.
- */
- protected static void initializeGlobalSecurityConfiguration() {
- org.opensaml.xml.Configuration.setGlobalSecurityConfiguration(
- EaafDefaultSecurityConfigurationBootstrap.buildDefaultConfig());
- }
-}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSecurityConfigurationBootstrap.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSecurityConfigurationBootstrap.java
index f3e50e4e..97f0f225 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSecurityConfigurationBootstrap.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafDefaultSecurityConfigurationBootstrap.java
@@ -19,14 +19,17 @@
package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize;
-import org.opensaml.xml.encryption.EncryptionConstants;
-import org.opensaml.xml.security.BasicSecurityConfiguration;
-import org.opensaml.xml.security.DefaultSecurityConfigurationBootstrap;
-import org.opensaml.xml.security.credential.BasicKeyInfoGeneratorFactory;
-import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorManager;
-import org.opensaml.xml.security.keyinfo.NamedKeyInfoGeneratorManager;
-import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory;
-import org.opensaml.xml.signature.SignatureConstants;
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap;
+import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
+import org.opensaml.xmlsec.encryption.support.RSAOAEPParameters;
+import org.opensaml.xmlsec.impl.BasicDecryptionConfiguration;
+import org.opensaml.xmlsec.impl.BasicEncryptionConfiguration;
+import org.opensaml.xmlsec.impl.BasicSignatureSigningConfiguration;
+import org.opensaml.xmlsec.impl.BasicSignatureValidationConfiguration;
+import org.opensaml.xmlsec.signature.support.SignatureConstants;
/**
* EAAF specific OpenSAML2 security configuration.
@@ -38,102 +41,137 @@ public class EaafDefaultSecurityConfigurationBootstrap
extends DefaultSecurityConfigurationBootstrap {
/**
- * Build EAAF security configuration for OpenSAML2.
+ * Set EAAF specific encryption configuration to OpenSAML 3.x.
*
* @return
*/
- public static BasicSecurityConfiguration buildDefaultConfig() {
- final BasicSecurityConfiguration config = new BasicSecurityConfiguration();
-
- populateSignatureParams(config);
- populateEncryptionParams(config);
- populateKeyInfoCredentialResolverParams(config);
- populateKeyInfoGeneratorManager(config);
- populateKeyParams(config);
+ public static BasicEncryptionConfiguration buildEaafEncryptionConfiguration() {
+ final BasicEncryptionConfiguration config = new BasicEncryptionConfiguration();
+
+ config.setBlacklistedAlgorithms(Arrays.asList(
+ EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15,
+ EncryptionConstants.ALGO_ID_BLOCKCIPHER_TRIPLEDES,
+ EncryptionConstants.ALGO_ID_KEYWRAP_TRIPLEDES));
+
+ config.setDataEncryptionAlgorithms(Arrays.asList(
+ // The order of these is significant.
+ EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128,
+ EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192,
+ EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256,
+
+ // register GCM algorithms
+ EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM,
+ EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192_GCM,
+ EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM));
+
+ config.setKeyTransportEncryptionAlgorithms(Arrays.asList(
+ // The order of the RSA algos is significant.
+ EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP,
+ EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP11,
+
+ // The order of these is not significant.
+ // These aren't really "preferences" per se. They just need to be registered
+ // so that they can be used if a credential with a key of that type and size is
+ // seen.
+ EncryptionConstants.ALGO_ID_KEYWRAP_AES128,
+ EncryptionConstants.ALGO_ID_KEYWRAP_AES192,
+ EncryptionConstants.ALGO_ID_KEYWRAP_AES256));
+
+ config.setRSAOAEPParameters(new RSAOAEPParameters(
+ SignatureConstants.ALGO_ID_DIGEST_SHA1,
+ EncryptionConstants.ALGO_ID_MGF1_SHA1,
+ null));
+
+ config.setDataKeyInfoGeneratorManager(buildDataEncryptionKeyInfoGeneratorManager());
+ config.setKeyTransportKeyInfoGeneratorManager(buildKeyTransportEncryptionKeyInfoGeneratorManager());
return config;
}
- protected static void populateKeyInfoGeneratorManager(final BasicSecurityConfiguration config) {
- final NamedKeyInfoGeneratorManager namedManager = new NamedKeyInfoGeneratorManager();
- config.setKeyInfoGeneratorManager(namedManager);
-
- namedManager.setUseDefaultManager(true);
- final KeyInfoGeneratorManager defaultManager = namedManager.getDefaultManager();
+ /**
+ * Set EAAF specific decryption configuration to OpenSAML 3.x.
+ *
+ * @return
+ */
+ public static BasicDecryptionConfiguration buildEaaftDecryptionConfiguration() {
+ final BasicDecryptionConfiguration config = new BasicDecryptionConfiguration();
- final BasicKeyInfoGeneratorFactory basicFactory = new BasicKeyInfoGeneratorFactory();
- basicFactory.setEmitPublicKeyValue(true);
+ config.setBlacklistedAlgorithms(Collections.singletonList(
+ EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15));
- final X509KeyInfoGeneratorFactory x509Factory = new X509KeyInfoGeneratorFactory();
- x509Factory.setEmitEntityCertificate(true);
+ config.setEncryptedKeyResolver(buildBasicEncryptedKeyResolver());
- defaultManager.registerFactory(basicFactory);
- defaultManager.registerFactory(x509Factory);
+ return config;
}
- protected static void populateSignatureParams(final BasicSecurityConfiguration config) {
-
- // use SHA256 instead of SHA1
- config.registerSignatureAlgorithmURI("RSA", SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
-
- config.registerSignatureAlgorithmURI("DSA", "http://www.w3.org/2000/09/xmldsig#dsa-sha1");
-
- // use SHA256 instead of SHA1
- config.registerSignatureAlgorithmURI("EC", SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256);
-
- // use SHA256 instead of SHA1
- config.registerSignatureAlgorithmURI("AES", SignatureConstants.ALGO_ID_MAC_HMAC_SHA256);
-
- config.registerSignatureAlgorithmURI("DESede", SignatureConstants.ALGO_ID_MAC_HMAC_SHA256);
-
- config.setSignatureCanonicalizationAlgorithm("http://www.w3.org/2001/10/xml-exc-c14n#");
- config.setSignatureHMACOutputLength(null);
+ /**
+ * Set EAAF specific signature-creation configuration to OpenSAML 3.x.
+ *
+ * @return
+ */
+ public static BasicSignatureSigningConfiguration buildEaafSignatureSigningConfiguration() {
+ final BasicSignatureSigningConfiguration config = new BasicSignatureSigningConfiguration();
+
+ config.setBlacklistedAlgorithms(Arrays.asList(
+ SignatureConstants.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5,
+ SignatureConstants.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5,
+ SignatureConstants.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5,
+ SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1,
+ SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA1,
+ SignatureConstants.ALGO_ID_SIGNATURE_DSA_SHA1,
+ SignatureConstants.ALGO_ID_DIGEST_SHA1));
+
+ config.setSignatureAlgorithms(Arrays.asList(
+ // The order within each key group is significant.
+ // The order of the key groups themselves is not significant.
+
+ // RSA
+ SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256,
+ SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA384,
+ SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512,
+
+ // ECDSA
+ SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256,
+ SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA384,
+ SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA512
+
+ // HMAC (all symmetric keys)
+ // SignatureConstants.ALGO_ID_MAC_HMAC_SHA256,
+ // SignatureConstants.ALGO_ID_MAC_HMAC_SHA384,
+ // SignatureConstants.ALGO_ID_MAC_HMAC_SHA512,
+ // SignatureConstants.ALGO_ID_MAC_HMAC_SHA1
+ ));
+
+ config.setSignatureReferenceDigestMethods(Arrays.asList(
+ // The order of these is significant.
+ SignatureConstants.ALGO_ID_DIGEST_SHA256,
+ SignatureConstants.ALGO_ID_DIGEST_SHA384,
+ SignatureConstants.ALGO_ID_DIGEST_SHA512));
+
+ config.setSignatureCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+
+ config.setKeyInfoGeneratorManager(buildSignatureKeyInfoGeneratorManager());
- // use SHA256 instead of SHA1
- config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);
+ return config;
}
- protected static void populateEncryptionParams(final BasicSecurityConfiguration config) {
- config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(128),
- "http://www.w3.org/2001/04/xmlenc#aes128-cbc");
- config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(192),
- "http://www.w3.org/2001/04/xmlenc#aes192-cbc");
- config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(256),
- "http://www.w3.org/2001/04/xmlenc#aes256-cbc");
-
- // support GCM mode
- config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(128),
- EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM);
-
- config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(192),
- EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192_GCM);
-
- config.registerDataEncryptionAlgorithmURI("AES", Integer.valueOf(256),
- EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM);
-
- config.registerDataEncryptionAlgorithmURI("DESede", Integer.valueOf(168),
- "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
- config.registerDataEncryptionAlgorithmURI("DESede", Integer.valueOf(192),
- "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
-
- config.registerKeyTransportEncryptionAlgorithmURI("RSA", null, "AES",
- "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
-
- config.registerKeyTransportEncryptionAlgorithmURI("RSA", null, "DESede",
- "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
-
- config.registerKeyTransportEncryptionAlgorithmURI("AES", Integer.valueOf(128), null,
- "http://www.w3.org/2001/04/xmlenc#kw-aes128");
- config.registerKeyTransportEncryptionAlgorithmURI("AES", Integer.valueOf(192), null,
- "http://www.w3.org/2001/04/xmlenc#kw-aes192");
- config.registerKeyTransportEncryptionAlgorithmURI("AES", Integer.valueOf(256), null,
- "http://www.w3.org/2001/04/xmlenc#kw-aes256");
- config.registerKeyTransportEncryptionAlgorithmURI("DESede", Integer.valueOf(168), null,
- "http://www.w3.org/2001/04/xmlenc#kw-tripledes");
- config.registerKeyTransportEncryptionAlgorithmURI("DESede", Integer.valueOf(192), null,
- "http://www.w3.org/2001/04/xmlenc#kw-tripledes");
-
- config.setAutoGeneratedDataEncryptionKeyAlgorithmURI(
- "http://www.w3.org/2001/04/xmlenc#aes128-cbc");
+ /**
+ * Set EAAF specific signature-verification configuration to OpenSAML 3.x.
+ *
+ * @return
+ */
+ public static BasicSignatureValidationConfiguration buildEaafSignatureValidationConfiguration() {
+ final BasicSignatureValidationConfiguration config = new BasicSignatureValidationConfiguration();
+
+ config.setBlacklistedAlgorithms(Arrays.asList(
+ SignatureConstants.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5,
+ SignatureConstants.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5,
+ SignatureConstants.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5,
+ SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1,
+ SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA1,
+ SignatureConstants.ALGO_ID_SIGNATURE_DSA_SHA1,
+ SignatureConstants.ALGO_ID_DIGEST_SHA1));
+
+ return config;
}
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafOpenSaml3xInitializer.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafOpenSaml3xInitializer.java
new file mode 100644
index 00000000..42d4d736
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/opensaml/initialize/EaafOpenSaml3xInitializer.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 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:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.xml.XMLConstants;
+
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributeBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributeMarshaller;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributeUnmarshaller;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributesBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributesMarshaller;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestedAttributesUnmarshaller;
+
+import org.opensaml.core.config.ConfigurationService;
+import org.opensaml.core.config.InitializationException;
+import org.opensaml.core.config.InitializationService;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.xmlsec.DecryptionConfiguration;
+import org.opensaml.xmlsec.EncryptionConfiguration;
+import org.opensaml.xmlsec.SignatureSigningConfiguration;
+import org.opensaml.xmlsec.SignatureValidationConfiguration;
+
+import lombok.extern.slf4j.Slf4j;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.xml.BasicParserPool;
+import net.shibboleth.utilities.java.support.xml.ParserPool;
+
+/**
+ * EAAF specific OpenSAML Initializer.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class EaafOpenSaml3xInitializer extends InitializationService {
+
+ /**
+ * EAAF specific OpenSAML3.x initialization.
+ *
+ * @throws InitializationException In case of an error
+ * @throws ComponentInitializationException
+ */
+ public static synchronized void eaafInitialize() throws InitializationException, ComponentInitializationException {
+ log.debug("Initializing OpenSAML 3.x ... ");
+ initialize();
+
+ log.debug("Injecting EAAF-specific configuration into OpenSAML 3.x ... ");
+ injectEaafSecurityProperty();
+ injectEaafExtenstions();
+
+ XMLObjectProviderRegistrySupport.setParserPool(eaafSecuredBasicParserPool());
+
+ log.info("OpenSAML3.x with EAAF extensions initialized");
+
+ }
+
+ private static void injectEaafSecurityProperty() {
+ ConfigurationService.register(EncryptionConfiguration.class,
+ EaafDefaultSecurityConfigurationBootstrap.buildEaafEncryptionConfiguration());
+
+ ConfigurationService.register(DecryptionConfiguration.class,
+ EaafDefaultSecurityConfigurationBootstrap.buildEaaftDecryptionConfiguration());
+
+ ConfigurationService.register(SignatureSigningConfiguration.class,
+ EaafDefaultSecurityConfigurationBootstrap.buildEaafSignatureSigningConfiguration());
+
+ ConfigurationService.register(SignatureValidationConfiguration.class,
+ EaafDefaultSecurityConfigurationBootstrap.buildEaafSignatureValidationConfiguration());
+
+ }
+
+ private static void injectEaafExtenstions() {
+ XMLObjectProviderRegistrySupport.registerObjectProvider(
+ EaafRequestedAttribute.DEFAULT_ELEMENT_NAME, new EaafRequestedAttributeBuilder(),
+ new EaafRequestedAttributeMarshaller(), new EaafRequestedAttributeUnmarshaller());
+
+ XMLObjectProviderRegistrySupport.registerObjectProvider(
+ EaafRequestedAttributes.DEFAULT_ELEMENT_NAME, new EaafRequestedAttributesBuilder(),
+ new EaafRequestedAttributesMarshaller(), new EaafRequestedAttributesUnmarshaller());
+
+ }
+
+ /**
+ * Build a secured OpenSAML 3.x XML parser-pool.
+ *
+ * @return {@link ParserPool}
+ * @throws ComponentInitializationException In case of an initialization error
+ */
+ @Nonnull
+ private static ParserPool eaafSecuredBasicParserPool() throws ComponentInitializationException {
+ // Get parser pool manager
+ final BasicParserPool ppMgr = new BasicParserPool();
+ // Note: this is necessary due to an unresolved Xerces deferred DOM issue/bug
+ ppMgr.setBuilderFeatures(getSecureDocumentBuilderFeatures());
+ ppMgr.setNamespaceAware(true);
+ ppMgr.setIgnoreComments(true);
+ ppMgr.setExpandEntityReferences(false);
+ ppMgr.setXincludeAware(false);
+ ppMgr.initialize();
+ return ppMgr;
+ }
+
+ @Nonnull
+ private static Map<String, Boolean> getSecureDocumentBuilderFeatures() {
+ final Map<String, Boolean> features = new HashMap<>();
+ features.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
+
+ // Ignore the external DTD completely
+ // Note: this is for Xerces only:
+ features.put("http://apache.org/xml/features/nonvalidating/load-external-dtd", Boolean.FALSE);
+ // This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all
+ // XML entity attacks are prevented
+ // Xerces 2 only -
+ // http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl
+ features.put("http://apache.org/xml/features/disallow-doctype-decl", Boolean.TRUE);
+
+ // If you can't completely disable DTDs, then at least do the following:
+ // Xerces 1 -
+ // http://xerces.apache.org/xerces-j/features.html#external-general-entities
+ // Xerces 2 -
+ // http://xerces.apache.org/xerces2-j/features.html#external-general-entities
+ features.put("http://xml.org/sax/features/external-general-entities", Boolean.FALSE);
+
+ // Xerces 1 -
+ // http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
+ // Xerces 2 -
+ // http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
+ features.put("http://xml.org/sax/features/external-parameter-entities", Boolean.FALSE);
+
+ return features;
+ }
+
+}