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 15:46:34 UTC

svn commit: r1681118 - in /webservices/wss4j/trunk: ws-security-common/src/main/java/org/apache/wss4j/common/ ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ ws-security-dom/src/main/java/org/apache/wss4j/dom/util/ ws-security-dom/src/tes...

Author: coheigea
Date: Fri May 22 13:46:33 2015
New Revision: 1681118

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

Added:
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java
      - copied, changed from r1680505, webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java
      - copied, changed from r1680505, webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java
Removed:
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java
Modified:
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java

Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java?rev=1681118&r1=1681117&r2=1681118&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java (original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java Fri May 22 13:46:33 2015
@@ -98,6 +98,7 @@ public class WSS4JConstants {
         "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/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java?rev=1681118&r1=1681117&r2=1681118&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java Fri May 22 13:46:33 2015
@@ -46,7 +46,9 @@ import org.apache.wss4j.dom.str.STRParse
 import org.apache.wss4j.dom.str.STRParserParameters;
 import org.apache.wss4j.dom.str.STRParserResult;
 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;
 import org.w3c.dom.Element;
 
 /**
@@ -146,7 +148,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/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java?rev=1681118&r1=1681117&r2=1681118&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java Fri May 22 13:46:33 2015
@@ -35,12 +35,17 @@ 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.apache.wss4j.common.bsp.BSPEnforcer;
 import org.apache.wss4j.common.bsp.BSPRule;
 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.token.DOMX509IssuerSerial;
 import org.apache.wss4j.common.token.SecurityTokenReference;
@@ -55,10 +60,13 @@ import org.apache.wss4j.dom.str.Encrypte
 import org.apache.wss4j.dom.str.STRParser;
 import org.apache.wss4j.dom.str.STRParserParameters;
 import org.apache.wss4j.dom.str.STRParserResult;
+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;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -231,8 +239,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) {
@@ -264,6 +280,39 @@ public class EncryptedKeyProcessor imple
         return 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", "Attachment not found"
+                );
+            }
+            Attachment attachment = attachments.get(0);
+            InputStream inputStream = attachment.getSourceStream();
+            
+            return JavaUtils.getBytesFromStream(inputStream);
+        } catch (UnsupportedCallbackException | IOException e) {
+            throw new WSSecurityException(
+                    WSSecurityException.ErrorCode.FAILED_CHECK, e);
+        }
+    }
+    
     /**
      * Generates a random secret key using the algorithm specified in the
      * first DataReference URI
@@ -276,7 +325,7 @@ public class EncryptedKeyProcessor imple
             
             if (uri != null) {
                 Element ee = 
-                    ReferenceListProcessor.findEncryptedDataElement(refList.getOwnerDocument(), 
+                    EncryptionUtils.findEncryptedDataElement(refList.getOwnerDocument(), 
                                                                     wsDocInfo, uri);
                 String algorithmURI = X509Util.getEncAlgo(ee);
                 alg = JCEMapper.getJCEKeyAlgorithmFromURI(algorithmURI);
@@ -512,7 +561,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);
@@ -555,7 +604,7 @@ public class EncryptedKeyProcessor imple
             algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
         }
 
-        return ReferenceListProcessor.decryptEncryptedData(
+        return EncryptionUtils.decryptEncryptedData(
             doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo, data
         );
     }

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java?rev=1681118&r1=1681117&r2=1681118&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java Fri May 22 13:46:33 2015
@@ -19,32 +19,24 @@
 
 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.Collections;
 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 org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 import org.apache.wss4j.common.bsp.BSPEnforcer;
 import org.apache.wss4j.common.bsp.BSPRule;
 import org.apache.wss4j.common.crypto.AlgorithmSuite;
 import org.apache.wss4j.common.crypto.AlgorithmSuiteValidator;
-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.principal.WSDerivedKeyTokenPrincipal;
 import org.apache.wss4j.common.token.SecurityTokenReference;
-import org.apache.wss4j.common.util.AttachmentUtils;
 import org.apache.wss4j.common.util.KeyUtils;
 import org.apache.wss4j.common.util.XMLUtils;
 import org.apache.wss4j.dom.WSConstants;
@@ -52,19 +44,13 @@ import org.apache.wss4j.dom.WSDataRef;
 import org.apache.wss4j.dom.WSDocInfo;
 import org.apache.wss4j.dom.WSSecurityEngineResult;
 import org.apache.wss4j.dom.handler.RequestData;
-import org.apache.wss4j.dom.message.CallbackLookup;
 import org.apache.wss4j.dom.str.STRParser;
 import org.apache.wss4j.dom.str.STRParserParameters;
 import org.apache.wss4j.dom.str.STRParserResult;
 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.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.apache.wss4j.dom.util.X509Util;
 
 public class ReferenceListProcessor implements Processor {
     private static final org.slf4j.Logger LOG = 
@@ -141,7 +127,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 = 
@@ -211,7 +198,7 @@ public class ReferenceListProcessor impl
         }
 
         return 
-            decryptEncryptedData(
+            EncryptionUtils.decryptEncryptedData(
                 doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo, data
             );
     }
@@ -261,269 +248,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();
-        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");
-        if (typeStr != null &&
-            (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_CONTENT_ONLY.equals(typeStr) ||
-            WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr))) {
-
-            return decryptAttachment(dataRefURI, 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 WSDataRef
-    decryptAttachment(
-        String dataRefURI,
-        Element encData,
-        SecretKey symmetricKey,
-        String symEncAlgo,
-        RequestData requestData
-    ) throws WSSecurityException {
-        WSDataRef dataRef = new WSDataRef();
-        dataRef.setWsuId(dataRefURI);
-        dataRef.setAlgorithm(symEncAlgo);
-        
-        try {
-            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");
-            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());
-
-            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 | IOException
-            | NoSuchAlgorithmException | 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;
-    }
-    
-    /**
-     * @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/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java?rev=1681118&r1=1681117&r2=1681118&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java Fri May 22 13:46:33 2015
@@ -47,6 +47,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.xmlsec.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/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java?rev=1681118&r1=1681117&r2=1681118&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java Fri May 22 13:46:33 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.XmlSchemaDateFormat;
 import org.apache.wss4j.dom.validate.Credential;
 import org.apache.wss4j.dom.validate.Validator;
@@ -568,7 +569,7 @@ public class SignatureProcessor implemen
                 }
                 ref.setTransformAlgorithms(transformAlgorithms);
                 
-                ref.setXpath(ReferenceListProcessor.getXPath(se));
+                ref.setXpath(EncryptionUtils.getXPath(se));
                 protectedRefs.add(ref);
             }
         }

Copied: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java (from r1680505, webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java)
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java?p2=webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java&p1=webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java&r1=1680505&r2=1681118&rev=1681118&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java Fri May 22 13:46:33 2015
@@ -17,14 +17,11 @@
  * under the License.
  */
 
-package org.apache.wss4j.dom.processor;
+package org.apache.wss4j.dom.util;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 import javax.crypto.Cipher;
@@ -33,31 +30,20 @@ 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.bsp.BSPEnforcer;
-import org.apache.wss4j.common.bsp.BSPRule;
-import org.apache.wss4j.common.crypto.AlgorithmSuite;
-import org.apache.wss4j.common.crypto.AlgorithmSuiteValidator;
 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.principal.WSDerivedKeyTokenPrincipal;
-import org.apache.wss4j.common.token.SecurityTokenReference;
 import org.apache.wss4j.common.util.AttachmentUtils;
-import org.apache.wss4j.common.util.KeyUtils;
 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.WSSecurityEngineResult;
 import org.apache.wss4j.dom.handler.RequestData;
 import org.apache.wss4j.dom.message.CallbackLookup;
-import org.apache.wss4j.dom.str.STRParser;
-import org.apache.wss4j.dom.str.STRParserParameters;
-import org.apache.wss4j.dom.str.STRParserResult;
-import org.apache.wss4j.dom.str.SecurityTokenRefSTRParser;
-import org.apache.wss4j.dom.util.WSSecurityUtil;
 import org.apache.xml.security.algorithms.JCEMapper;
 import org.apache.xml.security.encryption.XMLCipher;
 import org.apache.xml.security.encryption.XMLEncryptionException;
@@ -65,200 +51,12 @@ 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 class ReferenceListProcessor implements Processor {
-    private static final org.slf4j.Logger LOG = 
-        org.slf4j.LoggerFactory.getLogger(ReferenceListProcessor.class);
+public final class EncryptionUtils {
     
-    public List<WSSecurityEngineResult> handleToken(
-        Element elem, 
-        RequestData data, 
-        WSDocInfo wsDocInfo 
-    ) throws WSSecurityException {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Found reference list element");
-        }
-        List<WSDataRef> dataRefs = handleReferenceList(elem, data, wsDocInfo);
-        WSSecurityEngineResult result = 
-            new WSSecurityEngineResult(WSConstants.ENCR, dataRefs);
-        String tokenId = elem.getAttributeNS(null, "Id");
-        if (!"".equals(tokenId)) {
-            result.put(WSSecurityEngineResult.TAG_ID, tokenId);
-        }
-        wsDocInfo.addTokenElement(elem);
-        wsDocInfo.addResult(result);
-        return Collections.singletonList(result);
-    }
-
-    /**
-     * Dereferences and decodes encrypted data elements.
-     * 
-     * @param elem contains the <code>ReferenceList</code> to the encrypted
-     *             data elements
-     */
-    private List<WSDataRef> handleReferenceList(
-        Element elem, 
-        RequestData data,
-        WSDocInfo wsDocInfo
-    ) throws WSSecurityException {
-        List<WSDataRef> dataRefs = new ArrayList<>();
-        for (Node node = elem.getFirstChild(); 
-            node != null; 
-            node = node.getNextSibling()
-        ) {
-            if (Node.ELEMENT_NODE == node.getNodeType()
-                && WSConstants.ENC_NS.equals(node.getNamespaceURI())
-                && "DataReference".equals(node.getLocalName())) {
-                String dataRefURI = ((Element) node).getAttributeNS(null, "URI");
-                dataRefURI = XMLUtils.getIDFromReference(dataRefURI);
-                
-                // See whether we have already processed the encrypted node 
-                if (!wsDocInfo.hasResult(WSConstants.ENCR, dataRefURI)) {
-                    WSDataRef dataRef = 
-                        decryptDataRefEmbedded(
-                            elem.getOwnerDocument(), dataRefURI, data, wsDocInfo);
-                    dataRefs.add(dataRef);
-                }
-            }
-        }
-        
-        return dataRefs;
-    }
-
-    
-    /**
-     * Decrypt an (embedded) EncryptedData element referenced by dataRefURI.
-     */
-    private WSDataRef decryptDataRefEmbedded(
-        Document doc, 
-        String dataRefURI, 
-        RequestData data,
-        WSDocInfo wsDocInfo
-    ) throws WSSecurityException {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Found data reference: " + dataRefURI);
-        }
-        //
-        // Find the encrypted data element referenced by dataRefURI
-        //
-        Element encryptedDataElement = findEncryptedDataElement(doc, wsDocInfo, dataRefURI);
-        
-        if (encryptedDataElement != null && data.isRequireSignedEncryptedDataElements()) {
-            List<WSSecurityEngineResult> signedResults = 
-                wsDocInfo.getResultsByTag(WSConstants.SIGN);
-            WSSecurityUtil.verifySignedElement(encryptedDataElement, signedResults);
-        }
-        //
-        // Prepare the SecretKey object to decrypt EncryptedData
-        //
-        String symEncAlgo = X509Util.getEncAlgo(encryptedDataElement);
-        Element keyInfoElement =
-            XMLUtils.getDirectChildElement(
-                    encryptedDataElement, "KeyInfo", WSConstants.SIG_NS
-                );
-        // KeyInfo cannot be null
-        if (keyInfoElement == null) {
-            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, "noKeyinfo");
-        }
-        // Check BSP compliance
-        checkBSPCompliance(keyInfoElement, symEncAlgo, data.getBSPEnforcer());
-        
-        //
-        // Try to get a security reference token, if none found try to get a
-        // shared key using a KeyName.
-        //
-        Element secRefToken = 
-            XMLUtils.getDirectChildElement(
-                keyInfoElement, "SecurityTokenReference", WSConstants.WSSE_NS
-            );
-        SecretKey symmetricKey = null;
-        Principal principal = null;
-        if (secRefToken == null) {
-            symmetricKey = X509Util.getSharedKey(keyInfoElement, symEncAlgo, data.getCallbackHandler());
-        } else {
-            STRParserParameters parameters = new STRParserParameters();
-            parameters.setData(data);
-            parameters.setWsDocInfo(wsDocInfo);
-            parameters.setStrElement(secRefToken);
-            if (symEncAlgo != null) {
-                parameters.setDerivationKeyLength(KeyUtils.getKeyLength(symEncAlgo));
-            }
-            
-            STRParser strParser = new SecurityTokenRefSTRParser();
-            STRParserResult parserResult = strParser.parseSecurityTokenReference(parameters);
-            byte[] secretKey = parserResult.getSecretKey();
-            principal = parserResult.getPrincipal();
-            symmetricKey = KeyUtils.prepareSecretKey(symEncAlgo, secretKey);
-        }
-        
-        // Check for compliance against the defined AlgorithmSuite
-        AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
-        if (algorithmSuite != null) {
-            AlgorithmSuiteValidator algorithmSuiteValidator = new
-                AlgorithmSuiteValidator(algorithmSuite);
-
-            if (principal instanceof WSDerivedKeyTokenPrincipal) {
-                algorithmSuiteValidator.checkDerivedKeyAlgorithm(
-                    ((WSDerivedKeyTokenPrincipal)principal).getAlgorithm()
-                );
-                algorithmSuiteValidator.checkEncryptionDerivedKeyLength(
-                    ((WSDerivedKeyTokenPrincipal)principal).getLength()
-                );
-            }
-
-            algorithmSuiteValidator.checkSymmetricKeyLength(symmetricKey.getEncoded().length);
-            algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
-        }
-
-        return 
-            decryptEncryptedData(
-                doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo, data
-            );
-    }
-    
-    /**
-     * Check for BSP compliance
-     * @param keyInfoElement The KeyInfo element child
-     * @param encAlgo The encryption algorithm
-     * @throws WSSecurityException
-     */
-    private static void checkBSPCompliance(
-        Element keyInfoElement, 
-        String encAlgo,
-        BSPEnforcer bspEnforcer
-    ) throws WSSecurityException {
-        // We can only have one token reference
-        int result = 0;
-        Node node = keyInfoElement.getFirstChild();
-        Element child = null;
-        while (node != null) {
-            if (Node.ELEMENT_NODE == node.getNodeType()) {
-                result++;
-                child = (Element)node;
-            }
-            node = node.getNextSibling();
-        }
-        if (result != 1) {
-            bspEnforcer.handleBSPRule(BSPRule.R5424);
-        }
-        
-        if (child == null || !WSConstants.WSSE_NS.equals(child.getNamespaceURI()) || 
-            !SecurityTokenReference.SECURITY_TOKEN_REFERENCE.equals(child.getLocalName())) {
-            bspEnforcer.handleBSPRule(BSPRule.R5426);
-        }
-        
-        // EncryptionAlgorithm cannot be null
-        if (encAlgo == null) {
-            bspEnforcer.handleBSPRule(BSPRule.R5601);
-        }
-        // EncryptionAlgorithm must be 3DES, or AES128, or AES256
-        if (!WSConstants.TRIPLE_DES.equals(encAlgo)
-            && !WSConstants.AES_128.equals(encAlgo)
-            && !WSConstants.AES_128_GCM.equals(encAlgo)
-            && !WSConstants.AES_256.equals(encAlgo)
-            && !WSConstants.AES_256_GCM.equals(encAlgo)) {
-            bspEnforcer.handleBSPRule(BSPRule.R5620);
-        }
+    private EncryptionUtils() {
+        // complete
     }
 
     /**
@@ -283,8 +81,7 @@ public class ReferenceListProcessor impl
             callbackLookup.getElement(dataRefURI, null, true);
         if (encryptedDataElement == null) {
             throw new WSSecurityException(
-                WSSecurityException.ErrorCode.INVALID_SECURITY, "dataRef", 
-                new Object[] {dataRefURI});
+                WSSecurityException.ErrorCode.INVALID_SECURITY, "dataRef", dataRefURI);
         }
         if (encryptedDataElement.getLocalName().equals(WSConstants.ENCRYPTED_HEADER)
             && encryptedDataElement.getNamespaceURI().equals(WSConstants.WSSE11_NS)) {
@@ -324,11 +121,24 @@ public class ReferenceListProcessor impl
 
         // 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))) {
 
-            return decryptAttachment(dataRefURI, encData, symmetricKey, symEncAlgo, requestData);
+            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);
@@ -388,9 +198,36 @@ public class ReferenceListProcessor impl
         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,
@@ -401,19 +238,7 @@ public class ReferenceListProcessor impl
         dataRef.setAlgorithm(symEncAlgo);
         
         try {
-            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");
-            if (uri == null || uri.length() < 5) {
-                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
-            }
-            if (!uri.startsWith("cid:")) {
+            if (uri == null || uri.length() < 5 || !uri.startsWith("cid:")) {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
             }
             dataRef.setWsuId(uri);
@@ -434,7 +259,7 @@ public class ReferenceListProcessor impl
             if (attachments == null || attachments.isEmpty() || !attachmentId.equals(attachments.get(0).getId())) {
                 throw new WSSecurityException(
                         WSSecurityException.ErrorCode.INVALID_SECURITY,
-                        "empty", new Object[] {"Attachment not found"}
+                        "empty", "Attachment not found"
                 );
             }
             Attachment attachment = attachments.get(0);
@@ -447,7 +272,18 @@ public class ReferenceListProcessor impl
             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"));
@@ -466,7 +302,8 @@ public class ReferenceListProcessor impl
             attachmentCallbackHandler.handle(new Callback[]{attachmentResultCallback});
 
         } catch (UnsupportedCallbackException | IOException
-            | NoSuchAlgorithmException | NoSuchPaddingException e) {
+            | NoSuchAlgorithmException | NoSuchPaddingException 
+            | ParserConfigurationException | SAXException e) {
             throw new WSSecurityException(
                     WSSecurityException.ErrorCode.FAILED_CHECK, e);
         }

Copied: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java (from r1680505, webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java)
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java?p2=webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java&p1=webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java&r1=1680505&r2=1681118&rev=1681118&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java Fri May 22 13:46:33 2015
@@ -17,7 +17,7 @@
  * 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;
@@ -72,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/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java?rev=1681118&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java (added)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java Fri May 22 13:46:33 2015
@@ -0,0 +1,185 @@
+/**
+ * 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.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.WSS4JConstants;
+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.common.KeystoreCallbackHandler;
+import org.apache.wss4j.dom.common.SOAPUtil;
+import org.apache.wss4j.dom.handler.RequestData;
+import org.apache.wss4j.dom.handler.WSHandlerResult;
+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 {
+        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
+            int read = 0;
+            byte[] buf = new byte[4096];
+            while ((read = inputStream.read(buf)) != -1) {
+                byteArrayOutputStream.write(buf, 0, read);
+            }
+            return byteArrayOutputStream.toByteArray();
+        }
+    }
+
+    // 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);
+
+        encrypt.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
+        encrypt.getParts().add(new WSEncryptionPart("cid:Attachments", "Content"));
+
+        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);
+        
+        XMLUtils.setNamespace(cipherValue, WSS4JConstants.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 WSHandlerResult 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, requestData);
+    }
+}