Skip to content
This repository was archived by the owner on May 26, 2020. It is now read-only.

Commit 61de37c

Browse files
committed
SANTUARIO-532 Introduced ElementSelector + SecurePartFactory
1 parent 83ea8fa commit 61de37c

File tree

56 files changed

+1566
-372
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1566
-372
lines changed

pom.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@
541541
<targetJdk>1.8</targetJdk>
542542
<clirr.version>2.8</clirr.version>
543543
<maven-owasp-plugin-version>5.2.4</maven-owasp-plugin-version>
544+
<mockito.version>3.3.0</mockito.version>
544545

545546
<!-- Allow Clirr severity to be overriden by the command-line option -DminSeverity=level -->
546547
<minSeverity>info</minSeverity>
@@ -577,6 +578,12 @@
577578
<version>${junit.version}</version>
578579
<scope>test</scope>
579580
</dependency>
581+
<dependency>
582+
<groupId>org.junit.jupiter</groupId>
583+
<artifactId>junit-jupiter-params</artifactId>
584+
<version>${junit.version}</version>
585+
<scope>test</scope>
586+
</dependency>
580587
<dependency>
581588
<groupId>org.xmlunit</groupId>
582589
<artifactId>xmlunit-core</artifactId>
@@ -646,6 +653,12 @@
646653
<version>0.7.2</version>
647654
<scope>test</scope>
648655
</dependency>
656+
<dependency>
657+
<groupId>org.mockito</groupId>
658+
<artifactId>mockito-junit-jupiter</artifactId>
659+
<version>${mockito.version}</version>
660+
<scope>test</scope>
661+
</dependency>
649662
</dependencies>
650663

651664
<distributionManagement>

src/main/java/org/apache/xml/security/resource/xmlsecurity_de.properties

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,13 @@ stax.unsupportedKeyTransp = Der public-key Algorithmus ist zu kurz um den symmet
189189
stax.recursiveKeyReference = Rekursive Schl\u00fcssel referenzierung detektiert.
190190
stax.ecParametersNotSupported = ECParameters werden nicht unterst\u00fctzt.
191191
stax.namedCurveMissing = NamedCurve fehlt.
192-
stax.encryption.securePartNotFound = Part zum Verschl\u00fcsseln nicht gefunden: {0}
193-
stax.signature.securePartNotFound = Part zum Signieren nicht gefunden: {0}
194-
stax.multipleSignaturesNotSupported = Mehrere Signaturen werden nicht unterstützt.
192+
stax.encryption.tooFewOccurrences = Zu wenige ({0}/{1}) Elemente gefunden zum Verschl\u00fcsslen: {2}
193+
stax.encryption.tooManyOccurrences = Zu viele ({0}/{1}) Elemente gefunden zum Verschl\u00fcsslen: {2}
194+
stax.signature.tooFewOccurrences = Zu wenige ({0}/{1}) Elemente gefunden zum Signieren: {2}
195+
stax.signature.tooManyOccurrences = Zu viele ({0}/{1}) Elemente gefunden zum Signieren: {2}
196+
stax.multipleSignaturesNotSupported = Mehrere Signaturen werden nicht unterst\u00fctzt.
195197
stax.signature.keyNameMissing = KeyName nicht konfiguriert.
196-
stax.keyNotFoundForName = Kein Schl\u00fcssel für Schl\u00fcsselname konfiguriert: {0}
198+
stax.keyNotFoundForName = Kein Schl\u00fcssel f\u00fcr Schl\u00fcsselname konfiguriert: {0}
197199
stax.keyTypeNotSupported = Key vom Typ {0} nicht f\u00fcr einen Key-Namenssuche unterst\u00fctzt
198200
stax.idsetbutnotgenerated = An Id attribute is specified, but Id generation is disabled
199201
stax.idgenerationdisablewithmultipleparts = Id generation must not be disabled when multiple parts need signing

