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);
+ }
+ }
}
|