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 2012/07/18 16:28:36 UTC

svn commit: r1362961 - 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/resources/messages/ test/java/org/apache/xml/security/test/dom/encryption/ ...

Author: coheigea
Date: Wed Jul 18 14:28:35 2012
New Revision: 1362961

URL: http://svn.apache.org/viewvc?rev=1362961&view=rev
Log:
Added support for adding an EncryptedKey as an EncryptedData KeyInfo for outbound streaming XML Encryption + tests

Modified:
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/OutboundXMLSec.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/impl/processor/output/XMLEncryptOutputProcessor.java
    santuario/xml-security-java/trunk/src/main/resources/messages/errors.properties
    santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.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/OutboundXMLSec.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/OutboundXMLSec.java?rev=1362961&r1=1362960&r2=1362961&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/OutboundXMLSec.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/OutboundXMLSec.java Wed Jul 18 14:28:35 2012
@@ -20,15 +20,18 @@ package org.apache.xml.security.stax.ext
 
 import java.io.OutputStream;
 import java.security.Key;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
 import java.util.List;
-import java.util.UUID;
 
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamWriter;
 
+import org.apache.xml.security.stax.config.JCEAlgorithmMapper;
 import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
 import org.apache.xml.security.stax.impl.DocumentContextImpl;
 import org.apache.xml.security.stax.impl.OutputProcessorChainImpl;
@@ -37,6 +40,7 @@ import org.apache.xml.security.stax.impl
 import org.apache.xml.security.stax.impl.processor.output.FinalOutputProcessor;
 import org.apache.xml.security.stax.impl.processor.output.XMLEncryptOutputProcessor;
 import org.apache.xml.security.stax.impl.processor.output.XMLSignatureOutputProcessor;
+import org.apache.xml.security.stax.impl.util.IDGenerator;
 
 /**
  * Outbound Streaming-XML-Security
@@ -161,7 +165,7 @@ public class OutboundXMLSec {
         }
         
         final SecurityToken securityToken = new XMLSecSecurityToken(key, x509Certificates);
-        final String securityTokenid = UUID.randomUUID().toString();
+        final String securityTokenid = IDGenerator.generateID("SIG");
         
         final SecurityTokenProvider securityTokenProvider = new SecurityTokenProvider() {
 
@@ -181,16 +185,44 @@ public class OutboundXMLSec {
     }
     
     private void configureEncryptionKeys(final SecurityContextImpl securityContextImpl) throws XMLSecurityException {
+        // Sort out transport keys / key wrapping keys first.
+        Key transportKey = securityProperties.getEncryptionTransportKey();
+        X509Certificate transportCert = securityProperties.getEncryptionUseThisCertificate();
+        X509Certificate[] transportCerts = null;
+        if (transportCert != null) {
+            transportCerts = new X509Certificate[]{transportCert};
+        }
+        final SecurityToken transportSecurityToken = new XMLSecSecurityToken(transportKey, transportCerts);
+        
+        // Now sort out the session key
         Key key = securityProperties.getEncryptionKey();
-        /*
-        X509Certificate[] x509Certificates = securityProperties.getSignatureCerts();
-        if (key instanceof PrivateKey && (x509Certificates == null || x509Certificates.length == 0)) {
-            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, "noUserCertsFound");
+        if (key == null) {
+            if (transportCert == null && transportKey == null) {
+                throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, "encryptionKeyMissing");
+            }
+            // If none is configured then generate one
+            String keyAlgorithm = 
+                JCEAlgorithmMapper.getJCERequiredKeyFromURI(securityProperties.getEncryptionSymAlgorithm());
+            KeyGenerator keyGen;
+            try {
+                keyGen = KeyGenerator.getInstance(keyAlgorithm);
+            } catch (NoSuchAlgorithmException e) {
+                throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
+            }
+            //the sun JCE provider expects the real key size for 3DES (112 or 168 bit)
+            //whereas bouncy castle expects the block size of 128 or 192 bits
+            if (keyAlgorithm.contains("AES")) {
+                int keyLength = 
+                    JCEAlgorithmMapper.getKeyLengthFromURI(securityProperties.getEncryptionSymAlgorithm());
+                keyGen.init(keyLength);
+            }
+
+            key = keyGen.generateKey();
         }
-        */
         