src/main/java/org/apache/xml/security/resource/xmlsecurity_en.properties

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,10 @@ stax.unsupportedKeyTransp = public key algorithm too weak to encrypt symmetric k
189189
stax.recursiveKeyReference = Recursive key reference detected.
190190
stax.ecParametersNotSupported = ECParameters not supported.
191191
stax.namedCurveMissing = NamedCurve is missing.
192-
stax.encryption.securePartNotFound = Part to encrypt not found: {0}
193-
stax.signature.securePartNotFound = Part to sign not found: {0}
192+
stax.encryption.tooFewOccurrences = Too few ({0}/{1}) elements found to encrypt: {2}
193+
stax.encryption.tooManyOccurrences = Too many ({0}/{1}) elements found to encrypt: {2}
194+
stax.signature.tooFewOccurrences = Too few ({0}/{1}) elements found to sign: {2}
195+
stax.signature.tooManyOccurrences = Too many ({0}/{1}) elements found to sign: {2}
194196
stax.multipleSignaturesNotSupported = Multiple signatures are not supported.
195197
stax.signature.keyNameMissing = KeyName not configured.
196198
stax.keyNotFoundForName = No key configured for KeyName: {0}

src/main/java/org/apache/xml/security/stax/ext/AbstractOutputProcessor.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@
2222
import java.util.Collections;
2323
import java.util.HashSet;
2424
import java.util.List;
25-
import java.util.Map;
2625
import java.util.Set;
2726

2827
import javax.xml.namespace.QName;
2928
import javax.xml.stream.XMLStreamException;
30-
import javax.xml.stream.events.Attribute;
3129

3230
import org.apache.xml.security.exceptions.XMLSecurityException;
3331
import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
@@ -37,6 +35,7 @@
3735
import org.apache.xml.security.stax.ext.stax.XMLSecEventFactory;
3836
import org.apache.xml.security.stax.ext.stax.XMLSecNamespace;
3937
import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
38+
import org.apache.xml.security.utils.KeyValue;
4039
import org.w3c.dom.Attr;
4140
import org.w3c.dom.Element;
4241
import org.w3c.dom.NamedNodeMap;
@@ -230,24 +229,25 @@ protected void outputAsEvent(OutputProcessorChain outputProcessorChain, XMLSecEv
230229
outputProcessorChain.processEvent(xmlSecEvent);
231230
}
232231

