encryptionPartSelectors = securityProperties.getEncryptionPartSelectors();
+ outputProcessorChain.getSecurityContext().put(
+ XMLSecurityConstants.ENCRYPTION_PART_SELECTORS,
+ encryptionPartSelectors
+ );
}
}
if (output instanceof OutputStream) {
@@ -177,11 +140,7 @@ private XMLStreamWriter processOutMessage(
throw new IllegalArgumentException(output + " is not supported as output");
}
- XMLSecurityStreamWriter streamWriter = new XMLSecurityStreamWriter(outputProcessorChain);
- streamWriter.setSignEntireRequestPart(signEntireRequestPart);
- streamWriter.setEncryptEntireRequestPart(encryptEntireRequestPart);
-
- return streamWriter;
+ return new XMLSecurityStreamWriter(outputProcessorChain);
}
private void initializeOutputProcessor(OutputProcessorChainImpl outputProcessorChain, OutputProcessor outputProcessor, XMLSecurityConstants.Action action) throws XMLSecurityException {
diff --git a/src/main/java/org/apache/xml/security/stax/ext/RootElementSelector.java b/src/main/java/org/apache/xml/security/stax/ext/RootElementSelector.java
new file mode 100644
index 0000000000..18e8bbd328
--- /dev/null
+++ b/src/main/java/org/apache/xml/security/stax/ext/RootElementSelector.java
@@ -0,0 +1,33 @@
+package org.apache.xml.security.stax.ext;
+
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+
+/**
+ * Selects the root element as the element to secure.
+ * This replaces {@link SecurePart#setSecureEntireRequest(boolean)}.
+ */
+public class RootElementSelector implements ElementSelector {
+
+ private static final class LazilyLoaded {
+
+ @SuppressWarnings("PMD.AccessorClassGeneration")
+ private static final RootElementSelector INSTANCE = new RootElementSelector();
+ }
+
+ private RootElementSelector() {
+ }
+
+ @Override
+ public boolean select(XMLSecStartElement element) {
+ return element != null && element.getParentXMLSecStartElement() == null;
+ }
+
+ @Override
+ public String toString() {
+ return "/*";
+ }
+
+ public static RootElementSelector getInstance() {
+ return LazilyLoaded.INSTANCE;
+ }
+}
diff --git a/src/main/java/org/apache/xml/security/stax/ext/SecurePart.java b/src/main/java/org/apache/xml/security/stax/ext/SecurePart.java
index 42586b3276..6542c7c641 100644
--- a/src/main/java/org/apache/xml/security/stax/ext/SecurePart.java
+++ b/src/main/java/org/apache/xml/security/stax/ext/SecurePart.java
@@ -18,14 +18,18 @@
*/
package org.apache.xml.security.stax.ext;
+import org.apache.xml.security.stax.ext.XMLSecurityProperties.SecurePartSelectorBuilder;
+
import javax.xml.namespace.QName;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
/**
- * Class to describe which and how an element must be secured
- *
+ * Class to describe which and how an element must be secured.
+ * The "which" is deprecated in favor of a dedicated and more flexible {@link ElementSelector}, and is only supported
+ * for backward compatibility.
+ * The "how" is the sole and dedicated purpose of this class.
*/
public class SecurePart {
@@ -108,7 +112,10 @@ public SecurePart(String externalReference, String[] transforms, String digestMe
}
/**
- * The name of the element to be secured
+ * The name of the element to be secured.
+ * The framework now uses {@link ElementSelector#select(javax.xml.stream.events.StartElement)}
+ * instead to define which element(s) to secure.
+ * This method is only supported for backward compatibility.
*
* @return The Element-Local-Name
*/
@@ -116,6 +123,11 @@ public QName getName() {
return name;
}
+ /**
+ * Sets which element to secure based on a given qualified name.
+ * Consider {@link XPathElementSelector} with an expression such as "//local-name" instead, or a more complex expression
+ * such as "//*[namespace-uri() = 'urn:ns0' and local-name() = 'element']" when you need to match namespaces.
+ */
public void setName(QName name) {
this.name = name;
}
@@ -132,6 +144,8 @@ public void setModifier(Modifier modifier) {
* The ID of the element to secure (encrypt or sign), possibly {@code null}.
* This matches the attribute value of an element that has an attribute with a name given by
* {@link XMLSecurityProperties#getIdAttributeNS()}.
+ * The framework now uses {@link ElementSelector#select(org.apache.xml.security.stax.ext.stax.XMLSecStartElement)}
+ * instead to define which element(s) to secure.
*
* @return The ID of the element to secure, possibly {@code null}.
*/
@@ -139,6 +153,10 @@ public String getIdToSecure() {
return idToSecure;
}
+ /**
+ * Sets which element to secure based on a given attribute value.
+ * Consider using {@link ByAttributeElementSelector} instead.
+ */
public void setIdToSecure(String idToSecure) {
this.idToSecure = idToSecure;
}
@@ -153,7 +171,6 @@ public String getIdToSign() {
/**
* Use {@link #setIdToSecure(String)} instead.
- * @param idToSign
*/
@Deprecated
public void setIdToSign(String idToSign) {
@@ -192,19 +209,51 @@ public void setDigestMethod(String digestMethod) {
this.digestMethod = digestMethod;
}
+ /**
+ * If this secure part is required or not.
+ * The framework now uses {@link SecurePartSelector#getRequiredNumOccurrences()} instead.
+ * This method is only supported for backward compatibility.
+ */
public boolean isRequired() {
return required;
}
+ /**
+ * Sets if this element is required, which is {@code true} by default.
+ * Consider using {@link SecurePartSelectorBuilder#requireNumOccurrences(int)} instead, with a value of {@code 1} (required) or
+ * {@code -1} (not required).
+ */
public void setRequired(boolean required) {
this.required = required;
}
+ /**
+ * If the entire request is to be secured.
+ * The framework now uses {@link ElementSelector#select(org.apache.xml.security.stax.ext.stax.XMLSecStartElement)}
+ * instead to define which element(s) to secure.
+ */
public boolean isSecureEntireRequest() {
return secureEntireRequest;
}
+ /**
+ * Sets if the entire request is to be secured.
+ * Setting this to {@code true} is equivalent to selecting the root element.
+ * Consider using {@link RootElementSelector} instead.
+ */
public void setSecureEntireRequest(boolean secureEntireRequest) {
this.secureEntireRequest = secureEntireRequest;
}
+
+ @Override
+ public String toString() {
+ if (idToSecure != null) {
+ return idToSecure;
+ } else if (name != null) {
+ return name.toString();
+ } else if (externalReference != null) {
+ return externalReference;
+ }
+ return super.toString();
+ }
}
diff --git a/src/main/java/org/apache/xml/security/stax/ext/SecurePartFactory.java b/src/main/java/org/apache/xml/security/stax/ext/SecurePartFactory.java
new file mode 100644
index 0000000000..4414d72a5c
--- /dev/null
+++ b/src/main/java/org/apache/xml/security/stax/ext/SecurePartFactory.java
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.stax.ext;
+
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * This interface allows implementations to create a secure for a selected element.
+ * An example of a typical implementation:
+ *
+ * {@code
+ * SecurePartFactory securePartFactory = (name, element) -> new SecurePart(name, SecurePart.Modifier.Content);
+ * }
+ *
+ *
+ * @see ElementSelector
+ */
+public interface SecurePartFactory {
+
+ /**
+ * Creates a secure part given a selected element.
+ * The framework calls this method whenever {@link ElementSelector#select(QName, Element)} returns {@code true}.
+ * The selected element is defined by a qualified name and a skeleton DOM element, which have the same values as
+ * what passes {@link ElementSelector#select(QName, Element)}.
+ * If a selector for example never selects any elements with {@code null} name or {@code null} skeleton DOM element,
+ * then the corresponding factory will never be called with such values either.
+ * Implementations should return a secure part containing instructions how to secure the element.
+ *
+ * Implementations may return {@code null} to deselect the element after all, overriding the element selector's
+ * decision.
+ *
+ *
+ * @param name The qualified name, possibly {@code null}.
+ * @param element The skeleton DOM element, possibly {@code null}.
+ * @return A secure part, or {@code null} to skip this element after all.
+ * @see ElementSelector#select(QName, Element)
+ */
+ SecurePart createSecurePart(XMLSecStartElement element);
+}
diff --git a/src/main/java/org/apache/xml/security/stax/ext/SecurePartSelector.java b/src/main/java/org/apache/xml/security/stax/ext/SecurePartSelector.java
new file mode 100644
index 0000000000..fcaba058b6
--- /dev/null
+++ b/src/main/java/org/apache/xml/security/stax/ext/SecurePartSelector.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.stax.ext;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * This class is used by the framework to group an element selector, a secure part factory and a required number of
+ * occurrences.
+ * It is not intended to be used by callers of the framework, hence the package-private constructor.
+ */
+public class SecurePartSelector {
+
+ private final Supplier> actionsSupplier;
+ private final ElementSelector elementSelector;
+ private final SecurePartFactory securePartFactory;
+ private final int requiredNumOccurrences;
+
+ SecurePartSelector(Supplier> actionsSupplier, ElementSelector elementSelector, SecurePartFactory securePartFactory, int requiredNumOccurrences) {
+ requireNonNull(actionsSupplier, "actions supplier is null");
+ requireNonNull(elementSelector, "element selector is null");
+ requireNonNull(securePartFactory, "secure part factory is null");
+ this.actionsSupplier = actionsSupplier;
+ this.elementSelector = elementSelector;
+ this.securePartFactory = securePartFactory;
+ this.requiredNumOccurrences = requiredNumOccurrences;
+ }
+
+ public List getActions() {
+ List actions = actionsSupplier.get();
+ requireNonNull(actions, "actions is null");
+ return actions;
+ }
+
+ public int getRequiredNumOccurrences() {
+ return requiredNumOccurrences;
+ }
+
+ public SecurePart select(XMLSecStartElement element) {
+ if (elementSelector.select(element)) {
+ return securePartFactory.createSecurePart(element);
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return elementSelector.toString();
+ }
+}
diff --git a/src/main/java/org/apache/xml/security/stax/ext/SecurityContext.java b/src/main/java/org/apache/xml/security/stax/ext/SecurityContext.java
index 1d303bb311..5bc2329c08 100644
--- a/src/main/java/org/apache/xml/security/stax/ext/SecurityContext.java
+++ b/src/main/java/org/apache/xml/security/stax/ext/SecurityContext.java
@@ -21,11 +21,13 @@
import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
import java.util.List;
-import java.util.Map;
/**
*/
public interface SecurityContext extends SecurityEventListener {
+
+ XMLSecurityProperties getSecurityProperties();
+
void put(String key, T value);
T get(String key);
@@ -34,14 +36,6 @@ public interface SecurityContext extends SecurityEventListener {
void putList(Object key, T value);
- void putAsList(Object key, T value);
-
- List getAsList(Object key);
-
- void putAsMap(Object key, T mapKey, U mapValue);
-
- Map getAsMap(Object key);
-
/**
* Registers a SecurityEventListener to receive Security-Events
*
diff --git a/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java b/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java
index 8980057d31..c8a219eacb 100644
--- a/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java
+++ b/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java
@@ -23,6 +23,7 @@
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.RSAPrivateKey;
import java.util.HashSet;
+import java.util.List;
import javax.crypto.SecretKey;
import javax.xml.bind.JAXBContext;
@@ -137,7 +138,8 @@ public static XMLSecurityProperties validateAndApplyDefaultsToOutboundSecurityPr
throw new XMLSecurityConfigurationException("stax.idsetbutnotgenerated");
}
- if (securityProperties.getSignatureSecureParts() != null && securityProperties.getSignatureSecureParts().size() > 1 && !securityProperties.isSignatureGenerateIds()) {
+ List signaturePartSelectors = securityProperties.getSignaturePartSelectors();
+ if (signaturePartSelectors != null && signaturePartSelectors.size() > 1 && !securityProperties.isSignatureGenerateIds()) {
throw new XMLSecurityConfigurationException("stax.idgenerationdisablewithmultipleparts");
}
diff --git a/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityConstants.java b/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityConstants.java
index 75485a1d53..c98f9e9e5d 100644
--- a/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityConstants.java
+++ b/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityConstants.java
@@ -257,8 +257,8 @@ public enum DIRECTION {
public static final String PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION = "PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION";
public static final String PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTED_KEY = "PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTED_KEY";
- public static final String SIGNATURE_PARTS = "signatureParts";
- public static final String ENCRYPTION_PARTS = "encryptionParts";
+ public static final String SIGNATURE_PART_SELECTORS = "signaturePartSelectors";
+ public static final String ENCRYPTION_PART_SELECTORS = "encryptionPartSelectors";
public static final Action SIGNATURE = new Action("Signature");
public static final Action ENCRYPTION = new Action("Encryption");
diff --git a/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java b/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java
index 8ee89f448d..9cf2ac995f 100644
--- a/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java
+++ b/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java
@@ -18,15 +18,23 @@
*/
package org.apache.xml.security.stax.ext;
-import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;
-
import java.security.Key;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
import javax.xml.namespace.QName;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;
+
+import static java.util.Objects.requireNonNull;
/**
* Main configuration class to supply keys etc.
@@ -47,7 +55,7 @@ public class XMLSecurityProperties {
private String encryptionKeyTransportDigestAlgorithm;
private String encryptionKeyTransportMGFAlgorithm;
private byte[] encryptionKeyTransportOAEPParams;
- private final List encryptionParts = new LinkedList<>();
+ private final List securePartSelectors = new ArrayList<>();
private Key encryptionKey;
private Key encryptionTransportKey;
private SecurityTokenConstants.KeyIdentifier encryptionKeyIdentifier;
@@ -55,7 +63,6 @@ public class XMLSecurityProperties {
private Key decryptionKey;
- private final List signatureParts = new LinkedList<>();
private String signatureAlgorithm;
private String signatureDigestAlgorithm;
private String signatureCanonicalizationAlgorithm;
@@ -95,12 +102,11 @@ protected XMLSecurityProperties(XMLSecurityProperties xmlSecurityProperties) {
this.encryptionKeyTransportDigestAlgorithm = xmlSecurityProperties.encryptionKeyTransportDigestAlgorithm;
this.encryptionKeyTransportMGFAlgorithm = xmlSecurityProperties.encryptionKeyTransportMGFAlgorithm;
this.encryptionKeyTransportOAEPParams = xmlSecurityProperties.encryptionKeyTransportOAEPParams;
- this.encryptionParts.addAll(xmlSecurityProperties.encryptionParts);
+ this.securePartSelectors.addAll(xmlSecurityProperties.securePartSelectors);
this.encryptionKey = xmlSecurityProperties.encryptionKey;
this.encryptionTransportKey = xmlSecurityProperties.encryptionTransportKey;
this.encryptionKeyIdentifier = xmlSecurityProperties.encryptionKeyIdentifier;
this.decryptionKey = xmlSecurityProperties.decryptionKey;
- this.signatureParts.addAll(xmlSecurityProperties.signatureParts);
this.signatureAlgorithm = xmlSecurityProperties.signatureAlgorithm;
this.signatureDigestAlgorithm = xmlSecurityProperties.signatureDigestAlgorithm;
this.signatureCanonicalizationAlgorithm = xmlSecurityProperties.signatureCanonicalizationAlgorithm;
@@ -250,12 +256,20 @@ public Key getEncryptionKey() {
}
/**
- * Adds a part which must be encrypted by the framework
+ * Adds a part which must be encrypted by the framework.
+ * Consider using {@link #addSecurePartSelector()} instead.
*
* @param securePart
*/
+ @SuppressWarnings("PMD.AccessorClassGeneration")
public void addEncryptionPart(SecurePart securePart) {
- encryptionParts.add(securePart);
+ SecurePartElementSelector securePartElementSelector = new SecurePartElementSelector(securePart);
+ addSecurePartSelector()
+ .forAction(XMLSecurityConstants.ENCRYPTION)
+ .selectElement(securePartElementSelector)
+ .securePartWith(securePartElementSelector)
+ .requireNumOccurrences(securePart.isRequired() ? 1 : -1)
+ .build();
}
/**
@@ -263,8 +277,62 @@ public void addEncryptionPart(SecurePart securePart) {
*
* @return A List of SecurePart's
*/
- public List getEncryptionSecureParts() {
- return encryptionParts;
+ public List getEncryptionPartSelectors() {
+ return getSecurePartSelectorsFor(XMLSecurityConstants.ENCRYPTION);
+ }
+
+ private List getSecurePartSelectorsFor(XMLSecurityConstants.Action action) {
+ return securePartSelectors
+ .stream()
+ .filter(securePartSelector -> securePartSelector.getActions().contains(action))
+ .collect(Collectors.toList());
+ }
+
+ private class SecurePartElementSelector implements ElementSelector, SecurePartFactory {
+
+ private final SecurePart securePart;
+ private final ElementSelector elementSelector;
+ private boolean selected;
+
+ private SecurePartElementSelector(SecurePart securePart) {
+ requireNonNull(securePart, "secure part is null");
+ this.securePart = securePart;
+ ElementSelector elementSelector;
+ if (securePart.getExternalReference() != null) {
+ elementSelector = DocumentElementSelector.getInstance();
+ } else if (securePart.getIdToSecure() != null) {
+ elementSelector = new ByAttributeElementSelector(() -> getIdAttributeNS(), securePart.getIdToSecure());
+ } else if (securePart.getName() != null) {
+ elementSelector = new ByNameElementSelector(securePart.getName());
+ } else if (securePart.isSecureEntireRequest()) {
+ elementSelector = element -> {
+ boolean selected = RootElementSelector.getInstance().select(element);
+ if (selected) {
+ // Preserve legacy behavior for backward compatibility.
+ securePart.setName(element.getName());
+ }
+ return selected;
+ };
+ } else {
+ elementSelector = NoElementSelector.getInstance();
+ }
+ this.elementSelector = elementSelector;
+ }
+
+ @Override
+ public boolean select(XMLSecStartElement element) {
+ return selected = elementSelector.select(element);
+ }
+
+ @Override
+ public SecurePart createSecurePart(XMLSecStartElement element) {
+ return selected ? securePart : null;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(securePart);
+ }
}
/**
@@ -344,12 +412,25 @@ public void setSignatureCerts(X509Certificate[] signatureCerts) {
this.signatureCerts = signatureCerts;
}
+ /**
+ * Adds a part to be signed by the framework.
+ * Consider using {@link #addSecurePartSelector()} instead.
+ *
+ * @see #addSecurePartSelector()
+ */
+ @SuppressWarnings("PMD.AccessorClassGeneration")
public void addSignaturePart(SecurePart securePart) {
- signatureParts.add(securePart);
+ SecurePartElementSelector securePartElementSelector = new SecurePartElementSelector(securePart);
+ addSecurePartSelector()
+ .forAction(XMLSecurityConstants.SIGNATURE)
+ .selectElement(securePartElementSelector)
+ .securePartWith(securePartElementSelector)
+ .requireNumOccurrences(securePart.isRequired() ? 1 : -1)
+ .build();
}
- public List getSignatureSecureParts() {
- return signatureParts;
+ public List getSignaturePartSelectors() {
+ return getSecurePartSelectorsFor(XMLSecurityConstants.SIGNATURE);
}
public String getSignatureAlgorithm() {
@@ -539,4 +620,170 @@ public AlgorithmParameterSpec getAlgorithmParameterSpec() {
public void setAlgorithmParameterSpec(AlgorithmParameterSpec algorithmParameterSpec) {
this.algorithmParameterSpec = algorithmParameterSpec;
}
+
+ /**
+ * Adds a part to be secured by the framework using an element selector, secure part factory and required number
+ * of occurrences defined on the builder.
+ * The element selector defines which elements to encrypt.
+ * The secure part factory defines how to sign the elements.
+ * The required number of occurrences defines how many elements must be signed, and is verified after having
+ * processed the entire document.
+ * Processing will fail when the number of occurrences mismatches the required number.
+ * Use {@code -1} to disable verification.
+ * Use {@code 0} to verify that a secure part never occurs.
+ *
+ * @see SecurePartSelectorBuilder#selectElement(ElementSelector)
+ * @see SecurePartSelectorBuilder#securePartWith(SecurePartFactory)
+ * @see SecurePartSelectorBuilder#requireNumOccurrences(int)
+ */
+ @SuppressWarnings("PMD.AccessorClassGeneration")
+ public SecurePartSelectorBuilder addSecurePartSelector() {
+ return new SecurePartSelectorBuilder();
+ }
+
+ /**
+ * A builder for secure part selectors which will be added to the security properties upon {@link #build()}.
+ * Use {@link #addSecurePartSelector()} to start building a signature part selector.
+ * @see #addSecurePartSelector()
+ */
+ public class SecurePartSelectorBuilder {
+
+ private List actions;
+ private ElementSelector elementSelector;
+ private SecurePartFactory securePartFactory;
+ private int requiredNumOccurrences = -1;
+
+ private SecurePartSelectorBuilder() {
+ }
+
+ /**
+ * Sets the actions to build a secure part selector for.
+ * The default is {@code null}, which means that the secure part selector will apply to all the actions
+ * defined on the security properties itself.
+ *
+ * @param actions The actions to build a secure part selector for, which may be {@code null}.
+ * @return This builder.
+ */
+ public SecurePartSelectorBuilder forActions(List actions) {
+ this.actions = actions;
+ return this;
+ }
+
+ /**
+ * Adds an action to build a secure part selector for.
+ *
+ * @param action The action to build a secure part selector for, which must not be {@code null}.
+ * @return This builder.
+ */
+ public SecurePartSelectorBuilder forAction(XMLSecurityConstants.Action action) {
+ requireNonNull(action, "action is null");
+ if (this.actions == null) {
+ this.actions = new ArrayList<>(2);
+ }
+ this.actions.add(action);
+ return this;
+ }
+
+ /**
+ * Selects the elements to secure based on the given element selector.
+ *
+ * @param elementSelector An element selector, which must not be {@code null}.
+ * @return This builder.
+ */
+ public SecurePartSelectorBuilder selectElement(ElementSelector elementSelector) {
+ requireNonNull(elementSelector, "element selector is null");
+ this.elementSelector = elementSelector;
+ return this;
+ }
+
+ /**
+ * Selects the root element to secure.
+ * This is equivalent to {@link SecurePart#setSecureEntireRequest(boolean)}.
+ *
+ * @return This builder.
+ */
+ public SecurePartSelectorBuilder selectRootElement() {
+ return selectElement(RootElementSelector.getInstance());
+ }
+
+ /**
+ * Selects (an) element(s) to secure by name.
+ *
+ * @param name The name to select an element to secure by, which must not be {@code null}.
+ * @return This builder.
+ */
+ public SecurePartSelectorBuilder selectElementByName(QName name) {
+ return selectElement(new ByNameElementSelector(name));
+ }
+
+ /**
+ * Selects the element(s) to secure by value of a given attribute name.
+ * When the given attribute name is {@code null}, {@link #getIdAttributeNS()} will be used.
+ *
+ * @param name The name of the attribute, which may be {@code null}.
+ * @param value The value of the attribute, which must not be {@code null}.
+ * @return This builder.
+ */
+ public SecurePartSelectorBuilder selectElementByAttributeValue(QName name, String value) {
+ return selectElement(new ByAttributeElementSelector(() -> name != null ? name : getIdAttributeNS(), value));
+ }
+
+ /**
+ * Selects the element(s) to secure by value of the attribute name given by {@link #getIdAttributeNS()}.
+ *
+ * @param value The attribute value to select an element by, which must not be {@code null}.
+ * @return This builder.
+ */
+ public SecurePartSelectorBuilder selectElementByAttributeValue(String value) {
+ return selectElementByAttributeValue(null, value);
+ }
+
+ /**
+ * Secures an element with the parameters given by the secure part created with the factory upon selection.
+ *
+ * @param securePartFactory The factory to create a secure part with upon selection, which must not be {@code null}.
+ * @return This builder.
+ */
+ public SecurePartSelectorBuilder securePartWith(SecurePartFactory securePartFactory) {
+ requireNonNull(securePartFactory, "secure part factory is null");
+ this.securePartFactory = securePartFactory;
+ return this;
+ }
+
+ /**
+ * Secures an element with the given modifier upon selection.
+ *
+ * @param modifier The modifier to secure an element with upon selection, which must not be {@code null}.
+ * @return This builder.
+ */
+ public SecurePartSelectorBuilder securePartWithModifier(SecurePart.Modifier modifier) {
+ requireNonNull(modifier, "modifier is null");
+ return securePartWith((element) -> element != null ? new SecurePart(element.getName(), modifier) : null);
+ }
+
+ /**
+ * Requires a given number of occurrences, which will be verified after processing.
+ * The default is {@code -1}, which means verification is disabled.
+ * Use {@code 0} to verify that a secure part never occurs.
+ *
+ * @param requiredNumOccurrences A required number of occurrences, or {@code -1} for no such requirement.
+ * @return This builder.
+ */
+ public SecurePartSelectorBuilder requireNumOccurrences(int requiredNumOccurrences) {
+ this.requiredNumOccurrences = requiredNumOccurrences;
+ return this;
+ }
+
+ /**
+ * Builds a secure part selector and adds it to the security properties.
+ *
+ * @return A secure part selector, never {@code null}.
+ */
+ public SecurePartSelector build() {
+ Supplier> actionsSupplier = () -> actions != null ? actions : XMLSecurityProperties.this.actions;
+ SecurePartSelector securePartSelector = new SecurePartSelector(actionsSupplier, elementSelector, securePartFactory, requiredNumOccurrences);
+ XMLSecurityProperties.this.securePartSelectors.add(securePartSelector);
+ return securePartSelector;
+ }
+ }
}
diff --git a/src/main/java/org/apache/xml/security/stax/impl/AbstractSecurityContextImpl.java b/src/main/java/org/apache/xml/security/stax/impl/AbstractSecurityContextImpl.java
index 1b58164218..bde9fc1a66 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/AbstractSecurityContextImpl.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/AbstractSecurityContextImpl.java
@@ -19,6 +19,7 @@
package org.apache.xml.security.stax.impl;
import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.stax.ext.XMLSecurityProperties;
import org.apache.xml.security.stax.securityEvent.SecurityEvent;
import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
@@ -30,6 +31,15 @@ public class AbstractSecurityContextImpl {
@SuppressWarnings("unchecked")
private final Map content = Collections.synchronizedMap(new HashMap());
private final List securityEventListeners = new ArrayList<>(2);
+ private final XMLSecurityProperties securityProperties;
+
+ public AbstractSecurityContextImpl(XMLSecurityProperties securityProperties) {
+ this.securityProperties = securityProperties;
+ }
+
+ public XMLSecurityProperties getSecurityProperties() {
+ return securityProperties;
+ }
public void addSecurityEventListener(SecurityEventListener securityEventListener) {
if (securityEventListener != null) {
@@ -75,34 +85,4 @@ public void putList(Object key, T value) {
}
entry.addAll(value);
}
-
- @SuppressWarnings("unchecked")
- public void putAsList(Object key, T value) {
- List entry = (List) content.get(key);
- if (entry == null) {
- entry = new ArrayList<>();
- content.put(key, entry);
- }
- entry.add(value);
- }
-
- @SuppressWarnings("unchecked")
- public List getAsList(Object key) {
- return (List) content.get(key);
- }
-
- @SuppressWarnings("unchecked")
- public void putAsMap(Object key, T mapKey, U mapValue) {
- Map entry = (Map) content.get(key);
- if (entry == null) {
- entry = new HashMap<>();
- content.put(key, entry);
- }
- entry.put(mapKey, mapValue);
- }
-
- @SuppressWarnings("unchecked")
- public Map getAsMap(Object key) {
- return (Map) content.get(key);
- }
}
diff --git a/src/main/java/org/apache/xml/security/stax/impl/EncryptionPartDef.java b/src/main/java/org/apache/xml/security/stax/impl/EncryptionPartDef.java
index d23cb94992..455e68ac72 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/EncryptionPartDef.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/EncryptionPartDef.java
@@ -19,6 +19,7 @@
package org.apache.xml.security.stax.impl;
import org.apache.xml.security.stax.ext.SecurePart;
+import org.apache.xml.security.stax.ext.SecurePartSelector;
import java.security.Key;
@@ -28,6 +29,7 @@
*/
public class EncryptionPartDef {
+ private SecurePartSelector securePartSelector;
private SecurePart securePart;
private SecurePart.Modifier modifier;
private Key symmetricKey;
@@ -36,6 +38,14 @@ public class EncryptionPartDef {
private String cipherReferenceId;
private String mimeType;
+ public SecurePartSelector getSecurePartSelector() {
+ return securePartSelector;
+ }
+
+ public void setSecurePartSelector(SecurePartSelector securePartSelector) {
+ this.securePartSelector = securePartSelector;
+ }
+
public SecurePart getSecurePart() {
return securePart;
}
diff --git a/src/main/java/org/apache/xml/security/stax/impl/InboundSecurityContextImpl.java b/src/main/java/org/apache/xml/security/stax/impl/InboundSecurityContextImpl.java
index 40c8711507..fa082d7bc3 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/InboundSecurityContextImpl.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/InboundSecurityContextImpl.java
@@ -21,6 +21,7 @@
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.config.ConfigurationProperties;
import org.apache.xml.security.stax.ext.InboundSecurityContext;
+import org.apache.xml.security.stax.ext.XMLSecurityProperties;
import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
import org.apache.xml.security.stax.securityToken.SecurityTokenProvider;
import org.apache.xml.security.stax.securityEvent.AlgorithmSuiteSecurityEvent;
@@ -39,6 +40,10 @@ public class InboundSecurityContextImpl extends AbstractSecurityContextImpl impl
private final Map> securityTokenProviders =
new HashMap<>();
+ public InboundSecurityContextImpl(XMLSecurityProperties securityProperties) {
+ super(securityProperties);
+ }
+
@Override
protected void forwardSecurityEvent(SecurityEvent securityEvent) throws XMLSecurityException {
if (!InboundSecurityContextImpl.allowMD5Algorithm && SecurityEventConstants.AlgorithmSuite.equals(securityEvent.getSecurityEventType())) {
diff --git a/src/main/java/org/apache/xml/security/stax/impl/OutboundSecurityContextImpl.java b/src/main/java/org/apache/xml/security/stax/impl/OutboundSecurityContextImpl.java
index e87cde87d4..db34a91d0c 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/OutboundSecurityContextImpl.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/OutboundSecurityContextImpl.java
@@ -19,6 +19,7 @@
package org.apache.xml.security.stax.impl;
import org.apache.xml.security.stax.ext.OutboundSecurityContext;
+import org.apache.xml.security.stax.ext.XMLSecurityProperties;
import org.apache.xml.security.stax.securityToken.SecurityTokenProvider;
import org.apache.xml.security.stax.securityToken.OutboundSecurityToken;
@@ -36,6 +37,10 @@ public class OutboundSecurityContextImpl extends AbstractSecurityContextImpl imp
private final Map> securityTokenProviders =
new HashMap<>();
+ public OutboundSecurityContextImpl(XMLSecurityProperties securityProperties) {
+ super(securityProperties);
+ }
+
@Override
public void registerSecurityTokenProvider(String id, SecurityTokenProvider securityTokenProvider) {
if (id == null) {
diff --git a/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java b/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java
index c89089bc6f..f4d0594e23 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java
@@ -19,6 +19,7 @@
package org.apache.xml.security.stax.impl;
import org.apache.xml.security.stax.ext.SecurePart;
+import org.apache.xml.security.stax.ext.SecurePartSelector;
/**
* SignaturePartDef holds information about parts to be signed
@@ -26,6 +27,7 @@
*/
public class SignaturePartDef {
+ private SecurePartSelector securePartSelector;
private SecurePart securePart;
private String sigRefId;
private String digestValue;
@@ -36,6 +38,14 @@ public class SignaturePartDef {
private boolean externalResource;
private boolean generateXPointer;
+ public SecurePartSelector getSecurePartSelector() {
+ return securePartSelector;
+ }
+
+ public void setSecurePartSelector(SecurePartSelector elementSelector) {
+ this.securePartSelector = elementSelector;
+ }
+
public SecurePart getSecurePart() {
return securePart;
}
diff --git a/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamWriter.java b/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamWriter.java
index bd0fda2218..b7a1672aee 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamWriter.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamWriter.java
@@ -20,8 +20,6 @@
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.ext.OutputProcessorChain;
-import org.apache.xml.security.stax.ext.SecurePart;
-import org.apache.xml.security.stax.ext.XMLSecurityConstants;
import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
import org.apache.xml.security.stax.ext.stax.XMLSecEventFactory;
@@ -49,8 +47,6 @@ public class XMLSecurityStreamWriter implements XMLStreamWriter {
private NSContext namespaceContext = new NSContext(null);
private boolean endDocumentWritten = false;
private boolean haveToWriteEndElement = false;
- private SecurePart signEntireRequestPart;
- private SecurePart encryptEntireRequestPart;
public XMLSecurityStreamWriter(OutputProcessorChain outputProcessorChain) {
this.outputProcessorChain = outputProcessorChain;
@@ -118,22 +114,6 @@ public void writeStartElement(String prefix, String localName, String namespaceU
Element element;
if (elementStack == null) {
element = new Element(elementStack, namespaceContext, namespaceURI, localName, prefix);
- if (signEntireRequestPart != null) {
- signEntireRequestPart.setName(new QName(namespaceURI, localName, prefix));
- outputProcessorChain.getSecurityContext().putAsMap(
- XMLSecurityConstants.SIGNATURE_PARTS,
- signEntireRequestPart.getName(),
- signEntireRequestPart
- );
- }
- if (encryptEntireRequestPart != null) {
- encryptEntireRequestPart.setName(new QName(namespaceURI, localName, prefix));
- outputProcessorChain.getSecurityContext().putAsMap(
- XMLSecurityConstants.ENCRYPTION_PARTS,
- encryptEntireRequestPart.getName(),
- encryptEntireRequestPart
- );
- }
} else {
element = new Element(elementStack, namespaceURI, localName, prefix);
}
@@ -165,7 +145,6 @@ public void writeEndElement() throws XMLStreamException {
Element element = this.elementStack;
this.elementStack = this.elementStack.getParentElement();
chainProcessEvent(XMLSecEventFactory.createXmlSecEndElement(element.getQName()));
-
}
@Override
@@ -353,22 +332,6 @@ public Object getProperty(String name) throws IllegalArgumentException {
throw new IllegalArgumentException("Properties not supported");
}
- public SecurePart getSignEntireRequestPart() {
- return signEntireRequestPart;
- }
-
- public void setSignEntireRequestPart(SecurePart signEntireRequestPart) {
- this.signEntireRequestPart = signEntireRequestPart;
- }
-
- public SecurePart getEncryptEntireRequestPart() {
- return encryptEntireRequestPart;
- }
-
- public void setEncryptEntireRequestPart(SecurePart encryptEntireRequestPart) {
- this.encryptEntireRequestPart = encryptEntireRequestPart;
- }
-
private static class Element {
private Element parentElement;
diff --git a/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractSignatureReferenceVerifyInputProcessor.java b/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractSignatureReferenceVerifyInputProcessor.java
index e9a7a0e2cf..55b564bc05 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractSignatureReferenceVerifyInputProcessor.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractSignatureReferenceVerifyInputProcessor.java
@@ -61,9 +61,9 @@
import org.apache.xml.security.stax.impl.transformer.canonicalizer.Canonicalizer20010315_OmitCommentsTransformer;
import org.apache.xml.security.stax.impl.util.DigestOutputStream;
import org.apache.xml.security.stax.impl.util.IDGenerator;
-import org.apache.xml.security.stax.impl.util.KeyValue;
import org.apache.xml.security.stax.securityEvent.AlgorithmSuiteSecurityEvent;
import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
+import org.apache.xml.security.utils.KeyValue;
import org.apache.xml.security.utils.UnsyncBufferedOutputStream;
import org.apache.xml.security.utils.XMLUtils;
import org.slf4j.Logger;
diff --git a/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractEncryptOutputProcessor.java b/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractEncryptOutputProcessor.java
index ad822a60c2..a01899f221 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractEncryptOutputProcessor.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractEncryptOutputProcessor.java
@@ -29,7 +29,6 @@
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
@@ -47,6 +46,7 @@
import org.apache.xml.security.stax.ext.AbstractOutputProcessor;
import org.apache.xml.security.stax.ext.OutputProcessorChain;
import org.apache.xml.security.stax.ext.SecurePart;
+import org.apache.xml.security.stax.ext.SecurePartSelector;
import org.apache.xml.security.stax.ext.XMLSecurityConstants;
import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
import org.apache.xml.security.stax.ext.stax.XMLSecCharacters;
@@ -74,14 +74,15 @@ public abstract class AbstractEncryptOutputProcessor extends AbstractOutputProce
}
private AbstractInternalEncryptionOutputProcessor activeInternalEncryptionOutputProcessor;
+ private final List encryptionPartDefList = new ArrayList<>();
public AbstractEncryptOutputProcessor() throws XMLSecurityException {
super();
}
- @Override
- public abstract void processEvent(XMLSecEvent xmlSecEvent, OutputProcessorChain outputProcessorChain)
- throws XMLStreamException, XMLSecurityException;
+ public List getEncryptionPartDefList() {
+ return encryptionPartDefList;
+ }
@Override
public void doFinal(OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
@@ -94,26 +95,27 @@ protected void doFinalInternal(OutputProcessorChain outputProcessorChain) throws
}
protected void verifyEncryptionParts(OutputProcessorChain outputProcessorChain) throws XMLSecurityException {
- List encryptionPartDefs =
- outputProcessorChain.getSecurityContext().getAsList(EncryptionPartDef.class);
-
- Map dynamicSecureParts = outputProcessorChain.getSecurityContext().getAsMap(XMLSecurityConstants.ENCRYPTION_PARTS);
- Iterator> securePartsMapIterator = dynamicSecureParts.entrySet().iterator();
- loop:
- while (securePartsMapIterator.hasNext()) {
- Map.Entry securePartEntry = securePartsMapIterator.next();
- final SecurePart securePart = securePartEntry.getValue();
-
- if (securePart.isRequired()) {
- for (int i = 0; encryptionPartDefs != null && i < encryptionPartDefs.size(); i++) {
- EncryptionPartDef encryptionPartDef = encryptionPartDefs.get(i);
-
- if (encryptionPartDef.getSecurePart() == securePart) {
- continue loop;
+ List encryptionPartDefs = getEncryptionPartDefList();
+ List encryptionPartSelectors = outputProcessorChain.getSecurityContext().get(XMLSecurityConstants.ENCRYPTION_PART_SELECTORS);
+ if (encryptionPartSelectors != null) {
+ loop:
+ for (SecurePartSelector encryptionPartSelector : encryptionPartSelectors) {
+ int requiredNumOccurrences = encryptionPartSelector.getRequiredNumOccurrences();
+ if (requiredNumOccurrences >= 0) {
+ int numOccurrences = 0;
+ for (EncryptionPartDef encryptionPartDef : encryptionPartDefs) {
+ if (encryptionPartDef.getSecurePartSelector().equals(encryptionPartSelector)) {
+ numOccurrences++;
+ }
+ }
+ if (numOccurrences < requiredNumOccurrences) {
+ throw new XMLSecurityException("stax.encryption.tooFewOccurrences",
+ new Object[]{numOccurrences, requiredNumOccurrences, encryptionPartSelector});
+ } else if (numOccurrences > requiredNumOccurrences) {
+ throw new XMLSecurityException("stax.encryption.tooManyOccurrences",
+ new Object[]{numOccurrences, requiredNumOccurrences, encryptionPartSelector});
}
}
- throw new XMLSecurityException("stax.encryption.securePartNotFound",
- new Object[] {securePart.getName()});
}
}
}
diff --git a/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java b/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java
index fe2e657699..0f0bae15a8 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java
@@ -41,6 +41,7 @@
import org.apache.xml.security.stax.ext.OutputProcessorChain;
import org.apache.xml.security.stax.ext.ResourceResolver;
import org.apache.xml.security.stax.ext.SecurePart;
+import org.apache.xml.security.stax.ext.SecurePartSelector;
import org.apache.xml.security.stax.ext.Transformer;
import org.apache.xml.security.stax.ext.XMLSecurityConstants;
import org.apache.xml.security.stax.ext.XMLSecurityUtils;
@@ -52,7 +53,6 @@
import org.apache.xml.security.stax.impl.util.DigestOutputStream;
import org.apache.xml.security.utils.UnsyncBufferedOutputStream;
import org.apache.xml.security.utils.XMLUtils;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -73,10 +73,6 @@ public List getSignaturePartDefList() {
return signaturePartDefList;
}
- @Override
- public abstract void processEvent(XMLSecEvent xmlSecEvent, OutputProcessorChain outputProcessorChain)
- throws XMLStreamException, XMLSecurityException;
-
@Override
public void doFinal(OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
doFinalInternal(outputProcessorChain);
@@ -84,26 +80,22 @@ public void doFinal(OutputProcessorChain outputProcessorChain) throws XMLStreamE
}
protected void doFinalInternal(OutputProcessorChain outputProcessorChain) throws XMLSecurityException, XMLStreamException {
- Map dynamicSecureParts =
- outputProcessorChain.getSecurityContext().getAsMap(XMLSecurityConstants.SIGNATURE_PARTS);
- if (dynamicSecureParts != null) {
- Iterator> securePartsMapIterator = dynamicSecureParts.entrySet().iterator();
- while (securePartsMapIterator.hasNext()) {
- Map.Entry securePartEntry = securePartsMapIterator.next();
- final SecurePart securePart = securePartEntry.getValue();
- if (securePart.getExternalReference() != null) {
- digestExternalReference(outputProcessorChain, securePart);
- }
- }
+ List securePartSelectors = getSecurityProperties().getSignaturePartSelectors();
+ for (SecurePartSelector securePartSelector : securePartSelectors) {
+ digestExternalReference(outputProcessorChain, securePartSelector);
}
verifySignatureParts(outputProcessorChain);
}
protected void digestExternalReference(
- OutputProcessorChain outputProcessorChain, SecurePart securePart)
+ OutputProcessorChain outputProcessorChain, SecurePartSelector securePartSelector)
throws XMLSecurityException, XMLStreamException {
+ final SecurePart securePart = securePartSelector.select(null);
+ if (securePart == null || securePart.getExternalReference() == null) {
+ return;
+ }
final String externalReference = securePart.getExternalReference();
ResourceResolver resourceResolver =
ResourceResolverMapper.getResourceResolver(
@@ -118,6 +110,7 @@ protected void digestExternalReference(
InputStream inputStream = resourceResolver.getInputStreamFromExternalReference();
SignaturePartDef signaturePartDef = new SignaturePartDef();
+ signaturePartDef.setSecurePartSelector(securePartSelector);
signaturePartDef.setSecurePart(securePart);
signaturePartDef.setSigRefId(externalReference);
signaturePartDef.setExternalResource(true);
@@ -149,24 +142,25 @@ protected void digestExternalReference(
protected void verifySignatureParts(OutputProcessorChain outputProcessorChain) throws XMLSecurityException {
List signaturePartDefs = getSignaturePartDefList();
- Map dynamicSecureParts = outputProcessorChain.getSecurityContext().getAsMap(XMLSecurityConstants.SIGNATURE_PARTS);
- if (dynamicSecureParts != null) {
- Iterator> securePartsMapIterator = dynamicSecureParts.entrySet().iterator();
+ List signaturePartSelectors = outputProcessorChain.getSecurityContext().get(XMLSecurityConstants.SIGNATURE_PART_SELECTORS);
+ if (signaturePartSelectors != null) {
loop:
- while (securePartsMapIterator.hasNext()) {
- Map.Entry securePartEntry = securePartsMapIterator.next();
- final SecurePart securePart = securePartEntry.getValue();
-
- if (securePart.isRequired()) {
- for (int i = 0; i < signaturePartDefs.size(); i++) {
- SignaturePartDef signaturePartDef = signaturePartDefs.get(i);
-
- if (signaturePartDef.getSecurePart() == securePart) {
- continue loop;
+ for (SecurePartSelector signaturePartSelector : signaturePartSelectors) {
+ int requiredNumOccurrences = signaturePartSelector.getRequiredNumOccurrences();
+ if (requiredNumOccurrences >= 0) {
+ int numOccurrences = 0;
+ for (SignaturePartDef signaturePartDef : signaturePartDefs) {
+ if (signaturePartDef.getSecurePartSelector().equals(signaturePartSelector)) {
+ numOccurrences++;
}
}
- throw new XMLSecurityException("stax.signature.securePartNotFound",
- new Object[] {securePart.getName()});
+ if (numOccurrences < requiredNumOccurrences) {
+ throw new XMLSecurityException("stax.signature.tooFewOccurrences",
+ new Object[]{numOccurrences, requiredNumOccurrences, signaturePartSelector});
+ } else if (numOccurrences > requiredNumOccurrences) {
+ throw new XMLSecurityException("stax.signature.tooManyOccurrences",
+ new Object[]{numOccurrences, requiredNumOccurrences, signaturePartSelector});
+ }
}
}
}
diff --git a/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java b/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java
index 1264d24df4..3231d37a42 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java
@@ -41,6 +41,7 @@
import org.apache.xml.security.stax.config.JCEAlgorithmMapper;
import org.apache.xml.security.stax.ext.OutputProcessorChain;
import org.apache.xml.security.stax.ext.SecurePart;
+import org.apache.xml.security.stax.ext.SecurePartSelector;
import org.apache.xml.security.stax.ext.XMLSecurityConstants;
import org.apache.xml.security.stax.ext.XMLSecurityUtils;
import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
@@ -51,6 +52,7 @@
import org.apache.xml.security.stax.securityToken.OutboundSecurityToken;
import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;
import org.apache.xml.security.stax.securityToken.SecurityTokenProvider;
+import org.apache.xml.security.utils.KeyValue;
import org.apache.xml.security.utils.XMLUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -74,8 +76,10 @@ public void processEvent(XMLSecEvent xmlSecEvent, OutputProcessorChain outputPro
//avoid double encryption when child elements matches too
if (getActiveInternalEncryptionOutputProcessor() == null) {
- SecurePart securePart = securePartMatches(xmlSecStartElement, outputProcessorChain, XMLSecurityConstants.ENCRYPTION_PARTS);
- if (securePart != null) {
+ KeyValue match = securePartMatches(xmlSecStartElement, outputProcessorChain, XMLSecurityConstants.ENCRYPTION_PART_SELECTORS);
+ if (match != null) {
+ SecurePartSelector securePartSelector = match.getKey();
+ SecurePart securePart = match.getValue();
LOG.debug("Matched encryptionPart for encryption");
String tokenId = outputProcessorChain.getSecurityContext().get(
XMLSecurityConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
@@ -84,12 +88,13 @@ public void processEvent(XMLSecEvent xmlSecEvent, OutputProcessorChain outputPro
final OutboundSecurityToken securityToken = securityTokenProvider.getSecurityToken();
EncryptionPartDef encryptionPartDef = new EncryptionPartDef();
+ encryptionPartDef.setSecurePartSelector(securePartSelector);
encryptionPartDef.setSecurePart(securePart);
encryptionPartDef.setModifier(securePart.getModifier());
encryptionPartDef.setEncRefId(IDGenerator.generateID(null));
encryptionPartDef.setKeyId(securityTokenProvider.getId());
encryptionPartDef.setSymmetricKey(securityToken.getSecretKey(getSecurityProperties().getEncryptionSymAlgorithm()));
- outputProcessorChain.getSecurityContext().putAsList(EncryptionPartDef.class, encryptionPartDef);
+ getEncryptionPartDefList().add(encryptionPartDef);
AbstractInternalEncryptionOutputProcessor internalEncryptionOutputProcessor =
createInternalEncryptionOutputProcessor(
diff --git a/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java b/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java
index e98d3b76d0..3c3871ed15 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java
@@ -25,6 +25,8 @@
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
+import org.apache.xml.security.stax.ext.SecurePartSelector;
+import org.apache.xml.security.utils.KeyValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.xml.security.exceptions.XMLSecurityException;
@@ -64,13 +66,16 @@ public void processEvent(XMLSecEvent xmlSecEvent, OutputProcessorChain outputPro
//avoid double signature when child elements matches too
if (getActiveInternalSignatureOutputProcessor() == null) {
- SecurePart securePart = securePartMatches(xmlSecStartElement, outputProcessorChain, XMLSecurityConstants.SIGNATURE_PARTS);
- if (securePart != null) {
+ KeyValue match = securePartMatches(xmlSecStartElement, outputProcessorChain, XMLSecurityConstants.SIGNATURE_PART_SELECTORS);
+ if (match != null) {
+ SecurePartSelector securePartSelector = match.getKey();
+ SecurePart securePart = match.getValue();
LOG.debug("Matched securePart for signature");
InternalSignatureOutputProcessor internalSignatureOutputProcessor = null;
SignaturePartDef signaturePartDef = new SignaturePartDef();
+ signaturePartDef.setSecurePartSelector(securePartSelector);
signaturePartDef.setSecurePart(securePart);
signaturePartDef.setTransforms(securePart.getTransforms());
if (signaturePartDef.getTransforms() == null) {
diff --git a/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecEventBaseImpl.java b/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecEventBaseImpl.java
index 4763c58f17..5e782f8c27 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecEventBaseImpl.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecEventBaseImpl.java
@@ -37,7 +37,7 @@
public abstract class XMLSecEventBaseImpl implements XMLSecEvent {
private static final EmptyIterator EMPTY_ITERATOR = new EmptyIterator();
- protected XMLSecStartElement parentXMLSecStartELement;
+ protected XMLSecStartElement parentXMLSecStartElement;
@SuppressWarnings("unchecked")
protected static EmptyIterator getEmptyIterator() {
@@ -46,26 +46,26 @@ protected static EmptyIterator getEmptyIterator() {
@Override
public void setParentXMLSecStartElement(XMLSecStartElement xmlSecStartElement) {
- this.parentXMLSecStartELement = xmlSecStartElement;
+ this.parentXMLSecStartElement = xmlSecStartElement;
}
@Override
public XMLSecStartElement getParentXMLSecStartElement() {
- return parentXMLSecStartELement;
+ return parentXMLSecStartElement;
}
@Override
public int getDocumentLevel() {
- if (parentXMLSecStartELement != null) {
- return parentXMLSecStartELement.getDocumentLevel();
+ if (parentXMLSecStartElement != null) {
+ return parentXMLSecStartElement.getDocumentLevel();
}
return 0;
}
@Override
public void getElementPath(List list) {
- if (parentXMLSecStartELement != null) {
- parentXMLSecStartELement.getElementPath(list);
+ if (parentXMLSecStartElement != null) {
+ parentXMLSecStartElement.getElementPath(list);
}
}
@@ -81,7 +81,7 @@ public XMLSecStartElement getStartElementAtLevel(int level) {
if (getDocumentLevel() < level) {
return null;
}
- return parentXMLSecStartELement.getStartElementAtLevel(level);
+ return parentXMLSecStartElement.getStartElementAtLevel(level);
}
@Override
diff --git a/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecStartElementImpl.java b/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecStartElementImpl.java
index 5d02871a99..b9cbf8d72b 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecStartElementImpl.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecStartElementImpl.java
@@ -89,8 +89,8 @@ public Iterator getAttributes() {
@Override
public void getAttributesFromCurrentScope(List comparableAttributeList) {
comparableAttributeList.addAll(attributes);
- if (parentXMLSecStartELement != null) {
- parentXMLSecStartELement.getAttributesFromCurrentScope(comparableAttributeList);
+ if (parentXMLSecStartElement != null) {
+ parentXMLSecStartElement.getAttributesFromCurrentScope(comparableAttributeList);
}
}
@@ -126,7 +126,7 @@ public XMLSecStartElement getStartElementAtLevel(int level) {
} else if (thisLevel == level) {
return this;
} else {
- return parentXMLSecStartELement.getStartElementAtLevel(level);
+ return parentXMLSecStartElement.getStartElementAtLevel(level);
}
}
@@ -142,8 +142,8 @@ public Iterator getNamespaces() {
@Override
public void getNamespacesFromCurrentScope(List comparableNamespaceList) {
- if (parentXMLSecStartELement != null) {
- parentXMLSecStartELement.getNamespacesFromCurrentScope(comparableNamespaceList);
+ if (parentXMLSecStartElement != null) {
+ parentXMLSecStartElement.getNamespacesFromCurrentScope(comparableNamespaceList);
}
comparableNamespaceList.addAll(namespaces);
}
@@ -183,8 +183,8 @@ public String getNamespaceURI(String prefix) {
return comparableNamespace.getNamespaceURI();
}
}
- if (parentXMLSecStartELement != null) {
- return parentXMLSecStartELement.getNamespaceURI(prefix);
+ if (parentXMLSecStartElement != null) {
+ return parentXMLSecStartElement.getNamespaceURI(prefix);
}
return null;
}
@@ -197,8 +197,8 @@ public String getPrefix(String namespaceURI) {
return comparableNamespace.getPrefix();
}
}
- if (parentXMLSecStartELement != null) {
- return parentXMLSecStartELement.getNamespaceContext().getPrefix(namespaceURI);
+ if (parentXMLSecStartElement != null) {
+ return parentXMLSecStartElement.getNamespaceContext().getPrefix(namespaceURI);
}
return null;
}
@@ -231,8 +231,8 @@ public String getNamespaceURI(String prefix) {
return comparableNamespace.getNamespaceURI();
}
}
- if (parentXMLSecStartELement != null) {
- return parentXMLSecStartELement.getNamespaceURI(prefix);
+ if (parentXMLSecStartElement != null) {
+ return parentXMLSecStartElement.getNamespaceURI(prefix);
}
return null;
}
diff --git a/src/main/java/org/apache/xml/security/stax/impl/util/KeyValue.java b/src/main/java/org/apache/xml/security/utils/KeyValue.java
similarity index 92%
rename from src/main/java/org/apache/xml/security/stax/impl/util/KeyValue.java
rename to src/main/java/org/apache/xml/security/utils/KeyValue.java
index efaa319d00..7077dbe81d 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/util/KeyValue.java
+++ b/src/main/java/org/apache/xml/security/utils/KeyValue.java
@@ -16,14 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.xml.security.stax.impl.util;
+package org.apache.xml.security.utils;
/**
*/
public class KeyValue {
- private E key;
- private K value;
+ private final E key;
+ private final K value;
public KeyValue(E key, K value) {
this.key = key;
diff --git a/src/test/java/org/apache/xml/security/stax/ext/ByAttributeElementSelectorTest.java b/src/test/java/org/apache/xml/security/stax/ext/ByAttributeElementSelectorTest.java
new file mode 100644
index 0000000000..4c2fc6d7b7
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/stax/ext/ByAttributeElementSelectorTest.java
@@ -0,0 +1,55 @@
+package org.apache.xml.security.stax.ext;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+import org.apache.xml.security.stax.impl.stax.XMLSecAttributeImpl;
+import org.apache.xml.security.stax.impl.stax.XMLSecStartElementImpl;
+import org.junit.jupiter.api.Test;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class ByAttributeElementSelectorTest {
+
+ @Test
+ public void testConstructionThrowsWhenValueIsNull() {
+ assertThrows(NullPointerException.class, () -> new ByAttributeElementSelector(new QName("attr1"), null));
+ }
+
+ @Test
+ public void testSelection() {
+ QName attributeName = new QName("attr1");
+ String value = "val1";
+ ByAttributeElementSelector elementSelector = new ByAttributeElementSelector(attributeName, value);
+ assertThat(elementSelector.select(null), is(false));
+
+ QName elementName = new QName("element");
+ List attributes1 = asList(new XMLSecAttributeImpl(attributeName, "val1"));
+ XMLSecStartElement element1 = new XMLSecStartElementImpl(elementName, attributes1, null);
+ assertThat(elementSelector.select(element1), is(true));
+
+ List attributes2 = asList(new XMLSecAttributeImpl(attributeName, "val2"));
+ XMLSecStartElement element2 = new XMLSecStartElementImpl(elementName, attributes2, null);
+ assertThat(elementSelector.select(element2), is(false));
+
+ QName attributeName2 = new QName("attr2");
+ List attributes3 = asList(new XMLSecAttributeImpl(attributeName2, "val1"));
+ XMLSecStartElement element3 = new XMLSecStartElementImpl(elementName, attributes3, null);
+ assertThat(elementSelector.select(element3), is(false));
+ }
+
+ @Test
+ public void testStringValue() {
+ assertThat(new ByAttributeElementSelector(new QName("attr1"), "val1").toString(), is(equalTo("//*[@attr1='val1']")));
+ assertThat(new ByAttributeElementSelector(new QName("urn:test:ns", "attr1"), "val1").toString(), is(equalTo("//*[@{urn:test:ns}attr1='val1']")));
+ assertThat(new ByAttributeElementSelector(new QName(null, "attr1", "pf1"), "val1").toString(), is(equalTo("//*[@attr1='val1']")));
+ assertThat(new ByAttributeElementSelector(new QName("urn:test:ns", "attr1", "pf1"), "val1").toString(), is(equalTo("//*[@{urn:test:ns}attr1='val1']")));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/xml/security/stax/ext/ByNameElementSelectorTest.java b/src/test/java/org/apache/xml/security/stax/ext/ByNameElementSelectorTest.java
new file mode 100644
index 0000000000..ceb6fdd7ed
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/stax/ext/ByNameElementSelectorTest.java
@@ -0,0 +1,39 @@
+package org.apache.xml.security.stax.ext;
+
+import javax.xml.namespace.QName;
+
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+import org.apache.xml.security.stax.impl.stax.XMLSecStartElementImpl;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class ByNameElementSelectorTest {
+
+ @Test
+ public void testConstructionThrowsWhenNameIsNull() {
+ assertThrows(NullPointerException.class, () -> new ByNameElementSelector(null));
+ }
+
+ @Test
+ public void testSelection() {
+ QName name = new QName("element");
+ ByNameElementSelector elementSelector = new ByNameElementSelector(name);
+ assertThat(elementSelector.select(null), is(false));
+ XMLSecStartElement element = new XMLSecStartElementImpl(name, null, null);
+ assertThat(elementSelector.select(element), is(true));
+ XMLSecStartElement anotherElement = new XMLSecStartElementImpl(new QName("urn:test:ns", "element"), null, null);
+ assertThat(elementSelector.select(anotherElement), is(false));
+ }
+
+ @Test
+ public void testStringValue() {
+ assertThat(new ByNameElementSelector(new QName("element")).toString(), is(equalTo("//element")));
+ assertThat(new ByNameElementSelector(new QName("urn:test:ns", "element")).toString(), is(equalTo("//{urn:test:ns}element")));
+ assertThat(new ByNameElementSelector(new QName(null, "element", "pf")).toString(), is(equalTo("//element")));
+ assertThat(new ByNameElementSelector(new QName("urn:test:ns0", "element", "pf0")).toString(), is(equalTo("//{urn:test:ns0}element")));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/xml/security/stax/ext/DocumentElementSelectorTest.java b/src/test/java/org/apache/xml/security/stax/ext/DocumentElementSelectorTest.java
new file mode 100644
index 0000000000..2d0b1e6c2a
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/stax/ext/DocumentElementSelectorTest.java
@@ -0,0 +1,27 @@
+package org.apache.xml.security.stax.ext;
+
+import javax.xml.namespace.QName;
+
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+import org.apache.xml.security.stax.impl.stax.XMLSecStartElementImpl;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+public class DocumentElementSelectorTest {
+
+ @Test
+ public void testSelection() {
+ DocumentElementSelector elementSelector = DocumentElementSelector.getInstance();
+ assertThat(elementSelector.select(null), is(true));
+ XMLSecStartElement element = new XMLSecStartElementImpl(new QName("root"), null, null);
+ assertThat(elementSelector.select(element), is(false));
+ }
+
+ @Test
+ public void testStringValue() {
+ assertThat(DocumentElementSelector.getInstance().toString(), is(equalTo("/")));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/xml/security/stax/ext/NoElementSelectorTest.java b/src/test/java/org/apache/xml/security/stax/ext/NoElementSelectorTest.java
new file mode 100644
index 0000000000..61dc445840
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/stax/ext/NoElementSelectorTest.java
@@ -0,0 +1,27 @@
+package org.apache.xml.security.stax.ext;
+
+import javax.xml.namespace.QName;
+
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+import org.apache.xml.security.stax.impl.stax.XMLSecStartElementImpl;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+public class NoElementSelectorTest {
+
+ @Test
+ public void testSelection() {
+ NoElementSelector elementSelector = NoElementSelector.getInstance();
+ assertThat(elementSelector.select(null), is(false));
+ XMLSecStartElement element = new XMLSecStartElementImpl(new QName("element"), null, null);
+ assertThat(elementSelector.select(element), is(false));
+ }
+
+ @Test
+ public void testStringValue() {
+ assertThat(NoElementSelector.getInstance().toString(), is(equalTo("")));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/xml/security/stax/ext/RootElementSelectorTest.java b/src/test/java/org/apache/xml/security/stax/ext/RootElementSelectorTest.java
new file mode 100644
index 0000000000..954ebdd2a6
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/stax/ext/RootElementSelectorTest.java
@@ -0,0 +1,33 @@
+package org.apache.xml.security.stax.ext;
+
+import javax.xml.namespace.QName;
+
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+import org.apache.xml.security.stax.impl.stax.XMLSecStartElementImpl;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+public class RootElementSelectorTest {
+
+ @Test
+ public void testSelection() {
+ RootElementSelector elementSelector = RootElementSelector.getInstance();
+ assertThat(elementSelector, is(notNullValue()));
+ assertThat(elementSelector.select(null), is(false));
+ XMLSecStartElement rootElement = new XMLSecStartElementImpl(new QName("root"), null, null);
+ assertThat(elementSelector.select(rootElement), is(true));
+ XMLSecStartElement branchElement = new XMLSecStartElementImpl(new QName("branch"), null, null, rootElement);
+ assertThat(elementSelector.select(branchElement), is(false));
+ XMLSecStartElement anotherRootElement = new XMLSecStartElementImpl(new QName("anotherRoot"), null, null);
+ assertThat(elementSelector.select(anotherRootElement), is(true));
+ }
+
+ @Test
+ public void testStringValue() {
+ assertThat(RootElementSelector.getInstance().toString(), is(equalTo("/*")));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/xml/security/stax/ext/SecurePartSelectorTest.java b/src/test/java/org/apache/xml/security/stax/ext/SecurePartSelectorTest.java
new file mode 100644
index 0000000000..2935c10ead
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/stax/ext/SecurePartSelectorTest.java
@@ -0,0 +1,113 @@
+package org.apache.xml.security.stax.ext;
+
+import java.util.Collections;
+import java.util.UUID;
+
+import javax.xml.namespace.QName;
+
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+import org.apache.xml.security.stax.impl.stax.XMLSecStartElementImpl;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class SecurePartSelectorTest {
+
+ @Test
+ public void testConstructionThrowsWhenActionsSupplierIsNull() {
+ assertThrows(NullPointerException.class, () -> new SecurePartSelector(null, mock(ElementSelector.class), mock(SecurePartFactory.class), -1));
+ }
+
+ @Test
+ public void testConstructionThrowsWhenElementSelectorIsNull() {
+ assertThrows(NullPointerException.class, () -> new SecurePartSelector(Collections::emptyList, null, mock(SecurePartFactory.class), -1));
+ }
+
+ @Test
+ public void testConstructionThrowsWhenSecurePartFactoryIsNull() {
+ assertThrows(NullPointerException.class, () -> new SecurePartSelector(Collections::emptyList, mock(ElementSelector.class), null, -1));
+ }
+
+ @Test
+ public void testSelectReturnsNullWhenNotSelected() throws Exception {
+ QName name = new QName("element");
+ XMLSecStartElement element = new XMLSecStartElementImpl(name, null, null);
+ ElementSelector elementSelector = mock(ElementSelector.class);
+ when(elementSelector.select(element)).thenReturn(false);
+ SecurePartFactory securePartFactory = mock(SecurePartFactory.class);
+
+ SecurePartSelector securePartSelector = new SecurePartSelector(Collections::emptyList, elementSelector, securePartFactory, -1);
+
+ assertThat(securePartSelector.select(element), is(nullValue()));
+ verify(securePartFactory, never()).createSecurePart(nullable(XMLSecStartElement.class));
+ }
+
+ @Test
+ public void testSelectDelegatesToFactory() throws Exception {
+ QName name = new QName("element");
+ XMLSecStartElement element = new XMLSecStartElementImpl(name, null, null);
+ ElementSelector elementSelector = mock(ElementSelector.class);
+ when(elementSelector.select(element)).thenReturn(true);
+ SecurePartFactory securePartFactory = mock(SecurePartFactory.class);
+ SecurePart securePart = new SecurePart(name, SecurePart.Modifier.Element);
+ when(securePartFactory.createSecurePart(element)).thenReturn(securePart);
+
+ SecurePartSelector securePartSelector = new SecurePartSelector(Collections::emptyList, elementSelector, securePartFactory, -1);
+
+ assertThat(securePartSelector.select(element), is(securePart));
+ verify(securePartFactory).createSecurePart(element);
+ verifyNoMoreInteractions(securePartFactory);
+ }
+
+ @Test
+ public void testToStringDelegatesToElementSelector() {
+ ElementSelector elementSelector = mock(ElementSelector.class);
+ String elementSelectorStringValue = UUID.randomUUID().toString();
+ when(elementSelector.toString()).thenReturn(elementSelectorStringValue);
+ SecurePartFactory securePartFactory = mock(SecurePartFactory.class);
+
+ SecurePartSelector securePartSelector = new SecurePartSelector(Collections::emptyList, elementSelector, securePartFactory, -1);
+
+ assertThat(securePartSelector.toString(), is(equalTo(elementSelectorStringValue)));
+ }
+
+ @Test
+ public void testRequiredNumOccurrences() {
+ ElementSelector elementSelector = mock(ElementSelector.class);
+ SecurePartFactory securePartFactory = mock(SecurePartFactory.class);
+
+ SecurePartSelector securePartSelector = new SecurePartSelector(Collections::emptyList, elementSelector, securePartFactory, 2);
+
+ assertThat(securePartSelector.getRequiredNumOccurrences(), is(2));
+ }
+
+ @Test
+ public void testActions() {
+ ElementSelector elementSelector = mock(ElementSelector.class);
+ SecurePartFactory securePartFactory = mock(SecurePartFactory.class);
+
+ SecurePartSelector securePartSelector = new SecurePartSelector(() -> Collections.singletonList(XMLSecurityConstants.ENCRYPTION), elementSelector, securePartFactory, -1);
+
+ assertThat(securePartSelector.getActions(), is(equalTo(Collections.singletonList(XMLSecurityConstants.ENCRYPTION))));
+ }
+
+ @Test
+ public void testGetActionsThrowsWhenSuppliedActionsAreNull() {
+ ElementSelector elementSelector = mock(ElementSelector.class);
+ SecurePartFactory securePartFactory = mock(SecurePartFactory.class);
+
+ SecurePartSelector securePartSelector = new SecurePartSelector(() -> null, elementSelector, securePartFactory, -1);
+
+ assertThrows(NullPointerException.class, () -> securePartSelector.getActions());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/xml/security/stax/ext/XMLSecurityPropertiesTest.java b/src/test/java/org/apache/xml/security/stax/ext/XMLSecurityPropertiesTest.java
new file mode 100644
index 0000000000..6a05460017
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/stax/ext/XMLSecurityPropertiesTest.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.stax.ext;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.xml.security.stax.ext.SecurePart.Modifier;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+import org.apache.xml.security.stax.impl.stax.XMLSecStartElementImpl;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
+
+public class XMLSecurityPropertiesTest {
+
+ @Test
+ public void testDefaultValues() {
+ XMLSecurityProperties properties = new XMLSecurityProperties();
+ assertThat(properties.getEncryptionPartSelectors(), is(empty()));
+ assertThat(properties.getSignaturePartSelectors(), is(empty()));
+ }
+
+ @Test
+ public void testAddEncryptionPart() {
+ XMLSecurityProperties properties = new XMLSecurityProperties();
+ QName name = new QName("tag");
+ SecurePart encryptionPart = new SecurePart(name, Modifier.Element);
+ properties.addEncryptionPart(encryptionPart);
+ List selectors = properties.getEncryptionPartSelectors();
+ assertThat(selectors, hasSize(1));
+ SecurePartSelector selector = selectors.get(0);
+ XMLSecStartElement element = new XMLSecStartElementImpl(name, null, null);
+ assertThat(selector.select(element), is(sameInstance(encryptionPart)));
+ }
+
+ @Test
+ public void testAddSignaturePart() {
+ XMLSecurityProperties properties = new XMLSecurityProperties();
+ QName name = new QName("tag");
+ SecurePart signaturePart = new SecurePart(name, Modifier.Element);
+ properties.addSignaturePart(signaturePart);
+ List selectors = properties.getSignaturePartSelectors();
+ assertThat(selectors, hasSize(1));
+ SecurePartSelector selector = selectors.get(0);
+ XMLSecStartElement element = new XMLSecStartElementImpl(name, null, null);
+ assertThat(selector.select(element), is(sameInstance(signaturePart)));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/xml/security/stax/impl/securityToken/SecurityTokenFactoryImplTest.java b/src/test/java/org/apache/xml/security/stax/impl/securityToken/SecurityTokenFactoryImplTest.java
index 20575df6ad..213a44e6a5 100644
--- a/src/test/java/org/apache/xml/security/stax/impl/securityToken/SecurityTokenFactoryImplTest.java
+++ b/src/test/java/org/apache/xml/security/stax/impl/securityToken/SecurityTokenFactoryImplTest.java
@@ -61,7 +61,7 @@ public void setUp() throws Exception {
xmlSecurityProperties = new XMLSecurityProperties();
- inboundSecurityContext = new InboundSecurityContextImpl();
+ inboundSecurityContext = new InboundSecurityContextImpl(xmlSecurityProperties);
}
@@ -90,7 +90,7 @@ public void testKeyNameTokenWithSignatureVerificationKeySet() throws Exception {
xmlSecurityProperties.addKeyNameMapping("mykey", loadPublicKey("dsa.key", "DSA"));
xmlSecurityProperties.setSignatureVerificationKey(loadPublicKey("rsa.key", "RSA"));
- InboundSecurityContext inboundSecurityContext = new InboundSecurityContextImpl();
+ InboundSecurityContext inboundSecurityContext = new InboundSecurityContextImpl(xmlSecurityProperties);
InboundSecurityToken token =
factory.getSecurityToken(keyInfoType, keyUsage, xmlSecurityProperties, inboundSecurityContext);
@@ -106,7 +106,7 @@ public void testKeyNameTokenWithoutKeyInMap() throws Exception {
SecurityTokenConstants.KeyUsage keyUsage = SecurityTokenConstants.KeyUsage_Signature_Verification;
- InboundSecurityContext inboundSecurityContext = new InboundSecurityContextImpl();
+ InboundSecurityContext inboundSecurityContext = new InboundSecurityContextImpl(xmlSecurityProperties);
XMLSecurityException exception = Assertions.assertThrows(XMLSecurityException.class, () -> {
factory.getSecurityToken(keyInfoType, keyUsage, xmlSecurityProperties, inboundSecurityContext);
@@ -126,7 +126,7 @@ public void testKeyNameTokenWithWrongKeyInMap() throws Exception {
xmlSecurityProperties.addKeyNameMapping("mykey", privateKey);
- InboundSecurityContext inboundSecurityContext = new InboundSecurityContextImpl();
+ InboundSecurityContext inboundSecurityContext = new InboundSecurityContextImpl(xmlSecurityProperties);
XMLSecurityException exception = Assertions.assertThrows(XMLSecurityException.class, () -> {
factory.getSecurityToken(keyInfoType, keyUsage, xmlSecurityProperties, inboundSecurityContext);
diff --git a/src/test/java/org/apache/xml/security/test/stax/InputProcessorChainTest.java b/src/test/java/org/apache/xml/security/test/stax/InputProcessorChainTest.java
index 3dc4e65df0..2cf0cdf86e 100644
--- a/src/test/java/org/apache/xml/security/test/stax/InputProcessorChainTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/InputProcessorChainTest.java
@@ -20,6 +20,7 @@
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.config.Init;
+import org.apache.xml.security.stax.ext.XMLSecurityProperties;
import org.apache.xml.security.stax.impl.InboundSecurityContextImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -98,7 +99,7 @@ public void doFinal(InputProcessorChain inputProcessorChain) throws XMLStreamExc
@Test
public void testAddProcessorPhase1() {
- InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(new InboundSecurityContextImpl());
+ InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(new InboundSecurityContextImpl(new XMLSecurityProperties()));
AbstractInputProcessor inputProcessor1 = new AbstractInputProcessor() {
};
@@ -119,7 +120,7 @@ public void testAddProcessorPhase1() {
@Test
public void testAddProcessorPhase2() {
- InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(new InboundSecurityContextImpl());
+ InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(new InboundSecurityContextImpl(new XMLSecurityProperties()));
AbstractInputProcessor inputProcessor1 = new AbstractInputProcessor() {
};
@@ -159,7 +160,7 @@ public void testAddProcessorPhase2() {
@Test
public void testAddProcessorBefore1() {
- InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(new InboundSecurityContextImpl());
+ InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(new InboundSecurityContextImpl(new XMLSecurityProperties()));
AbstractInputProcessor inputProcessor1 = new AbstractInputProcessor() {
};
@@ -202,7 +203,7 @@ public void testAddProcessorBefore1() {
@Test
public void testAddProcessorAfter1() {
- InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(new InboundSecurityContextImpl());
+ InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(new InboundSecurityContextImpl(new XMLSecurityProperties()));
AbstractInputProcessor inputProcessor1 = new AbstractInputProcessor() {
};
@@ -245,7 +246,7 @@ public void testAddProcessorAfter1() {
@Test
public void testAddProcessorBeforeAndAfter1() {
- InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(new InboundSecurityContextImpl());
+ InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(new InboundSecurityContextImpl(new XMLSecurityProperties()));
AbstractInputProcessor inputProcessor1 = new AbstractInputProcessor() {
};
diff --git a/src/test/java/org/apache/xml/security/test/stax/OutputProcessorChainTest.java b/src/test/java/org/apache/xml/security/test/stax/OutputProcessorChainTest.java
index d6d49c8557..f8bc7e317b 100644
--- a/src/test/java/org/apache/xml/security/test/stax/OutputProcessorChainTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/OutputProcessorChainTest.java
@@ -106,7 +106,7 @@ public void doFinal(OutputProcessorChain outputProcessorChain) throws XMLStreamE
@Test
public void testAddProcessorPhase1() {
- OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(new OutboundSecurityContextImpl());
+ OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(new OutboundSecurityContextImpl(new XMLSecurityProperties()));
AbstractOutputProcessor outputProcessor1 = new AbstractOutputProcessor() {
};
@@ -127,7 +127,7 @@ public void testAddProcessorPhase1() {
@Test
public void testAddProcessorPhase2() {
- OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(new OutboundSecurityContextImpl());
+ OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(new OutboundSecurityContextImpl(new XMLSecurityProperties()));
AbstractOutputProcessor outputProcessor1 = new AbstractOutputProcessor() {
};
@@ -167,7 +167,7 @@ public void testAddProcessorPhase2() {
@Test
public void testAddProcessorBefore1() {
- OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(new OutboundSecurityContextImpl());
+ OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(new OutboundSecurityContextImpl(new XMLSecurityProperties()));
AbstractOutputProcessor outputProcessor1 = new AbstractOutputProcessor() {
};
@@ -210,7 +210,7 @@ public void testAddProcessorBefore1() {
@Test
public void testAddProcessorAfter1() {
- OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(new OutboundSecurityContextImpl());
+ OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(new OutboundSecurityContextImpl(new XMLSecurityProperties()));
AbstractOutputProcessor outputProcessor1 = new AbstractOutputProcessor() {
};
@@ -253,7 +253,7 @@ public void testAddProcessorAfter1() {
@Test
public void testAddProcessorBeforeAndAfter1() {
- OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(new OutboundSecurityContextImpl());
+ OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(new OutboundSecurityContextImpl(new XMLSecurityProperties()));
AbstractOutputProcessor outputProcessor1 = new AbstractOutputProcessor() {
};
diff --git a/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java b/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java
index 87f1e2d511..7c8db54d4e 100644
--- a/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java
@@ -75,7 +75,7 @@ public void setUp() throws Exception {
public void testPassThroughDocumentEvents() throws Exception {
XMLSecurityProperties securityProperties = new XMLSecurityProperties();
securityProperties.setSkipDocumentEvents(false);
- InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
+ InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl(securityProperties);
InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
inputProcessorChain.addProcessor(new EventReaderProcessor());
XMLSecurityStreamReader xmlSecurityStreamReader = new XMLSecurityStreamReader(inputProcessorChain, securityProperties);
@@ -87,7 +87,7 @@ public void testPassThroughDocumentEvents() throws Exception {
public void testSkipThroughDocumentEvents() throws Exception {
XMLSecurityProperties securityProperties = new XMLSecurityProperties();
securityProperties.setSkipDocumentEvents(true);
- InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
+ InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl(securityProperties);
InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
inputProcessorChain.addProcessor(new EventReaderProcessor());
XMLSecurityStreamReader xmlSecurityStreamReader = new XMLSecurityStreamReader(inputProcessorChain, securityProperties);
@@ -98,7 +98,7 @@ public void testSkipThroughDocumentEvents() throws Exception {
@Test
public void testIdentityTransformSource() throws Exception {
XMLSecurityProperties securityProperties = new XMLSecurityProperties();
- InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
+ InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl(securityProperties);
InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
inputProcessorChain.addProcessor(new EventReaderProcessor());
XMLSecurityStreamReader xmlSecurityStreamReader = new XMLSecurityStreamReader(inputProcessorChain, securityProperties);
@@ -117,11 +117,11 @@ public void testDocumentDeclaration() throws Exception {
ByteArrayInputStream xmlInput = new ByteArrayInputStream(xml.getBytes(StandardCharsets.ISO_8859_1));
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLStreamReader stdXmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlInput);
- InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
- InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
- inputProcessorChain.addProcessor(new EventReaderProcessor(stdXmlStreamReader));
XMLSecurityProperties securityProperties = new XMLSecurityProperties();
securityProperties.setSkipDocumentEvents(false);
+ InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl(securityProperties);
+ InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
+ inputProcessorChain.addProcessor(new EventReaderProcessor(stdXmlStreamReader));
XMLSecurityStreamReader xmlSecurityStreamReader = new XMLSecurityStreamReader(inputProcessorChain, securityProperties);
advanceToFirstEvent(xmlSecurityStreamReader);
assertThat(xmlSecurityStreamReader.getEventType(), is(XMLStreamConstants.START_DOCUMENT));
@@ -148,11 +148,11 @@ public void testDocumentDeclarationWithoutOptionalAttributes() throws Exception
ByteArrayInputStream xmlInput = new ByteArrayInputStream(xml.getBytes(StandardCharsets.ISO_8859_1));
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLStreamReader stdXmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlInput);
- InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
- InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
- inputProcessorChain.addProcessor(new EventReaderProcessor(stdXmlStreamReader));
XMLSecurityProperties securityProperties = new XMLSecurityProperties();
securityProperties.setSkipDocumentEvents(false);
+ InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl(securityProperties);
+ InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
+ inputProcessorChain.addProcessor(new EventReaderProcessor(stdXmlStreamReader));
XMLSecurityStreamReader xmlSecurityStreamReader = new XMLSecurityStreamReader(inputProcessorChain, securityProperties);
advanceToFirstEvent(xmlSecurityStreamReader);
assertThat(xmlSecurityStreamReader.getEventType(), is(XMLStreamConstants.START_DOCUMENT));
@@ -169,11 +169,11 @@ public void testDocumentDeclarationWhenSkipDocumentEvents() throws Exception {
ByteArrayInputStream xmlInput = new ByteArrayInputStream(xml.getBytes(StandardCharsets.ISO_8859_1));
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLStreamReader stdXmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlInput);
- InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
- InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
- inputProcessorChain.addProcessor(new EventReaderProcessor(stdXmlStreamReader));
XMLSecurityProperties securityProperties = new XMLSecurityProperties();
securityProperties.setSkipDocumentEvents(true);
+ InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl(securityProperties);
+ InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
+ inputProcessorChain.addProcessor(new EventReaderProcessor(stdXmlStreamReader));
XMLSecurityStreamReader xmlSecurityStreamReader = new XMLSecurityStreamReader(inputProcessorChain, securityProperties);
advanceToFirstEvent(xmlSecurityStreamReader);
assertThat(xmlSecurityStreamReader.getEventType(), is(XMLStreamConstants.START_ELEMENT));
@@ -198,7 +198,7 @@ private static void advanceToFirstEvent(XMLStreamReader xmlStreamReader) throws
@Test
public void testCorrectness() throws Exception {
XMLSecurityProperties securityProperties = new XMLSecurityProperties();
- InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
+ InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl(securityProperties);
DocumentContextImpl documentContext = new DocumentContextImpl();
documentContext.setEncoding(StandardCharsets.UTF_8.name());
InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext, documentContext);
diff --git a/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamWriterTest.java b/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamWriterTest.java
index b2f395769d..fa956870c2 100644
--- a/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamWriterTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamWriterTest.java
@@ -63,7 +63,7 @@ public void setUp() throws Exception {
@Test
public void testIdentityTransformResult() throws Exception {
StringWriter securityStringWriter = new StringWriter();
- OutboundSecurityContextImpl securityContext = new OutboundSecurityContextImpl();
+ OutboundSecurityContextImpl securityContext = new OutboundSecurityContextImpl(new XMLSecurityProperties());
OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(securityContext);
outputProcessorChain.addProcessor(new EventWriterProcessor(securityStringWriter));
XMLSecurityStreamWriter xmlSecurityStreamWriter = new XMLSecurityStreamWriter(outputProcessorChain);
@@ -196,7 +196,7 @@ public Iterator getPrefixes(String namespaceURI) {
@Test
public void testNullPrefix() throws Exception {
StringWriter securityStringWriter = new StringWriter();
- OutboundSecurityContextImpl securityContext = new OutboundSecurityContextImpl();
+ OutboundSecurityContextImpl securityContext = new OutboundSecurityContextImpl(new XMLSecurityProperties());
OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(securityContext);
outputProcessorChain.addProcessor(new EventWriterProcessor(securityStringWriter));
XMLSecurityStreamWriter xmlSecurityStreamWriter = new XMLSecurityStreamWriter(outputProcessorChain);
diff --git a/src/test/java/org/apache/xml/security/test/stax/encryption/EncryptionCreationTest.java b/src/test/java/org/apache/xml/security/test/stax/encryption/EncryptionCreationTest.java
index 995bce64f6..f4184cc622 100644
--- a/src/test/java/org/apache/xml/security/test/stax/encryption/EncryptionCreationTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/encryption/EncryptionCreationTest.java
@@ -215,7 +215,7 @@ public void testExceptionOnElementToEncryptNotFound() throws Exception {
properties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
SecurePart securePart =
- new SecurePart(new QName("urn:example:po", "NotExistingElement"), SecurePart.Modifier.Content);
+ new SecurePart(new QName("urn:example:po", "NonExistingElement"), SecurePart.Modifier.Content);
properties.addEncryptionPart(securePart);
OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
@@ -233,7 +233,7 @@ public void testExceptionOnElementToEncryptNotFound() throws Exception {
fail("Exception expected");
} catch (XMLStreamException e) {
assertTrue(e.getCause() instanceof XMLSecurityException);
- assertEquals("Part to encrypt not found: {urn:example:po}NotExistingElement", e.getCause().getMessage());
+ assertEquals("Too few (0/1) elements found to encrypt: {urn:example:po}NonExistingElement", e.getCause().getMessage());
}
}
@@ -1718,7 +1718,7 @@ private void testEncryptionIdToEncrypt(SecurePart securePart) throws Exception {
"\n";
XMLSecurityProperties properties = new XMLSecurityProperties();
properties.setIdAttributeNS(new QName("attr1"));
- properties.setActions(Collections.singletonList(XMLSecurityConstants.ENCRYPT));
+ properties.setActions(Collections.singletonList(XMLSecurityConstants.ENCRYPTION));
properties.addEncryptionPart(securePart);
byte[] bits192 = "abcdefghijklmnopqrstuvwx".getBytes(StandardCharsets.US_ASCII);
SecretKey transportKey = new SecretKeySpec(bits192, "AES");
@@ -1751,7 +1751,7 @@ public void testEncryptionIdToSecureSupersedesName() throws Exception {
"\n";
XMLSecurityProperties properties = new XMLSecurityProperties();
properties.setIdAttributeNS(new QName("attr1"));
- properties.setActions(Collections.singletonList(XMLSecurityConstants.ENCRYPT));
+ properties.setActions(Collections.singletonList(XMLSecurityConstants.ENCRYPTION));
SecurePart securePart = new SecurePart(new QName("Branch1"), SecurePart.Modifier.Element);
securePart.setIdToSecure("def");
properties.addEncryptionPart(securePart);
diff --git a/src/test/java/org/apache/xml/security/test/stax/signature/AbstractSignatureCreationTest.java b/src/test/java/org/apache/xml/security/test/stax/signature/AbstractSignatureCreationTest.java
index cf76f2d6f1..9768db8326 100644
--- a/src/test/java/org/apache/xml/security/test/stax/signature/AbstractSignatureCreationTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/signature/AbstractSignatureCreationTest.java
@@ -35,6 +35,7 @@
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.signature.XMLSignatureInput;
import org.apache.xml.security.stax.ext.SecurePart;
+import org.apache.xml.security.stax.ext.SecurePartSelector;
import org.apache.xml.security.test.dom.DSNamespaceContext;
import org.apache.xml.security.test.stax.utils.XMLSecEventAllocator;
import org.apache.xml.security.utils.resolver.ResourceResolverContext;
@@ -46,6 +47,7 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import static org.apache.xml.security.test.stax.utils.TestUtils.toSecureParts;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -107,18 +109,18 @@ public void createXMLInputFactory() throws Exception {
protected void verifyUsingDOM(
Document document,
X509Certificate cert,
- List secureParts
+ List securePartSelectors
) throws Exception {
- verifyUsingDOM(document, cert, secureParts, null);
+ verifyUsingDOM(document, cert, securePartSelectors, null);
}
protected void verifyUsingDOM(
Document document,
X509Certificate cert,
- List secureParts,
+ List securePartSelectors,
boolean secureValidation
) throws Exception {
- verifyUsingDOM(document, cert, secureParts, null,
+ verifyUsingDOM(document, cert, securePartSelectors, null,
true, "Id", secureValidation);
}
@@ -128,10 +130,10 @@ protected void verifyUsingDOM(
protected void verifyUsingDOM(
Document document,
X509Certificate cert,
- List secureParts,
+ List securePartSelectors,
ResourceResolverSpi resourceResolverSpi
) throws Exception {
- verifyUsingDOM(document, cert, secureParts, resourceResolverSpi, true, "Id", true);
+ verifyUsingDOM(document, cert, securePartSelectors, resourceResolverSpi, true, "Id", true);
}
/**
@@ -140,12 +142,13 @@ protected void verifyUsingDOM(
protected void verifyUsingDOM(
Document document,
X509Certificate cert,
- List secureParts,
+ List securePartSelectors,
ResourceResolverSpi resourceResolverSpi,
boolean keyInfoRequired,
String idAttributeNS,
boolean secureValidation
) throws Exception {
+ List secureParts = toSecureParts(document, securePartSelectors);
XPath xpath = getXPath();
String expression = "//dsig:Signature[1]";
@@ -182,8 +185,9 @@ protected void verifyUsingDOM(
protected void verifyUsingDOM(
Document document,
Key key,
- List secureParts
+ List securePartSelectors
) throws Exception {
+ List secureParts = toSecureParts(document, securePartSelectors);
XPath xpath = getXPath();
String expression = "//dsig:Signature[1]";
@@ -206,8 +210,9 @@ protected void verifyUsingDOM(
protected void verifyUsingDOMWithoutId(
Document document,
Key key,
- List secureParts
+ List securePartSelectors
) throws Exception {
+ List secureParts = toSecureParts(document, securePartSelectors);
XPath xpath = getXPath();
String expression = "//dsig:Signature[1]";
@@ -234,8 +239,9 @@ protected void verifyUsingDOMWithoutId(
protected void verifyUsingDOMWithoutIdAndDefaultTransform (
Document document,
Key key,
- List secureParts
+ List securePartSelectors
) throws Exception {
+ List secureParts = toSecureParts(document, securePartSelectors);
XPath xpath = getXPath();
String expression = "//dsig:Signature[1]";
diff --git a/src/test/java/org/apache/xml/security/test/stax/signature/PKSignatureCreationTest.java b/src/test/java/org/apache/xml/security/test/stax/signature/PKSignatureCreationTest.java
index 51a0f81c57..529fc3c185 100644
--- a/src/test/java/org/apache/xml/security/test/stax/signature/PKSignatureCreationTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/signature/PKSignatureCreationTest.java
@@ -104,7 +104,7 @@ public void testRSA_SHA1() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -147,7 +147,7 @@ public void testRSA_SHA256() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -190,7 +190,7 @@ public void testRSA_SHA384() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -233,7 +233,7 @@ public void testRSA_SHA512() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -278,7 +278,7 @@ public void testRSA_RIPEMD160() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -323,7 +323,7 @@ public void testRSA_SHA1_MGF1() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -368,7 +368,7 @@ public void testRSA_SHA224_MGF1() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -413,7 +413,7 @@ public void testRSA_SHA256_MGF1() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -458,7 +458,7 @@ public void testRSA_SHA384_MGF1() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -503,7 +503,7 @@ public void testRSA_SHA512_MGF1() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -549,7 +549,7 @@ public void testRSA_SSA_PSS() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, rsaKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -592,7 +592,7 @@ public void testECDSA_SHA1() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -635,7 +635,7 @@ public void testECDSA_SHA224() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -678,7 +678,7 @@ public void testECDSA_SHA256() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -721,7 +721,7 @@ public void testECDSA_SHA384() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -764,7 +764,7 @@ public void testECDSA_SHA512() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
@Test
@@ -809,7 +809,7 @@ public void testECDSA_RIPEMD160() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignatureSecureParts());
+ verifyUsingDOM(document, ecKeyPair.getPublic(), properties.getSignaturePartSelectors());
}
diff --git a/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationReferenceURIResolverTest.java b/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationReferenceURIResolverTest.java
index 09aa7371c4..6b7fa17402 100644
--- a/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationReferenceURIResolverTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationReferenceURIResolverTest.java
@@ -108,7 +108,7 @@ public void testSignatureCreationWithExternalFilesystemXMLReference() throws Exc
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts(), false);
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors(), false);
}
@Test
@@ -159,7 +159,7 @@ public void testSignatureCreationWithExternalFilesystemBinaryReference() throws
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts(), false);
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors(), false);
}
@Test
@@ -217,7 +217,7 @@ public void testSignatureCreationWithExternalHttpReference() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts(), resolverDirectHTTP);
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors(), resolverDirectHTTP);
} finally {
HttpRequestRedirectorProxy.stopHttpEngine();
}
@@ -271,6 +271,6 @@ public void testSignatureCreationWithSameDocumentXPointerIdApostropheReference()
assertTrue(uri.startsWith("#xpointer"));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
}
\ No newline at end of file
diff --git a/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java b/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java
index 0d227b5c9f..96730ac1b8 100644
--- a/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java
@@ -64,6 +64,7 @@
import static org.apache.xml.security.stax.ext.XMLSecurityConstants.NS_C14N_EXCL;
import static org.apache.xml.security.stax.ext.XMLSecurityConstants.NS_XMLDSIG_ENVELOPED_SIGNATURE;
+import static org.apache.xml.security.test.stax.utils.TestUtils.toSecureParts;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -127,7 +128,7 @@ public void testSignatureCreation() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -180,7 +181,7 @@ public void testSignatureCreationRetrieveSignatureValue() throws Exception {
assertNotNull(sigValueEvent.getSignatureValue());
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -203,7 +204,7 @@ public void testExceptionOnElementToSignNotFound() throws Exception {
properties.setSignatureCerts(new X509Certificate[]{cert});
SecurePart securePart =
- new SecurePart(new QName("urn:example:po", "NotExistingElement"), SecurePart.Modifier.Content);
+ new SecurePart(new QName("urn:example:po", "NonExistingElement"), SecurePart.Modifier.Content);
properties.addSignaturePart(securePart);
OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
@@ -221,7 +222,7 @@ public void testExceptionOnElementToSignNotFound() throws Exception {
fail("Exception expected");
} catch (XMLStreamException e) {
assertTrue(e.getCause() instanceof XMLSecurityException);
- assertEquals("Part to sign not found: {urn:example:po}NotExistingElement", e.getCause().getMessage());
+ assertEquals("Too few (0/1) elements found to sign: {urn:example:po}NonExistingElement", e.getCause().getMessage());
}
}
@@ -286,7 +287,7 @@ public void testEnvelopedSignatureCreation() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -350,7 +351,7 @@ public void testEnvelopedSignatureCreationC14n11() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -414,7 +415,7 @@ public void testSignRootElementInRequest() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -527,7 +528,7 @@ private void signAtSpecificPosition(int position, QName positionQName, boolean s
assertEquals(childNode.getLocalName(), "Signature");
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -583,7 +584,7 @@ public void testIdAttributeNS() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts(), null, true, "ID", true);
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors(), null, true, "ID", true);
}
@@ -632,7 +633,7 @@ public void testMultipleElements() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -697,7 +698,7 @@ public void testMultipleSignatures() throws Exception {
(NodeList) xpath.evaluate(expression, document, XPathConstants.NODESET);
assertTrue(sigElements.getLength() == 2);
- for (SecurePart secPart : properties.getSignatureSecureParts()) {
+ for (SecurePart secPart : toSecureParts(document, properties.getSignaturePartSelectors())) {
if (secPart.getName() == null) {
continue;
}
@@ -752,7 +753,7 @@ public void testHMACSignatureCreation() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, key, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, key, properties.getSignaturePartSelectors());
}
@Test
@@ -800,7 +801,7 @@ public void testStrongSignatureCreation() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -863,7 +864,7 @@ public void testDSASignatureCreation() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -921,7 +922,7 @@ public void testECDSASignatureCreation() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -980,7 +981,7 @@ public void testStrongECDSASignatureCreation() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1027,7 +1028,7 @@ public void testDifferentC14nMethod() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1095,7 +1096,7 @@ public void testDifferentC14nMethodForReference() throws Exception {
assertEquals(XMLSecurityConstants.NS_XMLDSIG_SHA1, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1163,7 +1164,7 @@ public void testDifferentDigestMethodForReference() throws Exception {
assertEquals("http://www.w3.org/2001/04/xmlenc#sha256", element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1210,7 +1211,7 @@ public void testC14n11Method() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1263,7 +1264,7 @@ public void testExcC14nInclusivePrefixes() throws Exception {
assertEquals("", ((Element)nodeList.item(1)).getAttribute(XMLSecurityConstants.ATT_NULL_PrefixList.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1309,7 +1310,7 @@ public void testSignatureCreationRSAKeyValue() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1368,7 +1369,7 @@ public void testSignatureCreationECDSAKeyValue() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1423,7 +1424,7 @@ public void testSignatureCreationSKI() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1469,7 +1470,7 @@ public void testSignatureCreationX509Certificate() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1515,7 +1516,7 @@ public void testSignatureCreationX509SubjectName() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1565,7 +1566,7 @@ public void testSignatureCreationMultipleKeyIdentifiers() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1613,7 +1614,7 @@ public void testSignatureCreationTransformBase64() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1661,7 +1662,7 @@ public void testNoKeyInfo() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts(), null, false, "Id", true);
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors(), null, false, "Id", true);
}
@@ -1713,7 +1714,7 @@ public void testSignatureCreationKeyName() throws Exception {
assertEquals(cert.getIssuerDN().getName(), nodeList.item(0).getFirstChild().getTextContent());
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -1763,7 +1764,7 @@ public void testSignatureCreationWithoutId() throws Exception {
assertEquals(cert.getIssuerDN().getName(), nodeList.item(0).getFirstChild().getTextContent());
// Verify using DOM
- verifyUsingDOMWithoutId(document, cert.getPublicKey(), properties.getSignatureSecureParts());
+ verifyUsingDOMWithoutId(document, cert.getPublicKey(), properties.getSignaturePartSelectors());
}
@Test
@@ -1818,6 +1819,6 @@ public void testSignatureCreationWithoutOmittedDefaultTransform() throws Excepti
assertEquals(cert.getIssuerDN().getName(), nodeList.item(0).getFirstChild().getTextContent());
// Verify using DOM
- verifyUsingDOMWithoutIdAndDefaultTransform(document, cert.getPublicKey(), properties.getSignatureSecureParts());
+ verifyUsingDOMWithoutIdAndDefaultTransform(document, cert.getPublicKey(), properties.getSignaturePartSelectors());
}
}
diff --git a/src/test/java/org/apache/xml/security/test/stax/signature/SignatureDigestCreationTest.java b/src/test/java/org/apache/xml/security/test/stax/signature/SignatureDigestCreationTest.java
index 9f91975188..6ca64f52e6 100644
--- a/src/test/java/org/apache/xml/security/test/stax/signature/SignatureDigestCreationTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/signature/SignatureDigestCreationTest.java
@@ -105,7 +105,7 @@ public void testSHA1() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -160,7 +160,7 @@ public void testSHA224() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -215,7 +215,7 @@ public void testSHA256() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -270,7 +270,7 @@ public void testSHA384() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -325,7 +325,7 @@ public void testSHA512() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -382,7 +382,7 @@ public void testRIPEMD160() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -439,7 +439,7 @@ public void testWhirlpool() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -496,7 +496,7 @@ public void testSHA3_224() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -553,7 +553,7 @@ public void testSHA3_256() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -610,7 +610,7 @@ public void testSHA3_384() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
@Test
@@ -667,7 +667,7 @@ public void testSHA3_512() throws Exception {
assertEquals(digestAlgorithm, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
}
}
\ No newline at end of file
diff --git a/src/test/java/org/apache/xml/security/test/stax/signature/SignatureEncryptionTest.java b/src/test/java/org/apache/xml/security/test/stax/signature/SignatureEncryptionTest.java
index 649d584234..ffa989472b 100644
--- a/src/test/java/org/apache/xml/security/test/stax/signature/SignatureEncryptionTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/signature/SignatureEncryptionTest.java
@@ -123,7 +123,7 @@ public void testSignatureEncryption() throws Exception {
assertEquals(nodeList.getLength(), 1);
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getSignaturePartSelectors());
TestSecurityEventListener testSecurityEventListener =
verifyUsingStAX(baos.toByteArray(), encryptionKey, cert.getPublicKey());
@@ -192,7 +192,7 @@ public void testSignatureEncryptionSameElement() throws Exception {
assertEquals(nodeList.getLength(), 1);
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getEncryptionPartSelectors());
TestSecurityEventListener testSecurityEventListener =
verifyUsingStAX(baos.toByteArray(), encryptionKey, cert.getPublicKey());
@@ -269,7 +269,7 @@ public void testEnvelopedSignatureEncryptionElement() throws Exception {
assertEquals(nodeList.getLength(), 1);
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getEncryptionPartSelectors());
TestSecurityEventListener testSecurityEventListener =
verifyUsingStAX(baos.toByteArray(), encryptionKey, cert.getPublicKey());
@@ -346,7 +346,7 @@ public void testEnvelopedSignatureEncryptionContent() throws Exception {
assertEquals(nodeList.getLength(), 1);
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getEncryptionPartSelectors());
TestSecurityEventListener testSecurityEventListener =
verifyUsingStAX(baos.toByteArray(), encryptionKey, cert.getPublicKey());
@@ -415,7 +415,7 @@ public void testEncryptionSignature() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, cert, properties.getEncryptionPartSelectors());
// Decrypt using DOM API
Document doc =
diff --git a/src/test/java/org/apache/xml/security/test/stax/signature/SignatureHMACCreationTest.java b/src/test/java/org/apache/xml/security/test/stax/signature/SignatureHMACCreationTest.java
index dbddfb68bf..24c20cc204 100644
--- a/src/test/java/org/apache/xml/security/test/stax/signature/SignatureHMACCreationTest.java
+++ b/src/test/java/org/apache/xml/security/test/stax/signature/SignatureHMACCreationTest.java
@@ -89,7 +89,7 @@ public void testHMACSHA1() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, key, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, key, properties.getSignaturePartSelectors());
}
@Test
@@ -134,7 +134,7 @@ public void testHMACSHA_224() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, key, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, key, properties.getSignaturePartSelectors());
}
@Test
@@ -179,7 +179,7 @@ public void testHMACSHA_256() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, key, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, key, properties.getSignaturePartSelectors());
}
@Test
@@ -224,7 +224,7 @@ public void testHMACSHA_384() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, key, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, key, properties.getSignaturePartSelectors());
}
@Test
@@ -269,7 +269,7 @@ public void testHMACSHA_512() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, key, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, key, properties.getSignaturePartSelectors());
}
@Test
@@ -316,7 +316,7 @@ public void testRIPEMD160() throws Exception {
}
// Verify using DOM
- verifyUsingDOM(document, key, properties.getSignatureSecureParts());
+ verifyUsingDOM(document, key, properties.getSignaturePartSelectors());
}
diff --git a/src/test/java/org/apache/xml/security/test/stax/utils/TestUtils.java b/src/test/java/org/apache/xml/security/test/stax/utils/TestUtils.java
new file mode 100644
index 0000000000..24f44a9dfa
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/test/stax/utils/TestUtils.java
@@ -0,0 +1,153 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.test.stax.utils;
+
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.apache.xml.security.stax.ext.SecurePart;
+import org.apache.xml.security.stax.ext.SecurePartSelector;
+import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
+import org.apache.xml.security.stax.ext.stax.XMLSecNamespace;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
+import org.apache.xml.security.stax.impl.stax.XMLSecAttributeImpl;
+import org.apache.xml.security.stax.impl.stax.XMLSecNamespaceImpl;
+import org.apache.xml.security.stax.impl.stax.XMLSecStartElementImpl;
+import org.apache.xml.security.utils.KeyValue;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.DocumentTraversal;
+import org.w3c.dom.traversal.NodeFilter;
+import org.w3c.dom.traversal.TreeWalker;
+
+public class TestUtils {
+
+ public static List toSecureParts(Document document, List securePartSelectors) {
+ List secureParts = new ArrayList<>(securePartSelectors.size());
+ TreeWalker walker = ((DocumentTraversal) document).createTreeWalker(document.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);
+ Map elementsByNode = new IdentityHashMap<>();
+ for (Node node = walker.getCurrentNode(); node != null; node = walker.nextNode()) {
+ QName name = convertNodeToQName(node);
+ KeyValue, List> attributesAndNamespaces = convertNodeToAttributesAndNamespaces(node);
+ List attributes = attributesAndNamespaces.getKey();
+ List namespaces = attributesAndNamespaces.getValue();
+ XMLSecStartElement parent = elementsByNode.get(node.getParentNode());
+ XMLSecStartElement element = new XMLSecStartElementImpl(name, attributes, namespaces, parent);
+ elementsByNode.put(node, element);
+ for (SecurePartSelector securePartSelector : securePartSelectors) {
+ SecurePart securePart = securePartSelector.select(element);
+ if (securePart != null) {
+ secureParts.add(securePart);
+ break;
+ }
+ }
+ }
+ return secureParts;
+ }
+
+ public static Matcher containsRegex(String pattern) {
+ return containsRegex(pattern, true, 1);
+ }
+
+ public static Matcher containsRegex(Pattern pattern) {
+ return containsRegex(pattern, true, 1);
+ }
+
+ public static Matcher containsRegex(String pattern, int times) {
+ return containsRegex(pattern, false, times);
+ }
+
+ public static Matcher containsRegex(Pattern pattern, int times) {
+ return containsRegex(pattern, false, times);
+ }
+
+ public static Matcher containsRegex(String pattern, boolean atLeast, int times) {
+ return containsRegex(Pattern.compile(pattern), atLeast, times);
+ }
+
+ public static Matcher containsRegex(Pattern pattern, boolean atLeast, int times) {
+ return new TypeSafeDiagnosingMatcher() {
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a string containing the pattern ").appendValue(pattern)
+ .appendText(atLeast ? " at least " : " exactly ").appendValue(times).appendText(" times");
+ }
+
+ @Override
+ protected boolean matchesSafely(String actual, Description mismatchDescription) {
+ java.util.regex.Matcher matcher = pattern.matcher(actual);
+ int found = 0;
+ while (matcher.find()) {
+ found++;
+ }
+ boolean matches = atLeast ? found >= times : found == times;
+ if (!matches) {
+ mismatchDescription.appendText("the string was ").appendValue(actual);
+ }
+ return matches;
+ }
+ };
+ }
+
+ public static QName convertNodeToQName(Node node) {
+ String namespaceURI = node.getNamespaceURI();
+ if (namespaceURI == null) {
+ namespaceURI = XMLConstants.NULL_NS_URI;
+ }
+ String prefix = node.getPrefix();
+ if (prefix == null) {
+ prefix = XMLConstants.DEFAULT_NS_PREFIX;
+ }
+ String localName = node.getLocalName();
+ if (localName == null) {
+ throw new IllegalArgumentException("Local name is null, indicating that DOM level 2 is not supported while it is required. If created using a DocumentBuilder, be sure to setNamespaceAware(true).");
+ }
+ return new QName(namespaceURI, localName, prefix);
+ }
+
+ public static KeyValue, List> convertNodeToAttributesAndNamespaces(Node node) {
+ NamedNodeMap attributesAndNamespaces = node.getAttributes();
+ List attributes = new ArrayList<>(attributesAndNamespaces.getLength());
+ List namespaces = new ArrayList<>(attributesAndNamespaces.getLength());
+ for (int i = 0, n = attributesAndNamespaces.getLength(); i != n; i++) {
+ Attr attr = (Attr) attributesAndNamespaces.item(i);
+ if (attr.getName().equals("xmlns")) {
+ namespaces.add(XMLSecNamespaceImpl.getInstance(null, attr.getValue()));
+ } else if (attr.getName().startsWith("xmlns:")) {
+ namespaces.add(XMLSecNamespaceImpl.getInstance(attr.getName().substring(6), attr.getValue()));
+ } else {
+ QName name = convertNodeToQName(attr);
+ attributes.add(new XMLSecAttributeImpl(name, attr.getValue()));
+ }
+ }
+ return new KeyValue<>(attributes, namespaces);
+ }
+}
diff --git a/src/test/java/org/apache/xml/security/test/stax/utils/TestUtilsTest.java b/src/test/java/org/apache/xml/security/test/stax/utils/TestUtilsTest.java
new file mode 100644
index 0000000000..3753ee6ae7
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/test/stax/utils/TestUtilsTest.java
@@ -0,0 +1,77 @@
+package org.apache.xml.security.test.stax.utils;
+
+import java.io.StringReader;
+import java.util.List;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
+import org.apache.xml.security.stax.ext.stax.XMLSecNamespace;
+import org.apache.xml.security.utils.KeyValue;
+import org.junit.jupiter.api.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+import static org.apache.xml.security.test.stax.utils.TestUtils.convertNodeToAttributesAndNamespaces;
+import static org.apache.xml.security.test.stax.utils.TestUtils.convertNodeToQName;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+public class TestUtilsTest {
+
+ @Test
+ public void testConvertNodeToAttributesAndNamespace() throws Exception {
+ String xml = " ";
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ Document document = documentBuilderFactory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
+ Node node = document.getFirstChild();
+ QName name = convertNodeToQName(node);
+ assertThat(name.getLocalPart(), is(equalTo("localPart")));
+ assertThat(name.getNamespaceURI(), is(equalTo("urn:test:ns")));
+ assertThat(name.getPrefix(), is(equalTo("prefix")));
+ KeyValue, List> attributesAndNamespaces = convertNodeToAttributesAndNamespaces(node);
+ List attributes = attributesAndNamespaces.getKey();
+ List namespaces = attributesAndNamespaces.getValue();
+ assertThat(namespaces.size(), is(2));
+ int namespaceIndex1 = 0;
+ for (XMLSecNamespace namespace : namespaces) {
+ if (namespace.getPrefix().equals("prefix")) {
+ break;
+ }
+ namespaceIndex1++;
+ }
+ int namespaceIndex2 = (namespaceIndex1 + 1) % namespaces.size();
+ XMLSecNamespace namespace1 = namespaces.get(namespaceIndex1);
+ assertThat(namespace1.getPrefix(), is(equalTo("prefix")));
+ assertThat(namespace1.getNamespaceURI(), is(equalTo("urn:test:ns")));
+ assertThat(namespace1.isDefaultNamespaceDeclaration(), is(false));
+ XMLSecNamespace namespace2 = namespaces.get(namespaceIndex2);
+ assertThat(namespace2.getPrefix(), is(equalTo(XMLConstants.DEFAULT_NS_PREFIX)));
+ assertThat(namespace2.getNamespaceURI(), is(equalTo("urn:test:default-ns")));
+ assertThat(namespace2.isDefaultNamespaceDeclaration(), is(true));
+ assertThat(attributes.size(), is(2));
+ int attrIndex1 = 0;
+ for (XMLSecAttribute attribute : attributes) {
+ if (attribute.getValue().equals("val1")) {
+ break;
+ }
+ attrIndex1++;
+ }
+ int attrIndex2 = (attrIndex1 + 1) % attributes.size();
+ XMLSecAttribute attr1 = attributes.get(attrIndex1);
+ assertThat(attr1.getAttributeNamespace(), is(equalTo(namespace1)));
+ assertThat(attr1.getName().getLocalPart(), is(equalTo("attr1")));
+ assertThat(attr1.getName().getNamespaceURI(), is(equalTo("urn:test:ns")));
+ assertThat(attr1.getValue(), is(equalTo("val1")));
+ XMLSecAttribute attr2 = attributes.get(attrIndex2);
+ assertThat(attr2.getAttributeNamespace(), is(equalTo(namespace2)));
+ assertThat(attr2.getName().getLocalPart(), is(equalTo("attr2")));
+ assertThat(attr2.getName().getNamespaceURI(), is(equalTo(XMLConstants.NULL_NS_URI)));
+ assertThat(attr2.getValue(), is(equalTo("val2")));
+ }
+}