-        final SecurityToken securityToken = new XMLSecSecurityToken(key, null);
-        final String securityTokenid = UUID.randomUUID().toString();
+        final XMLSecSecurityToken securityToken = new XMLSecSecurityToken(key, null);
+        securityToken.setKeyWrappingToken(transportSecurityToken);
+        final String securityTokenid = IDGenerator.generateID(null);
         
         final SecurityTokenProvider securityTokenProvider = new SecurityTokenProvider() {
 
@@ -212,34 +244,46 @@ public class OutboundXMLSec {
     private static class XMLSecSecurityToken implements SecurityToken {
         private Key key;
         private X509Certificate[] certs;
+        private boolean asymmetric;
+        private SecurityToken keyWrappingToken;
         
         public XMLSecSecurityToken(Key key, X509Certificate[] certs) {
             this.key = key;
             this.certs = certs;
+            if (key instanceof PrivateKey || key instanceof PublicKey || certs != null) {
+                asymmetric = true;
+            }
         }
 
         public String getId() {
             return null;
         }
 
-
         public Object getProcessor() {
             return null;
         }
 
         public boolean isAsymmetric() {
-            return false;
+            return asymmetric;
         }
 
         public Key getSecretKey(
             String algorithmURI, XMLSecurityConstants.KeyUsage keyUsage
         ) throws XMLSecurityException {
-            return key;
+            if (key instanceof SecretKey || key instanceof PrivateKey) {
+                return key;
+            }
+            return null;
         }
 
         public PublicKey getPublicKey(
             String algorithmURI, XMLSecurityConstants.KeyUsage keyUsage
         ) throws XMLSecurityException {
+            if (key instanceof PublicKey) {
+                return (PublicKey)key;
+            } else if (certs != null && certs.length > 0) {
+                return certs[0].getPublicKey();
+            }
             return null;
         }
 
@@ -249,9 +293,13 @@ public class OutboundXMLSec {
 
         public void verify() throws XMLSecurityException {
         }
+        
+        public void setKeyWrappingToken(SecurityToken keyWrappingToken) {
+            this.keyWrappingToken = keyWrappingToken;
+        }
 
         public SecurityToken getKeyWrappingToken() {
-            return null;
+            return keyWrappingToken;
         }
 
         public XMLSecurityConstants.TokenType getTokenType() {

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=1362961&r1=1362960&r2=1362961&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 Jul 18 14:28:35 2012
@@ -93,6 +93,15 @@ public class XMLSecurityProperties {
     private String encryptionKeyTransportAlgorithm;
     private final List<SecurePart> encryptionParts = new LinkedList<SecurePart>();
     private Key encryptionKey;
+    private Key encryptionTransportKey;
+    
+    public void setEncryptionTransportKey(Key encryptionTransportKey) {
+        this.encryptionTransportKey = encryptionTransportKey;
+    }
+    
+    public Key getEncryptionTransportKey() {
+        return encryptionTransportKey;
+    }
 
     public void setEncryptionKey(Key encryptionKey) {
         this.encryptionKey = encryptionKey;

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=1362961&r1=1362960&r2=1362961&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 Jul 18 14:28:35 2012
@@ -20,19 +20,30 @@ package org.apache.xml.security.stax.imp
 
 import java.io.IOException;
 import java.security.InvalidKeyException;
+import java.security.Key;
 import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.List;
 
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
 import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 
+import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.xml.security.stax.config.JCEAlgorithmMapper;
 import org.apache.xml.security.stax.ext.OutputProcessorChain;
 import org.apache.xml.security.stax.ext.SecurePart;
+import org.apache.xml.security.stax.ext.SecurityToken;
 import org.apache.xml.security.stax.ext.SecurityTokenProvider;
 import org.apache.xml.security.stax.ext.XMLSecurityConstants;
 import org.apache.xml.security.stax.ext.XMLSecurityException;
+import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
 import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
 import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
 import org.apache.xml.security.stax.impl.EncryptionPartDef;
@@ -76,7 +87,8 @@ public class XMLEncryptOutputProcessor e
                         internalEncryptionOutputProcessor =
                                 createInternalEncryptionOutputProcessor(
                                         encryptionPartDef, xmlSecStartElement, 
-                                        outputProcessorChain.getDocumentContext().getEncoding()
+                                        outputProcessorChain.getDocumentContext().getEncoding(),
+                                        securityTokenProvider.getSecurityToken().getKeyWrappingToken()
                                 );
                         internalEncryptionOutputProcessor.setXMLSecurityProperties(getSecurityProperties());
                         internalEncryptionOutputProcessor.setAction(getAction());
@@ -101,21 +113,93 @@ public class XMLEncryptOutputProcessor e
     protected AbstractInternalEncryptionOutputProcessor createInternalEncryptionOutputProcessor(
         EncryptionPartDef encryptionPartDef,
         XMLSecStartElement startElement,
-        String encoding
+        String encoding,
+        final SecurityToken keyWrappingToken
     ) throws XMLStreamException, XMLSecurityException {
         try {
             final AbstractInternalEncryptionOutputProcessor processor = 
                     new AbstractInternalEncryptionOutputProcessor(encryptionPartDef,
                                         startElement,
                                         encoding) {
-                /*
-                 * Do not write out a KeyInfo Element (for now)
-                 */
+
                 @Override
                 protected void createKeyInfoStructure(OutputProcessorChain outputProcessorChain)
                         throws XMLStreamException, XMLSecurityException {
-                    //createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo, true, null);
-                    //createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo);
+                    if (keyWrappingToken == null) {
+                        // Do not write out a KeyInfo element
+                        return;
+                    }
+                    PublicKey pubKey = keyWrappingToken.getPublicKey(
+                            getSecurityProperties().getEncryptionKeyTransportAlgorithm(), null);
+                    SecretKey secretKey = (SecretKey)keyWrappingToken.getSecretKey(
+                            getSecurityProperties().getEncryptionKeyTransportAlgorithm(), null);
+                    if (pubKey == null && secretKey == null) {
+                        // Do not write out a KeyInfo element
+                        return;
+                    }
+                    
+                    createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo, true, null);
+                    
+                    List<XMLSecAttribute> attributes = new ArrayList<XMLSecAttribute>(1);
+                    String keyId = getEncryptionPartDef().getKeyId();
+                    if (keyId == null) {
+                        keyId = IDGenerator.generateID("EK");
+                    }
+                    attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Id, keyId));
+                    createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptedKey, true, attributes);
+
+                    attributes = new ArrayList<XMLSecAttribute>(1);
+                    attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, getSecurityProperties().getEncryptionKeyTransportAlgorithm()));
+                    createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptionMethod, false, attributes);
+                    createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptionMethod);
+                    createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherData, false, null);
+                    createStartElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherValue, false, null);
+
+                    try {
+                        //encrypt the symmetric session key with the public key from the receiver:
+                        String jceid = JCEAlgorithmMapper.translateURItoJCEID(getSecurityProperties().getEncryptionKeyTransportAlgorithm());
+                        Cipher cipher = Cipher.getInstance(jceid);
+                        if (pubKey != null) {
+                            cipher.init(Cipher.WRAP_MODE, pubKey);
+                        } else {
+                            cipher.init(Cipher.WRAP_MODE, secretKey);
+                        }
+
+                        String tokenId = outputProcessorChain.getSecurityContext().get(XMLSecurityConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
+                        SecurityTokenProvider securityTokenProvider = outputProcessorChain.getSecurityContext().getSecurityTokenProvider(tokenId);
+                        
+                        Key ephemeralKey = 
+                            securityTokenProvider.getSecurityToken().getSecretKey(getSecurityProperties().getEncryptionSymAlgorithm(), null);
+                        if (pubKey != null) {
+                            int blockSize = cipher.getBlockSize();
+                            if (blockSize > 0 && blockSize < ephemeralKey.getEncoded().length) {
+                                throw new XMLSecurityException(
+                                    XMLSecurityException.ErrorCode.FAILURE, 
+                                    "unsupportedKeyTransp", 
+                                    "public key algorithm too weak to encrypt symmetric key"
+                                );
+                            }
+                        }
+                        byte[] encryptedEphemeralKey = cipher.wrap(ephemeralKey);
+
+                        createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(encryptedEphemeralKey));
+
+                    } catch (NoSuchPaddingException e) {
+                        throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
+                    } catch (NoSuchAlgorithmException e) {
+                        throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
+                    } catch (InvalidKeyException e) {
+                        throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
+                    } catch (IllegalBlockSizeException e) {
+                        throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
+                    }
+
+                    createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherValue);
+                    createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_CipherData);
+
+                    createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_xenc_EncryptedKey);
+                    
+                    createEndElementAndOutputAsEvent(outputProcessorChain, XMLSecurityConstants.TAG_dsig_KeyInfo);
                 }
             };
             return processor;

