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

Commit

Permalink
SANTUARIO-532 Introduced ElementSelector + SecurePartFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
peterdemaeyer committed May 22, 2020
1 parent 83ea8fa commit 61de37c
Show file tree
Hide file tree
Showing 56 changed files with 1,566 additions and 372 deletions.
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@
<targetJdk>1.8</targetJdk>
<clirr.version>2.8</clirr.version>
<maven-owasp-plugin-version>5.2.4</maven-owasp-plugin-version>
<mockito.version>3.3.0</mockito.version>

<!-- Allow Clirr severity to be overriden by the command-line option -DminSeverity=level -->
<minSeverity>info</minSeverity>
Expand Down Expand Up @@ -577,6 +578,12 @@
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.xmlunit</groupId>
<artifactId>xmlunit-core</artifactId>
Expand Down Expand Up @@ -646,6 +653,12 @@
<version>0.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<distributionManagement>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,13 @@ stax.unsupportedKeyTransp = Der public-key Algorithmus ist zu kurz um den symmet
stax.recursiveKeyReference = Rekursive Schl\u00fcssel referenzierung detektiert.
stax.ecParametersNotSupported = ECParameters werden nicht unterst\u00fctzt.
stax.namedCurveMissing = NamedCurve fehlt.
stax.encryption.securePartNotFound = Part zum Verschl\u00fcsseln nicht gefunden: {0}
stax.signature.securePartNotFound = Part zum Signieren nicht gefunden: {0}
stax.multipleSignaturesNotSupported = Mehrere Signaturen werden nicht unterstützt.
stax.encryption.tooFewOccurrences = Zu wenige ({0}/{1}) Elemente gefunden zum Verschl\u00fcsslen: {2}
stax.encryption.tooManyOccurrences = Zu viele ({0}/{1}) Elemente gefunden zum Verschl\u00fcsslen: {2}
stax.signature.tooFewOccurrences = Zu wenige ({0}/{1}) Elemente gefunden zum Signieren: {2}
stax.signature.tooManyOccurrences = Zu viele ({0}/{1}) Elemente gefunden zum Signieren: {2}
stax.multipleSignaturesNotSupported = Mehrere Signaturen werden nicht unterst\u00fctzt.
stax.signature.keyNameMissing = KeyName nicht konfiguriert.
stax.keyNotFoundForName = Kein Schl\u00fcssel für Schl\u00fcsselname konfiguriert: {0}
stax.keyNotFoundForName = Kein Schl\u00fcssel f\u00fcr Schl\u00fcsselname konfiguriert: {0}
stax.keyTypeNotSupported = Key vom Typ {0} nicht f\u00fcr einen Key-Namenssuche unterst\u00fctzt
stax.idsetbutnotgenerated = An Id attribute is specified, but Id generation is disabled
stax.idgenerationdisablewithmultipleparts = Id generation must not be disabled when multiple parts need signing
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,10 @@ stax.unsupportedKeyTransp = public key algorithm too weak to encrypt symmetric k
stax.recursiveKeyReference = Recursive key reference detected.
stax.ecParametersNotSupported = ECParameters not supported.
stax.namedCurveMissing = NamedCurve is missing.
stax.encryption.securePartNotFound = Part to encrypt not found: {0}
stax.signature.securePartNotFound = Part to sign not found: {0}
stax.encryption.tooFewOccurrences = Too few ({0}/{1}) elements found to encrypt: {2}
stax.encryption.tooManyOccurrences = Too many ({0}/{1}) elements found to encrypt: {2}
stax.signature.tooFewOccurrences = Too few ({0}/{1}) elements found to sign: {2}
stax.signature.tooManyOccurrences = Too many ({0}/{1}) elements found to sign: {2}
stax.multipleSignaturesNotSupported = Multiple signatures are not supported.
stax.signature.keyNameMissing = KeyName not configured.
stax.keyNotFoundForName = No key configured for KeyName: {0}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;

import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
Expand All @@ -37,6 +35,7 @@
import org.apache.xml.security.stax.ext.stax.XMLSecEventFactory;
import org.apache.xml.security.stax.ext.stax.XMLSecNamespace;
import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
import org.apache.xml.security.utils.KeyValue;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
Expand Down Expand Up @@ -230,24 +229,25 @@ protected void outputAsEvent(OutputProcessorChain outputProcessorChain, XMLSecEv
outputProcessorChain.processEvent(xmlSecEvent);
}

