Author: giger
Date: Mon Jun 17 10:42:36 2013
New Revision: 1493709

URL: http://svn.apache.org/r1493709
Log:
WSS-452 - Streaming code does not support an EncryptedData security header 
element without a preceeding ReferenceList 

Added:
    
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/EncryptedDataInputHandler.java
      - copied, changed from r1493521, 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/ReferenceListInputHandler.java
Modified:
    
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSConstants.java
    
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/DecryptInputProcessor.java
    
webservices/wss4j/trunk/ws-security-stax/src/main/resources/wss/wss-config.xml
    
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/EncDecryptionTest.java

Modified: 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSConstants.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSConstants.java?rev=1493709&r1=1493708&r2=1493709&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSConstants.java
 (original)
+++ 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSConstants.java
 Mon Jun 17 10:42:36 2013
@@ -272,6 +272,8 @@ public class WSSConstants extends XMLSec
 
     public static final String PROP_TIMESTAMP_SECURITYEVENT = "PROP_TIMESTAMP";
 
+    public static final String PROP_ENCRYPTED_DATA_REFS = 
"PROP_ENCRYPTED_DATA_REFS";
+
     public static final Action TIMESTAMP = new 
Action(ConfigurationConstants.TIMESTAMP);
     public static final Action USERNAMETOKEN = new 
Action(ConfigurationConstants.USERNAME_TOKEN);
     public static final Action USERNAMETOKEN_SIGNED = new 
Action(ConfigurationConstants.USERNAME_TOKEN_SIGNATURE);

Modified: 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/DecryptInputProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/DecryptInputProcessor.java?rev=1493709&r1=1493708&r2=1493709&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/DecryptInputProcessor.java
 (original)
+++ 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/DecryptInputProcessor.java
 Mon Jun 17 10:42:36 2013
@@ -23,9 +23,11 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import javax.xml.bind.JAXBElement;
 import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
 
 import org.apache.wss4j.binding.wss10.SecurityTokenReferenceType;
 import org.apache.wss4j.common.bsp.BSPRule;
@@ -194,7 +196,34 @@ public class DecryptInputProcessor exten
         TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent = 
WSSUtils.createTokenSecurityEvent(inboundSecurityToken, 
encryptedDataType.getId());
         inboundSecurityContext.registerSecurityEvent(tokenSecurityEvent);
     }
-    
+
+    @Override
+    public void doFinal(InputProcessorChain inputProcessorChain) throws 
XMLStreamException, XMLSecurityException {
+        //find already processed references by the EncryptedDataHandler
+        List<String> encryptedDataRefs = 
inputProcessorChain.getSecurityContext().getAsList(WSSConstants.PROP_ENCRYPTED_DATA_REFS);
+        if (encryptedDataRefs != null && !encryptedDataRefs.isEmpty()) {
+            Map<String, ReferenceType> references = getReferences();
+            List<ReferenceType> processedReferences = getProcessedReferences();
+            if (references != null) {
+                Iterator<Map.Entry<String,ReferenceType>> iterator = 
references.entrySet().iterator();
+                while(iterator.hasNext()){
+                    Map.Entry<String,ReferenceType> next = iterator.next();
+                    final ReferenceType referenceType = next.getValue();
+                    String uri = 
WSSUtils.dropReferenceMarker(referenceType.getURI());
+
+                    Iterator<String> encryptedDataIterator = 
encryptedDataRefs.iterator();
+                    while (encryptedDataIterator.hasNext()) {
+                        String s = encryptedDataIterator.next();
+                        if (s.equals(uri)) {
+                            processedReferences.add(referenceType);
+                        }
+                    }
+                }
+            }
+        }
+        super.doFinal(inputProcessorChain);
+    }
+
     /*
    <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"; 
Id="EncDataId-1612925417" Type="http://www.w3.org/2001/04/xmlenc#Content";>
        <xenc:EncryptionMethod xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"; 
Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"; />

Copied: 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/EncryptedDataInputHandler.java
 (from r1493521, 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/ReferenceListInputHandler.java)
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/EncryptedDataInputHandler.java?p2=webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/EncryptedDataInputHandler.java&p1=webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/ReferenceListInputHandler.java&r1=1493521&r2=1493709&rev=1493709&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/ReferenceListInputHandler.java
 (original)
+++ 
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/EncryptedDataInputHandler.java
 Mon Jun 17 10:42:36 2013
@@ -18,31 +18,64 @@
  */
 package org.apache.wss4j.stax.impl.processor.input;
 