Modified: santuario/xml-security-java/trunk/src/main/resources/messages/errors.properties
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/resources/messages/errors.properties?rev=1362961&r1=1362960&r2=1362961&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/resources/messages/errors.properties (original)
+++ santuario/xml-security-java/trunk/src/main/resources/messages/errors.properties Wed Jul 18 14:28:35 2012
@@ -103,6 +103,7 @@ decryptionCryptoFailure = DecryptionCryp
 encryptionKeyStoreNotSet = Encryption KeyStore is not set
 encryptionCryptoClassWrong = EncryptionCryptoClass must be a sub-class of CryptoBase
 encryptionCryptoFailure = EncryptionCrypto instantiation failed
+encryptionKeyMissing = The encryption key or cert is missing
 
 signatureKeyStoreNotSet = Signature KeyStore is not set
 signatureCryptoClassWrong = SignatureCryptoClass must be a sub-class of CryptoBase

Modified: santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.java?rev=1362961&r1=1362960&r2=1362961&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.java (original)
+++ santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.java Wed Jul 18 14:28:35 2012
@@ -181,7 +181,7 @@ public class XMLCipherTest extends org.j
      * encrypted using an RSA key.  Reverse using KEK
      */
     @org.junit.Test
-    public void testAES128ElementRSAKWCipherUsingKEK() throws Exception {
+    public void testAES256ElementRSAKWCipherUsingKEK() throws Exception {
 
         Document d = document(); // source
         Document ed = null;
@@ -232,7 +232,7 @@ public class XMLCipherTest extends org.j
             //decrypt
             key = null;
             ee = (Element) ed.getElementsByTagName("xenc:EncryptedData").item(0);
-            cipher = XMLCipher.getInstance(XMLCipher.AES_128);
+            cipher = XMLCipher.getInstance(XMLCipher.AES_256);
             cipher.init(XMLCipher.DECRYPT_MODE, null);
             cipher.setKEK(priv);
             dd = cipher.doFinal(ed, ee);
@@ -241,7 +241,7 @@ public class XMLCipherTest extends org.j
             assertEquals(source, target);
         } else {
             log.warn(
-                "Test testAES128ElementRSAKWCipherUsingKEK skipped as "
+                "Test testAES256ElementRSAKWCipherUsingKEK skipped as "
                 + "necessary algorithms not available"
             );
         }
@@ -253,7 +253,7 @@ public class XMLCipherTest extends org.j
      * EncryptedKey by hand
      */
     @org.junit.Test
-    public void testAES192ElementAES256KWCipher() throws Exception {
+    public void testAES192Element3DESKWCipher() throws Exception {
 
         Document d = document(); // source
         Document ed = null;
@@ -328,7 +328,7 @@ public class XMLCipherTest extends org.j
             assertEquals(source, target);
         } else {
             log.warn(
-                "Test testAES192ElementAES256KWCipher skipped as "
+                "Test testAES192Element3DESKWCipher skipped as "
                 + "necessary algorithms not available"
             );
         }

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=1362961&r1=1362960&r2=1362961&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 Jul 18 14:28:35 2012
@@ -22,11 +22,16 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
 
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.crypto.SecretKeyFactory;
 import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.SecretKeySpec;
 import javax.xml.namespace.QName;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.stream.XMLInputFactory;
@@ -278,11 +283,7 @@ public class EncryptionCreationTest exte
         Assert.assertEquals(nodeList.getLength(), 2);
     }
     
-    /*
-    
-    /**
-     * Test encryption using a generated AES 128 bit key that is
-     * encrypted using a AES 192 bit key.  Then reverse using the KEK
+    // Test encryption using a generated AES 128 bit key that is encrypted using a AES 192 bit key. 
     @Test
     public void testAES128ElementAES192KWCipherUsingKEKOutbound() throws Exception {
         // Set up the Configuration
@@ -290,52 +291,35 @@ public class EncryptionCreationTest exte
         XMLSecurityConstants.Action[] actions = 
             new XMLSecurityConstants.Action[]{XMLSecurityConstants.ENCRYPT};
         properties.setOutAction(actions);
-        properties.loadEncryptionKeystore(
-            this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray()
-        );
-        properties.setEncryptionUser("receiver");
-        properties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes128-cbc");
-        properties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#kw-aes192");
-        
-        SecurePart securePart = new SecurePart("PaymentInfo", "urn:example:po", SecurePart.Modifier.Element);
-        properties.addEncryptionPart(securePart);
         
-        SecurityContextImpl securityContextImpl = new SecurityContextImpl();
-        // Set up a Key Encryption Key
+        // Set the key up
         byte[] bits192 = "abcdefghijklmnopqrstuvwx".getBytes();
-        SecretKey kek = new SecretKeySpec(bits192, "AES");
-
-        // Generate a traffic key
+        SecretKey transportKey = new SecretKeySpec(bits192, "AES");
+        properties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#kw-aes192");
+        properties.setEncryptionTransportKey(transportKey);
+        
         KeyGenerator keygen = KeyGenerator.getInstance("AES");
         keygen.init(128);
-        SecretKey secretKey = keygen.generateKey();
+        SecretKey key = keygen.generateKey();
+        properties.setEncryptionKey(key);
+        properties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes128-cbc");
         
-        EncryptionSecurityToken securityToken = new EncryptionSecurityToken(secretKey);
-        String id = UUID.randomUUID().toString();
-        EncryptionSecurityTokenProvider securityTokenProvider = 
-                new EncryptionSecurityTokenProvider(securityToken, id);
-        securityContextImpl.registerSecurityTokenProvider(id, securityTokenProvider);
-        securityContextImpl.put(XMLSecurityConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION, id);
-
-        final DocumentContextImpl documentContext = new DocumentContextImpl();
-        documentContext.setEncoding("UTF-8");
-        InputStream sourceDocument = 
-                this.getClass().getClassLoader().getResourceAsStream("testdata/plaintext.xml");
+        SecurePart securePart = 
+               new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Element);
+        properties.addEncryptionPart(securePart);
         
-        // Add processor to the chain
-        OutputProcessorChainImpl processorChain = 
-            new OutputProcessorChainImpl(securityContextImpl, documentContext);
-        processorChain.addProcessor(
-            new EKEncryptOutputProcessor(properties, XMLSecurityConstants.ENCRYPT, kek)
-        );
+        OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        processorChain.addProcessor(new FinalOutputProcessor(baos, "UTF-8", properties, null));
+        XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, "UTF-8");
         
-        XMLStreamWriter xmlStreamWriter = new XMLSecurityStreamWriter(processorChain);
+        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 = 
@@ -354,68 +338,50 @@ public class EncryptionCreationTest exte
             );
         Assert.assertEquals(nodeList.getLength(), 1);
         
-        // Decrypt using Apache Santuario
-        decryptUsingSantuario("http://www.w3.org/2001/04/xmlenc#tripledes-cbc", null, kek, document);
+        // Decrypt using DOM API
+        decryptUsingDOM("http://www.w3.org/2001/04/xmlenc#tripledes-cbc", null, transportKey, document);
     }
     
-    /**
-     * Test encryption using a generated AES 256 bit key that is
-     * encrypted using an RSA key.  Reverse using KEK
+    // Test encryption using a generated AES 256 bit key that is encrypted using an RSA key. 
     @Test
-    public void testAES128ElementRSAKWCipherUsingKEK() throws Exception {
+    public void testAES256ElementRSAKWCipherUsingKEKOutbound() throws Exception {
         // Set up the Configuration
         XMLSecurityProperties properties = new XMLSecurityProperties();
         XMLSecurityConstants.Action[] actions = 
             new XMLSecurityConstants.Action[]{XMLSecurityConstants.ENCRYPT};
         properties.setOutAction(actions);
-        properties.loadEncryptionKeystore(
-            this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray()
-        );
-        properties.setEncryptionUser("receiver");
-        properties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes256-cbc");
-        properties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-1_5");
         
-        SecurePart securePart = new SecurePart("PaymentInfo", "urn:example:po", SecurePart.Modifier.Element);
-        properties.addEncryptionPart(securePart);
-        
-        SecurityContextImpl securityContextImpl = new SecurityContextImpl();
+        // 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();
-
-        // Generate a traffic key
+        properties.setEncryptionTransportKey(pub);
+        properties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-1_5");
+        
         KeyGenerator keygen = KeyGenerator.getInstance("AES");
         keygen.init(256);
-        SecretKey secretKey = keygen.generateKey();
+        SecretKey key = keygen.generateKey();
+        properties.setEncryptionKey(key);
+        properties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes256-cbc");
         
-        EncryptionSecurityToken securityToken = new EncryptionSecurityToken(secretKey);
-        String id = UUID.randomUUID().toString();
-        EncryptionSecurityTokenProvider securityTokenProvider = 
-                new EncryptionSecurityTokenProvider(securityToken, id);
-        securityContextImpl.registerSecurityTokenProvider(id, securityTokenProvider);
-        securityContextImpl.put(XMLSecurityConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION, id);
-
-        final DocumentContextImpl documentContext = new DocumentContextImpl();
-        documentContext.setEncoding("UTF-8");
-        InputStream sourceDocument = 
-                this.getClass().getClassLoader().getResourceAsStream("testdata/plaintext.xml");
+        SecurePart securePart = 
+               new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Element);
+        properties.addEncryptionPart(securePart);
         
-        // Add processor to the chain
-        OutputProcessorChainImpl processorChain = 
-            new OutputProcessorChainImpl(securityContextImpl, documentContext);
-        processorChain.addProcessor(
-            new EKEncryptOutputProcessor(properties, XMLSecurityConstants.ENCRYPT, pub)
-        );
+        OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        processorChain.addProcessor(new FinalOutputProcessor(baos, "UTF-8", properties, null));
+        XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, "UTF-8");
         
-        XMLStreamWriter xmlStreamWriter = new XMLSecurityStreamWriter(processorChain);
+        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 = 
@@ -434,13 +400,11 @@ public class EncryptionCreationTest exte
             );
         Assert.assertEquals(nodeList.getLength(), 1);
         
-        // Decrypt using Apache Santuario
-        decryptUsingSantuario("http://www.w3.org/2001/04/xmlenc#tripledes-cbc", null, priv, document);
+        // Decrypt using DOM API
+        decryptUsingDOM("http://www.w3.org/2001/04/xmlenc#tripledes-cbc", null, priv, document);
     }
     
-    /**
-     * Test encryption using a generated AES 192 bit key that is
-     * encrypted using a 3DES key.  Then reverse using the KEK
+    // Test encryption using a generated AES 192 bit key that is encrypted using a 3DES key.  
     @Test
     public void testAES192Element3DESKWCipher() throws Exception {
         // Set up the Configuration
@@ -448,51 +412,34 @@ public class EncryptionCreationTest exte
         XMLSecurityConstants.Action[] actions = 
             new XMLSecurityConstants.Action[]{XMLSecurityConstants.ENCRYPT};
         properties.setOutAction(actions);
-        properties.loadEncryptionKeystore(
-            this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray()
-        );
-        properties.setEncryptionUser("receiver");
-        properties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes192-cbc");
-        properties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#kw-tripledes");
         
-        SecurePart securePart = new SecurePart("PaymentInfo", "urn:example:po", SecurePart.Modifier.Element);
-        properties.addEncryptionPart(securePart);
+        // Set the key up
+        SecretKey transportKey = generateDESSecretKey();
+        properties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#kw-tripledes");
+        properties.setEncryptionTransportKey(transportKey);
         
-        SecurityContextImpl securityContextImpl = new SecurityContextImpl();
-        // Set up a Key Encryption Key
-        SecretKey kek = generateSecretKey();
-
-        // Generate a traffic key
         KeyGenerator keygen = KeyGenerator.getInstance("AES");
         keygen.init(192);
-        SecretKey secretKey = keygen.generateKey();
+        SecretKey key = keygen.generateKey();
+        properties.setEncryptionKey(key);
+        properties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes192-cbc");
         
-        EncryptionSecurityToken securityToken = new EncryptionSecurityToken(secretKey);
-        String id = UUID.randomUUID().toString();
-        EncryptionSecurityTokenProvider securityTokenProvider = 
-                new EncryptionSecurityTokenProvider(securityToken, id);
-        securityContextImpl.registerSecurityTokenProvider(id, securityTokenProvider);
-        securityContextImpl.put(XMLSecurityConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION, id);
-
-        final DocumentContextImpl documentContext = new DocumentContextImpl();
-        documentContext.setEncoding("UTF-8");
-        InputStream sourceDocument = 
-                this.getClass().getClassLoader().getResourceAsStream("testdata/plaintext.xml");
+        SecurePart securePart = 
+               new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Element);
+        properties.addEncryptionPart(securePart);
         
-        // Add processor to the chain
-        OutputProcessorChainImpl processorChain = 
-            new OutputProcessorChainImpl(securityContextImpl, documentContext);
-        processorChain.addProcessor(
-            new EKEncryptOutputProcessor(properties, XMLSecurityConstants.ENCRYPT, kek)
-        );
+        OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        processorChain.addProcessor(new FinalOutputProcessor(baos, "UTF-8", properties, null));
+        XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, "UTF-8");
         
-        XMLStreamWriter xmlStreamWriter = new XMLSecurityStreamWriter(processorChain);
+        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 = 
@@ -511,11 +458,11 @@ public class EncryptionCreationTest exte
             );
         Assert.assertEquals(nodeList.getLength(), 1);
         
-        // Decrypt using Apache Santuario
-        decryptUsingSantuario("http://www.w3.org/2001/04/xmlenc#tripledes-cbc", null, kek, document);
+        // Decrypt using DOM API
+        decryptUsingDOM("http://www.w3.org/2001/04/xmlenc#tripledes-cbc", null, transportKey, document);
     }
-    */
     
+
     /**
      * Generate a secret key
      */