You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2012/01/20 19:51:24 UTC

svn commit: r1234064 - in /cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml: AbstractXmlSigInHandler.java XmlSigOutInterceptor.java

Author: coheigea
Date: Fri Jan 20 18:51:24 2012
New Revision: 1234064

URL: http://svn.apache.org/viewvc?rev=1234064&view=rev
Log:
Updating RS-Security code to work with Santuario 1.5

Modified:
    cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
    cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java

Modified: cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java?rev=1234064&r1=1234063&r2=1234064&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java (original)
+++ cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java Fri Jan 20 18:51:24 2012
@@ -27,6 +27,7 @@ import javax.xml.stream.XMLStreamReader;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.message.Message;
@@ -34,6 +35,7 @@ import org.apache.cxf.rs.security.common
 import org.apache.cxf.rs.security.common.TrustValidator;
 import org.apache.cxf.staxutils.W3CDOMStreamReader;
 import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.keys.KeyInfo;
@@ -86,7 +88,15 @@ public class AbstractXmlSigInHandler ext
         boolean valid = false;
         Reference ref = null;
         try {
-            XMLSignature signature = new XMLSignature(signatureElement, "");    
+            XMLSignature signature = new XMLSignature(signatureElement, "");
+            // TODO re-enable this line once we pick up xmlsec 1.5.0
+            // XMLSignature signature = new XMLSignature(signatureElement, "", true);  
+            ref = getReference(signature);
+            Element signedElement = validateReference(root, ref);
+            if (signedElement.hasAttributeNS(null, "ID")) {
+                signedElement.setIdAttributeNS(null, "ID", true);
+            }
+            
             // See also WSS4J SAMLUtil.getCredentialFromKeyInfo 
             KeyInfo keyInfo = signature.getKeyInfo();
             
@@ -99,14 +109,11 @@ public class AbstractXmlSigInHandler ext
                     valid = signature.checkSignatureValue(pk);
                 }
             }
-            // is this call redundant given that signature.checkSignatureValue uses References ?
-            ref = getReference(signature);
-            Element signedElement = validateReference(root, ref);
             
             // validate trust 
             new TrustValidator().validateTrust(crypto, cert, keyInfo.getPublicKey());
             
-            if (persistSignature) {
+            if (valid && persistSignature) {
                 message.setContent(XMLSignature.class, signature);
                 message.setContent(Element.class, signedElement);
             }
@@ -220,9 +227,84 @@ public class AbstractXmlSigInHandler ext
         String expectedID = ref.getURI().substring(1);
         
         if (!expectedID.equals(rootId)) {
-            return (Element)DOMUtils.findChildWithAtt(root, null, "ID", expectedID);
+            return findElementById(root, expectedID, true);
         } else {
             return root;
         }
     }
+    
+    /**
+     * Returns the single element that contains an Id with value
+     * <code>uri</code> and <code>namespace</code>. The Id can be either a wsu:Id or an Id
+     * with no namespace. This is a replacement for a XPath Id lookup with the given namespace. 
+     * It's somewhat faster than XPath, and we do not deal with prefixes, just with the real
+     * namespace URI
+     * 
+     * If checkMultipleElements is true and there are multiple elements, we log a 
+     * warning and return null as this can be used to get around the signature checking.
+     * 
+     * @param startNode Where to start the search
+     * @param value Value of the Id attribute
+     * @param checkMultipleElements If true then go through the entire tree and return 
+     *        null if there are multiple elements with the same Id
+     * @return The found element if there was exactly one match, or
+     *         <code>null</code> otherwise
+     */
+    private static Element findElementById(
+        Node startNode, String value, boolean checkMultipleElements
+    ) {
+        //
+        // Replace the formerly recursive implementation with a depth-first-loop lookup
+        //
+        Node startParent = startNode.getParentNode();
+        Node processedNode = null;
+        Element foundElement = null;
+        String id = value;
+
+        while (startNode != null) {
+            // start node processing at this point
+            if (startNode.getNodeType() == Node.ELEMENT_NODE) {
+                Element se = (Element) startNode;
+                // Try the wsu:Id first
+                String attributeNS = se.getAttributeNS(WSConstants.WSU_NS, "Id");
+                if ("".equals(attributeNS) || !id.equals(attributeNS)) {
+                    attributeNS = se.getAttributeNS(null, "Id");
+                }
+                if ("".equals(attributeNS) || !id.equals(attributeNS)) {
+                    attributeNS = se.getAttributeNS(null, "ID");
+                }
+                if (!"".equals(attributeNS) && id.equals(attributeNS)) {
+                    if (!checkMultipleElements) {
+                        return se;
+                    } else if (foundElement == null) {
+                        foundElement = se; // Continue searching to find duplicates
+                    } else {
+                        // Multiple elements with the same 'Id' attribute value
+                        return null;
+                    }
+                }
+            }
+
+            processedNode = startNode;
+            startNode = startNode.getFirstChild();
+
+            // no child, this node is done.
+            if (startNode == null) {
+                // close node processing, get sibling
+                startNode = processedNode.getNextSibling();
+            }
+            // no more siblings, get parent, all children
+            // of parent are processed.
+            while (startNode == null) {
+                processedNode = processedNode.getParentNode();
+                if (processedNode == startParent) {
+                    return foundElement;
+                }
+                // close parent node processing (processed node now)
+                startNode = processedNode.getNextSibling();
+            }
+        }
+        return foundElement;
+    }
+    
 }

Modified: cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java?rev=1234064&r1=1234063&r2=1234064&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java (original)
+++ cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java Fri Jan 20 18:51:24 2012
@@ -163,7 +163,8 @@ public class XmlSigOutInterceptor extend
         newDoc.adoptNode(docEl);
         Element object = newDoc.createElementNS(Constants.SignatureSpecNS, "ds:Object");
         object.appendChild(docEl);
-        object.setAttribute("ID", id);
+        docEl.setAttributeNS(null, "ID", id);
+        docEl.setIdAttributeNS(null, "ID", true);  
         
         XMLSignature sig = new XMLSignature(newDoc, "", sigAlgo);
         newDoc.appendChild(sig.getElement());
@@ -184,7 +185,8 @@ public class XmlSigOutInterceptor extend
         Document newDoc = DOMUtils.createDocument();
         doc.removeChild(docEl);
         newDoc.adoptNode(docEl);
-        docEl.setAttribute("ID", id);
+        docEl.setAttributeNS(null, "ID", id);
+        docEl.setIdAttributeNS(null, "ID", true);  
         
         Element root = newDoc.createElementNS(envelopeQName.getNamespaceURI(), 
                 envelopeQName.getPrefix() + ":" + envelopeQName.getLocalPart());
@@ -205,7 +207,8 @@ public class XmlSigOutInterceptor extend
             String id, 
             String referenceURI,
             String sigAlgo) throws Exception {
-        doc.getDocumentElement().setAttribute("ID", id);    
+        doc.getDocumentElement().setAttributeNS(null, "ID", id);
+        doc.getDocumentElement().setIdAttributeNS(null, "ID", true);    
     
         XMLSignature sig = new XMLSignature(doc, "", sigAlgo);
         doc.getDocumentElement().appendChild(sig.getElement());