+import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
-import org.apache.xml.security.binding.xmlenc.ReferenceList;
+import org.apache.wss4j.stax.ext.WSSConstants;
 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
+import org.apache.xml.security.binding.xmlenc.ReferenceList;
+import org.apache.xml.security.binding.xmlenc.ReferenceType;
 import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.stax.ext.AbstractInputSecurityHeaderHandler;
 import org.apache.xml.security.stax.ext.InputProcessorChain;
+import org.apache.xml.security.stax.ext.XMLSecurityConstants;
 import org.apache.xml.security.stax.ext.XMLSecurityProperties;
 import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
 
+import javax.xml.stream.events.Attribute;
 import java.util.Deque;
+import java.util.Iterator;
 
 /**
- * Processor for the ReferenceList XML Structure
+ * Processor for the EncryptedData XML Structure in the security header
  */
-public class ReferenceListInputHandler extends 
AbstractInputSecurityHeaderHandler {
+public class EncryptedDataInputHandler extends 
AbstractInputSecurityHeaderHandler {
 
     @Override
     public void handle(final InputProcessorChain inputProcessorChain, final 
XMLSecurityProperties securityProperties,
                        final Deque<XMLSecEvent> eventQueue, final Integer 
index) throws XMLSecurityException {
 
-        final ReferenceList referenceList = (ReferenceList) 
parseStructure(eventQueue, index, securityProperties);
-
-        //instantiate a new DecryptInputProcessor and add it to the chain
-        inputProcessorChain.addProcessor(
-                new DecryptInputProcessor(null, referenceList, 
(WSSSecurityProperties) securityProperties,
-                        (WSInboundSecurityContext) 
inputProcessorChain.getSecurityContext()));
+        XMLSecEvent xmlSecEvent = null;
+        final Iterator<XMLSecEvent> xmlSecEventIterator = 
eventQueue.descendingIterator();
+        int curIdx = 0;
+        while (curIdx++ <= index) {
+            xmlSecEvent = xmlSecEventIterator.next();
+        }
+        if (!(xmlSecEvent instanceof XMLSecStartElement)) {
+            throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
+        }
+        final XMLSecStartElement encryptedDataElement = 
xmlSecEvent.asStartElement();
+        final Attribute idAttribute = 
encryptedDataElement.getAttributeByName(XMLSecurityConstants.ATT_NULL_Id);
+
+        DecryptInputProcessor decryptInputProcessor =
+                new DecryptInputProcessor(null, new ReferenceList(), 
(WSSSecurityProperties) securityProperties,
+                        (WSInboundSecurityContext) 
inputProcessorChain.getSecurityContext()) {
+
+                    @Override
+                    protected ReferenceType 
matchesReferenceId(XMLSecStartElement xmlSecStartElement) {
+                        if (xmlSecStartElement == encryptedDataElement) {
+                            ReferenceType referenceType = new ReferenceType();
+                            if (idAttribute != null) {
+                                final String uri = idAttribute.getValue();
+                                referenceType.setURI("#" + uri);
+                                
inputProcessorChain.getSecurityContext().putAsList(WSSConstants.PROP_ENCRYPTED_DATA_REFS,
 uri);
+                            }
+                            inputProcessorChain.removeProcessor(this);
+                            return referenceType;
+                        }
+                        return null;
+                    }
+                };
+        inputProcessorChain.addProcessor(decryptInputProcessor);
     }
 }

Modified: 
webservices/wss4j/trunk/ws-security-stax/src/main/resources/wss/wss-config.xml
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/resources/wss/wss-config.xml?rev=1493709&r1=1493708&r2=1493709&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-stax/src/main/resources/wss/wss-config.xml 
(original)
+++ 
webservices/wss4j/trunk/ws-security-stax/src/main/resources/wss/wss-config.xml 
Mon Jun 17 10:42:36 2013
@@ -16,6 +16,9 @@
         <Handler NAME="ReferenceList"
                  URI="http://www.w3.org/2001/04/xmlenc#";
                  
JAVACLASS="org.apache.wss4j.stax.impl.processor.input.ReferenceListInputHandler"/>
+        <Handler NAME="EncryptedData"
+                 URI="http://www.w3.org/2001/04/xmlenc#";
+                 
JAVACLASS="org.apache.wss4j.stax.impl.processor.input.EncryptedDataInputHandler"/>
         <Handler NAME="Signature"
                  URI="http://www.w3.org/2000/09/xmldsig#";
                  
JAVACLASS="org.apache.wss4j.stax.impl.processor.input.WSSSignatureInputHandler"/>

Modified: 
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/EncDecryptionTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/EncDecryptionTest.java?rev=1493709&r1=1493708&r2=1493709&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/EncDecryptionTest.java
 (original)
+++ 
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/EncDecryptionTest.java
 Mon Jun 17 10:42:36 2013
@@ -22,9 +22,11 @@ import org.apache.commons.compress.compr
 import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
 import org.apache.wss4j.common.ConfigurationConstants;
 import org.apache.wss4j.common.bsp.BSPRule;
+import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.crypto.CryptoFactory;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.WSEncryptionPart;
 import org.apache.wss4j.dom.handler.WSHandlerConstants;
 import org.apache.wss4j.dom.message.WSSecEncrypt;
 import org.apache.wss4j.dom.message.WSSecHeader;
@@ -50,6 +52,7 @@ import org.apache.xml.security.utils.Bas
 import org.testng.Assert;
 import org.testng.annotations.Test;
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
@@ -2499,4 +2502,135 @@ public class EncDecryptionTest extends A
             }
         }
     }
