You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2016/01/05 16:35:50 UTC

svn commit: r1723098 - /webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java

Author: coheigea
Date: Tue Jan  5 15:35:49 2016
New Revision: 1723098

URL: http://svn.apache.org/viewvc?rev=1723098&view=rev
Log:
[WSS-563] - Cannot decrypt non XML conform attachements

Modified:
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java?rev=1723098&r1=1723097&r2=1723098&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java Tue Jan  5 15:35:49 2016
@@ -34,9 +34,11 @@ import org.apache.xml.security.encryptio
 import org.apache.xml.security.encryption.XMLEncryptionException;
 import org.apache.xml.security.exceptions.Base64DecodingException;
 import org.apache.xml.security.utils.Base64;
+import org.apache.xml.security.utils.JavaUtils;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.xml.sax.SAXException;
 
@@ -49,6 +51,7 @@ import javax.security.auth.callback.Unsu
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.ParserConfigurationException;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.NoSuchAlgorithmException;
@@ -359,12 +362,27 @@ public final class EncryptionUtils {
         InputStream attachmentInputStream =
                 AttachmentUtils.setupAttachmentDecryptionStream(
                         symEncAlgo, cipher, symmetricKey, attachment.getSourceStream());
-
+        
         // For the xop:Include case, we need to replace the xop:Include Element with the
         // decrypted Element
         DocumentBuilder db =
                 org.apache.xml.security.utils.XMLUtils.createDocumentBuilder(false);
-        Document document = db.parse(attachmentInputStream);
+        byte[] bytes = JavaUtils.getBytesFromStream(attachmentInputStream);
+
+        Document document = null;
+        try {
+            document = db.parse(new ByteArrayInputStream(bytes));
+        } catch (SAXException ex) {
+            // See if a prefix was not bound. Try to fix the DOM Element in this case.
+            if (ex.getMessage() != null && ex.getMessage().startsWith("The prefix")
+                && ex.getMessage().endsWith("is not bound.")) {
+                String fixedElementStr = setParentPrefixes(encData, new String(bytes));
+                document = db.parse(new ByteArrayInputStream(fixedElementStr.getBytes()));
+            } else {
+                throw ex;
+            }
+        }
+        
         Node decryptedNode =
             encData.getOwnerDocument().importNode(document.getDocumentElement(), true);
         encData.getParentNode().appendChild(decryptedNode);
@@ -373,6 +391,39 @@ public final class EncryptionUtils {
         return decryptedNode;
     }
 
+    /**
+     * Set the parent prefix definitions on the "String" (representation of the Element to be parsed)
+     */
+    private static String setParentPrefixes(Element target, String str) {
+        Node parent = target;
+        
+        // Get the point at where to insert new prefix definitions
+        int insertionIndex = str.indexOf('>');
+        StringBuilder prefix = new StringBuilder(str.substring(0, insertionIndex));
+        StringBuilder suffix = new StringBuilder(str.substring(insertionIndex, str.length()));
+        
+        // Don't add more than 20 prefixes
+        int prefixAddedCount = 0;
+        while (parent.getParentNode() != null && prefixAddedCount < 20
+            && !(Node.DOCUMENT_NODE == parent.getParentNode().getNodeType())) {
+            parent = parent.getParentNode();
+            NamedNodeMap attributes = parent.getAttributes();
+            for (int i = 0; i < attributes.getLength(); i++) {
+                Node attribute = attributes.item(i);
+                String attrDef = "xmlns:" + attribute.getLocalName();
+                if (WSConstants.XMLNS_NS.equals(attribute.getNamespaceURI()) && !prefix.toString().contains(attrDef)) {
+                    attrDef += "=\"" + attribute.getNodeValue() + "\"";
+                    prefix.append(" " + attrDef);
+                    prefixAddedCount++;
+                }
+                if (prefixAddedCount >= 20) {
+                    break;
+                }
+            }
+        }
+
+        return prefix.toString() + suffix.toString();
+    }
 
     /**
      * @param decryptedNode the decrypted node