The following patch for the encryption testcase on github works for me...
Colm.
On Wed, Jul 23, 2014 at 5:02 PM, mujahedsyed <[email protected]> wrote:
> Hi Colm,
>
> Thank you for the reply.
>
> As per decryptUsingStAX method in EncryptionUtils class I tried to code
> something similar but it returns a document object rather void:
>
> public static Document decryptUsingStAX(InputStream inputStream,
> List<QName> namesToEncrypt, Key privateKey) throws
> Exception {
> // Set up the Configuration
> XMLSecurityProperties properties = new
> XMLSecurityProperties();
> List<XMLSecurityConstants.Action> actions = new
> ArrayList<XMLSecurityConstants.Action>();
> actions.add(XMLSecurityConstants.ENCRYPT);
> properties.setActions(actions);
>
> properties.setDecryptionKey(privateKey);
>
> InboundXMLSec inboundXMLSec =
> XMLSec.getInboundWSSec(properties);
>
> XMLInputFactory xmlInputFactory =
> XMLInputFactory.newInstance();
> final XMLStreamReader xmlStreamReader = xmlInputFactory
> .createXMLStreamReader(inputStream);
>
> TestSecurityEventListener eventListener = new
> TestSecurityEventListener();
> XMLStreamReader securityStreamReader =
> inboundXMLSec.processInMessage(
> xmlStreamReader, null, eventListener);
>
> while (securityStreamReader.hasNext()) {
> securityStreamReader.next();
> }
>
> xmlStreamReader.close();
> inputStream.close();
>
> // Check that what we were expecting to be encrypted was
> actually
> // encrypted
> List<EncryptedElementSecurityEvent> encryptedElementEvents
> = eventListener
>
> .getSecurityEvents(SecurityEventConstants.EncryptedElement);
>
> for (int i = 0; i < encryptedElementEvents.size(); i++) {
> System.out.println(i + ": " +
> encryptedElementEvents.get(i));
> }
>
> for (QName nameToEncrypt : namesToEncrypt) {
> boolean found = false;
> for (EncryptedElementSecurityEvent
> encryptedElement :
> encryptedElementEvents) {
> if (encryptedElement.isEncrypted()
> && nameToEncrypt
>
> .equals(getEncryptedQName(encryptedElement
>
> .getElementPath()))) {
> found = true;
> System.out.println("nameToEncrypt
> " + nameToEncrypt);
> break;
> }
> if (!found) {
> throw new Exception("Element not
> found");
> }
> }
> }
>
> Document document = StAX2DOM.readDoc(
> XMLUtils.createDocumentBuilder(false),
> securityStreamReader);
> return document;
> }
>
> Now, in my main method I have instructions like:
> // Decrypt
> Key privateKey = keyStore
> .getKey("myservicekey",
> "skpass".toCharArray());
> ByteArrayInputStream bais = new
> ByteArrayInputStream(baos.toByteArray());
>
> Document result = EncryptionUtils.decryptUsingStAX(bais,
> namesToEncrypt, privateKey);
> // check decrypt done successfully
> String resultString = getStringFromDocument(result);
> System.out.println("result:\n" + resultString.toString());
>
> The method getStringFromDocument is a helper method
>
> public String getStringFromDocument(Document doc) {
> try {
> DOMSource domSource = new DOMSource(doc);
> StringWriter writer = new StringWriter();
> StreamResult result = new StreamResult(writer);
> TransformerFactory tf =
> TransformerFactory.newInstance();
> Transformer transformer = tf.newTransformer();
> transformer.transform(domSource, result);
> return writer.toString();
> } catch (TransformerException ex) {
> ex.printStackTrace();
> return null;
> }
> }
>
> The output is:
> result:
> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
>
>
> Apologies if the question looks stupid but I am really struggling to figure
> out the way to achieve the task, I would appreciate your assistance.
> Thanks very much in advance,
> Regards
> Mujahed
>
>
>
>
> --
> View this message in context:
> http://apache-xml-project.6118.n7.nabble.com/newbie-decryption-stream-using-stax-tp41280p41286.html
> Sent from the Apache XML - Security - Dev mailing list archive at
> Nabble.com.
>
--
Colm O hEigeartaigh
Talend Community Coder
http://coders.talend.com
diff --git a/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/EncryptionStAXTest.java b/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/EncryptionStAXTest.java
index f114de1..1190a36 100644
--- a/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/EncryptionStAXTest.java
+++ b/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/EncryptionStAXTest.java
@@ -21,6 +21,7 @@ package org.apache.coheigea.santuario.xmlencryption;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
+import java.io.StringWriter;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
@@ -30,6 +31,13 @@ import java.util.List;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.xml.namespace.QName;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
/**
* This tests using the StAX API of Apache Santuario - XML Security for Java for XML Encryption.
@@ -67,9 +75,26 @@ public class EncryptionStAXTest extends org.junit.Assert {
// Decrypt using StAX
Key privateKey = keyStore.getKey("myservicekey", "skpass".toCharArray());
- EncryptionUtils.decryptUsingStAX(
+ Document doc = EncryptionUtils.decryptUsingStAX(
new ByteArrayInputStream(baos.toByteArray()), namesToEncrypt, privateKey);
+
+ String resultString = getStringFromDocument(doc);
+ System.out.println("result:\n" + resultString.toString());
}
-
+ public String getStringFromDocument(Document doc) {
+ try {
+ DOMSource domSource = new DOMSource(doc);
+ StringWriter writer = new StringWriter();
+ StreamResult result = new StreamResult(writer);
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer transformer = tf.newTransformer();
+ transformer.transform(domSource, result);
+ return writer.toString();
+ } catch (TransformerException ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+
}
diff --git a/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/EncryptionUtils.java b/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/EncryptionUtils.java
index 9ef2406..7d3495a 100644
--- a/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/EncryptionUtils.java
+++ b/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/EncryptionUtils.java
@@ -47,6 +47,7 @@ import org.apache.xml.security.stax.ext.XMLSecurityProperties;
import org.apache.xml.security.stax.securityEvent.EncryptedElementSecurityEvent;
import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;
+import org.apache.xml.security.utils.XMLUtils;
import org.junit.Assert;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -210,7 +211,7 @@ public final class EncryptionUtils {
/**
* Decrypt the document using the StAX API of Apache Santuario - XML Security for Java.
*/
- public static void decryptUsingStAX(
+ public static Document decryptUsingStAX(
InputStream inputStream,
List<QName> namesToEncrypt,
Key privateKey
@@ -254,6 +255,8 @@ public final class EncryptionUtils {
}
Assert.assertTrue(found);
}
+
+ return StAX2DOM.readDoc(XMLUtils.createDocumentBuilder(false), securityStreamReader);
}
private static QName getEncryptedQName(List<QName> qnames) {
diff --git a/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/StAX2DOM.java b/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/StAX2DOM.java
new file mode 100644
index 0000000..f142218
--- /dev/null
+++ b/apache/santuario/santuario-xml-encryption/src/test/java/org/apache/coheigea/santuario/xmlencryption/StAX2DOM.java
@@ -0,0 +1,238 @@
+/**
+ * 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.coheigea.santuario.xmlencryption;
+
+import org.w3c.dom.*;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+/**
+ * @author $Author$
+ * @version $Revision$ $Date$
+ */
+public class StAX2DOM {
+ static final String XML_NS = "http://www.w3.org/2000/xmlns/";
+
+ public static Document readDoc(DocumentBuilder documentBuilder, XMLStreamReader xmlStreamReader) throws XMLStreamException {
+ //skip possible text at the beginning of a document and go directly to the root tag
+ while (xmlStreamReader.hasNext() && xmlStreamReader.next() != XMLStreamConstants.START_ELEMENT) {
+ }
+ Document document = documentBuilder.newDocument();
+ StAX2DOM.readDocElements(document, document, xmlStreamReader, false, false);
+ xmlStreamReader.close();
+ return document;
+ }
+
+ public static void readDocElements(Document doc, Node parent,
+ XMLStreamReader reader, boolean repairing, boolean recordLoc)
+ throws XMLStreamException {
+
+ int event = reader.getEventType();
+ while (reader.hasNext()) {
+ switch (event) {
+ case XMLStreamConstants.START_ELEMENT:
+ startElement(doc, parent, reader, repairing, recordLoc);
+/*
+ if (parent instanceof Document) {
+ return;
+ }
+*/
+ break;
+ case XMLStreamConstants.END_DOCUMENT:
+ return;
+ case XMLStreamConstants.END_ELEMENT:
+ return;
+ case XMLStreamConstants.NAMESPACE:
+ break;
+ case XMLStreamConstants.ATTRIBUTE:
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ if (parent != null) {
+ recordLoc = addLocation(doc,
+ parent.appendChild(doc.createTextNode(reader.getText())),
+ reader, recordLoc);
+ }
+ break;
+ case XMLStreamConstants.COMMENT:
+ if (parent != null) {
+ parent.appendChild(doc.createComment(reader.getText()));
+ }
+ break;
+ case XMLStreamConstants.CDATA:
+ recordLoc = addLocation(doc,
+ parent.appendChild(doc.createCDATASection(reader.getText())),
+ reader, recordLoc);
+ break;
+ case XMLStreamConstants.PROCESSING_INSTRUCTION:
+ parent.appendChild(doc.createProcessingInstruction(reader.getPITarget(), reader.getPIData()));
+ break;
+ case XMLStreamConstants.ENTITY_REFERENCE:
+ parent.appendChild(doc.createProcessingInstruction(reader.getPITarget(), reader.getPIData()));
+ break;
+ default:
+ break;
+ }
+
+ if (reader.hasNext()) {
+ event = reader.next();
+ }
+ }
+ }
+
+ static boolean addLocation(Document doc, Node node,
+ XMLStreamReader reader,
+ boolean recordLoc) {
+ if (recordLoc) {
+ Location loc = reader.getLocation();
+ if (loc != null && (loc.getColumnNumber() != 0 || loc.getLineNumber() != 0)) {
+ try {
+ final int charOffset = loc.getCharacterOffset();
+ final int colNum = loc.getColumnNumber();
+ final int linNum = loc.getLineNumber();
+ final String pubId = loc.getPublicId() == null ? doc.getDocumentURI() : loc.getPublicId();
+ final String sysId = loc.getSystemId() == null ? doc.getDocumentURI() : loc.getSystemId();
+ Location loc2 = new Location() {
+ @Override
+ public int getCharacterOffset() {
+ return charOffset;
+ }
+
+ @Override
+ public int getColumnNumber() {
+ return colNum;
+ }
+
+ @Override
+ public int getLineNumber() {
+ return linNum;
+ }
+
+ @Override
+ public String getPublicId() {
+ return pubId;
+ }
+
+ @Override
+ public String getSystemId() {
+ return sysId;
+ }
+ };
+ node.setUserData("location", loc2, new UserDataHandler() {
+ @Override
+ public void handle(short operation, String key, Object data, Node src, Node dst) {
+ if (operation == NODE_CLONED) {
+ dst.setUserData(key, data, this);
+ }
+ }
+ });
+ } catch (Exception ex) {
+ //possibly not DOM level 3, won't be able to record this then
+ return false;
+ }
+ }
+ }
+ return recordLoc;
+ }
+
+ /**
+ * @param parent
+ * @param reader
+ * @return
+ * @throws javax.xml.stream.XMLStreamException
+ *
+ */
+ static Element startElement(Document doc,
+ Node parent,
+ XMLStreamReader reader,
+ boolean repairing,
+ boolean recordLocation)
+ throws XMLStreamException {
+
+ Element e = doc.createElementNS(reader.getNamespaceURI(), reader.getLocalName());
+ if (reader.getPrefix() != null) {
+ e.setPrefix(reader.getPrefix());
+ }
+ e = (Element) parent.appendChild(e);
+ recordLocation = addLocation(doc, e, reader, recordLocation);
+
+ for (int ns = 0; ns < reader.getNamespaceCount(); ns++) {
+ String uri = reader.getNamespaceURI(ns);
+ String prefix = reader.getNamespacePrefix(ns);
+
+ declare(e, uri, prefix);
+ }
+
+ for (int att = 0; att < reader.getAttributeCount(); att++) {
+ String name = reader.getAttributeLocalName(att);
+ String prefix = reader.getAttributePrefix(att);
+ if (prefix != null && prefix.length() > 0) {
+ name = prefix + ":" + name;
+ }
+
+ Attr attr = doc.createAttributeNS(reader.getAttributeNamespace(att), name);
+ attr.setValue(reader.getAttributeValue(att));
+ e.setAttributeNode(attr);
+ }
+
+ if (repairing && !isDeclared(e, reader.getNamespaceURI(), reader.getPrefix())) {
+ declare(e, reader.getNamespaceURI(), reader.getPrefix());
+ }
+
+ reader.next();
+
+ readDocElements(doc, e, reader, repairing, recordLocation);
+
+ return e;
+ }
+
+ static void declare(Element node, String uri, String prefix) {
+ String qualname;
+ if (prefix != null && prefix.length() > 0) {
+ qualname = "xmlns:" + prefix;
+ } else {
+ qualname = "xmlns";
+ }
+ Attr attr = node.getOwnerDocument().createAttributeNS(XML_NS, qualname);
+ attr.setValue(uri);
+ node.setAttributeNodeNS(attr);
+ }
+
+ static boolean isDeclared(Element e, String namespaceURI, String prefix) {
+ Attr att;
+ if (prefix != null && prefix.length() > 0) {
+ att = e.getAttributeNodeNS(XML_NS, prefix);
+ } else {
+ att = e.getAttributeNode("xmlns");
+ }
+
+ if (att != null && att.getNodeValue().equals(namespaceURI)) {
+ return true;
+ }
+
+ if (e.getParentNode() instanceof Element) {
+ return isDeclared((Element) e.getParentNode(), namespaceURI, prefix);
+ }
+
+ return false;
+ }
+}