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 2015/05/22 16:34:20 UTC

svn commit: r1681129 - in /webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src: main/java/org/apache/wss4j/dom/ main/java/org/apache/wss4j/dom/processor/ main/java/org/apache/wss4j/dom/util/ test/java/org/apache/wss4j/dom/message/

Author: coheigea
Date: Fri May 22 14:34:20 2015
New Revision: 1681129

URL: http://svn.apache.org/r1681129
Log:
Initial support added to the DOM code to support xop:Include processing


Conflicts:
	ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java
	ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java
	ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
	ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
	ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java

Added:
    webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java
    webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java
      - copied, changed from r1680507, webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java
    webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java
Removed:
    webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java
Modified:
    webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java
    webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java
    webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
    webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
    webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
    webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java

Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java Fri May 22 14:34:20 2015
@@ -102,6 +102,7 @@ public final class WSConstants {
         "http://docs.oasis-open.org/wss/oasis-wss-SwAProfile-1.1#Attachment-Content-Only";
     public static final String SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE =
         "http://docs.oasis-open.org/wss/oasis-wss-SwAProfile-1.1#Attachment-Complete";
+    public static final String XOP_NS = "http://www.w3.org/2004/08/xop/include";
     
     public static final String KEYTRANSPORT_RSA15 = 
         "http://www.w3.org/2001/04/xmlenc#rsa-1_5";

Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java Fri May 22 14:34:20 2015
@@ -45,7 +45,9 @@ import org.apache.wss4j.dom.bsp.BSPEnfor
 import org.apache.wss4j.dom.handler.RequestData;
 import org.apache.wss4j.dom.str.STRParser;
 import org.apache.wss4j.dom.str.SecurityTokenRefSTRParser;
+import org.apache.wss4j.dom.util.EncryptionUtils;
 import org.apache.wss4j.dom.util.WSSecurityUtil;
+import org.apache.wss4j.dom.util.X509Util;
 
 /**
  * This will process incoming <code>xenc:EncryptedData</code> elements.
@@ -141,7 +143,7 @@ public class EncryptedDataProcessor impl
             algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
         }
 
-        WSDataRef dataRef = ReferenceListProcessor.decryptEncryptedData(
+        WSDataRef dataRef = EncryptionUtils.decryptEncryptedData(
                 elem.getOwnerDocument(), encryptedDataId, elem, key, symEncAlgo, request);
 
         WSSecurityEngineResult result =

Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java Fri May 22 14:34:20 2015
@@ -20,6 +20,7 @@
 package org.apache.wss4j.dom.processor;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
@@ -34,6 +35,9 @@ import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.OAEPParameterSpec;
 import javax.crypto.spec.PSource;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -43,6 +47,8 @@ import org.apache.wss4j.common.bsp.BSPRu
 import org.apache.wss4j.common.crypto.AlgorithmSuite;
 import org.apache.wss4j.common.crypto.AlgorithmSuiteValidator;
 import org.apache.wss4j.common.crypto.CryptoType;
+import org.apache.wss4j.common.ext.Attachment;
+import org.apache.wss4j.common.ext.AttachmentRequestCallback;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.util.KeyUtils;
 import org.apache.wss4j.dom.WSConstants;
@@ -55,10 +61,13 @@ import org.apache.wss4j.dom.message.toke
 import org.apache.wss4j.dom.message.token.SecurityTokenReference;
 import org.apache.wss4j.dom.str.EncryptedKeySTRParser;
 import org.apache.wss4j.dom.str.STRParser;
+import org.apache.wss4j.dom.util.EncryptionUtils;
 import org.apache.wss4j.dom.util.WSSecurityUtil;
+import org.apache.wss4j.dom.util.X509Util;
 import org.apache.xml.security.algorithms.JCEMapper;
 import org.apache.xml.security.exceptions.Base64DecodingException;
 import org.apache.xml.security.utils.Base64;
+import org.apache.xml.security.utils.JavaUtils;
 
 public class EncryptedKeyProcessor implements Processor {
     private static final org.slf4j.Logger LOG = 
@@ -204,8 +213,16 @@ public class EncryptedKeyProcessor imple
         
         byte[] encryptedEphemeralKey = null;
         byte[] decryptedBytes = null;
+        
         try {
-            encryptedEphemeralKey = getDecodedBase64EncodedData(xencCipherValue);
+            // Get the key bytes from CipherValue directly or via an attachment
+            String xopUri = EncryptionUtils.getXOPURIFromCipherValue(xencCipherValue);
+            if (xopUri != null && xopUri.startsWith("cid:")) {
+                encryptedEphemeralKey = getDecryptedKeyBytesFromAttachment(xopUri, data);
+            } else {
+                encryptedEphemeralKey = getDecodedBase64EncodedData(xencCipherValue);
+            }
+            
             String keyAlgorithm = JCEMapper.translateURItoJCEID(encryptedKeyTransportMethod);
             decryptedBytes = cipher.unwrap(encryptedEphemeralKey, keyAlgorithm, Cipher.SECRET_KEY).getEncoded();
         } catch (IllegalStateException ex) {
@@ -238,6 +255,40 @@ public class EncryptedKeyProcessor imple
         return java.util.Collections.singletonList(result);
     }
     
+    private byte[] getDecryptedKeyBytesFromAttachment(
+        String xopUri, RequestData data
+    ) throws WSSecurityException {
+        CallbackHandler attachmentCallbackHandler = data.getAttachmentCallbackHandler();
+        if (attachmentCallbackHandler == null) {
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
+        }
+
+        final String attachmentId = xopUri.substring(4);
+
+        AttachmentRequestCallback attachmentRequestCallback = new AttachmentRequestCallback();
+        attachmentRequestCallback.setAttachmentId(attachmentId);
+
+        try {
+            attachmentCallbackHandler.handle(new Callback[]{attachmentRequestCallback});
+            
+            List<Attachment> attachments = attachmentRequestCallback.getAttachments();
+            if (attachments == null || attachments.isEmpty() || !attachmentId.equals(attachments.get(0).getId())) {
+                throw new WSSecurityException(
+                    WSSecurityException.ErrorCode.INVALID_SECURITY,
+                    "empty", new Object[] {"Attachment not found"}
+                );
+            }
+            Attachment attachment = attachments.get(0);
+            InputStream inputStream = attachment.getSourceStream();
+            
+            return JavaUtils.getBytesFromStream(inputStream);
+        } catch (UnsupportedCallbackException e) {
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+        } catch (IOException e) {
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+        }
+    }
+    
     /**
      * Generates a random secret key using the algorithm specified in the
      * first DataReference URI
@@ -253,7 +304,7 @@ public class EncryptedKeyProcessor imple
             int size = 16;
             if (!dataRefURIs.isEmpty()) {
                 String uri = dataRefURIs.iterator().next();
-                Element ee = ReferenceListProcessor.findEncryptedDataElement(doc, wsDocInfo, uri);
+                Element ee = EncryptionUtils.findEncryptedDataElement(doc, wsDocInfo, uri);
                 String algorithmURI = X509Util.getEncAlgo(ee);
                 alg = JCEMapper.getJCEKeyAlgorithmFromURI(algorithmURI);
                 size = KeyUtils.getKeyLength(algorithmURI);
@@ -524,7 +575,7 @@ public class EncryptedKeyProcessor imple
         // Find the encrypted data element referenced by dataRefURI
         //
         Element encryptedDataElement = 
-            ReferenceListProcessor.findEncryptedDataElement(doc, docInfo, dataRefURI);
+            EncryptionUtils.findEncryptedDataElement(doc, docInfo, dataRefURI);
         if (encryptedDataElement != null && data.isRequireSignedEncryptedDataElements()) {
             List<WSSecurityEngineResult> signedResults = 
                 docInfo.getResultsByTag(WSConstants.SIGN);
@@ -567,7 +618,7 @@ public class EncryptedKeyProcessor imple
             algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
         }
 
-        return ReferenceListProcessor.decryptEncryptedData(
+        return EncryptionUtils.decryptEncryptedData(
             doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo, data
         );
     }

Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java Fri May 22 14:34:20 2015
@@ -19,31 +19,18 @@
 
 package org.apache.wss4j.dom.processor;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.NoSuchAlgorithmException;
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import javax.crypto.Cipher;
-import javax.crypto.NoSuchPaddingException;
 import javax.crypto.SecretKey;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.apache.wss4j.common.ext.Attachment;
-import org.apache.wss4j.common.ext.AttachmentRequestCallback;
-import org.apache.wss4j.common.ext.AttachmentResultCallback;
-import org.apache.wss4j.common.util.AttachmentUtils;
-import org.apache.xml.security.algorithms.JCEMapper;
-import org.w3c.dom.Attr;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
+
 import org.apache.wss4j.common.bsp.BSPRule;
 import org.apache.wss4j.common.crypto.AlgorithmSuite;
 import org.apache.wss4j.common.crypto.AlgorithmSuiteValidator;
@@ -56,14 +43,12 @@ import org.apache.wss4j.dom.WSDocInfo;
 import org.apache.wss4j.dom.WSSecurityEngineResult;
 import org.apache.wss4j.dom.bsp.BSPEnforcer;
 import org.apache.wss4j.dom.handler.RequestData;
-import org.apache.wss4j.dom.message.CallbackLookup;
-import org.apache.wss4j.dom.message.DOMCallbackLookup;
 import org.apache.wss4j.dom.message.token.SecurityTokenReference;
 import org.apache.wss4j.dom.str.STRParser;
 import org.apache.wss4j.dom.str.SecurityTokenRefSTRParser;
+import org.apache.wss4j.dom.util.EncryptionUtils;
 import org.apache.wss4j.dom.util.WSSecurityUtil;
-import org.apache.xml.security.encryption.XMLCipher;
-import org.apache.xml.security.encryption.XMLEncryptionException;
+import org.apache.wss4j.dom.util.X509Util;
 
 public class ReferenceListProcessor implements Processor {
     private static final org.slf4j.Logger LOG = 
@@ -141,7 +126,8 @@ public class ReferenceListProcessor impl
         //
         // Find the encrypted data element referenced by dataRefURI
         //
-        Element encryptedDataElement = findEncryptedDataElement(doc, wsDocInfo, dataRefURI);
+        Element encryptedDataElement = 
+            EncryptionUtils.findEncryptedDataElement(doc, wsDocInfo, dataRefURI);
         
         if (encryptedDataElement != null && data.isRequireSignedEncryptedDataElements()) {
             List<WSSecurityEngineResult> signedResults = 
@@ -208,7 +194,7 @@ public class ReferenceListProcessor impl
         }
 
         return 
-            decryptEncryptedData(
+            EncryptionUtils.decryptEncryptedData(
                 doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo, data
             );
     }
@@ -258,269 +244,5 @@ public class ReferenceListProcessor impl
         }
     }
 
-    /**
-     * Look up the encrypted data. First try Id="someURI". If no such Id then try 
-     * wsu:Id="someURI".
-     * 
-     * @param doc The document in which to find EncryptedData
-     * @param wsDocInfo The WSDocInfo object to use
-     * @param dataRefURI The URI of EncryptedData
-     * @return The EncryptedData element
-     * @throws WSSecurityException if the EncryptedData element referenced by dataRefURI is 
-     * not found
-     */
-    public static Element
-    findEncryptedDataElement(
-        Document doc,
-        WSDocInfo wsDocInfo,
-        String dataRefURI
-    ) throws WSSecurityException {
-        CallbackLookup callbackLookup = wsDocInfo.getCallbackLookup();
-        if (callbackLookup == null) {
-            callbackLookup = new DOMCallbackLookup(doc);
-        }
-        Element encryptedDataElement = 
-            callbackLookup.getElement(dataRefURI, null, true);
-        if (encryptedDataElement == null) {
-            throw new WSSecurityException(
-                WSSecurityException.ErrorCode.INVALID_SECURITY, "dataRef", 
-                new Object[] {dataRefURI});
-        }
-        if (encryptedDataElement.getLocalName().equals(WSConstants.ENCRYPTED_HEADER)
-            && encryptedDataElement.getNamespaceURI().equals(WSConstants.WSSE11_NS)) {
-            Node child = encryptedDataElement.getFirstChild();
-            while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
-                child = child.getNextSibling();
-            }
-            return (Element)child;
-        }
-        return encryptedDataElement;
-    }
-
-    
-    /**
-     * Decrypt the EncryptedData argument using a SecretKey.
-     * @param doc The (document) owner of EncryptedData
-     * @param dataRefURI The URI of EncryptedData
-     * @param encData The EncryptedData element
-     * @param symmetricKey The SecretKey with which to decrypt EncryptedData
-     * @param symEncAlgo The symmetric encryption algorithm to use
-     * @throws WSSecurityException
-     */
-    public static WSDataRef
-    decryptEncryptedData(
-        Document doc,
-        String dataRefURI,
-        Element encData,
-        SecretKey symmetricKey,
-        String symEncAlgo,
-        RequestData requestData
-    ) throws WSSecurityException {
-
-        WSDataRef dataRef = new WSDataRef();
-        dataRef.setEncryptedElement(encData);
-        dataRef.setWsuId(dataRefURI);
-        dataRef.setAlgorithm(symEncAlgo);
-
-        String typeStr = encData.getAttributeNS(null, "Type");
-        if (typeStr != null &&
-            (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_CONTENT_ONLY.equals(typeStr) ||
-            WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr))) {
-
-            try {
-                Element cipherData = WSSecurityUtil.getDirectChildElement(encData, "CipherData", WSConstants.ENC_NS);
-                if (cipherData == null) {
-                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
-                }
-                Element cipherReference = WSSecurityUtil.getDirectChildElement(cipherData, "CipherReference", WSConstants.ENC_NS);
-                if (cipherReference == null) {
-                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
-                }
-                String uri = cipherReference.getAttributeNS(null, "URI");
-                if (uri == null || uri.length() < 5) {
-                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
-                }
-                if (!uri.startsWith("cid:")) {
-                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
-                }
-                dataRef.setWsuId(uri);
-                dataRef.setAttachment(true);
-
-                CallbackHandler attachmentCallbackHandler = requestData.getAttachmentCallbackHandler();
-                if (attachmentCallbackHandler == null) {
-                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
-                }
-
-                final String attachmentId = uri.substring(4);
-
-                AttachmentRequestCallback attachmentRequestCallback = new AttachmentRequestCallback();
-                attachmentRequestCallback.setAttachmentId(attachmentId);
-
-                attachmentCallbackHandler.handle(new Callback[]{attachmentRequestCallback});
-                List<Attachment> attachments = attachmentRequestCallback.getAttachments();
-                if (attachments == null || attachments.isEmpty() || !attachmentId.equals(attachments.get(0).getId())) {
-                    throw new WSSecurityException(
-                            WSSecurityException.ErrorCode.INVALID_SECURITY,
-                            "empty", new Object[] {"Attachment not found"}
-                    );
-                }
-                Attachment attachment = attachments.get(0);
-
-                final String encAlgo = X509Util.getEncAlgo(encData);
-                final String jceAlgorithm =
-                        JCEMapper.translateURItoJCEID(encAlgo);
-                final Cipher cipher = Cipher.getInstance(jceAlgorithm);
-
-                InputStream attachmentInputStream =
-                        AttachmentUtils.setupAttachmentDecryptionStream(
-                                encAlgo, cipher, symmetricKey, attachment.getSourceStream());
-
-                Attachment resultAttachment = new Attachment();
-                resultAttachment.setId(attachment.getId());
-                resultAttachment.setMimeType(encData.getAttributeNS(null, "MimeType"));
-                resultAttachment.setSourceStream(attachmentInputStream);
-                resultAttachment.addHeaders(attachment.getHeaders());
-
-                if (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr)) {
-                    AttachmentUtils.readAndReplaceEncryptedAttachmentHeaders(
-                            resultAttachment.getHeaders(), attachmentInputStream);
-                }
-
-                AttachmentResultCallback attachmentResultCallback = new AttachmentResultCallback();
-                attachmentResultCallback.setAttachment(resultAttachment);
-                attachmentResultCallback.setAttachmentId(resultAttachment.getId());
-                attachmentCallbackHandler.handle(new Callback[]{attachmentResultCallback});
-
-            } catch (UnsupportedCallbackException e) {
-                throw new WSSecurityException(
-                        WSSecurityException.ErrorCode.FAILED_CHECK, e);
-            } catch (IOException e) {
-                throw new WSSecurityException(
-                        WSSecurityException.ErrorCode.FAILED_CHECK, e);
-            } catch (NoSuchAlgorithmException e) {
-                throw new WSSecurityException(
-                        WSSecurityException.ErrorCode.FAILED_CHECK, e);
-            } catch (NoSuchPaddingException e) {
-                throw new WSSecurityException(
-                        WSSecurityException.ErrorCode.FAILED_CHECK, e);
-            }
-
-            dataRef.setContent(true);
-            // Remove this EncryptedData from the security header to avoid processing it again
-            encData.getParentNode().removeChild(encData);
-            
-            return dataRef;
-        }
-
-        boolean content = X509Util.isContent(encData);
-        dataRef.setContent(content);
-        
-        Node parent = encData.getParentNode();
-        Node previousSibling = encData.getPreviousSibling();
-        if (content) {
-            encData = (Element) encData.getParentNode();
-            parent = encData.getParentNode();
-        }
-
-        XMLCipher xmlCipher = null;
-        try {
-            xmlCipher = XMLCipher.getInstance(symEncAlgo);
-            xmlCipher.setSecureValidation(true);
-            xmlCipher.init(XMLCipher.DECRYPT_MODE, symmetricKey);
-        } catch (XMLEncryptionException ex) {
-            throw new WSSecurityException(
-                    WSSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, ex
-            );
-        }
-        
-        try {
-            xmlCipher.doFinal(doc, encData, content);
-        } catch (Exception ex) {
-            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
-        }
-        
-        if (parent.getLocalName().equals(WSConstants.ENCRYPTED_HEADER)
-            && parent.getNamespaceURI().equals(WSConstants.WSSE11_NS)
-            || parent.getLocalName().equals(WSConstants.ENCRYPED_ASSERTION_LN)
-            && parent.getNamespaceURI().equals(WSConstants.SAML2_NS)) {
-                
-            Node decryptedHeader = parent.getFirstChild();
-            Node soapHeader = parent.getParentNode();
-            soapHeader.replaceChild(decryptedHeader, parent);
-
-            dataRef.setProtectedElement((Element)decryptedHeader);
-            dataRef.setXpath(getXPath(decryptedHeader));
-        } else if (content) {
-            dataRef.setProtectedElement(encData);
-            dataRef.setXpath(getXPath(encData));
-        } else {
-            Node decryptedNode;
-            if (previousSibling == null) {
-                decryptedNode = parent.getFirstChild();
-            } else {
-                decryptedNode = previousSibling.getNextSibling();
-            }
-            if (decryptedNode != null && Node.ELEMENT_NODE == decryptedNode.getNodeType()) {
-                dataRef.setProtectedElement((Element)decryptedNode);
-            }
-            dataRef.setXpath(getXPath(decryptedNode));
-        }
-        
-        return dataRef;
-    }
-    
-    
-    public String getId() {
-        return null;
-    }
-
-    
-    /**
-     * @param decryptedNode the decrypted node
-     * @return a fully built xpath 
-     *        (eg. &quot;/soapenv:Envelope/soapenv:Body/ns:decryptedElement&quot;)
-     *        if the decryptedNode is an Element or an Attr node and is not detached
-     *        from the document. <code>null</code> otherwise
-     */
-    public static String getXPath(Node decryptedNode) {
-        if (decryptedNode == null) {
-            return null;
-        }
-        
-        String result = "";
-        if (Node.ELEMENT_NODE == decryptedNode.getNodeType()) {
-            result = decryptedNode.getNodeName();
-            result = prependFullPath(result, decryptedNode.getParentNode());
-        } else if (Node.ATTRIBUTE_NODE == decryptedNode.getNodeType()) {
-            result = "@" + decryptedNode.getNodeName();
-            result = prependFullPath(result, ((Attr)decryptedNode).getOwnerElement());
-        } else {
-            return null;
-        }
-        
-        return result;
-    }
-
-
-    /**
-     * Recursively build an absolute xpath (starting with the root &quot;/&quot;)
-     * 
-     * @param xpath the xpath expression built so far
-     * @param node the current node whose name is to be prepended
-     * @return a fully built xpath
-     */
-    private static String prependFullPath(String xpath, Node node) {
-        if (node == null) {
-            // probably a detached node... not really useful
-            return null;
-        } else if (Node.ELEMENT_NODE == node.getNodeType()) {
-            xpath = node.getNodeName() + "/" + xpath;
-            return prependFullPath(xpath, node.getParentNode());
-        } else if (Node.DOCUMENT_NODE == node.getNodeType()) {
-            return "/" + xpath;
-        } else {
-            return prependFullPath(xpath, node.getParentNode());
-        }
-    }
-
 }