+
+    @Test
+    public void testEncryptedDataSecurityHeaderWithoutReferenceInbound() 
throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        {
+            InputStream sourceDocument = 
this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+
+            Document doc = 
documentBuilderFactory.newDocumentBuilder().parse(sourceDocument);
+
+            WSSecHeader secHeader = new WSSecHeader();
+            secHeader.insertSecurityHeader(doc);
+            Element securityHeaderElement = secHeader.getSecurityHeader();
+            
securityHeaderElement.appendChild(doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/";,
 "definitions").item(0));
+
+            WSSecEncrypt builder = new WSSecEncrypt();
+            builder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
+            builder.setUserInfo("receiver");
+            Crypto crypto = 
CryptoFactory.getInstance("transmitter-crypto.properties");
+            builder.prepare(doc, crypto);
+
+            WSEncryptionPart encP = new WSEncryptionPart("definitions", 
"http://schemas.xmlsoap.org/wsdl/";, "Element");
+            List<WSEncryptionPart> encryptionParts = new 
ArrayList<WSEncryptionPart>();
+            encryptionParts.add(encP);
+            Element ref = builder.encryptForRef(null, encryptionParts);
+            
ref.removeChild(ref.getElementsByTagNameNS("http://www.w3.org/2001/04/xmlenc#";, 
"DataReference").item(0));
+            builder.addExternalRefElement(ref, secHeader);
+            builder.prependToHeader(secHeader);
+
+            javax.xml.transform.Transformer transformer = 
TRANSFORMER_FACTORY.newTransformer();
+            transformer.transform(new DOMSource(doc), new StreamResult(baos));
+        }
+
+        //done encryption; now test decryption:
+        {
+            WSSSecurityProperties securityProperties = new 
WSSSecurityProperties();
+            
securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"),
 "default".toCharArray());
+            securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+            Document document = doInboundSecurity(securityProperties, 
xmlInputFactory.createXMLStreamReader(new 
ByteArrayInputStream(baos.toByteArray())));
+
+            //no encrypted content
+            NodeList nodeList = 
document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(),
 WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 0);