protected SecurePart securePartMatches(XMLSecStartElement xmlSecStartElement,
OutputProcessorChain outputProcessorChain, String dynamicParts) {
Map<Object, SecurePart> dynamicSecureParts = outputProcessorChain.getSecurityContext().getAsMap(dynamicParts);
return securePartMatches(xmlSecStartElement, dynamicSecureParts);
protected KeyValue<SecurePartSelector, SecurePart> securePartMatches(XMLSecStartElement xmlSecStartElement,
OutputProcessorChain outputProcessorChain,
String dynamicPartSelectors) {
OutboundSecurityContext securityContext = outputProcessorChain.getSecurityContext();
List<SecurePartSelector> dynamicSecurePartSelectors = securityContext.get(dynamicPartSelectors);
return securePartMatches(xmlSecStartElement, dynamicSecurePartSelectors);
}

protected SecurePart securePartMatches(XMLSecStartElement xmlSecStartElement, Map<Object, SecurePart> secureParts) {
SecurePart securePart = null;
if (secureParts != null) {
securePart = secureParts.get(xmlSecStartElement.getName());
if (securePart == null) {
Attribute attribute = xmlSecStartElement.getAttributeByName(securityProperties.getIdAttributeNS());
if (attribute != null) {
securePart = secureParts.get(attribute.getValue());
protected KeyValue<SecurePartSelector, SecurePart> securePartMatches(XMLSecStartElement xmlSecStartElement,
List<SecurePartSelector> securePartSelectors) {
if (securePartSelectors != null) {
for (SecurePartSelector securePartSelector : securePartSelectors) {
SecurePart securePart = securePartSelector.select(xmlSecStartElement);
if (securePart != null) {
return new KeyValue<>(securePartSelector, securePart);
}
}
}
return securePart;
return null;
}

protected void outputDOMElement(Element element, OutputProcessorChain outputProcessorChain)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.apache.xml.security.stax.ext;

import java.util.function.Supplier;

import javax.xml.namespace.QName;
import javax.xml.stream.events.Attribute;

import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;

import static java.util.Objects.requireNonNull;

/**
* Selects an element to secure based on a given value of a supplied attribute name.
*/
public class ByAttributeElementSelector implements ElementSelector {

private final Supplier<QName> nameSupplier;
private final String value;

ByAttributeElementSelector(Supplier<QName> nameSupplier, String value) {
requireNonNull(value, "value is null");
this.nameSupplier = nameSupplier;
this.value = value;
}

public ByAttributeElementSelector(QName name, String value) {
this(() -> name, value);
}

@Override
public boolean select(XMLSecStartElement element) {
if (element != null) {
QName name = nameSupplier.get();
if (name != null) {
Attribute attribute = element.getAttributeByName(name);
if (attribute != null && value.equals(attribute.getValue())) {
return true;
}
}
}
return false;
}

@Override
public String toString() {
return "//*[@" + nameSupplier.get() + "='" + value + "']";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.apache.xml.security.stax.ext;

import javax.xml.namespace.QName;

import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;

import static java.util.Objects.requireNonNull;

/**
* This class selects XML elements by name.
*/
public class ByNameElementSelector implements ElementSelector {

private final QName name;

public ByNameElementSelector(QName name) {
requireNonNull(name, "name is null");
this.name = name;
}

@Override
public boolean select(XMLSecStartElement element) {
return element != null && element.getName().equals(name);
}

@Override
public String toString() {
return "//" + name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.apache.xml.security.stax.ext;

import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;

/**
* This singleton selects the document element.
*/
public class DocumentElementSelector implements ElementSelector {

private static class LazilyLoaded {

@SuppressWarnings("PMD.AccessorClassGeneration")
private static final DocumentElementSelector INSTANCE = new DocumentElementSelector();
}

private DocumentElementSelector() {
}

@Override
public boolean select(XMLSecStartElement element) {
return element == null;
}

@Override
public String toString() {
return "/";
}

public static DocumentElementSelector getInstance() {
return LazilyLoaded.INSTANCE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* 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;

/**
* This interface allows implementors to select <i>which</i> elements to secure, based on an element's qualified name
* and skeleton DOM element.
*/
public interface ElementSelector {

/**
* Selects a given element for securing, or {@code null} to indicate the document element (the document as a whole).
* In practice, the element {@code null} is used to select secure parts that define external references to be
* digested.
*
* @param element The element to select, possibly {@code null}.
* @return {@code true} to select the given element for securing, {@code false} otherwise.
*/
boolean select(XMLSecStartElement element);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.apache.xml.security.stax.ext;

public interface ElementSelectorFactory {

ElementSelector createElementSelector();
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public XMLStreamReader processInMessage(
requestSecurityEvents = Collections.emptyList();
}

final InboundSecurityContextImpl inboundSecurityContext = new InboundSecurityContextImpl();
final InboundSecurityContextImpl inboundSecurityContext = new InboundSecurityContextImpl(securityProperties);
inboundSecurityContext.putList(SecurityEvent.class, requestSecurityEvents);
inboundSecurityContext.addSecurityEventListener(securityEventListener);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.apache.xml.security.stax.ext;

import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;

public class NoElementSelector implements ElementSelector {

private static class LazilyLoaded {

@SuppressWarnings("PMD.AccessorClassGeneration")
private static final NoElementSelector INSTANCE = new NoElementSelector();
}

private NoElementSelector() {
}

@Override
public boolean select(XMLSecStartElement element) {
return false;
}

@Override
public String toString() {
return "";
}

public static NoElementSelector getInstance() {
return LazilyLoaded.INSTANCE;
}
}
Loading

0 comments on commit 61de37c

Please sign in to comment.