+

Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java Fri May 22 14:34:20 2015
@@ -48,6 +48,7 @@ import org.apache.wss4j.dom.WSDocInfo;
 import org.apache.wss4j.dom.WSSecurityEngineResult;
 import org.apache.wss4j.dom.handler.RequestData;
 import org.apache.wss4j.dom.saml.WSSSAMLKeyInfoProcessor;
+import org.apache.wss4j.dom.util.EncryptionUtils;
 import org.apache.wss4j.dom.validate.Credential;
 import org.apache.wss4j.dom.validate.Validator;
 import org.opensaml.xml.signature.KeyInfo;
@@ -265,7 +266,7 @@ public class SAMLTokenProcessor implemen
                 }
                 ref.setTransformAlgorithms(transformAlgorithms);
     
-                ref.setXpath(ReferenceListProcessor.getXPath(token));
+                ref.setXpath(EncryptionUtils.getXPath(token));
                 protectedRefs.add(ref);
             }
         }

Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java Fri May 22 14:34:20 2015
@@ -82,6 +82,7 @@ import org.apache.wss4j.dom.str.Signatur
 import org.apache.wss4j.dom.transform.AttachmentContentSignatureTransform;
 import org.apache.wss4j.dom.transform.STRTransform;
 import org.apache.wss4j.dom.transform.STRTransformUtil;