+        }
+    }
+
+    @Test
+    public void testEncryptedDataSecurityHeaderPrependedReferenceInbound() 
throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        {
+            InputStream sourceDocument = 
this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+
+            Document doc = 
documentBuilderFactory.newDocumentBuilder().parse(sourceDocument);
+
+            WSSecHeader secHeader = new WSSecHeader();
+            secHeader.insertSecurityHeader(doc);
+            Element securityHeaderElement = secHeader.getSecurityHeader();
+            
securityHeaderElement.appendChild(doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/";,
 "definitions").item(0));
+
+            WSSecEncrypt builder = new WSSecEncrypt();
+            builder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
+            builder.setUserInfo("receiver");
+            Crypto crypto = 
CryptoFactory.getInstance("transmitter-crypto.properties");
+            builder.prepare(doc, crypto);
+
+            WSEncryptionPart encP = new WSEncryptionPart("definitions", 
"http://schemas.xmlsoap.org/wsdl/";, "Element");
+            List<WSEncryptionPart> encryptionParts = new 
ArrayList<WSEncryptionPart>();
+            encryptionParts.add(encP);
+            Element ref = builder.encryptForRef(null, encryptionParts);
+            builder.addExternalRefElement(ref, secHeader);
+            builder.prependToHeader(secHeader);
+
+            javax.xml.transform.Transformer transformer = 
TRANSFORMER_FACTORY.newTransformer();
+            transformer.transform(new DOMSource(doc), new StreamResult(baos));
+        }
+
+        //done encryption; now test decryption:
+        {
+            WSSSecurityProperties securityProperties = new 
WSSSecurityProperties();
+            
securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"),
 "default".toCharArray());
+            securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+            Document document = doInboundSecurity(securityProperties, 
xmlInputFactory.createXMLStreamReader(new 
ByteArrayInputStream(baos.toByteArray())));
+
+            //no encrypted content
+            NodeList nodeList = 
document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(),
 WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 0);
+        }
+    }
+
+    @Test
+    public void testEncryptedDataSecurityHeaderAppendedReferenceInbound() 
throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        {
+            InputStream sourceDocument = 
this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+
+            Document doc = 
documentBuilderFactory.newDocumentBuilder().parse(sourceDocument);
+
+            WSSecHeader secHeader = new WSSecHeader();
+            secHeader.insertSecurityHeader(doc);
+            Element securityHeaderElement = secHeader.getSecurityHeader();
+            
securityHeaderElement.appendChild(doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/";,
 "definitions").item(0));
+
+            WSSecEncrypt builder = new WSSecEncrypt();
+            builder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
+            builder.setUserInfo("receiver");
+            Crypto crypto = 
CryptoFactory.getInstance("transmitter-crypto.properties");
+            builder.prepare(doc, crypto);
+
+            WSEncryptionPart encP = new WSEncryptionPart("definitions", 
"http://schemas.xmlsoap.org/wsdl/";, "Element");
+            List<WSEncryptionPart> encryptionParts = new 
ArrayList<WSEncryptionPart>();
+            encryptionParts.add(encP);
+            Element ref = builder.encryptForRef(null, encryptionParts);
+            builder.prependToHeader(secHeader);
+            //builder.addExternalRefElement(ref, secHeader);
+            securityHeaderElement.appendChild(ref);
+
+            javax.xml.transform.Transformer transformer = 
TRANSFORMER_FACTORY.newTransformer();
+            transformer.transform(new DOMSource(doc), new StreamResult(baos));
+        }
+
+        //done encryption; now test decryption:
+        {
+            WSSSecurityProperties securityProperties = new 
WSSSecurityProperties();
+            
securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"),
 "default".toCharArray());
+            securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+            Document document = doInboundSecurity(securityProperties, 
xmlInputFactory.createXMLStreamReader(new 
ByteArrayInputStream(baos.toByteArray())));
+
+            //no encrypted content
+            NodeList nodeList = 
document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(),
 WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 0);
+        }
+    }
 }


Reply via email to