Repository: cxf
Updated Branches:
  refs/heads/master 6c118849e -> dc8b98085


[CXF-6209][CXF-6210] - Bug in processing Signed/Encrypted Elements policies 
with multiple XPaths
 - XPath evaluation failure on the client side causes all subsequent 
evaluations to fail


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/dc8b9808
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/dc8b9808
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/dc8b9808

Branch: refs/heads/master
Commit: dc8b98085c95692cd632047c2d4f8d222c78bfb7
Parents: 6c11884
Author: Colm O hEigeartaigh <cohei...@apache.org>
Authored: Tue Jan 20 15:04:00 2015 +0000
Committer: Colm O hEigeartaigh <cohei...@apache.org>
Committed: Tue Jan 20 15:04:29 2015 +0000

----------------------------------------------------------------------
 .../wss4j/PolicyBasedWSS4JInInterceptor.java    | 12 +--
 .../policyhandlers/AbstractBindingBuilder.java  | 82 ++++++++++----------
 .../policyhandlers/TransportBindingHandler.java | 14 +---
 .../apache/cxf/systest/ws/parts/PartsTest.java  | 50 ++++++++++++
 .../cxf/systest/ws/parts/DoubleItParts.wsdl     |  3 +
 .../org/apache/cxf/systest/ws/parts/client.xml  | 15 ++++
 .../multiple-encrypted-elements-policy.xml      | 48 ++++++++++++
 .../org/apache/cxf/systest/ws/parts/server.xml  | 14 ++++
 8 files changed, 183 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
 
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
index f118eeb..fd636c3 100644
--- 
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
+++ 
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
@@ -555,15 +555,17 @@ public class PolicyBasedWSS4JInInterceptor extends 
WSS4JInInterceptor {
                 if (elements != null && elements.getXPaths() != null 
                     && !elements.getXPaths().isEmpty()) {
                     List<String> expressions = new ArrayList<String>();
+                    MapNamespaceContext namespaceContext = new 
MapNamespaceContext();
+                    
                     for (org.apache.wss4j.policy.model.XPath xPath : 
elements.getXPaths()) {
                         expressions.add(xPath.getXPath());
+                        Map<String, String> namespaceMap = 
xPath.getPrefixNamespaceMap();
+                        if (namespaceMap != null) {
+                            namespaceContext.addNamespaces(namespaceMap);
+                        }
                     }
 
-                    if (elements.getXPaths().get(0).getPrefixNamespaceMap() != 
null) {
-                        xpath.setNamespaceContext(
-                            new 
MapNamespaceContext(elements.getXPaths().get(0).getPrefixNamespaceMap())
-                        );
-                    }
+                    xpath.setNamespaceContext(namespaceContext);
                     try {
                         CryptoCoverageUtil.checkCoverage(soapEnvelope, refs,
                                                          xpath, expressions, 
type, scope);

http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
 
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
index 87e6cb6..a697e41 100644
--- 
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
+++ 
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
@@ -1194,21 +1194,12 @@ public abstract class AbstractBindingBuilder extends 
AbstractCommonBindingHandle
         // Handle sign/enc parts
         result.addAll(this.getParts(sign, includeBody, parts, found));
         
-        
         // Handle sign/enc elements
-        try {
-            result.addAll(this.getElements("Element", xpaths, found, sign));
-        } catch (XPathExpressionException e) {
-            LOG.log(Level.FINE, e.getMessage(), e);
-            // REVISIT
-        }
+        result.addAll(this.getElements("Element", xpaths, found, sign));
         
-        // Handle content encrypted elements
-        try {
+        if (!sign) {
+            // Handle content encrypted elements
             result.addAll(this.getElements("Content", contentXpaths, found, 
sign));
-        } catch (XPathExpressionException e) {
-            LOG.log(Level.FINE, e.getMessage(), e);
-            // REVISIT
         }
         
         return result;
@@ -1323,7 +1314,7 @@ public abstract class AbstractBindingBuilder extends 
AbstractCommonBindingHandle
     protected List<WSEncryptionPart> getElements(String encryptionModifier,
             List<org.apache.wss4j.policy.model.XPath> xpaths, 
             List<Element> found,
-            boolean forceId) throws XPathExpressionException, SOAPException {
+            boolean forceId) throws SOAPException {
         
         List<WSEncryptionPart> result = new ArrayList<WSEncryptionPart>();
         
@@ -1335,33 +1326,27 @@ public abstract class AbstractBindingBuilder extends 
AbstractCommonBindingHandle
                     xpath.setNamespaceContext(new 
MapNamespaceContext(xPath.getPrefixNamespaceMap()));
                 }
                
-                NodeList list = (NodeList)xpath.evaluate(xPath.getXPath(), 
saaj.getSOAPPart().getEnvelope(),
-                                               XPathConstants.NODESET);
-                for (int x = 0; x < list.getLength(); x++) {
-                    Element el = (Element)list.item(x);
-                    
-                    if (!found.contains(el)) {
-                        String id = null;
-                        if (forceId) {
-                            id = this.addWsuIdToElement(el);
-                        } else {
-                            //not forcing an ID on this.  Use one if there is 
one 
-                            //there already, but don't force one
-                            Attr idAttr = el.getAttributeNodeNS(null, "Id");
-                            if (idAttr == null) {
-                                //then try the wsu:Id value
-                                idAttr = 
el.getAttributeNodeNS(PolicyConstants.WSU_NAMESPACE_URI, "Id");
-                            }
-                            if (idAttr != null) {
-                                id = idAttr.getValue();
-                            }
-                        }
-                        WSEncryptionPart part = 
-                            new WSEncryptionPart(id, encryptionModifier);
-                        part.setElement(el);
-                        part.setXpath(xPath.getXPath());
+                NodeList list = null;
+                try {
+                    list = (NodeList)xpath.evaluate(xPath.getXPath(), 
saaj.getSOAPPart().getEnvelope(),
+                                                             
XPathConstants.NODESET);
+                } catch (XPathExpressionException e) {
+                    LOG.log(Level.WARNING, "Failure in evaluating an XPath 
expression", e);
+                }
+                
+                if (list != null) {
+                    for (int x = 0; x < list.getLength(); x++) {
+                        Element el = (Element)list.item(x);
                         
-                        result.add(part);
+                        if (!found.contains(el)) {
+                            String id = setIdOnElement(el, forceId);
+                            WSEncryptionPart part = 
+                                new WSEncryptionPart(id, encryptionModifier);
+                            part.setElement(el);
+                            part.setXpath(xPath.getXPath());
+                            
+                            result.add(part);
+                        }
                     }
                 }
             }
@@ -1370,6 +1355,25 @@ public abstract class AbstractBindingBuilder extends 
AbstractCommonBindingHandle
         return result;
     }
     
+    private String setIdOnElement(Element element, boolean forceId) {
+        if (forceId) {
+            return this.addWsuIdToElement(element);
+        }
+        
+        //not forcing an ID on this.  Use one if there is one 
+        //there already, but don't force one
+        Attr idAttr = element.getAttributeNodeNS(null, "Id");
+        if (idAttr == null) {
+            //then try the wsu:Id value
+            idAttr = 
element.getAttributeNodeNS(PolicyConstants.WSU_NAMESPACE_URI, "Id");
+        }
+        if (idAttr != null) {
+            return idAttr.getValue();
+        }
+        
+        return null;
+    }
+    
     protected WSSecEncryptedKey getEncryptedKeyBuilder(AbstractTokenWrapper 
wrapper, 
                                                        AbstractToken token) 
throws WSSecurityException {
         WSSecEncryptedKey encrKey = new WSSecEncryptedKey(wssConfig);

http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
 
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
index bc90e3c..5947969 100644
--- 
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
+++ 
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
@@ -28,7 +28,6 @@ import java.util.logging.Level;
 import javax.xml.crypto.dsig.Reference;
 import javax.xml.soap.SOAPException;
 import javax.xml.soap.SOAPMessage;
-import javax.xml.xpath.XPathExpressionException;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -639,16 +638,9 @@ public class TransportBindingHandler extends 
AbstractBindingBuilder {
         
         if (signedElements != null) {
             // Handle SignedElements
-            try {
-                result.addAll(
-                    this.getElements(
-                        "Element", signedElements.getXPaths(), found, true
-                    )
-                );
-            } catch (XPathExpressionException e) {
-                LOG.log(Level.FINE, e.getMessage(), e);
-                // REVISIT
-            }
+            result.addAll(
+                this.getElements("Element", signedElements.getXPaths(), found, 
true)
+            );
         }
 
         return result;

http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/parts/PartsTest.java
----------------------------------------------------------------------
diff --git 
a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/parts/PartsTest.java
 
b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/parts/PartsTest.java
index b1bbeb1..1b0b3b8 100644
--- 
a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/parts/PartsTest.java
+++ 
b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/parts/PartsTest.java
@@ -436,6 +436,56 @@ public class PartsTest extends 
AbstractBusClientServerTestBase {
     }
     
     @org.junit.Test
+    public void testMultipleEncryptedElements() throws Exception {
+        
+        if (test.isStreaming() || STAX_PORT.equals(test.getPort())) {
+            return;
+        }
+
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = PartsTest.class.getResource("client.xml");
+
+        Bus bus = bf.createBus(busFile.toString());
+        SpringBusFactory.setDefaultBus(bus);
+        SpringBusFactory.setThreadDefaultBus(bus);
+
+        URL wsdl = PartsTest.class.getResource("DoubleItParts.wsdl");
+        Service service = Service.create(wsdl, SERVICE_QNAME);
+       
+        // Successful invocation
+        QName portQName = new QName(NAMESPACE, 
"DoubleItEncryptedElementsPort3");
+        DoubleItPortType port = service.getPort(portQName, 
DoubleItPortType.class);
+        updateAddressPort(port, test.getPort());
+        
+        if (test.isStreaming()) {
+            SecurityTestUtil.enableStreaming(port);
+        }
+        
+        port.doubleIt(25);
+        
+        // This should fail, as the service requires that the header must be 
encrypted
+        portQName = new QName(NAMESPACE, "DoubleItEncryptedElementsPort2");
+        port = service.getPort(portQName, DoubleItPortType.class);
+        updateAddressPort(port, test.getPort());
+        
+        if (test.isStreaming()) {
+            SecurityTestUtil.enableStreaming(port);
+        }
+        
+        try {
+            port.doubleIt(25);
+            fail("Failure expected on a header which isn't encrypted");
+        } catch (javax.xml.ws.soap.SOAPFaultException ex) {
+            String error = "EncryptedElements";
+            assertTrue(ex.getMessage().contains(error)
+                       || ex.getMessage().contains("To must be encrypted"));
+        }
+        
+        ((java.io.Closeable)port).close();
+        bus.shutdown(true);
+    }
+    
+    @org.junit.Test
     public void testContentEncryptedElements() throws Exception {
 
         SpringBusFactory bf = new SpringBusFactory();

http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl
----------------------------------------------------------------------
diff --git 
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl
 
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl
index 2981c36..645def6 100644
--- 
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl
+++ 
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl
@@ -100,6 +100,9 @@
         <wsdl:port name="DoubleItEncryptedElementsPort2" 
binding="tns:DoubleItStandardBinding">
             <soap:address 
location="http://localhost:9010/DoubleItEncryptedElements2"/>
         </wsdl:port>
+        <wsdl:port name="DoubleItEncryptedElementsPort3" 
binding="tns:DoubleItStandardBinding">
+            <soap:address 
location="http://localhost:9010/DoubleItEncryptedElements3"/>
+        </wsdl:port>
         <wsdl:port name="DoubleItContentEncryptedElementsPort" 
binding="tns:DoubleItStandardBinding">
             <soap:address 
location="http://localhost:9010/DoubleItContentEncryptedElements"/>
         </wsdl:port>

http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/client.xml
----------------------------------------------------------------------
diff --git 
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/client.xml
 
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/client.xml
index d49de99..6aa97be 100644
--- 
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/client.xml
+++ 
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/client.xml
@@ -234,6 +234,21 @@
             </p:policies>
         </jaxws:features>
     </jaxws:client>
+    <jaxws:client 
name="{http://www.example.org/contract/DoubleIt}DoubleItEncryptedElementsPort3"; 
createdFromAPI="true">
+        <jaxws:properties>
+            <entry key="ws-security.username" value="Alice"/>
+            <entry key="ws-security.callback-handler" 
value="org.apache.cxf.systest.ws.common.UTPasswordCallback"/>
+            <entry key="ws-security.encryption.properties" 
value="bob.properties"/>
+            <entry key="ws-security.encryption.username" value="bob"/>
+            <entry key="ws-security.signature.properties" 
value="alice.properties"/>
+            <entry key="ws-security.signature.username" value="alice"/>
+        </jaxws:properties>
+        <jaxws:features>
+            <p:policies>
+                <wsp:PolicyReference 
xmlns:wsp="http://www.w3.org/ns/ws-policy"; 
URI="classpath:/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml"/>
+            </p:policies>
+        </jaxws:features>
+    </jaxws:client>
     <jaxws:client 
name="{http://www.example.org/contract/DoubleIt}DoubleItContentEncryptedElementsPort";
 createdFromAPI="true">
         <jaxws:properties>
             <entry key="ws-security.username" value="Alice"/>

http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml
----------------------------------------------------------------------
diff --git 
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml
 
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml
new file mode 100644
index 0000000..a75f6fd
--- /dev/null
+++ 
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<wsp:Policy 
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
 xmlns:wsp="http://www.w3.org/ns/ws-policy"; wsu:Id="RequiredPartsPolicy">
+    <wsp:ExactlyOne>
+        <wsp:All>
+            <sp:AsymmetricBinding 
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702";>
+                <wsp:Policy>
+                    <sp:InitiatorToken>
+                        <wsp:Policy>
+                            <sp:X509Token 
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient";>
+                                <wsp:Policy>
+                                    <sp:WssX509V3Token10/>
+                                </wsp:Policy>
+                            </sp:X509Token>
+                        </wsp:Policy>
+                    </sp:InitiatorToken>
+                    <sp:RecipientToken>
+                        <wsp:Policy>
+                            <sp:X509Token 
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never";>
+                                <wsp:Policy>
+                                    <sp:WssX509V3Token10/>
+                                    <sp:RequireIssuerSerialReference/>
+                                </wsp:Policy>
+                            </sp:X509Token>
+                        </wsp:Policy>
+                    </sp:RecipientToken>
+                    <sp:Layout>
+                        <wsp:Policy>
+                            <sp:Lax/>
+                        </wsp:Policy>
+                    </sp:Layout>
+                    <sp:AlgorithmSuite>
+                        <wsp:Policy>
+                            <sp:Basic128/>
+                        </wsp:Policy>
+                    </sp:AlgorithmSuite>
+                </wsp:Policy>
+            </sp:AsymmetricBinding>
+            <sp:EncryptedElements 
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702";>
+                <sp:XPath xmlns:wsa="http://www.w3.org/2005/08/addressing"; 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/";>/soap:Envelope/soap:Header/wsa:To</sp:XPath>
+                <sp:XPath 
xmlns:example1="http://www.example.org/schema/DoubleIt";>//example1:DoubleIt</sp:XPath>
+            </sp:EncryptedElements>
+            <sp:SignedParts 
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702";>
+                <sp:Body/>
+            </sp:SignedParts>
+            <wsaws:UsingAddressing 
xmlns:wsaws="http://www.w3.org/2006/05/addressing/wsdl"/>
+        </wsp:All>
+    </wsp:ExactlyOne>
+</wsp:Policy>

http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/server.xml
----------------------------------------------------------------------
diff --git 
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/server.xml
 
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/server.xml
index 6616f10..40f10f1 100644
--- 
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/server.xml
+++ 
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/server.xml
@@ -212,6 +212,20 @@
             </p:policies>
         </jaxws:features>
     </jaxws:endpoint>
+    <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt"; 
id="EncryptedElements3" 
address="http://localhost:${testutil.ports.Server}/DoubleItEncryptedElements3"; 
serviceName="s:DoubleItService" endpointName="s:DoubleItEncryptedElementsPort3" 
implementor="org.apache.cxf.systest.ws.common.DoubleItImpl" 
wsdlLocation="org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl">
+        <jaxws:properties>
+            <entry key="ws-security.callback-handler" 
value="org.apache.cxf.systest.ws.common.UTPasswordCallback"/>
+            <entry key="ws-security.signature.properties" 
value="bob.properties"/>
+            <entry key="ws-security.encryption.username" value="alice"/>
+            <entry key="ws-security.encryption.properties" 
value="alice.properties"/>
+            <entry key="ws-security.subject.cert.constraints" 
value=".*O=apache.org.*"/>
+        </jaxws:properties>
+        <jaxws:features>
+            <p:policies>
+                <wsp:PolicyReference 
xmlns:wsp="http://www.w3.org/ns/ws-policy"; 
URI="classpath:/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml"/>
+            </p:policies>
+        </jaxws:features>
+    </jaxws:endpoint>
     <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt"; 
id="ContentEncryptedElements" 
address="http://localhost:${testutil.ports.Server}/DoubleItContentEncryptedElements";
 serviceName="s:DoubleItService" 
endpointName="s:DoubleItContentEncryptedElementsPort" 
implementor="org.apache.cxf.systest.ws.common.DoubleItImpl" 
wsdlLocation="org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl">
         <jaxws:properties>
             <entry key="ws-security.callback-handler" 
value="org.apache.cxf.systest.ws.common.UTPasswordCallback"/>

Reply via email to