+import org.apache.wss4j.dom.util.EncryptionUtils;
 import org.apache.wss4j.dom.util.WSSecurityUtil;
 import org.apache.wss4j.dom.util.XmlSchemaDateFormat;
 import org.apache.wss4j.dom.validate.Credential;
@@ -573,7 +574,7 @@ public class SignatureProcessor implemen
                 }
                 ref.setTransformAlgorithms(transformAlgorithms);
                 
-                ref.setXpath(ReferenceListProcessor.getXPath(se));
+                ref.setXpath(EncryptionUtils.getXPath(se));
                 protectedRefs.add(ref);
             }
         }

Added: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java?rev=1681129&view=auto
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java (added)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java Fri May 22 14:34:20 2015
@@ -0,0 +1,378 @@
+/**
+ * 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.wss4j.dom.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.wss4j.common.ext.Attachment;
+import org.apache.wss4j.common.ext.AttachmentRequestCallback;
+import org.apache.wss4j.common.ext.AttachmentResultCallback;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.AttachmentUtils;
+import org.apache.wss4j.common.util.XMLUtils;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.WSDataRef;
+import org.apache.wss4j.dom.WSDocInfo;
+import org.apache.wss4j.dom.handler.RequestData;
+import org.apache.wss4j.dom.message.CallbackLookup;
+import org.apache.wss4j.dom.message.DOMCallbackLookup;
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.encryption.XMLEncryptionException;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+public final class EncryptionUtils {
+    
+    private EncryptionUtils() {
+        // complete
+    }
+
+    /**
+     * Look up the encrypted data. First try Id="someURI". If no such Id then try 
+     * wsu:Id="someURI".
+     * 
+     * @param doc The document in which to find EncryptedData
+     * @param wsDocInfo The WSDocInfo object to use
+     * @param dataRefURI The URI of EncryptedData
+     * @return The EncryptedData element
+     * @throws WSSecurityException if the EncryptedData element referenced by dataRefURI is 
+     * not found
+     */
+    public static Element
+    findEncryptedDataElement(
+        Document doc,
+        WSDocInfo wsDocInfo,
+        String dataRefURI
+    ) throws WSSecurityException {
+        CallbackLookup callbackLookup = wsDocInfo.getCallbackLookup();
+        if (callbackLookup == null) {
+            callbackLookup = new DOMCallbackLookup(doc);
+        }
+        Element encryptedDataElement = 
+            callbackLookup.getElement(dataRefURI, null, true);
+        if (encryptedDataElement == null) {
+            throw new WSSecurityException(
+                WSSecurityException.ErrorCode.INVALID_SECURITY, "dataRef", 
+                new Object[] {dataRefURI});
+        }
+        if (encryptedDataElement.getLocalName().equals(WSConstants.ENCRYPTED_HEADER)
+            && encryptedDataElement.getNamespaceURI().equals(WSConstants.WSSE11_NS)) {
+            Node child = encryptedDataElement.getFirstChild();
+            while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
+                child = child.getNextSibling();
+            }
+            return (Element)child;
+        }
+        return encryptedDataElement;
+    }
+
+    
+    /**
+     * Decrypt the EncryptedData argument using a SecretKey.
+     * @param doc The (document) owner of EncryptedData
+     * @param dataRefURI The URI of EncryptedData
+     * @param encData The EncryptedData element
+     * @param symmetricKey The SecretKey with which to decrypt EncryptedData
+     * @param symEncAlgo The symmetric encryption algorithm to use
+     * @throws WSSecurityException
+     */
+    public static WSDataRef
+    decryptEncryptedData(
+        Document doc,
+        String dataRefURI,
+        Element encData,
+        SecretKey symmetricKey,
+        String symEncAlgo,
+        RequestData requestData
+    ) throws WSSecurityException {
+
+        WSDataRef dataRef = new WSDataRef();
+        dataRef.setEncryptedElement(encData);
+        dataRef.setWsuId(dataRefURI);
+        dataRef.setAlgorithm(symEncAlgo);
+
+        // See if it is an attachment, and handle that differently
+        String typeStr = encData.getAttributeNS(null, "Type");
+        String xopURI = getXOPURIFromEncryptedData(encData);
+        if (typeStr != null &&
+            (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_CONTENT_ONLY.equals(typeStr) ||
+            WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr))) {
+
+            Element cipherData = XMLUtils.getDirectChildElement(encData, "CipherData", WSConstants.ENC_NS);
+            if (cipherData == null) {
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
+            }
+            Element cipherReference = XMLUtils.getDirectChildElement(cipherData, "CipherReference", WSConstants.ENC_NS);
+            if (cipherReference == null) {
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
+            }
+            String uri = cipherReference.getAttributeNS(null, "URI");
+            
+            return decryptAttachment(dataRefURI, uri, false, encData, symmetricKey, symEncAlgo, requestData);
+        } else if (xopURI != null) {
+            return decryptAttachment(dataRefURI, xopURI, true, encData, symmetricKey, symEncAlgo, requestData);
+        }
+
+        boolean content = X509Util.isContent(encData);
+        dataRef.setContent(content);
+        
+        Node parent = encData.getParentNode();
+        Node previousSibling = encData.getPreviousSibling();
+        if (content) {
+            encData = (Element) encData.getParentNode();
+            parent = encData.getParentNode();
+        }
+
+        XMLCipher xmlCipher = null;
+        try {
+            xmlCipher = XMLCipher.getInstance(symEncAlgo);
+            xmlCipher.setSecureValidation(true);
+            xmlCipher.init(XMLCipher.DECRYPT_MODE, symmetricKey);
+        } catch (XMLEncryptionException ex) {
+            throw new WSSecurityException(
+                    WSSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, ex
+            );
+        }
+        
+        try {
+            xmlCipher.doFinal(doc, encData, content);
+        } catch (Exception ex) {
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
+        }
+        
+        if (parent.getLocalName().equals(WSConstants.ENCRYPTED_HEADER)
+            && parent.getNamespaceURI().equals(WSConstants.WSSE11_NS)
+            || parent.getLocalName().equals(WSConstants.ENCRYPED_ASSERTION_LN)
+            && parent.getNamespaceURI().equals(WSConstants.SAML2_NS)) {
+                
+            Node decryptedHeader = parent.getFirstChild();
+            Node soapHeader = parent.getParentNode();
+            soapHeader.replaceChild(decryptedHeader, parent);
+
+            dataRef.setProtectedElement((Element)decryptedHeader);
+            dataRef.setXpath(getXPath(decryptedHeader));
+        } else if (content) {
+            dataRef.setProtectedElement(encData);
+            dataRef.setXpath(getXPath(encData));
+        } else {
+            Node decryptedNode;
+            if (previousSibling == null) {
+                decryptedNode = parent.getFirstChild();
+            } else {
+                decryptedNode = previousSibling.getNextSibling();
+            }
+            if (decryptedNode != null && Node.ELEMENT_NODE == decryptedNode.getNodeType()) {
+                dataRef.setProtectedElement((Element)decryptedNode);
+            }
+            dataRef.setXpath(getXPath(decryptedNode));
+        }
+        
+        return dataRef;
+    }
+    
+    private static String getXOPURIFromEncryptedData(Element encData) {
+        Element cipherData = XMLUtils.getDirectChildElement(encData, "CipherData", WSConstants.ENC_NS);
+        if (cipherData != null) {
+            Element cipherValue = 
+                XMLUtils.getDirectChildElement(cipherData, "CipherValue", WSConstants.ENC_NS);
+            return getXOPURIFromCipherValue(cipherValue);
+        }
+        
+        return null;
+    }
+    
+    public static String getXOPURIFromCipherValue(Element cipherValue) {
+        if (cipherValue != null && cipherValue.hasAttributeNS(WSConstants.XMLNS_NS, "xop")
+            && WSConstants.XOP_NS.equals(cipherValue.getAttributeNS(WSConstants.XMLNS_NS, "xop"))) {
+            Element cipherValueChild =
+                XMLUtils.getDirectChildElement(cipherValue, "Include", WSConstants.XOP_NS);
+            if (cipherValueChild != null && cipherValueChild.hasAttributeNS(null, "href")) {
+                return cipherValueChild.getAttributeNS(null, "href");
+            }
+        }
+
+        return null;
+    }
+    
+    
+    private static WSDataRef
+    decryptAttachment(
+        String dataRefURI,
+        String uri,
+        boolean xop,
+        Element encData,
+        SecretKey symmetricKey,
+        String symEncAlgo,
+        RequestData requestData
+    ) throws WSSecurityException {
+        WSDataRef dataRef = new WSDataRef();
+        dataRef.setWsuId(dataRefURI);
+        dataRef.setAlgorithm(symEncAlgo);
+        
+        try {
+            if (uri == null || uri.length() < 5 || !uri.startsWith("cid:")) {
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
+            }
+            dataRef.setWsuId(uri);
+            dataRef.setAttachment(true);
+
+            CallbackHandler attachmentCallbackHandler = requestData.getAttachmentCallbackHandler();
+            if (attachmentCallbackHandler == null) {
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
+            }
+
+            final String attachmentId = uri.substring(4);
+
+            AttachmentRequestCallback attachmentRequestCallback = new AttachmentRequestCallback();
+            attachmentRequestCallback.setAttachmentId(attachmentId);
+
+            attachmentCallbackHandler.handle(new Callback[]{attachmentRequestCallback});
+            List<Attachment> attachments = attachmentRequestCallback.getAttachments();
+            if (attachments == null || attachments.isEmpty() || !attachmentId.equals(attachments.get(0).getId())) {
+                throw new WSSecurityException(
+                        WSSecurityException.ErrorCode.INVALID_SECURITY,
+                        "empty", new Object[] {"Attachment not found"}
+                );
+            }
+            Attachment attachment = attachments.get(0);
+
+            final String encAlgo = X509Util.getEncAlgo(encData);
+            final String jceAlgorithm =
+                    JCEMapper.translateURItoJCEID(encAlgo);
+            final Cipher cipher = Cipher.getInstance(jceAlgorithm);
+
+            InputStream attachmentInputStream =
+                    AttachmentUtils.setupAttachmentDecryptionStream(
+                            encAlgo, cipher, symmetricKey, attachment.getSourceStream());
+            
+            // For the xop:Include case, we need to replace the xop:Include Element with the
+            // decrypted Element
+            if (xop) {
+                DocumentBuilder db = 
+                    org.apache.xml.security.utils.XMLUtils.createDocumentBuilder(false);
+                Document doc = db.parse(attachmentInputStream);
+                Node importedNode = encData.getOwnerDocument().importNode(doc.getDocumentElement(), true);
+                encData.getParentNode().appendChild(importedNode);
+                org.apache.xml.security.utils.XMLUtils.repoolDocumentBuilder(db);
+            }
+            
+            Attachment resultAttachment = new Attachment();
+            resultAttachment.setId(attachment.getId());
+            resultAttachment.setMimeType(encData.getAttributeNS(null, "MimeType"));
+            resultAttachment.setSourceStream(attachmentInputStream);
+            resultAttachment.addHeaders(attachment.getHeaders());
+
+            String typeStr = encData.getAttributeNS(null, "Type");
+            if (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr)) {
+                AttachmentUtils.readAndReplaceEncryptedAttachmentHeaders(
+                        resultAttachment.getHeaders(), attachmentInputStream);
+            }
+
+            AttachmentResultCallback attachmentResultCallback = new AttachmentResultCallback();
+            attachmentResultCallback.setAttachment(resultAttachment);
+            attachmentResultCallback.setAttachmentId(resultAttachment.getId());
+            attachmentCallbackHandler.handle(new Callback[]{attachmentResultCallback});
+
+        } catch (UnsupportedCallbackException e) {
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+        } catch (IOException e) {
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+        } catch (NoSuchAlgorithmException e) {
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+        } catch (NoSuchPaddingException e) { 
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+        } catch (ParserConfigurationException e) { 
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+        } catch (SAXException e) {
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+        }
+
+        dataRef.setContent(true);
+        // Remove this EncryptedData from the security header to avoid processing it again
+        encData.getParentNode().removeChild(encData);
+        
+        return dataRef;
+    }
+    
+    /**
+     * @param decryptedNode the decrypted node
+     * @return a fully built xpath 
+     *        (eg. &quot;/soapenv:Envelope/soapenv:Body/ns:decryptedElement&quot;)
+     *        if the decryptedNode is an Element or an Attr node and is not detached
+     *        from the document. <code>null</code> otherwise
+     */
+    public static String getXPath(Node decryptedNode) {
+        if (decryptedNode == null) {
+            return null;
+        }
+        
+        String result = "";
+        if (Node.ELEMENT_NODE == decryptedNode.getNodeType()) {
+            result = decryptedNode.getNodeName();
+            result = prependFullPath(result, decryptedNode.getParentNode());
+        } else if (Node.ATTRIBUTE_NODE == decryptedNode.getNodeType()) {
+            result = "@" + decryptedNode.getNodeName();
+            result = prependFullPath(result, ((Attr)decryptedNode).getOwnerElement());
+        } else {
+            return null;
+        }
+        
+        return result;
+    }
+
+
+    /**
+     * Recursively build an absolute xpath (starting with the root &quot;/&quot;)
+     * 
+     * @param xpath the xpath expression built so far
+     * @param node the current node whose name is to be prepended
+     * @return a fully built xpath
+     */
+    private static String prependFullPath(String xpath, Node node) {
+        if (node == null) {
+            // probably a detached node... not really useful
+            return null;
+        } else if (Node.ELEMENT_NODE == node.getNodeType()) {
+            xpath = node.getNodeName() + "/" + xpath;
+            return prependFullPath(xpath, node.getParentNode());
+        } else if (Node.DOCUMENT_NODE == node.getNodeType()) {
+            return "/" + xpath;
+        } else {
+            return prependFullPath(xpath, node.getParentNode());
+        }
+    }
+
+}