233-
protected SecurePart securePartMatches(XMLSecStartElement xmlSecStartElement,
234-
OutputProcessorChain outputProcessorChain, String dynamicParts) {
235-
Map<Object, SecurePart> dynamicSecureParts = outputProcessorChain.getSecurityContext().getAsMap(dynamicParts);
236-
return securePartMatches(xmlSecStartElement, dynamicSecureParts);
232+
protected KeyValue<SecurePartSelector, SecurePart> securePartMatches(XMLSecStartElement xmlSecStartElement,
233+
OutputProcessorChain outputProcessorChain,
234+
String dynamicPartSelectors) {
235+
OutboundSecurityContext securityContext = outputProcessorChain.getSecurityContext();
236+
List<SecurePartSelector> dynamicSecurePartSelectors = securityContext.get(dynamicPartSelectors);
237+
return securePartMatches(xmlSecStartElement, dynamicSecurePartSelectors);
237238
}
238239

239-
protected SecurePart securePartMatches(XMLSecStartElement xmlSecStartElement, Map<Object, SecurePart> secureParts) {
240-
SecurePart securePart = null;
241-
if (secureParts != null) {
242-
securePart = secureParts.get(xmlSecStartElement.getName());
243-
if (securePart == null) {
244-
Attribute attribute = xmlSecStartElement.getAttributeByName(securityProperties.getIdAttributeNS());
245-
if (attribute != null) {
246-
securePart = secureParts.get(attribute.getValue());
240+
protected KeyValue<SecurePartSelector, SecurePart> securePartMatches(XMLSecStartElement xmlSecStartElement,
241+
List<SecurePartSelector> securePartSelectors) {
242+
if (securePartSelectors != null) {
243+
for (SecurePartSelector securePartSelector : securePartSelectors) {
244+
SecurePart securePart = securePartSelector.select(xmlSecStartElement);
245+
if (securePart != null) {
246+
return new KeyValue<>(securePartSelector, securePart);
247247
}
248248
}
249249
}
250-
return securePart;
250+
return null;
251251
}
252252

253253
protected void outputDOMElement(Element element, OutputProcessorChain outputProcessorChain)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.apache.xml.security.stax.ext;
2+
3+
import java.util.function.Supplier;
4+
5+
import javax.xml.namespace.QName;
6+
import javax.xml.stream.events.Attribute;
7+
8+
import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
9+
10+
import static java.util.Objects.requireNonNull;
11+
12+
/**
13+
* Selects an element to secure based on a given value of a supplied attribute name.
14+
*/
15+
public class ByAttributeElementSelector implements ElementSelector {
16+
17+
private final Supplier<QName> nameSupplier;
18+
private final String value;
19+
20+
ByAttributeElementSelector(Supplier<QName> nameSupplier, String value) {
21+
requireNonNull(value, "value is null");
22+
this.nameSupplier = nameSupplier;
23+
this.value = value;
24+
}
25+
26+
public ByAttributeElementSelector(QName name, String value) {
27+
this(() -> name, value);
28+
}
29+
30+
@Override
31+
public boolean select(XMLSecStartElement element) {
32+
if (element != null) {
33+
QName name = nameSupplier.get();
34+
if (name != null) {
35+
Attribute attribute = element.getAttributeByName(name);
36+
if (attribute != null && value.equals(attribute.getValue())) {
37+
return true;
38+
}
39+
}
40+
}
41+
return false;
42+
}
43+
44+
@Override
45+
public String toString() {
46+
return "//*[@" + nameSupplier.get() + "='" + value + "']";
47+
}
48+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.apache.xml.security.stax.ext;
2+
3+
import javax.xml.namespace.QName;
4+
5+
import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
6+
7+
import static java.util.Objects.requireNonNull;
8+
9+
/**
10+
* This class selects XML elements by name.
11+
*/
12+
public class ByNameElementSelector implements ElementSelector {
13+
14+
private final QName name;
15+
16+
public ByNameElementSelector(QName name) {
17+
requireNonNull(name, "name is null");
18+
this.name = name;
19+
}
20+
21+
@Override
22+
public boolean select(XMLSecStartElement element) {
23+
return element != null && element.getName().equals(name);
24+
}
25+
26+
@Override
27+
public String toString() {
28+
return "//" + name;
29+
}
30+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.apache.xml.security.stax.ext;
2+
3+
import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
4+
5+
/**
6+
* This singleton selects the document element.
7+
*/
8+
public class DocumentElementSelector implements ElementSelector {
9+
10+
private static class LazilyLoaded {
11+
12+
@SuppressWarnings("PMD.AccessorClassGeneration")
13+
private static final DocumentElementSelector INSTANCE = new DocumentElementSelector();
14+
}
15+
16+
private DocumentElementSelector() {
17+
}
18+
19+
@Override
20+
public boolean select(XMLSecStartElement element) {
21+
return element == null;
22+
}
23+
24+
@Override
25+
public String toString() {
26+
return "/";
27+
}
28+
29+
public static DocumentElementSelector getInstance() {
30+
return LazilyLoaded.INSTANCE;
31+
}
32+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.xml.security.stax.ext;
20+
21+
import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
22+
23+
/**
24+
* This interface allows implementors to select <i>which</i> elements to secure, based on an element's qualified name
25+
* and skeleton DOM element.
26+
*/
27+
public interface ElementSelector {
28+
29+
/**
30+
* Selects a given element for securing, or {@code null} to indicate the document element (the document as a whole).
31+
* In practice, the element {@code null} is used to select secure parts that define external references to be
32+
* digested.
33+
*
34+
* @param element The element to select, possibly {@code null}.
35+
* @return {@code true} to select the given element for securing, {@code false} otherwise.
36+
*/
37+
boolean select(XMLSecStartElement element);
38+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.apache.xml.security.stax.ext;
2+
3+
public interface ElementSelectorFactory {
4+
5+
ElementSelector createElementSelector();
6+
}

src/main/java/org/apache/xml/security/stax/ext/InboundXMLSec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public XMLStreamReader processInMessage(
115115
requestSecurityEvents = Collections.emptyList();
116116
}
117117

118-
final InboundSecurityContextImpl inboundSecurityContext = new InboundSecurityContextImpl();
118+
final InboundSecurityContextImpl inboundSecurityContext = new InboundSecurityContextImpl(securityProperties);
119119
inboundSecurityContext.putList(SecurityEvent.class, requestSecurityEvents);
120120
inboundSecurityContext.addSecurityEventListener(securityEventListener);
121121

0 commit comments

Comments
 (0)