You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by co...@apache.org on 2014/01/29 15:02:30 UTC

svn commit: r1562446 - in /santuario/xml-security-java/trunk/src: main/java/org/apache/xml/security/stax/ext/ main/java/org/apache/xml/security/stax/impl/processor/output/ main/java/org/apache/xml/security/stax/impl/securityToken/ test/java/org/apache/...

Author: coheigea
Date: Wed Jan 29 14:02:29 2014
New Revision: 1562446

URL: http://svn.apache.org/r1562446
Log:
Add the ability to set encryption key identifiers for the streaming case

Modified:
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/securityToken/GenericOutboundSecurityToken.java
    santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/encryption/EncryptionCreationTest.java

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java?rev=1562446&r1=1562445&r2=1562446&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java Wed Jan 29 14:02:29 2014
@@ -141,6 +141,9 @@ public class XMLSec {
                 if (securityProperties.getEncryptionSymAlgorithm() == null) {
                     securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes256-cbc");
                 }
+                if (securityProperties.getEncryptionKeyIdentifier() == null) {
+                    securityProperties.setEncryptionKeyIdentifier(SecurityTokenConstants.KeyIdentifier_IssuerSerial);
+                }
             }
         }
         return new XMLSecurityProperties(securityProperties);

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java?rev=1562446&r1=1562445&r2=1562446&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java Wed Jan 29 14:02:29 2014
@@ -51,6 +51,7 @@ public class XMLSecurityProperties {
     private final List<SecurePart> encryptionParts = new LinkedList<SecurePart>();
     private Key encryptionKey;
     private Key encryptionTransportKey;
+    private SecurityTokenConstants.KeyIdentifier encryptionKeyIdentifier;
 
     private Key decryptionKey;
 
@@ -83,6 +84,7 @@ public class XMLSecurityProperties {
         this.encryptionParts.addAll(xmlSecurityProperties.encryptionParts);
         this.encryptionKey = xmlSecurityProperties.encryptionKey;
         this.encryptionTransportKey = xmlSecurityProperties.encryptionTransportKey;
+        this.encryptionKeyIdentifier = xmlSecurityProperties.encryptionKeyIdentifier;
         this.decryptionKey = xmlSecurityProperties.decryptionKey;
         this.signatureParts.addAll(xmlSecurityProperties.signatureParts);
         this.signatureAlgorithm = xmlSecurityProperties.signatureAlgorithm;
@@ -103,6 +105,24 @@ public class XMLSecurityProperties {
     public void setSignatureKeyIdentifier(SecurityTokenConstants.KeyIdentifier signatureKeyIdentifier) {
         this.signatureKeyIdentifier = signatureKeyIdentifier;
     }
+    
+    /**
+     * returns the KeyIdentifierType which will be used in the secured document
+     *
+     * @return The KeyIdentifierType
+     */
+    public SecurityTokenConstants.KeyIdentifier getEncryptionKeyIdentifier() {
+        return encryptionKeyIdentifier;
+    }
+
+    /**
+     * Specifies the KeyIdentifierType to use in the secured document
+     *
+     * @param encryptionKeyIdentifier
+     */
+    public void setEncryptionKeyIdentifier(SecurityTokenConstants.KeyIdentifier encryptionKeyIdentifier) {
+        this.encryptionKeyIdentifier = encryptionKeyIdentifier;
+    }
 
     /**
      * Add an additional, non standard, InputProcessor to the chain

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java?rev=1562446&r1=1562445&r2=1562446&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java Wed Jan 29 14:02:29 2014
@@ -181,6 +181,18 @@ public class XMLSecurityUtils {
         
         X509Certificate x509Certificate = x509Certificates[0];
         PublicKey publicKey = x509Certificate.getPublicKey();
+        createKeyValueTokenStructure(abstractOutputProcessor, outputProcessorChain, publicKey);
+    }
+    
+    public static void createKeyValueTokenStructure(AbstractOutputProcessor abstractOutputProcessor,
+                                                    OutputProcessorChain outputProcessorChain, 
+                                                    PublicKey publicKey)
+            throws XMLStreamException, XMLSecurityException {
+
+        if (publicKey == null) {
+            throw new XMLSecurityException("stax.signature.publicKeyOrCertificateMissing");
+        }
+        
         String algorithm = publicKey.getAlgorithm();
 
         abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyValue, true, null);

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java?rev=1562446&r1=1562445&r2=1562446&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLEncryptOutputProcessor.java Wed Jan 29 14:02:29 2014
@@ -19,6 +19,7 @@
 package org.apache.xml.security.stax.impl.processor.output;
 
 import org.apache.commons.codec.binary.Base64;
+import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;
 import org.apache.xml.security.stax.securityToken.SecurityTokenProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -39,7 +40,9 @@ import javax.crypto.spec.OAEPParameterSp
 import javax.crypto.spec.PSource;
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
+
 import java.security.*;
+import java.security.cert.X509Certificate;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.MGF1ParameterSpec;
 import java.util.ArrayList;
@@ -177,6 +180,9 @@ public class XMLEncryptOutputProcessor e
                         }
 
                         createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptionMethod);
+                        
+                        createKeyInfoStructureForEncryptedKey(outputProcessorChain, keyWrappingToken);
+                        
                         createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherData, false, null);
                         createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherValue, false, null);
 
@@ -257,6 +263,45 @@ public class XMLEncryptOutputProcessor e
 
                         createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo);
                     }
+                    
+                    protected void createKeyInfoStructureForEncryptedKey(
+                        OutputProcessorChain outputProcessorChain,
+                        OutboundSecurityToken securityToken
+                    ) throws XMLStreamException, XMLSecurityException {
+                        SecurityTokenConstants.KeyIdentifier keyIdentifier = 
+                            getSecurityProperties().getEncryptionKeyIdentifier();
+
+                        X509Certificate[] x509Certificates = securityToken.getX509Certificates();
+                        if (x509Certificates == null) {
+                            if (securityToken.getPublicKey() != null 
+                                && SecurityTokenConstants.KeyIdentifier_KeyValue.equals(keyIdentifier)) {
+                                createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo, true, null);
+                                
+                                XMLSecurityUtils.createKeyValueTokenStructure(this, outputProcessorChain, 
+                                                                              securityToken.getPublicKey());
+                                createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo);
+                            }
+                            return;
+                        }
+
+                        createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo, true, null);
+
+                        if (keyIdentifier == null || SecurityTokenConstants.KeyIdentifier_IssuerSerial.equals(keyIdentifier)) {
+                            XMLSecurityUtils.createX509IssuerSerialStructure(this, outputProcessorChain, x509Certificates);
+                        } else if (SecurityTokenConstants.KeyIdentifier_KeyValue.equals(keyIdentifier)) {
+                            XMLSecurityUtils.createKeyValueTokenStructure(this, outputProcessorChain, x509Certificates);
+                        } else if (SecurityTokenConstants.KeyIdentifier_SkiKeyIdentifier.equals(keyIdentifier)) {
+                            XMLSecurityUtils.createX509SubjectKeyIdentifierStructure(this, outputProcessorChain, x509Certificates);
+                        } else if (SecurityTokenConstants.KeyIdentifier_X509KeyIdentifier.equals(keyIdentifier)) {
+                            XMLSecurityUtils.createX509CertificateStructure(this, outputProcessorChain, x509Certificates);
+                        } else if (SecurityTokenConstants.KeyIdentifier_X509SubjectName.equals(keyIdentifier)) {
+                            XMLSecurityUtils.createX509SubjectNameStructure(this, outputProcessorChain, x509Certificates);
+                        } else {
+                            throw new XMLSecurityException("stax.unsupportedToken", keyIdentifier);
+                        }
+                        
+                        createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo);
+                    }
                 };
         return processor;
     }

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/securityToken/GenericOutboundSecurityToken.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/securityToken/GenericOutboundSecurityToken.java?rev=1562446&r1=1562445&r2=1562446&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/securityToken/GenericOutboundSecurityToken.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/securityToken/GenericOutboundSecurityToken.java Wed Jan 29 14:02:29 2014
@@ -19,13 +19,13 @@
 package org.apache.xml.security.stax.impl.securityToken;
 
 import java.security.Key;
+import java.security.PublicKey;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
 import org.w3c.dom.Element;
-
 import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.stax.securityToken.OutboundSecurityToken;
 import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;
@@ -51,6 +51,9 @@ public class GenericOutboundSecurityToke
     public GenericOutboundSecurityToken(String id, SecurityTokenConstants.TokenType tokenType, Key key) {
         this(id, tokenType);
         setSecretKey("", key);
+        if (key instanceof PublicKey) {
+            setPublicKey((PublicKey)key);
+        }
     }
 
     public GenericOutboundSecurityToken(String id, SecurityTokenConstants.TokenType tokenType) {

Modified: santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/encryption/EncryptionCreationTest.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/encryption/EncryptionCreationTest.java?rev=1562446&r1=1562445&r2=1562446&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/encryption/EncryptionCreationTest.java (original)
+++ santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/encryption/EncryptionCreationTest.java Wed Jan 29 14:02:29 2014
@@ -24,8 +24,10 @@ import java.io.InputStream;
 import java.security.Key;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
+import java.security.KeyStore;
 import java.security.PrivateKey;
 import java.security.PublicKey;
+import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -47,6 +49,7 @@ import org.apache.xml.security.stax.ext.
 import org.apache.xml.security.stax.ext.XMLSec;
 import org.apache.xml.security.stax.ext.XMLSecurityConstants;
 import org.apache.xml.security.stax.ext.XMLSecurityProperties;
+import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;
 import org.apache.xml.security.test.stax.utils.XMLSecEventAllocator;
 import org.apache.xml.security.test.stax.utils.XmlReaderToWriter;
 import org.apache.xml.security.utils.XMLUtils;
@@ -463,6 +466,211 @@ public class EncryptionCreationTest exte
         Assert.assertEquals(nodeList.getLength(), 1);
     }
     
+    @Test
+    public void testEncryptedKeyKeyValueReference() 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);
+        
+        // Set the key up
+        // Generate an RSA key
+        KeyPairGenerator rsaKeygen = KeyPairGenerator.getInstance("RSA");
+        KeyPair kp = rsaKeygen.generateKeyPair();
+        PrivateKey priv = kp.getPrivate();
+        PublicKey pub = kp.getPublic();
+        properties.setEncryptionTransportKey(pub);
+        properties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-1_5");
+        
+        KeyGenerator keygen = KeyGenerator.getInstance("AES");
+        keygen.init(256);
+        SecretKey key = keygen.generateKey();
+        properties.setEncryptionKey(key);
+        properties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes256-cbc");
+        properties.setEncryptionKeyIdentifier(SecurityTokenConstants.KeyIdentifier_KeyValue);
+        
+        SecurePart securePart = 
+               new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Element);
+        properties.addEncryptionPart(securePart);
+        
+        OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, "UTF-8");
+        
+        InputStream sourceDocument = 
+                this.getClass().getClassLoader().getResourceAsStream(
+                        "ie/baltimore/merlin-examples/merlin-xmlenc-five/plaintext.xml");
+        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(sourceDocument);
+        
+        XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
+        xmlStreamWriter.close();
+        
+        // System.out.println("Got:\n" + new String(baos.toByteArray(), "UTF-8"));
+        
+        Document document = 
+            XMLUtils.createDocumentBuilder(false).parse(new ByteArrayInputStream(baos.toByteArray()));
+        
+        NodeList nodeList = document.getElementsByTagNameNS("urn:example:po", "PaymentInfo");
+        Assert.assertEquals(nodeList.getLength(), 0);
+        
+        // Check the CreditCard encrypted ok
+        nodeList = document.getElementsByTagNameNS("urn:example:po", "CreditCard");
+        Assert.assertEquals(nodeList.getLength(), 0);
+        
+        nodeList = document.getElementsByTagNameNS(
+                XMLSecurityConstants.TAG_xenc_EncryptedData.getNamespaceURI(),
+                XMLSecurityConstants.TAG_xenc_EncryptedData.getLocalPart()
+            );
+        Assert.assertEquals(nodeList.getLength(), 1);
+        
+        // Decrypt using DOM API
+        Document doc = 
+            decryptUsingDOM("http://www.w3.org/2001/04/xmlenc#tripledes-cbc", null, priv, document);
+        
+        // Check the CreditCard decrypted ok
+        nodeList = doc.getElementsByTagNameNS("urn:example:po", "CreditCard");
+        Assert.assertEquals(nodeList.getLength(), 1);
+    }
+    
+    @Test
+    public void testEncryptedKeyIssuerSerialReference() 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);
+        
+        // Set the key up
+        KeyStore keyStore = KeyStore.getInstance("jks");
+        keyStore.load(
+            this.getClass().getClassLoader().getResource("transmitter.jks").openStream(), 
+            "default".toCharArray()
+        );
+        PrivateKey priv = (PrivateKey)keyStore.getKey("transmitter", "default".toCharArray());
+        X509Certificate cert = (X509Certificate)keyStore.getCertificate("transmitter");
+        properties.setEncryptionUseThisCertificate(cert);
+        properties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-1_5");
+        
+        KeyGenerator keygen = KeyGenerator.getInstance("AES");
+        keygen.init(256);
+        SecretKey key = keygen.generateKey();
+        properties.setEncryptionKey(key);
+        properties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes256-cbc");
+        // properties.setEncryptionKeyIdentifier(SecurityTokenConstants.KeyIdentifier_KeyValue);
+        
+        SecurePart securePart = 
+               new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Element);
+        properties.addEncryptionPart(securePart);
+        
+        OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, "UTF-8");
+        
+        InputStream sourceDocument = 
+                this.getClass().getClassLoader().getResourceAsStream(
+                        "ie/baltimore/merlin-examples/merlin-xmlenc-five/plaintext.xml");
+        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(sourceDocument);
+        
+        XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
+        xmlStreamWriter.close();
+        
+        // System.out.println("Got:\n" + new String(baos.toByteArray(), "UTF-8"));
+        
+        Document document = 
+            XMLUtils.createDocumentBuilder(false).parse(new ByteArrayInputStream(baos.toByteArray()));
+        
+        NodeList nodeList = document.getElementsByTagNameNS("urn:example:po", "PaymentInfo");
+        Assert.assertEquals(nodeList.getLength(), 0);
+        
+        // Check the CreditCard encrypted ok
+        nodeList = document.getElementsByTagNameNS("urn:example:po", "CreditCard");
+        Assert.assertEquals(nodeList.getLength(), 0);
+        
+        nodeList = document.getElementsByTagNameNS(
+                XMLSecurityConstants.TAG_xenc_EncryptedData.getNamespaceURI(),
+                XMLSecurityConstants.TAG_xenc_EncryptedData.getLocalPart()
+            );
+        Assert.assertEquals(nodeList.getLength(), 1);
+        
+        // Decrypt using DOM API
+        Document doc = 
+            decryptUsingDOM("http://www.w3.org/2001/04/xmlenc#tripledes-cbc", null, priv, document);
+        
+        // Check the CreditCard decrypted ok
+        nodeList = doc.getElementsByTagNameNS("urn:example:po", "CreditCard");
+        Assert.assertEquals(nodeList.getLength(), 1);
+    }
+    
+    @Test
+    public void testEncryptedKeyX509CertificateReference() 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);
+        
+        // Set the key up
+        KeyStore keyStore = KeyStore.getInstance("jks");
+        keyStore.load(
+            this.getClass().getClassLoader().getResource("transmitter.jks").openStream(), 
+            "default".toCharArray()
+        );
+        PrivateKey priv = (PrivateKey)keyStore.getKey("transmitter", "default".toCharArray());
+        X509Certificate cert = (X509Certificate)keyStore.getCertificate("transmitter");
+        properties.setEncryptionUseThisCertificate(cert);
+        properties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-1_5");
+        
+        KeyGenerator keygen = KeyGenerator.getInstance("AES");
+        keygen.init(256);
+        SecretKey key = keygen.generateKey();
+        properties.setEncryptionKey(key);
+        properties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes256-cbc");
+        properties.setEncryptionKeyIdentifier(SecurityTokenConstants.KeyIdentifier_X509KeyIdentifier);
+        
+        SecurePart securePart = 
+               new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Element);
+        properties.addEncryptionPart(securePart);
+        
+        OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, "UTF-8");
+        
+        InputStream sourceDocument = 
+                this.getClass().getClassLoader().getResourceAsStream(
+                        "ie/baltimore/merlin-examples/merlin-xmlenc-five/plaintext.xml");
+        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(sourceDocument);
+        
+        XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
+        xmlStreamWriter.close();
+        
+        // System.out.println("Got:\n" + new String(baos.toByteArray(), "UTF-8"));
+        
+        Document document = 
+            XMLUtils.createDocumentBuilder(false).parse(new ByteArrayInputStream(baos.toByteArray()));
+        
+        NodeList nodeList = document.getElementsByTagNameNS("urn:example:po", "PaymentInfo");
+        Assert.assertEquals(nodeList.getLength(), 0);
+        
+        // Check the CreditCard encrypted ok
+        nodeList = document.getElementsByTagNameNS("urn:example:po", "CreditCard");
+        Assert.assertEquals(nodeList.getLength(), 0);
+        
+        nodeList = document.getElementsByTagNameNS(
+                XMLSecurityConstants.TAG_xenc_EncryptedData.getNamespaceURI(),
+                XMLSecurityConstants.TAG_xenc_EncryptedData.getLocalPart()
+            );
+        Assert.assertEquals(nodeList.getLength(), 1);
+        
+        // Decrypt using DOM API
+        Document doc = 
+            decryptUsingDOM("http://www.w3.org/2001/04/xmlenc#tripledes-cbc", null, priv, document);
+        
+        // Check the CreditCard decrypted ok
+        nodeList = doc.getElementsByTagNameNS("urn:example:po", "CreditCard");
+        Assert.assertEquals(nodeList.getLength(), 1);
+    }
+    
     // Test encryption using a generated AES 192 bit key that is encrypted using a 3DES key.  
     @Test
     public void testAES192Element3DESKWCipher() throws Exception {