Copied: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java (from r1680507, webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java)
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java?p2=webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java&p1=webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java&r1=1680507&r2=1681129&rev=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java Fri May 22 14:34:20 2015
@@ -17,13 +17,12 @@
  * under the License.
  */
 
-package org.apache.wss4j.dom.processor;
+package org.apache.wss4j.dom.util;
 
 import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.common.ext.WSPasswordCallback;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.util.KeyUtils;
-import org.apache.wss4j.dom.util.WSSecurityUtil;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.Text;
@@ -73,7 +72,7 @@ public final class X509Util {
         return symEncAlgo;
     }
 
-    protected static SecretKey getSharedKey(
+    public static SecretKey getSharedKey(
         Element keyInfoElem,
         String algorithm,
         CallbackHandler cb

Added: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java?rev=1681129&view=auto
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java (added)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java Fri May 22 14:34:20 2015
@@ -0,0 +1,190 @@
+/**
+ * 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.wss4j.dom.message;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.wss4j.common.WSEncryptionPart;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoFactory;
+import org.apache.wss4j.common.ext.Attachment;
+import org.apache.wss4j.common.util.XMLUtils;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.WSSConfig;
+import org.apache.wss4j.dom.WSSecurityEngine;
+import org.apache.wss4j.dom.WSSecurityEngineResult;
+import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
+import org.apache.wss4j.dom.common.SOAPUtil;
+import org.apache.wss4j.dom.handler.RequestData;
+import org.apache.wss4j.dom.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Test for processing an xop:Include inside a CipherValue Element
+ */
+public class XOPAttachmentTest extends org.junit.Assert {
+
+    private static final String SOAP_BODY = 
+        "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" 
+        + "<value xmlns=\"\">15</value>" 
+        + "</add>";
+    
+    private static final org.slf4j.Logger LOG =
+            org.slf4j.LoggerFactory.getLogger(XOPAttachmentTest.class);
+
+    private WSSecurityEngine secEngine = new WSSecurityEngine();
+    private Crypto crypto = null;
+
+    public XOPAttachmentTest() throws Exception {
+        WSSConfig.init();
+        crypto = CryptoFactory.getInstance();
+    }
+
+    protected byte[] readInputStream(InputStream inputStream) throws IOException {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        try {
+            int read = 0;
+            byte[] buf = new byte[4096];
+            while ((read = inputStream.read(buf)) != -1) {
+                byteArrayOutputStream.write(buf, 0, read);
+            }
+            return byteArrayOutputStream.toByteArray();
+        } finally {
+            byteArrayOutputStream.close();
+        }
+    }
+
+    // Set up a test to encrypt the SOAP Body + an attachment, which is the same content as 
+    // the SOAP Body. Then replace the encrypted SOAP Body with a xop:Include to the attachment,
+    // and modify the request to remove the encryption stuff pointing to the attachment.
+    @org.junit.Test
+    public void testEncryptedSOAPBody() throws Exception {
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecEncrypt encrypt = new WSSecEncrypt();
+        encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+        encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+
+        List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
+        parts.add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
+        parts.add(new WSEncryptionPart("cid:Attachments", "Content"));
+        encrypt.setParts(parts);
+
+        String attachmentId = UUID.randomUUID().toString();
+        final Attachment attachment = new Attachment();
+        attachment.setId(attachmentId);
+        attachment.setSourceStream(new ByteArrayInputStream(SOAP_BODY.getBytes("UTF-8")));
+
+        AttachmentCallbackHandler attachmentCallbackHandler = 
+            new AttachmentCallbackHandler(Collections.singletonList(attachment));
+        encrypt.setAttachmentCallbackHandler(attachmentCallbackHandler);
+        List<Attachment> encryptedAttachments = attachmentCallbackHandler.getResponseAttachments();
+
+        Document encryptedDoc = encrypt.build(doc, crypto, secHeader);
+        
+        // Find the SOAP Body + replace with a xop:Include to the attachment!
+        Element soapBody = WSSecurityUtil.findBodyElement(encryptedDoc);
+        assertNotNull(soapBody);
+        Element encryptedData = 
+            XMLUtils.getDirectChildElement(soapBody, "EncryptedData", WSConstants.ENC_NS);
+        encryptedData.removeAttributeNS(null, "Type");
+        Element cipherData = 
+            XMLUtils.getDirectChildElement(encryptedData, "CipherData", WSConstants.ENC_NS);
+        assertNotNull(cipherData);
+        Element cipherValue = 
+            XMLUtils.getDirectChildElement(cipherData, "CipherValue", WSConstants.ENC_NS);
+        assertNotNull(cipherValue);
+        
+        WSSecurityUtil.setNamespace(cipherValue, WSConstants.XOP_NS, "xop");
+        
+        Element cipherValueChild = encryptedDoc.createElementNS(WSConstants.XOP_NS, "Include");
+        cipherValueChild.setAttributeNS(null, "href", "cid:" + encryptedAttachments.get(0).getId());
+        cipherValue.replaceChild(cipherValueChild, cipherValue.getFirstChild());
+        
+        // Remove EncryptedData structure from the security header (which encrypted the attachment
+        // in the first place)
+        Element securityHeader = 
+            WSSecurityUtil.findWsseSecurityHeaderBlock(encryptedDoc, encryptedDoc.getDocumentElement(), false);
+        Element encryptedAttachmentData = 
+            XMLUtils.getDirectChildElement(securityHeader, "EncryptedData", WSConstants.ENC_NS);
+        assertNotNull(encryptedAttachmentData);
+        String encryptedDataId = encryptedAttachmentData.getAttributeNS(null, "Id");
+        securityHeader.removeChild(encryptedAttachmentData);
+
+        // Now get EncryptedKey + remove the reference to the EncryptedData above
+        Element encryptedKey = 
+            XMLUtils.getDirectChildElement(securityHeader, "EncryptedKey", WSConstants.ENC_NS);
+        assertNotNull(encryptedKey);
+        Element referenceList = 
+            XMLUtils.getDirectChildElement(encryptedKey, "ReferenceList", WSConstants.ENC_NS);
+        assertNotNull(referenceList);
+        Node child = referenceList.getFirstChild();
+        while (child != null) {
+            if (child instanceof Element && "DataReference".equals(child.getLocalName())
+                && WSConstants.ENC_NS.equals(child.getNamespaceURI())) {
+                String uri = ((Element)child).getAttributeNS(null, "URI");
+                if (uri.equals("#" + encryptedDataId)) {
+                    referenceList.removeChild(child);
+                    break;
+                }
+            }
+            child = child.getNextSibling();
+        }
+        
+        if (LOG.isDebugEnabled()) {
+            String outputString = XMLUtils.PrettyDocumentToString(encryptedDoc);
+            LOG.debug(outputString);
+            //System.out.println(outputString);
+        }
+
+        attachmentCallbackHandler = new AttachmentCallbackHandler(encryptedAttachments);
+        verify(encryptedDoc, attachmentCallbackHandler);
+        
+        String processedDoc = XMLUtils.PrettyDocumentToString(encryptedDoc);
+        assertTrue(processedDoc.contains(SOAP_BODY));
+    }
+
+    /**
+     * Verifies the soap envelope.
+     * This method verifies all the signature generated.
+     *
+     * @throws java.lang.Exception Thrown when there is a problem in verification
+     */
+    private List<WSSecurityEngineResult> verify(Document doc, CallbackHandler attachmentCallbackHandler) throws Exception {
+        RequestData requestData = new RequestData();
+        requestData.setAttachmentCallbackHandler(attachmentCallbackHandler);
+        requestData.setSigVerCrypto(crypto);
+        requestData.setDecCrypto(crypto);
+        requestData.setCallbackHandler(new KeystoreCallbackHandler());
+        return secEngine.processSecurityHeader(doc, null, requestData);
+    }
+}