Author: giger
Date: Fri Apr 20 10:11:46 2012
New Revision: 1328294
URL: http://svn.apache.org/viewvc?rev=1328294&view=rev
Log:
Introduce proprietary Compress-Transformation for Encryption / Decryption.
WSS-386
Added:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/util/MultiInputStream.java
(with props)
Modified:
webservices/wss4j/branches/swssf/streaming-ws-security/src/test/java/org/swssf/wss/test/EncDecryptionTest.java
webservices/wss4j/branches/swssf/streaming-ws-security/src/test/java/org/swssf/wss/test/VulnerabliltyVectorsTest.java
webservices/wss4j/branches/swssf/streaming-xml-security/pom.xml
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/config/TransformerAlgorithmMapper.java
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/AbstractOutputProcessor.java
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityProperties.java
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityUtils.java
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/input/AbstractDecryptInputProcessor.java
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/output/AbstractEncryptOutputProcessor.java
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/schemas/security-config.xsd
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/security-config.xml
Modified:
webservices/wss4j/branches/swssf/streaming-ws-security/src/test/java/org/swssf/wss/test/EncDecryptionTest.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/test/java/org/swssf/wss/test/EncDecryptionTest.java?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-ws-security/src/test/java/org/swssf/wss/test/EncDecryptionTest.java
(original)
+++
webservices/wss4j/branches/swssf/streaming-ws-security/src/test/java/org/swssf/wss/test/EncDecryptionTest.java
Fri Apr 20 10:11:46 2012
@@ -1227,4 +1227,99 @@ public class EncDecryptionTest extends A
Assert.assertEquals(nodeList.getLength(), 0);
}
}
+
+ @Test
+ public void testCompressedEncDecryption() throws Exception {
+
+ ByteArrayOutputStream baos;
+ {
+ WSSSecurityProperties securityProperties = new
WSSSecurityProperties();
+ WSSConstants.Action[] actions = new
WSSConstants.Action[]{WSSConstants.ENCRYPT};
+ securityProperties.setOutAction(actions);
+
securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"),
"default".toCharArray());
+ securityProperties.setEncryptionUser("receiver");
+
securityProperties.setEncryptionCompressionAlgorithm("http://www.apache.org/2012/04/xmlsec/gzip");
+
+ InputStream sourceDocument =
this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+ baos = doOutboundSecurity(securityProperties, sourceDocument);
+
+ Document document =
documentBuilderFactory.newDocumentBuilder().parse(new
ByteArrayInputStream(baos.toByteArray()));
+ NodeList nodeList =
document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(),
WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
+
Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(),
WSSConstants.TAG_wsse_Security.getLocalPart());
+
+ XPathExpression xPathExpression =
getXPath("/env:Envelope/env:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
+ Node node = (Node) xPathExpression.evaluate(document,
XPathConstants.NODE);
+ Assert.assertNotNull(node);
+
+ nodeList =
document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(),
WSSConstants.TAG_xenc_DataReference.getLocalPart());
+ Assert.assertEquals(nodeList.getLength(), 1);
+
+ nodeList =
document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(),
WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
+ Assert.assertEquals(nodeList.getLength(), 1);
+
+ xPathExpression =
getXPath("/env:Envelope/env:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#aes256-cbc']");
+ node = (Node) xPathExpression.evaluate(document,
XPathConstants.NODE);
+ Assert.assertNotNull(node);
+
+
Assert.assertEquals(node.getParentNode().getParentNode().getLocalName(),
"Body");
+ NodeList childNodes =
node.getParentNode().getParentNode().getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node child = childNodes.item(i);
+ if (child.getNodeType() == Node.TEXT_NODE) {
+ Assert.assertEquals(child.getTextContent().trim(), "");
+ } else if (child.getNodeType() == Node.ELEMENT_NODE) {
+ Assert.assertEquals(child, nodeList.item(0));
+ } else {
+ Assert.fail("Unexpected Node encountered");
+ }
+ }
+ }
+
+ //done encryption; now test decryption:
+ {
+ WSSSecurityProperties securityProperties = new
WSSSecurityProperties();
+
securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"),
"default".toCharArray());
+ securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+
+ SecurityEvent.Event[] expectedSecurityEvents = new
SecurityEvent.Event[]{
+ SecurityEvent.Event.X509Token,
+ SecurityEvent.Event.EncryptedPart,
+ SecurityEvent.Event.AlgorithmSuite,
+ SecurityEvent.Event.AlgorithmSuite,
+ SecurityEvent.Event.Operation,
+ };
+ final TestSecurityEventListener securityEventListener = new
TestSecurityEventListener(expectedSecurityEvents);
+
+ Document document = doInboundSecurity(securityProperties,
xmlInputFactory.createXMLStreamReader(new
ByteArrayInputStream(baos.toByteArray())), securityEventListener);
+
+ //header element must still be there
+ NodeList nodeList =
document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(),
WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
+ Assert.assertEquals(nodeList.getLength(), 1);
+
Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(),
WSSConstants.TAG_wsse_Security.getLocalPart());
+
+ //no encrypted content
+ nodeList =
document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(),
WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
+ Assert.assertEquals(nodeList.getLength(), 0);
+
+ securityEventListener.compare();
+
+ List<SecurityEvent> receivedSecurityEvents =
securityEventListener.getReceivedSecurityEvents();
+ for (int i = 0; i < receivedSecurityEvents.size(); i++) {
+ SecurityEvent securityEvent = receivedSecurityEvents.get(i);
+ if (securityEvent.getSecurityEventType() ==
SecurityEvent.Event.Operation) {
+ OperationSecurityEvent operationSecurityEvent =
(OperationSecurityEvent) securityEvent;
+ Assert.assertEquals(operationSecurityEvent.getOperation(),
new QName("http://schemas.xmlsoap.org/wsdl/", "definitions"));
+ } else if (securityEvent.getSecurityEventType() ==
SecurityEvent.Event.EncryptedPart) {
+ EncryptedPartSecurityEvent encryptedPartSecurityEvent =
(EncryptedPartSecurityEvent) securityEvent;
+
Assert.assertNotNull(encryptedPartSecurityEvent.getXmlEvent());
+
Assert.assertNotNull(encryptedPartSecurityEvent.getSecurityToken());
+
Assert.assertNotNull(encryptedPartSecurityEvent.getElementPath());
+ final QName expectedElementName = new
QName("http://schemas.xmlsoap.org/soap/envelope/", "Body");
+
Assert.assertEquals(encryptedPartSecurityEvent.getXmlEvent().asStartElement().getName(),
expectedElementName);
+
Assert.assertEquals(encryptedPartSecurityEvent.getElementPath().size(), 2);
+
Assert.assertEquals(encryptedPartSecurityEvent.getElementPath().get(encryptedPartSecurityEvent.getElementPath().size()
- 1), expectedElementName);
+ }
+ }
+ }
+ }
}
Modified:
webservices/wss4j/branches/swssf/streaming-ws-security/src/test/java/org/swssf/wss/test/VulnerabliltyVectorsTest.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/test/java/org/swssf/wss/test/VulnerabliltyVectorsTest.java?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-ws-security/src/test/java/org/swssf/wss/test/VulnerabliltyVectorsTest.java
(original)
+++
webservices/wss4j/branches/swssf/streaming-ws-security/src/test/java/org/swssf/wss/test/VulnerabliltyVectorsTest.java
Fri Apr 20 10:11:46 2012
@@ -198,7 +198,7 @@ public class VulnerabliltyVectorsTest ex
Assert.assertNotNull(throwable);
//todo exception should be a WSSecurityException
Assert.assertTrue(throwable instanceof XMLSecurityException);
- Assert.assertEquals(throwable.getMessage(), "The signature or
decryption was invalid (Some encryption references were not processed...
Probably security header ordering problem?)");
+ Assert.assertTrue(throwable.getMessage().contains("The signature
or decryption was invalid (Digest verification failed for URI"));
}
}
Modified: webservices/wss4j/branches/swssf/streaming-xml-security/pom.xml
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/pom.xml?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/pom.xml (original)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/pom.xml Fri Apr 20
10:11:46 2012
@@ -73,6 +73,11 @@
<version>1.5</version>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
Modified:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/config/TransformerAlgorithmMapper.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/config/TransformerAlgorithmMapper.java?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/config/TransformerAlgorithmMapper.java
(original)
+++
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/config/TransformerAlgorithmMapper.java
Fri Apr 20 10:11:46 2012
@@ -20,7 +20,6 @@ package org.swssf.xmlsec.config;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.swssf.xmlsec.ext.Transformer;
import org.swssf.xmlsec.ext.XMLSecurityException;
import org.swssf.xmlsec.ext.XMLSecurityUtils;
import org.xmlsecurity.ns.configuration.TransformAlgorithmType;
@@ -41,8 +40,9 @@ public class TransformerAlgorithmMapper
private static final transient Log logger =
LogFactory.getLog(TransformerAlgorithmMapper.class);
- private static Map<String, TransformAlgorithmType> algorithmsMap;
- private static Map<String, Class<Transformer>> algorithmsClassMap;
+ private static Map<String, Class> algorithmsClassMapInOut;
+ private static Map<String, Class> algorithmsClassMapIn;
+ private static Map<String, Class> algorithmsClassMapOut;
private TransformerAlgorithmMapper() {
}
@@ -50,25 +50,36 @@ public class TransformerAlgorithmMapper
@SuppressWarnings("unchecked")
protected synchronized static void init(TransformAlgorithmsType
transformAlgorithms) throws Exception {
List<TransformAlgorithmType> algorithms =
transformAlgorithms.getTransformAlgorithm();
- algorithmsMap = new HashMap<String,
TransformAlgorithmType>(algorithms.size());
- algorithmsClassMap = new HashMap<String, Class<Transformer>>();
+ algorithmsClassMapInOut = new HashMap<String, Class>();
+ algorithmsClassMapIn = new HashMap<String, Class>();
+ algorithmsClassMapOut = new HashMap<String, Class>();
for (int i = 0; i < algorithms.size(); i++) {
TransformAlgorithmType algorithmType = algorithms.get(i);
- algorithmsMap.put(algorithmType.getURI(), algorithmType);
- algorithmsClassMap.put(algorithmType.getURI(),
XMLSecurityUtils.loadClass(algorithmType.getJAVACLASS()));
+ if (algorithmType.getINOUT() == null) {
+ algorithmsClassMapInOut.put(algorithmType.getURI(),
XMLSecurityUtils.loadClass(algorithmType.getJAVACLASS()));
+ } else if ("IN".equals(algorithmType.getINOUT().value())) {
+ algorithmsClassMapIn.put(algorithmType.getURI(),
XMLSecurityUtils.loadClass(algorithmType.getJAVACLASS()));
+ } else if ("OUT".equals(algorithmType.getINOUT().value())) {
+ algorithmsClassMapOut.put(algorithmType.getURI(),
XMLSecurityUtils.loadClass(algorithmType.getJAVACLASS()));
+ } else {
+ throw new IllegalArgumentException("INOUT parameter " +
algorithmType.getINOUT().value() + " unsupported");
+ }
}
}
- public static Class<Transformer> getTransformerClass(String algoURI)
throws XMLSecurityException {
- Class<Transformer> clazz = algorithmsClassMap.get(algoURI);
+ public static Class<?> getTransformerClass(String algoURI, String inOut)
throws XMLSecurityException {
+ Class clazz;
+ if ("IN".equals(inOut)) {
+ clazz = algorithmsClassMapIn.get(algoURI);
+ } else if ("OUT".equals(inOut)) {
+ clazz = algorithmsClassMapOut.get(algoURI);
+ } else {
+ clazz = algorithmsClassMapInOut.get(algoURI);
+ }
if (clazz == null) {
throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK);
}
return clazz;
}
-
- public static TransformAlgorithmType getAlgorithmMapping(String algoURI) {
- return algorithmsMap.get(algoURI);
- }
}
Modified:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/AbstractOutputProcessor.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/AbstractOutputProcessor.java?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/AbstractOutputProcessor.java
(original)
+++
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/AbstractOutputProcessor.java
Fri Apr 20 10:11:46 2012
@@ -262,6 +262,15 @@ public abstract class AbstractOutputProc
attributes = new HashMap<QName, String>();
attributes.put(XMLSecurityConstants.ATT_NULL_URI, "#" +
encryptionPartDef.getEncRefId());
createStartElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_DataReference, attributes);
+ final String compressionAlgorithm =
getSecurityProperties().getEncryptionCompressionAlgorithm();
+ if (compressionAlgorithm != null) {
+ createStartElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_dsig_Transforms, null);
+ attributes = new HashMap<QName, String>();
+ attributes.put(XMLSecurityConstants.ATT_NULL_Algorithm,
compressionAlgorithm);
+ createStartElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_dsig_Transform, attributes);
+ createEndElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_dsig_Transform);
+ createEndElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_dsig_Transforms);
+ }
createEndElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_DataReference);
}
createEndElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_ReferenceList);
Modified:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityProperties.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityProperties.java?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityProperties.java
(original)
+++
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityProperties.java
Fri Apr 20 10:11:46 2012
@@ -162,6 +162,7 @@ public class XMLSecurityProperties {
private String encryptionUser;
private X509Certificate encryptionUseThisCertificate;
private String encryptionSymAlgorithm;
+ private String encryptionCompressionAlgorithm;
private String encryptionKeyTransportAlgorithm;
private List<SecurePart> encryptionParts = new LinkedList<SecurePart>();
@@ -322,6 +323,14 @@ public class XMLSecurityProperties {
this.encryptionUser = encryptionUser;
}
+ public String getEncryptionCompressionAlgorithm() {
+ return encryptionCompressionAlgorithm;
+ }
+
+ public void setEncryptionCompressionAlgorithm(String
encryptionCompressionAlgorithm) {
+ this.encryptionCompressionAlgorithm = encryptionCompressionAlgorithm;
+ }
+
private List<SecurePart> signatureParts = new LinkedList<SecurePart>();
private String signatureAlgorithm;
private String signatureDigestAlgorithm;
Modified:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityUtils.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityUtils.java?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityUtils.java
(original)
+++
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/ext/XMLSecurityUtils.java
Fri Apr 20 10:11:46 2012
@@ -209,8 +209,9 @@ public class XMLSecurityUtils {
return xmlEvent;
}
+ //todo optimize?
public static Transformer getTransformer(Object methodParameter1, Object
methodParameter2, String algorithm) throws XMLSecurityException,
InstantiationException, IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
- Class<Transformer> transformerClass =
TransformerAlgorithmMapper.getTransformerClass(algorithm);
+ Class<Transformer> transformerClass = (Class<Transformer>)
TransformerAlgorithmMapper.getTransformerClass(algorithm, null);
Transformer childTransformer;
try {
Constructor<Transformer> constructor =
transformerClass.getConstructor(Transformer.class);
Modified:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/input/AbstractDecryptInputProcessor.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/input/AbstractDecryptInputProcessor.java?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/input/AbstractDecryptInputProcessor.java
(original)
+++
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/input/AbstractDecryptInputProcessor.java
Fri Apr 20 10:11:46 2012
@@ -20,15 +20,19 @@ package org.swssf.xmlsec.impl.processor.
import org.apache.commons.codec.binary.Base64OutputStream;
import org.swssf.binding.xmldsig.KeyInfoType;
+import org.swssf.binding.xmldsig.TransformType;
+import org.swssf.binding.xmldsig.TransformsType;
import org.swssf.binding.xmlenc.EncryptedDataType;
import org.swssf.binding.xmlenc.ReferenceList;
import org.swssf.binding.xmlenc.ReferenceType;
import org.swssf.xmlsec.config.JCEAlgorithmMapper;
+import org.swssf.xmlsec.config.TransformerAlgorithmMapper;
import org.swssf.xmlsec.ext.*;
import org.swssf.xmlsec.impl.XMLSecurityEventReader;
import org.swssf.xmlsec.impl.securityToken.SecurityTokenFactory;
import org.swssf.xmlsec.impl.util.IDGenerator;
import org.swssf.xmlsec.impl.util.IVSplittingOutputStream;
+import org.swssf.xmlsec.impl.util.MultiInputStream;
import org.swssf.xmlsec.impl.util.ReplaceableOuputStream;
import org.xmlsecurity.ns.configuration.AlgorithmType;
@@ -47,6 +51,8 @@ import javax.xml.stream.events.Attribute
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import java.io.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
@@ -143,6 +149,7 @@ public abstract class AbstractDecryptInp
if (!tmpXmlEventList.isEmpty()) {
return tmpXmlEventList.pollLast();
}
+ return xmlEvent;
}
//duplicate id's are forbidden
if (processedReferences.contains(referenceType)) {
@@ -200,11 +207,46 @@ public abstract class AbstractDecryptInp
inputProcessorChain.getDocumentContext().removePathElement();
+ InputStream prologInputStream;
+ InputStream epilogInputStream;
+ try {
+ prologInputStream = writeWrapperStartElement(xmlEventNS);
+ epilogInputStream = writeWrapperEndElement();
+ } catch (UnsupportedEncodingException e) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, e);
+ } catch (IOException e) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, e);
+ }
+
+ InputStream decryptInputStream =
decryptionThread.getPipedInputStream();
+
+ TransformsType transformsType =
XMLSecurityUtils.getQNameType(referenceType.getAny(),
XMLSecurityConstants.TAG_dsig_Transforms);
+ if (transformsType != null) {
+ List<TransformType> transformTypes =
transformsType.getTransform();
+ if (transformTypes.size() > 1) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ TransformType transformType = transformTypes.get(0);
+ Class<InputStream> transformerClass = (Class<InputStream>)
TransformerAlgorithmMapper.getTransformerClass(transformType.getAlgorithm(),
"IN");
+ try {
+ Constructor<InputStream> constructor =
transformerClass.getConstructor(InputStream.class);
+ decryptInputStream =
constructor.newInstance(decryptInputStream);
+ } catch (InvocationTargetException e) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, e);
+ } catch (NoSuchMethodException e) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, e);
+ } catch (InstantiationException e) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, e);
+ } catch (IllegalAccessException e) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, e);
+ }
+ }
+
//spec says (4.2): "The cleartext octet sequence obtained in
step 3 is interpreted as UTF-8 encoded character data."
XMLEventReader xmlEventReader =
inputProcessorChain.getSecurityContext().<XMLInputFactory>get(
-
XMLSecurityConstants.XMLINPUTFACTORY).createXMLEventReader(decryptionThread.getPipedInputStream(),
- "UTF-8");
+
XMLSecurityConstants.XMLINPUTFACTORY).createXMLEventReader(
+ new MultiInputStream(prologInputStream,
decryptInputStream, epilogInputStream), "UTF-8");
//forward to wrapper element
forwardToWrapperElement(xmlEventReader);
@@ -225,6 +267,65 @@ public abstract class AbstractDecryptInp
return xmlEvent;
}
+ private InputStream writeWrapperStartElement(XMLEventNS startXMLElement)
throws IOException {
+
+ ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
+ //temporary writer to write the dummy wrapper element with all
namespaces in the current scope
+ //spec says (4.2): "The cleartext octet sequence obtained in step 3 is
interpreted as UTF-8 encoded character data."
+ Writer writer = new OutputStreamWriter(byteArrayOutputStream, "UTF-8");
+
+ writer.write('<');
+ writer.write(wrapperElementName.getPrefix());
+ writer.write(':');
+ writer.write(wrapperElementName.getLocalPart());
+ writer.write(' ');
+ writer.write("xmlns:");
+ writer.write(wrapperElementName.getPrefix());
+ writer.write("=\"");
+ writer.write(wrapperElementName.getNamespaceURI());
+ writer.write('\"');
+
+ //apply all namespaces from current scope to get a valid
documentfragment:
+ List<ComparableNamespace> comparableNamespacesToApply = new
LinkedList<ComparableNamespace>();
+ List<ComparableNamespace>[] comparableNamespaceList =
startXMLElement.getNamespaceList();
+ for (int i = 0; i < comparableNamespaceList.length; i++) {
+ List<ComparableNamespace> comparableNamespaces =
comparableNamespaceList[i];
+ Iterator<ComparableNamespace> comparableNamespaceIterator =
comparableNamespaces.iterator();
+ while (comparableNamespaceIterator.hasNext()) {
+ ComparableNamespace comparableNamespace =
comparableNamespaceIterator.next();
+ if
(!comparableNamespacesToApply.contains(comparableNamespace)) {
+ comparableNamespacesToApply.add(comparableNamespace);
+ }
+ }
+ }
+ Iterator<ComparableNamespace> comparableNamespaceIterator =
comparableNamespacesToApply.iterator();
+ while (comparableNamespaceIterator.hasNext()) {
+ ComparableNamespace comparableNamespace =
comparableNamespaceIterator.next();
+ writer.write(' ');
+ //todo write namespace ourself
+ writer.write(comparableNamespace.toString());
+ }
+
+ writer.write('>');
+ writer.close();
+ return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+ }
+
+ private InputStream writeWrapperEndElement() throws IOException {
+
+ ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
+ Writer writer = new OutputStreamWriter(byteArrayOutputStream, "UTF-8");
+
+ //close the dummy wrapper element:
+ writer.write("</");
+ writer.write(wrapperElementName.getPrefix());
+ writer.write(':');
+ writer.write(wrapperElementName.getLocalPart());
+ writer.write('>');
+ writer.close();
+ return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+ }
+
private void forwardToWrapperElement(XMLEventReader xmlEventReader) throws
XMLStreamException {
XMLEvent tmpXmlEvent;
do {
@@ -337,7 +438,7 @@ public abstract class AbstractDecryptInp
}
private List<ComparableNamespace>[] getNamespacesInScope(XMLEvent
xmlEvent, boolean encryptedHeader) {
- XMLEventNS xmlEventNS = (XMLEventNS)xmlEvent;
+ XMLEventNS xmlEventNS = (XMLEventNS) xmlEvent;
if (encryptedHeader) {
return Arrays.copyOfRange(xmlEventNS.getNamespaceList(), 2,
xmlEventNS.getNamespaceList().length);
} else {
@@ -346,7 +447,7 @@ public abstract class AbstractDecryptInp
}
private List<ComparableAttribute>[] getAttributesInScope(XMLEvent
xmlEvent, boolean encryptedHeader) {
- XMLEventNS xmlEventNS = (XMLEventNS)xmlEvent;
+ XMLEventNS xmlEventNS = (XMLEventNS) xmlEvent;
if (encryptedHeader) {
return Arrays.copyOfRange(xmlEventNS.getAttributeList(), 2,
xmlEventNS.getNamespaceList().length);
} else {
@@ -587,46 +688,8 @@ public abstract class AbstractDecryptInp
public void run() {
try {
- //temporary writer to write the dummy wrapper element with all
namespaces in the current scope
- //spec says (4.2): "The cleartext octet sequence obtained in
step 3 is interpreted as UTF-8 encoded character data."
- BufferedWriter tempBufferedWriter = new BufferedWriter(
- new OutputStreamWriter(
- pipedOutputStream,
- "UTF-8"
- )
- );
-
- writeWrapperStartElement(tempBufferedWriter);
- //calling flush after every piece to prevent data salad...
- tempBufferedWriter.flush();
-
IVSplittingOutputStream ivSplittingOutputStream = new
IVSplittingOutputStream(
- new CipherOutputStream(new
FilterOutputStream(pipedOutputStream) {
-
- @Override
- public void write(int b) throws IOException {
- out.write(b);
- }
-
- @Override
- public void write(byte[] b) throws IOException {
- out.write(b);
- }
-
- @Override
- public void write(byte[] b, int off, int len)
throws IOException {
- out.write(b, off, len);
- }
-
- @Override
- public void close() throws IOException {
- //we overwrite the close method and don't
delegate close. Close must be done separately.
- //The reason behind this is the
Base64DecoderStream which does the final on close() but after
- //that we have to write our dummy end tag
- //just calling flush here, seems to be fine
- out.flush();
- }
- }, getSymmetricCipher()),
+ new CipherOutputStream(pipedOutputStream,
getSymmetricCipher()),
getSymmetricCipher(), getSecretKey());
//buffering seems not to help
//bufferedOutputStream = new BufferedOutputStream(new
Base64OutputStream(ivSplittingOutputStream, false), 8192 * 5);
@@ -655,9 +718,6 @@ public abstract class AbstractDecryptInp
//close to get Cipher.doFinal() called
decryptOutputStream.close();
- writeWrapperEndElement(tempBufferedWriter);
- tempBufferedWriter.close();
-
logger.debug("Decryption thread finished");
} catch (Exception e) {
@@ -665,51 +725,6 @@ public abstract class AbstractDecryptInp
}
}
- private void writeWrapperStartElement(BufferedWriter
tempBufferedWriter) throws IOException {
- tempBufferedWriter.write('<');
- tempBufferedWriter.write(wrapperElementName.getPrefix());
- tempBufferedWriter.write(':');
- tempBufferedWriter.write(wrapperElementName.getLocalPart());
- tempBufferedWriter.write(' ');
- tempBufferedWriter.write("xmlns:");
- tempBufferedWriter.write(wrapperElementName.getPrefix());
- tempBufferedWriter.write("=\"");
- tempBufferedWriter.write(wrapperElementName.getNamespaceURI());
- tempBufferedWriter.write('\"');
-
- //apply all namespaces from current scope to get a valid
documentfragment:
- List<ComparableNamespace> comparableNamespacesToApply = new
LinkedList<ComparableNamespace>();
- List<ComparableNamespace>[] comparableNamespaceList =
startXMLElement.getNamespaceList();
- for (int i = 0; i < comparableNamespaceList.length; i++) {
- List<ComparableNamespace> comparableNamespaces =
comparableNamespaceList[i];
- Iterator<ComparableNamespace> comparableNamespaceIterator =
comparableNamespaces.iterator();
- while (comparableNamespaceIterator.hasNext()) {
- ComparableNamespace comparableNamespace =
comparableNamespaceIterator.next();
- if
(!comparableNamespacesToApply.contains(comparableNamespace)) {
- comparableNamespacesToApply.add(comparableNamespace);
- }
- }
- }
- Iterator<ComparableNamespace> comparableNamespaceIterator =
comparableNamespacesToApply.iterator();
- while (comparableNamespaceIterator.hasNext()) {
- ComparableNamespace comparableNamespace =
comparableNamespaceIterator.next();
- tempBufferedWriter.write(' ');
- tempBufferedWriter.write(comparableNamespace.toString());
- }
-
- tempBufferedWriter.write('>');
- }
-
- private void writeWrapperEndElement(BufferedWriter tempBufferedWriter)
throws IOException {
- //close the dummy wrapper element:
- tempBufferedWriter.write("</");
- tempBufferedWriter.write(wrapperElementName.getPrefix());
- tempBufferedWriter.write(':');
- tempBufferedWriter.write(wrapperElementName.getLocalPart());
- tempBufferedWriter.write('>');
- //real close of the stream
- }
-
protected Cipher getSymmetricCipher() {
return symmetricCipher;
}
Modified:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/output/AbstractEncryptOutputProcessor.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/output/AbstractEncryptOutputProcessor.java?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/output/AbstractEncryptOutputProcessor.java
(original)
+++
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/processor/output/AbstractEncryptOutputProcessor.java
Fri Apr 20 10:11:46 2012
@@ -20,6 +20,7 @@ package org.swssf.xmlsec.impl.processor.
import org.apache.commons.codec.binary.Base64OutputStream;
import org.swssf.xmlsec.config.JCEAlgorithmMapper;
+import org.swssf.xmlsec.config.TransformerAlgorithmMapper;
import org.swssf.xmlsec.ext.*;
import org.swssf.xmlsec.impl.EncryptionPartDef;
import org.swssf.xmlsec.impl.util.TrimmerOutputStream;
@@ -39,6 +40,8 @@ import javax.xml.stream.events.XMLEvent;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
@@ -112,8 +115,16 @@ public abstract class AbstractEncryptOut
Base64OutputStream base64EncoderStream = new
Base64OutputStream(new
BufferedOutputStream(characterEventGeneratorOutputStream), true, 76, new
byte[]{'\n'});
base64EncoderStream.write(iv);
+ OutputStream outputStream = new
CipherOutputStream(base64EncoderStream, symmetricCipher);
+
+ String compressionAlgorithm =
getSecurityProperties().getEncryptionCompressionAlgorithm();
+ if (compressionAlgorithm != null) {
+ Class<OutputStream> transformerClass =
(Class<OutputStream>)
TransformerAlgorithmMapper.getTransformerClass(compressionAlgorithm, "OUT");
+ Constructor<OutputStream> constructor =
transformerClass.getConstructor(OutputStream.class);
+ outputStream = constructor.newInstance(outputStream);
+ }
//the trimmer output stream is needed to strip away the dummy
wrapping element which must be added
- cipherOutputStream = new TrimmerOutputStream(new
CipherOutputStream(base64EncoderStream, symmetricCipher), 8192, 3, 4);
+ cipherOutputStream = new TrimmerOutputStream(outputStream,
8192, 3, 4);
//we create a new StAX writer for optimized namespace writing.
XMLOutputFactory xmlOutputFactory =
XMLOutputFactory.newInstance();
@@ -132,6 +143,14 @@ public abstract class AbstractEncryptOut
throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
} catch (InvalidKeyException e) {
throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
+ } catch (InvocationTargetException e) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, e);
+ } catch (NoSuchMethodException e) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, e);
+ } catch (InstantiationException e) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, e);
+ } catch (IllegalAccessException e) {
+ throw new
XMLSecurityException(XMLSecurityException.ErrorCode.FAILURE, e);
}
super.init(outputProcessorChain);
Added:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/util/MultiInputStream.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/util/MultiInputStream.java?rev=1328294&view=auto
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/util/MultiInputStream.java
(added)
+++
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/util/MultiInputStream.java
Fri Apr 20 10:11:46 2012
@@ -0,0 +1,83 @@
+/**
+ * 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.swssf.xmlsec.impl.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author $Author$
+ * @version $Revision$ $Date$
+ */
+public class MultiInputStream extends InputStream {
+
+ private InputStream[] inputStreams;
+ private int inputStreamCount;
+ private int inputStreamIndex = 0;
+
+ public MultiInputStream(InputStream... inputStreams) {
+ this.inputStreams = inputStreams;
+ this.inputStreamCount = inputStreams.length;
+ }
+
+ @Override
+ public int read() throws IOException {
+ for (int i = inputStreamIndex; i < inputStreamCount; i++) {
+ int b = inputStreams[i].read();
+ if (b >= 0) {
+ return b;
+ }
+ inputStreamIndex++;
+ }
+ return -1;
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ for (int i = inputStreamIndex; i < inputStreamCount; i++) {
+ int read = inputStreams[i].read(b, off, len);
+ if (read >= 0) {
+ return read;
+ }
+ inputStreamIndex++;
+ }
+ return -1;
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ throw new UnsupportedOperationException("skip() not supported");
+ }
+
+ @Override
+ public void close() throws IOException {
+ for (int i = 0; i < inputStreamCount; i++) {
+ try {
+ inputStreams[i].close();
+ } catch (IOException e) {
+ //ignore and try to close the others
+ }
+ }
+ }
+}
Propchange:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/util/MultiInputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/util/MultiInputStream.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/schemas/security-config.xsd
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/schemas/security-config.xsd?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/schemas/security-config.xsd
(original)
+++
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/schemas/security-config.xsd
Fri Apr 20 10:11:46 2012
@@ -20,11 +20,18 @@
</xs:extension>
</xs:simpleContent>
</xs:complexType>
+ <xs:simpleType name="inOutAttrType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="IN"/>
+ <xs:enumeration value="OUT"/>
+ </xs:restriction>
+ </xs:simpleType>
<xs:complexType name="TransformAlgorithmType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="URI" use="required"/>
<xs:attribute type="xs:string" name="JAVACLASS" use="required"/>
+ <xs:attribute type="con:inOutAttrType" name="INOUT" use="optional"
xmlns:con="http://www.xmlsecurity.org/NS/configuration"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
Modified:
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/security-config.xml
URL:
http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/security-config.xml?rev=1328294&r1=1328293&r2=1328294&view=diff
==============================================================================
---
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/security-config.xml
(original)
+++
webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/security-config.xml
Fri Apr 20 10:11:46 2012
@@ -48,6 +48,23 @@
<!-- XPath version 2b -->
<TransformAlgorithm URI="http://www.w3.org/2002/06/xmldsig-filter2"
JAVACLASS="org.apache.xml.security.transforms.implementations.TransformXPath2Filter"
/>
+
+ <TransformAlgorithm URI="http://www.apache.org/2012/04/xmlsec/gzip"
INOUT="IN"
+
JAVACLASS="org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream"
/>
+ <TransformAlgorithm URI="http://www.apache.org/2012/04/xmlsec/bzip2"
INOUT="IN"
+
JAVACLASS="org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream"
/>
+ <TransformAlgorithm URI="http://www.apache.org/2012/04/xmlsec/xz"
INOUT="IN"
+
JAVACLASS="org.apache.commons.compress.compressors.xz.XZCompressorInputStream"
/>
+ <TransformAlgorithm URI="http://www.apache.org/2012/04/xmlsec/pack200"
INOUT="IN"
+
JAVACLASS="org.apache.commons.compress.compressors.pack200.Pack200CompressorInputStream"
/>
+ <TransformAlgorithm URI="http://www.apache.org/2012/04/xmlsec/gzip"
INOUT="OUT"
+
JAVACLASS="org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream"
/>
+ <TransformAlgorithm URI="http://www.apache.org/2012/04/xmlsec/bzip2"
INOUT="OUT"
+
JAVACLASS="org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream"
/>
+ <TransformAlgorithm URI="http://www.apache.org/2012/04/xmlsec/xz"
INOUT="OUT"
+
JAVACLASS="org.apache.commons.compress.compressors.xz.XZCompressorOutputStream"
/>
+ <TransformAlgorithm URI="http://www.apache.org/2012/04/xmlsec/pack200"
INOUT="OUT"
+
JAVACLASS="org.apache.commons.compress.compressors.pack200.Pack200CompressorOutputStream"
/>
</TransformAlgorithms>
<JCEAlgorithmMappings>
<!-- MessageDigest Algorithms -->