Repository: camel Updated Branches: refs/heads/master da1813bbf -> 3817962c8
Add the ability to send a KeyValue in the EncryptedKey in camel-xmlsecurity Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/3817962c Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/3817962c Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/3817962c Branch: refs/heads/master Commit: 3817962c82d11461f02ba1ea170e5abebffd8259 Parents: da1813b Author: Colm O hEigeartaigh <cohei...@apache.org> Authored: Tue Dec 2 12:00:59 2014 +0000 Committer: Colm O hEigeartaigh <cohei...@apache.org> Committed: Tue Dec 2 12:01:56 2014 +0000 ---------------------------------------------------------------------- .../model/dataformat/XMLSecurityDataFormat.java | 12 +++++ .../xmlsecurity/XMLSecurityDataFormat.java | 35 +++++++++++--- .../dataformat/xmlsecurity/TestHelper.java | 3 +- .../xmlsecurity/XMLSecurityDataFormatTest.java | 51 ++++++++++++++++++++ 4 files changed, 92 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/3817962c/camel-core/src/main/java/org/apache/camel/model/dataformat/XMLSecurityDataFormat.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/XMLSecurityDataFormat.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/XMLSecurityDataFormat.java index 1cefdba..b5e02f6 100644 --- a/camel-core/src/main/java/org/apache/camel/model/dataformat/XMLSecurityDataFormat.java +++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/XMLSecurityDataFormat.java @@ -60,6 +60,8 @@ public class XMLSecurityDataFormat extends DataFormatDefinition implements Names private String digestAlgorithm; @XmlAttribute private String mgfAlgorithm; + @XmlAttribute + private boolean addKeyValueForEncryptedKey = true; @XmlTransient private KeyStoreParameters keyOrTrustStoreParameters; @@ -274,6 +276,8 @@ public class XMLSecurityDataFormat extends DataFormatDefinition implements Names if (mgfAlgorithm != null) { setProperty(camelContext, dataFormat, "mgfAlgorithm", this.getMgfAlgorithm()); } + + setProperty(camelContext, dataFormat, "addKeyValueForEncryptedKey", isAddKeyValueForEncryptedKey()); } public String getXmlCipherAlgorithm() { @@ -363,6 +367,14 @@ public class XMLSecurityDataFormat extends DataFormatDefinition implements Names public void setMgfAlgorithm(String mgfAlgorithm) { this.mgfAlgorithm = mgfAlgorithm; } + + public boolean isAddKeyValueForEncryptedKey() { + return addKeyValueForEncryptedKey; + } + + public void setAddKeyValueForEncryptedKey(boolean addKeyValueForEncryptedKey) { + this.addKeyValueForEncryptedKey = addKeyValueForEncryptedKey; + } @Override public void setNamespaces(Map<String, String> nspaces) { http://git-wip-us.apache.org/repos/asf/camel/blob/3817962c/components/camel-xmlsecurity/src/main/java/org/apache/camel/dataformat/xmlsecurity/XMLSecurityDataFormat.java ---------------------------------------------------------------------- diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/dataformat/xmlsecurity/XMLSecurityDataFormat.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/dataformat/xmlsecurity/XMLSecurityDataFormat.java index 3e816c5..ada0ce8 100755 --- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/dataformat/xmlsecurity/XMLSecurityDataFormat.java +++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/dataformat/xmlsecurity/XMLSecurityDataFormat.java @@ -29,6 +29,7 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; +import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Map; @@ -43,7 +44,6 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; - import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; import org.apache.camel.Exchange; @@ -139,6 +139,7 @@ public class XMLSecurityDataFormat implements DataFormat, CamelContextAware { private CamelContext camelContext; private DefaultNamespaceContext nsContext = new DefaultNamespaceContext(); + private boolean addKeyValueForEncryptedKey = true; public XMLSecurityDataFormat() { this.xmlCipherAlgorithm = XMLCipher.TRIPLEDES; @@ -475,8 +476,9 @@ public class XMLSecurityDataFormat implements DataFormat, CamelContextAware { } else { keyCipher = XMLCipher.getInstance(XMLCipher.RSA_OAEP, null, digestAlgorithm); } + keyCipher.init(XMLCipher.WRAP_MODE, keyEncryptionKey); - encrypt(exchange, document, stream, dataEncryptionKey, keyCipher); + encrypt(exchange, document, stream, dataEncryptionKey, keyCipher, keyEncryptionKey); } private void encryptSymmetric(Exchange exchange, Document document, OutputStream stream) throws Exception { @@ -499,7 +501,7 @@ public class XMLSecurityDataFormat implements DataFormat, CamelContextAware { XMLCipher keyCipher = XMLCipher.getInstance(generateXmlCipherAlgorithmKeyWrap()); keyCipher.init(XMLCipher.WRAP_MODE, keyEncryptionKey); - encrypt(exchange, document, stream, dataEncryptionKey, keyCipher); + encrypt(exchange, document, stream, dataEncryptionKey, keyCipher, keyEncryptionKey); } @@ -531,12 +533,12 @@ public class XMLSecurityDataFormat implements DataFormat, CamelContextAware { private void encrypt(Exchange exchange, Document document, OutputStream stream, Key dataEncryptionKey, - XMLCipher keyCipher) throws Exception { + XMLCipher keyCipher, Key keyEncryptionKey) throws Exception { XMLCipher xmlCipher = XMLCipher.getInstance(xmlCipherAlgorithm); xmlCipher.init(XMLCipher.ENCRYPT_MODE, dataEncryptionKey); if (secureTag.equalsIgnoreCase("")) { - embedKeyInfoInEncryptedData(document, keyCipher, xmlCipher, dataEncryptionKey); + embedKeyInfoInEncryptedData(document, keyCipher, xmlCipher, dataEncryptionKey, keyEncryptionKey); document = xmlCipher.doFinal(document, document.getDocumentElement()); } else { @@ -548,7 +550,8 @@ public class XMLSecurityDataFormat implements DataFormat, CamelContextAware { for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); document = node.getOwnerDocument(); - embedKeyInfoInEncryptedData(node.getOwnerDocument(), keyCipher, xmlCipher, dataEncryptionKey); + embedKeyInfoInEncryptedData(node.getOwnerDocument(), keyCipher, xmlCipher, + dataEncryptionKey, keyEncryptionKey); Document temp = xmlCipher.doFinal(node.getOwnerDocument(), (Element) node, getSecureTagContents()); document.importNode(temp.getDocumentElement().cloneNode(true), true); } @@ -603,7 +606,7 @@ public class XMLSecurityDataFormat implements DataFormat, CamelContextAware { keyStorePassword = keyOrTrustStoreParameters.getPassword(); } - if (this.keyStore == null) { + if (this.keyStore == null) { throw new IllegalStateException("A key store must be defined for asymmetric key decryption."); } @@ -719,10 +722,18 @@ public class XMLSecurityDataFormat implements DataFormat, CamelContextAware { return keyGenerator.generateKey(); } - private void embedKeyInfoInEncryptedData(Document document, XMLCipher keyCipher, XMLCipher xmlCipher, Key dataEncryptionkey) + private void embedKeyInfoInEncryptedData(Document document, XMLCipher keyCipher, + XMLCipher xmlCipher, Key dataEncryptionkey, + Key keyEncryptionKey) throws XMLEncryptionException { EncryptedKey encryptedKey = keyCipher.encryptKey(document, dataEncryptionkey, mgfAlgorithm, null); + if (addKeyValueForEncryptedKey && keyEncryptionKey instanceof PublicKey) { + KeyInfo keyInfo = new KeyInfo(document); + keyInfo.add(((PublicKey)keyEncryptionKey)); + encryptedKey.setKeyInfo(keyInfo); + } + KeyInfo keyInfo = new KeyInfo(document); keyInfo.add(encryptedKey); EncryptedData encryptedDataElement = xmlCipher.getEncryptedData(); @@ -1047,4 +1058,12 @@ public class XMLSecurityDataFormat implements DataFormat, CamelContextAware { this.mgfAlgorithm = mgfAlgorithm; } + public boolean isAddKeyValueForEncryptedKey() { + return addKeyValueForEncryptedKey; + } + + public void setAddKeyValueForEncryptedKey(boolean addKeyValueForEncryptedKey) { + this.addKeyValueForEncryptedKey = addKeyValueForEncryptedKey; + } + } http://git-wip-us.apache.org/repos/asf/camel/blob/3817962c/components/camel-xmlsecurity/src/test/java/org/apache/camel/dataformat/xmlsecurity/TestHelper.java ---------------------------------------------------------------------- diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/dataformat/xmlsecurity/TestHelper.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/dataformat/xmlsecurity/TestHelper.java index 900c334..0fff673 100644 --- a/components/camel-xmlsecurity/src/test/java/org/apache/camel/dataformat/xmlsecurity/TestHelper.java +++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/dataformat/xmlsecurity/TestHelper.java @@ -124,7 +124,7 @@ public class TestHelper { }); } - protected void testEncryption(String fragment, CamelContext context) throws Exception { + protected Document testEncryption(String fragment, CamelContext context) throws Exception { MockEndpoint resultEndpoint = context.getEndpoint("mock:encrypted", MockEndpoint.class); resultEndpoint.setExpectedMessageCount(1); context.start(); @@ -136,6 +136,7 @@ public class TestHelper { logMessage(exchange, inDoc); } Assert.assertTrue("The XML message has no encrypted data.", hasEncryptedData(inDoc)); + return inDoc; } http://git-wip-us.apache.org/repos/asf/camel/blob/3817962c/components/camel-xmlsecurity/src/test/java/org/apache/camel/dataformat/xmlsecurity/XMLSecurityDataFormatTest.java ---------------------------------------------------------------------- diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/dataformat/xmlsecurity/XMLSecurityDataFormatTest.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/dataformat/xmlsecurity/XMLSecurityDataFormatTest.java index 6bf3f96..19fab79 100755 --- a/components/camel-xmlsecurity/src/test/java/org/apache/camel/dataformat/xmlsecurity/XMLSecurityDataFormatTest.java +++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/dataformat/xmlsecurity/XMLSecurityDataFormatTest.java @@ -29,7 +29,10 @@ import org.apache.camel.converter.jaxp.XmlConverter; import org.apache.camel.test.junit4.CamelTestSupport; import org.apache.camel.util.jsse.KeyStoreParameters; import org.apache.xml.security.encryption.XMLCipher; +import org.junit.Assert; import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; /** * Unit test of the encryptXML data format. @@ -201,6 +204,54 @@ public class XMLSecurityDataFormatTest extends CamelTestSupport { }); xmlsecTestHelper.testEncryption(context); } + + @Test + public void testAsymmetricEncryptionAddKeyValue() throws Exception { + KeyStoreParameters tsParameters = new KeyStoreParameters(); + tsParameters.setPassword("password"); + tsParameters.setResource("sender.ts"); + + final XMLSecurityDataFormat xmlEncDataFormat = new XMLSecurityDataFormat(); + xmlEncDataFormat.setKeyOrTrustStoreParameters(tsParameters); + xmlEncDataFormat.setXmlCipherAlgorithm(testCypherAlgorithm); + xmlEncDataFormat.setRecipientKeyAlias("recipient"); + xmlEncDataFormat.setAddKeyValueForEncryptedKey(true); + + context.addRoutes(new RouteBuilder() { + public void configure() { + from("direct:start") + .marshal(xmlEncDataFormat).to("mock:encrypted"); + } + }); + Document doc = xmlsecTestHelper.testEncryption(TestHelper.XML_FRAGMENT, context); + NodeList nodeList = + doc.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "RSAKeyValue"); + Assert.assertTrue(nodeList.getLength() > 0); + } + + @Test + public void testAsymmetricEncryptionNoKeyValue() throws Exception { + KeyStoreParameters tsParameters = new KeyStoreParameters(); + tsParameters.setPassword("password"); + tsParameters.setResource("sender.ts"); + + final XMLSecurityDataFormat xmlEncDataFormat = new XMLSecurityDataFormat(); + xmlEncDataFormat.setKeyOrTrustStoreParameters(tsParameters); + xmlEncDataFormat.setXmlCipherAlgorithm(testCypherAlgorithm); + xmlEncDataFormat.setRecipientKeyAlias("recipient"); + xmlEncDataFormat.setAddKeyValueForEncryptedKey(false); + + context.addRoutes(new RouteBuilder() { + public void configure() { + from("direct:start") + .marshal(xmlEncDataFormat).to("mock:encrypted"); + } + }); + Document doc = xmlsecTestHelper.testEncryption(TestHelper.XML_FRAGMENT, context); + NodeList nodeList = + doc.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "RSAKeyValue"); + Assert.assertTrue(nodeList.getLength() == 0); + } /* * Decryption Tests