You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2013/08/27 15:52:29 UTC
[1/6] git commit: CAMEL-6339 Fixed the CS errors of camel-xmlsecurity
Updated Branches:
refs/heads/master db9fb33df -> 54ce5a02e
CAMEL-6339 Fixed the CS errors of camel-xmlsecurity
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/54ce5a02
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/54ce5a02
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/54ce5a02
Branch: refs/heads/master
Commit: 54ce5a02e809ccc82e81fb4124c9d13cb5910ee4
Parents: a8265a2
Author: Willem Jiang <ni...@apache.org>
Authored: Tue Aug 27 21:51:15 2013 +0800
Committer: Willem Jiang <ni...@apache.org>
Committed: Tue Aug 27 21:51:44 2013 +0800
----------------------------------------------------------------------
.../component/xmlsecurity/SantuarioUtil.java | 3 +
.../xmlsecurity/XmlVerifierEndpoint.java | 2 +-
.../xmlsecurity/api/DefaultKeyAccessor.java | 4 +-
.../xmlsecurity/api/DefaultKeySelector.java | 3 +-
.../api/DefaultValidationFailedHandler.java | 2 +-
.../api/DefaultXmlSignature2Message.java | 25 +--
.../component/xmlsecurity/api/KeyAccessor.java | 4 +-
.../xmlsecurity/api/XmlSignature2Message.java | 6 +-
.../xmlsecurity/api/XmlSignatureChecker.java | 6 +-
.../xmlsecurity/api/XmlSignatureConstants.java | 8 +-
.../api/XmlSignatureFormatException.java | 1 -
.../xmlsecurity/api/XmlSignatureHelper.java | 11 +-
...XmlSignatureInvalidContentHashException.java | 1 -
.../api/XmlSignatureInvalidException.java | 1 -
.../api/XmlSignatureInvalidKeyException.java | 1 -
.../api/XmlSignatureInvalidValueException.java | 1 -
.../api/XmlSignatureNoKeyException.java | 1 -
.../xmlsecurity/api/XmlSignatureProperties.java | 6 +-
.../processor/XmlSignerProcessor.java | 15 +-
.../processor/XmlVerifierConfiguration.java | 4 +-
.../processor/XmlVerifierProcessor.java | 12 +-
.../component/xmlsecurity/XmlSignatureTest.java | 160 +++++++++----------
.../util/EnvelopingXmlSignatureChecker.java | 2 +-
.../util/SameDocumentUriDereferencer.java | 10 +-
.../xmlsecurity/util/TestKeystore.java | 8 +-
.../xmlsecurity/util/TimestampProperty.java | 4 +-
26 files changed, 162 insertions(+), 139 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/SantuarioUtil.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/SantuarioUtil.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/SantuarioUtil.java
index 89ec52d..a9108a1 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/SantuarioUtil.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/SantuarioUtil.java
@@ -28,6 +28,9 @@ import org.apache.xml.security.utils.XMLUtils;
public final class SantuarioUtil {
+ private SantuarioUtil() {
+ //Helper class
+ }
public static void initializeSantuario() {
// Set ignoreLineBreaks to true
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
index 2f2ee7f..e2cc821 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
@@ -19,8 +19,8 @@ package org.apache.camel.component.xmlsecurity;
import javax.xml.crypto.KeySelector;
import org.apache.camel.Processor;
-import org.apache.camel.component.xmlsecurity.api.XmlSignature2Message;
import org.apache.camel.component.xmlsecurity.api.ValidationFailedHandler;
+import org.apache.camel.component.xmlsecurity.api.XmlSignature2Message;
import org.apache.camel.component.xmlsecurity.api.XmlSignatureChecker;
import org.apache.camel.component.xmlsecurity.processor.XmlVerifierConfiguration;
import org.apache.camel.component.xmlsecurity.processor.XmlVerifierProcessor;
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeyAccessor.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeyAccessor.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeyAccessor.java
index 5142a9e..7f97ffb 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeyAccessor.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeyAccessor.java
@@ -29,9 +29,11 @@ import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.X509Data;
-import org.apache.camel.Message;
import org.w3c.dom.Node;
+import org.apache.camel.Message;
+
+
/**
* Accesses the private key from a key-store and returns a KeyInfo which
* contains the X.509 certificate chain corresponding to the private key.
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeySelector.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeySelector.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeySelector.java
index 1999e40..4f82f87 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeySelector.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeySelector.java
@@ -62,7 +62,8 @@ public class DefaultKeySelector extends KeySelector {
}
public KeySelectorResult select(KeyInfo keyInfo, KeySelector.Purpose purpose, AlgorithmMethod method, XMLCryptoContext context)
- throws KeySelectorException {
+ throws KeySelectorException {
+
if (keyStoreAndAlias.getKeyStore() == null) {
return getNullKeyResult();
}
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultValidationFailedHandler.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultValidationFailedHandler.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultValidationFailedHandler.java
index abb8585..4dd579a 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultValidationFailedHandler.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultValidationFailedHandler.java
@@ -19,8 +19,8 @@ package org.apache.camel.component.xmlsecurity.api;
import java.security.InvalidKeyException;
import javax.xml.crypto.dsig.Reference;
-import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignature.SignatureValue;
+import javax.xml.crypto.dsig.XMLSignatureException;
/**
* Interrupts the validation by throwing an exception as soon as a validation
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultXmlSignature2Message.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultXmlSignature2Message.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultXmlSignature2Message.java
index 095487f..a9ebae4 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultXmlSignature2Message.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultXmlSignature2Message.java
@@ -35,13 +35,15 @@ import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
-import org.apache.camel.Message;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import org.apache.camel.Message;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
/**
* Maps the XML signature to a camel message. A output node is determined from
* the XML signature document via a node search and then serialized and set to
@@ -191,7 +193,8 @@ public class DefaultXmlSignature2Message implements XmlSignature2Message {
}
protected void transformNodeToByteArrayAndSetToOutputMessage(Input input, Message output, Node node)
- throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException, IOException {
+ throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException, IOException {
+
ByteArrayOutputStream os = new ByteArrayOutputStream();
XmlSignatureHelper.transformToOutputStream(node, os, omitXmlDeclaration(output, input));
output.setBody(os.toByteArray());
@@ -223,7 +226,8 @@ public class DefaultXmlSignature2Message implements XmlSignature2Message {
}
throw new XmlSignatureException(
String.format(
- "Cannot extract root node for the output document from the XML signature document. XPATH %s as specified in the output node search results into a node which has the wrong type.",
+ "Cannot extract root node for the output document from the XML signature document. "
+ + "XPATH %s as specified in the output node search results into a node which has the wrong type.",
xpathFilter.getXPath()));
}
@@ -237,14 +241,16 @@ public class DefaultXmlSignature2Message implements XmlSignature2Message {
if (index < 1) {
throw new XmlSignatureException(
String.format(
- "Wrong configuration: Value %s for the output node search %s has wrong format. Value must have the form '{<namespace>}<element local name>' or '<element local name>' if no the element has no namespace.",
+ "Wrong configuration: Value %s for the output node search %s has wrong format. "
+ + "Value must have the form '{<namespace>}<element local name>' or '<element local name>' if no the element has no namespace.",
search, input.getOutputNodeSearchType()));
}
namespace = search.substring(1, index);
if (search.length() < index + 1) {
throw new XmlSignatureException(
String.format(
- "Wrong configuration: Value %s for the output node search %s has wrong format. Value must have the form '{<namespace>}<element local name>' or '<element local name>' if no the element has no namespace.",
+ "Wrong configuration: Value %s for the output node search %s has wrong format. "
+ + "Value must have the form '{<namespace>}<element local name>' or '<element local name>' if no the element has no namespace.",
search, input.getOutputNodeSearchType()));
}
localName = search.substring(index + 1);
@@ -344,7 +350,7 @@ public class DefaultXmlSignature2Message implements XmlSignature2Message {
protected boolean isEnveloped(Input input) throws Exception { //NOPMD
for (Reference ref : input.getReferences()) {
if ("".equals(ref.getURI())) {
- for (Transform t : ((List<Transform>) ref.getTransforms())) {
+ for (Transform t : (List<Transform>)ref.getTransforms()) {
if (Transform.ENVELOPED.equals(t.getAlgorithm())) {
return true;
}
@@ -410,7 +416,8 @@ public class DefaultXmlSignature2Message implements XmlSignature2Message {
* if an error occurs
*/
protected DOMStructure getDomStructureForMessageBody(List<Reference> relevantReferences, List<XMLObject> relevantObjects)
- throws Exception { //NOPMD
+ throws Exception { //NOPMD
+
List<XMLObject> referencedObjects = getReferencedSameDocumentObjects(relevantReferences, relevantObjects);
if (referencedObjects.isEmpty()) {
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyAccessor.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyAccessor.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyAccessor.java
index 4f74da4..3bd8d04 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyAccessor.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyAccessor.java
@@ -20,9 +20,11 @@ import javax.xml.crypto.KeySelector;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
-import org.apache.camel.Message;
import org.w3c.dom.Node;
+import org.apache.camel.Message;
+
+
/**
* Returns the key selector and the optional KeyInfo instance for signing an XML
* document. There is a default implementation {@link DefaultKeySelector}.
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignature2Message.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignature2Message.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignature2Message.java
index 5d8c743..87ed5d3 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignature2Message.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignature2Message.java
@@ -21,9 +21,11 @@ import java.util.List;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.XMLObject;
-import org.apache.camel.Message;
import org.w3c.dom.Document;
+import org.apache.camel.Message;
+
+
/**
* Used in the signature verifier to map the references and objects of the XML
* signature to the output message.
@@ -41,7 +43,7 @@ public interface XmlSignature2Message {
*/
void mapToMessage(Input input, Message output) throws Exception;
- public static interface Input {
+ public interface Input {
/**
* Returns the references.
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureChecker.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureChecker.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureChecker.java
index a6982a2..6cb6072 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureChecker.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureChecker.java
@@ -23,9 +23,11 @@ import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignature.SignatureValue;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
-import org.apache.camel.Message;
import org.w3c.dom.Document;
+import org.apache.camel.Message;
+
+
/**
* This interface gives the application the possibility to check whether the
* expected parts are signed.
@@ -48,7 +50,7 @@ public interface XmlSignatureChecker {
*/
void checkBeforeCoreValidation(Input input) throws Exception;
- public static interface Input {
+ public interface Input {
/** Signed info instance. */
SignedInfo getSignedInfo();
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
index 216ae98..eed3fb0 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
@@ -18,10 +18,6 @@ package org.apache.camel.component.xmlsecurity.api;
public final class XmlSignatureConstants {
- private XmlSignatureConstants() {
- // no instance
- }
-
/**
* Header for indicating that the message body contains non-xml plain text.
* This header is used in the XML signature generator. If the value is set
@@ -62,4 +58,8 @@ public final class XmlSignatureConstants {
public static final String HEADER_CONTENT_REFERENCE_TYPE = "CamelXmlSignatureContentReferenceType";
+ private XmlSignatureConstants() {
+ // no instance
+ }
+
}
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureFormatException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureFormatException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureFormatException.java
index afbdaa8..d4832c7 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureFormatException.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureFormatException.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.component.xmlsecurity.api;
-import org.apache.camel.component.xmlsecurity.api.XmlSignatureException;
/**
* Exception thrown when the input for signing or verifying does not have the correct
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureHelper.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureHelper.java
index 9657fac..575f82b 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureHelper.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureHelper.java
@@ -61,7 +61,10 @@ import org.xml.sax.SAXException;
* Helps to construct the transformations and the canonicalization methods for
* the XML Signature generator.
*/
-public class XmlSignatureHelper {
+public final class XmlSignatureHelper {
+ private XmlSignatureHelper() {
+ //Helper class
+ }
/**
* Returns a configuration for a canonicalization algorithm.
@@ -400,7 +403,8 @@ public class XmlSignatureHelper {
}
public static void transformToOutputStream(Node node, OutputStream os, boolean omitXmlDeclaration)
- throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException, IOException {
+ throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException, IOException {
+
if (node.getNodeType() == Node.TEXT_NODE) {
byte[] bytes = tranformTextNodeToByteArray(node);
os.write(bytes);
@@ -410,7 +414,8 @@ public class XmlSignatureHelper {
}
public static void transformNonTextNodeToOutputStream(Node node, OutputStream os, boolean omitXmlDeclaration)
- throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException {
+ throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException {
+
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
if (omitXmlDeclaration) {
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidContentHashException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidContentHashException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidContentHashException.java
index 5476d9c..c34fcb9 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidContentHashException.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidContentHashException.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.component.xmlsecurity.api;
-import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidException;
/**
* This exception is thrown if the verification of a XML signature fails because
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidException.java
index c5d132f..b3aa314 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidException.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidException.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.component.xmlsecurity.api;
-import org.apache.camel.component.xmlsecurity.api.XmlSignatureException;
/**
* This exception is thrown if XML signature verification fails.
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidKeyException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidKeyException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidKeyException.java
index eaedb65..8569834 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidKeyException.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidKeyException.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.component.xmlsecurity.api;
-import org.apache.camel.component.xmlsecurity.api.XmlSignatureException;
/**
* Exception thrown during signing or verifying if the key type does not fit to
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidValueException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidValueException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidValueException.java
index b635917..42b5e4d 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidValueException.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidValueException.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.component.xmlsecurity.api;
-import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidException;
/**
* This exception is thrown if the verification of an XML signature fails
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureNoKeyException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureNoKeyException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureNoKeyException.java
index 0933a8f..523a8c2 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureNoKeyException.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureNoKeyException.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.component.xmlsecurity.api;
-import org.apache.camel.component.xmlsecurity.api.XmlSignatureException;
/**
* Exception thrown when no key for signing is found.
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureProperties.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureProperties.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureProperties.java
index 9f24215..ab36232 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureProperties.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureProperties.java
@@ -23,9 +23,11 @@ import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
-import org.apache.camel.Message;
import org.w3c.dom.Node;
+import org.apache.camel.Message;
+
+
/**
* You can provide further XML objects and references which will be added by the
* XML signature generator to the XML signature.
@@ -43,7 +45,7 @@ public interface XmlSignatureProperties {
*/
Output get(Input input) throws Exception;
- public static interface Input {
+ public interface Input {
/** Input message for reading header data */
Message getMessage();
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
index 120b81c..c9dc980 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
@@ -49,6 +49,12 @@ import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.parsers.ParserConfigurationException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.component.xmlsecurity.api.KeyAccessor;
@@ -62,11 +68,7 @@ import org.apache.camel.component.xmlsecurity.api.XmlSignatureProperties;
import org.apache.camel.util.IOHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
+
/**
* Creates from the message body a XML signature element which is returned in
@@ -388,7 +390,8 @@ public class XmlSignerProcessor extends XmlSignatureProcessor {
}
protected List<? extends XMLObject> getObjects(XmlSignatureProperties.Input input, XmlSignatureProperties.Output properties)
- throws Exception { //NOPMD
+ throws Exception { //NOPMD
+
if (isEnveloped()) {
if (properties == null || properties.getObjects() == null) {
return Collections.emptyList();
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierConfiguration.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierConfiguration.java
index 869abad..9e46143 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierConfiguration.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierConfiguration.java
@@ -20,10 +20,10 @@ import javax.xml.crypto.KeySelector;
import org.apache.camel.CamelContext;
import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.component.xmlsecurity.api.DefaultXmlSignature2Message;
import org.apache.camel.component.xmlsecurity.api.DefaultValidationFailedHandler;
-import org.apache.camel.component.xmlsecurity.api.XmlSignature2Message;
+import org.apache.camel.component.xmlsecurity.api.DefaultXmlSignature2Message;
import org.apache.camel.component.xmlsecurity.api.ValidationFailedHandler;
+import org.apache.camel.component.xmlsecurity.api.XmlSignature2Message;
import org.apache.camel.component.xmlsecurity.api.XmlSignatureChecker;
public class XmlVerifierConfiguration extends XmlSignatureConfiguration {
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierProcessor.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierProcessor.java
index 1fd40ee..386e795 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierProcessor.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierProcessor.java
@@ -36,6 +36,11 @@ import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.parsers.ParserConfigurationException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.component.xmlsecurity.api.ValidationFailedHandler;
@@ -47,10 +52,7 @@ import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidException;
import org.apache.camel.util.IOHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
+
/**
* XML signature verifier. Assumes that the input XML contains exactly one
@@ -139,7 +141,7 @@ public class XmlVerifierProcessor extends XmlSignatureProcessor {
}
// Check core validation status
boolean goon = coreValidity;
- if (coreValidity == false) {
+ if (!coreValidity) {
goon = handleSignatureValidationFailed(valContext, signature);
}
if (goon) {
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
index b1872a9..702a3e8 100644
--- a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
@@ -52,6 +52,8 @@ import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.spec.XPathFilterParameterSpec;
import javax.xml.crypto.dsig.spec.XPathType;
+import org.w3c.dom.Node;
+
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
@@ -84,12 +86,14 @@ import org.apache.camel.impl.JndiRegistry;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Before;
import org.junit.Test;
-import org.w3c.dom.Node;
-public class XmlSignatureTest extends CamelTestSupport {
+
+public class XmlSignatureTest extends CamelTestSupport {
+
+ private static String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<root xmlns=\"http://test/test\"><test>Test Message</test></root>";
private KeyPair keyPair;
- private static String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root xmlns=\"http://test/test\"><test>Test Message</test></root>";
@Override
protected JndiRegistry createRegistry() throws Exception {
@@ -119,15 +123,15 @@ public class XmlSignatureTest extends CamelTestSupport {
@Override
protected RouteBuilder[] createRouteBuilders() throws Exception {
- return new RouteBuilder[] { new RouteBuilder() {
+ return new RouteBuilder[] {new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: enveloping XML signature
onException(XmlSignatureException.class).handled(true).to(
"mock:exception");
from("direct:enveloping")
- .to("xmlsecurity:sign://enveloping?keyAccessor=#accessor")
- .to("xmlsecurity:verify://enveloping?keySelector=#selector")
- .to("mock:result");
+ .to("xmlsecurity:sign://enveloping?keyAccessor=#accessor")
+ .to("xmlsecurity:verify://enveloping?keySelector=#selector")
+ .to("mock:result");
// END SNIPPET: enveloping XML signature
}
}, new RouteBuilder() {
@@ -137,9 +141,9 @@ public class XmlSignatureTest extends CamelTestSupport {
onException(XmlSignatureException.class).handled(true).to(
"mock:exception");
from("direct:plaintext")
- .to("xmlsecurity:sign://plaintext?keyAccessor=#accessor&plainText=true&plainTextEncoding=UTF-8")
- .to("xmlsecurity:verify://plaintext?keySelector=#selector")
- .to("mock:result");
+ .to("xmlsecurity:sign://plaintext?keyAccessor=#accessor&plainText=true&plainTextEncoding=UTF-8")
+ .to("xmlsecurity:verify://plaintext?keySelector=#selector")
+ .to("mock:result");
// END SNIPPET: enveloping XML signature with plain text message
// body
}
@@ -149,9 +153,9 @@ public class XmlSignatureTest extends CamelTestSupport {
onException(XmlSignatureException.class).handled(true).to(
"mock:exception");
from("direct:enveloped")
- .to("xmlsecurity:sign://enveloped?keyAccessor=#accessor&parentLocalName=root&parentNamespace=http://test/test")
- .to("xmlsecurity:verify://enveloped?keySelector=#selector")
- .to("mock:result");
+ .to("xmlsecurity:sign://enveloped?keyAccessor=#accessor&parentLocalName=root&parentNamespace=http://test/test")
+ .to("xmlsecurity:verify://enveloped?keySelector=#selector")
+ .to("mock:result");
// END SNIPPET: enveloped XML signature
}
}, new RouteBuilder() {
@@ -167,17 +171,18 @@ public class XmlSignatureTest extends CamelTestSupport {
context.getEndpoint("xmlsecurity:verify://canonicalization",
XmlVerifierEndpoint.class).setKeySelector(KeySelector.singletonKeySelector(keyPair.getPublic()));
from("direct:canonicalization")
- .to("xmlsecurity:sign://canonicalization?canonicalizationMethod=#canonicalizationMethod1",
- "xmlsecurity:verify://canonicalization",
- "mock:result");
+ .to("xmlsecurity:sign://canonicalization?canonicalizationMethod=#canonicalizationMethod1",
+ "xmlsecurity:verify://canonicalization",
+ "mock:result");
// END SNIPPET: canonicalization
}
}, new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: signature and digest algorithm
from("direct:signaturedigestalgorithm")
- .to("xmlsecurity:sign://signaturedigestalgorithm?keyAccessor=#accessor&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha512&digestAlgorithm=http://www.w3.org/2001/04/xmlenc#sha512",
- "xmlsecurity:verify://signaturedigestalgorithm?keySelector=#selector")
+ .to("xmlsecurity:sign://signaturedigestalgorithm?keyAccessor=#accessor"
+ + "&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha512&digestAlgorithm=http://www.w3.org/2001/04/xmlenc#sha512",
+ "xmlsecurity:verify://signaturedigestalgorithm?keySelector=#selector")
.to("mock:result");
// END SNIPPET: signature and digest algorithm
}
@@ -185,8 +190,8 @@ public class XmlSignatureTest extends CamelTestSupport {
public void configure() throws Exception {
// START SNIPPET: transforms XPath2
from("direct:transformsXPath2")
- .to("xmlsecurity:sign://transformsXPath2?keyAccessor=#accessor&transformMethods=#transformsXPath2",
- "xmlsecurity:verify://transformsXPath2?keySelector=#selector")
+ .to("xmlsecurity:sign://transformsXPath2?keyAccessor=#accessor&transformMethods=#transformsXPath2",
+ "xmlsecurity:verify://transformsXPath2?keySelector=#selector")
.to("mock:result");
// END SNIPPET: transform XPath
}
@@ -196,8 +201,8 @@ public class XmlSignatureTest extends CamelTestSupport {
onException(XmlSignatureException.class).handled(false)
.to("mock:exception");
from("direct:transformsXsltXPath")
- .to("xmlsecurity:sign://transformsXsltXPath?keyAccessor=#accessor&transformMethods=#transformsXsltXPath",
- "xmlsecurity:verify://transformsXsltXPath?keySelector=#selector")
+ .to("xmlsecurity:sign://transformsXsltXPath?keyAccessor=#accessor&transformMethods=#transformsXsltXPath",
+ "xmlsecurity:verify://transformsXsltXPath?keySelector=#selector")
.to("mock:result");
// END SNIPPET: transforms XSLT,XPath
}
@@ -205,8 +210,8 @@ public class XmlSignatureTest extends CamelTestSupport {
public void configure() throws Exception {
// START SNIPPET: transforms XSLT,XPath - secure Validation disabled
from("direct:transformsXsltXPathSecureValDisabled")
- .to("xmlsecurity:sign://transformsXsltXPathSecureValDisabled?keyAccessor=#accessor&transformMethods=#transformsXsltXPath",
- "xmlsecurity:verify://transformsXsltXPathSecureValDisabled?keySelector=#selector&secureValidation=false")
+ .to("xmlsecurity:sign://transformsXsltXPathSecureValDisabled?keyAccessor=#accessor&transformMethods=#transformsXsltXPath",
+ "xmlsecurity:verify://transformsXsltXPathSecureValDisabled?keySelector=#selector&secureValidation=false")
.to("mock:result");
// END SNIPPET: transforms XSLT,XPath - secure Validation disabled
}
@@ -216,45 +221,44 @@ public class XmlSignatureTest extends CamelTestSupport {
onException(XmlSignatureException.class).handled(false).to(
"mock:exception");
from("direct:cryptocontextprops")
- .to("xmlsecurity:verify://cryptocontextprops?keySelector=#selectorKeyValue&cryptoContextProperties=#cryptoContextProperties")
- .to("mock:result");
+ .to("xmlsecurity:verify://cryptocontextprops?keySelector=#selectorKeyValue&cryptoContextProperties=#cryptoContextProperties")
+ .to("mock:result");
// END SNIPPET: cryptocontextprops
}
}, new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: URI dereferencer
from("direct:uridereferencer")
- .to("xmlsecurity:sign://uriderferencer?keyAccessor=#accessor&uriDereferencer=#uriDereferencer")
- .to("xmlsecurity:verify://uridereferencer?keySelector=#selector&uriDereferencer=#uriDereferencer")
- .to("mock:result");
+ .to("xmlsecurity:sign://uriderferencer?keyAccessor=#accessor&uriDereferencer=#uriDereferencer")
+ .to("xmlsecurity:verify://uridereferencer?keySelector=#selector&uriDereferencer=#uriDereferencer")
+ .to("mock:result");
// END SNIPPET: URI dereferencer
}
}, new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: keyAccessorKeySelectorDefault
from("direct:keyAccessorKeySelectorDefault")
- .to("xmlsecurity:sign://keyAccessorKeySelectorDefault?keyAccessor=#keyAccessorDefault&addKeyInfoReference=true")
- .to("xmlsecurity:verify://keyAccessorKeySelectorDefault?keySelector=#keySelectorDefault")
- .to("mock:result");
+ .to("xmlsecurity:sign://keyAccessorKeySelectorDefault?keyAccessor=#keyAccessorDefault&addKeyInfoReference=true")
+ .to("xmlsecurity:verify://keyAccessorKeySelectorDefault?keySelector=#keySelectorDefault")
+ .to("mock:result");
// END SNIPPET: keyAccessorKeySelectorDefault
}
}, new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: xmlSignatureChecker
- onException(XmlSignatureInvalidException.class).handled(false)
- .to("mock:exception");
+ onException(XmlSignatureInvalidException.class).handled(false).to("mock:exception");
from("direct:xmlSignatureChecker")
- .to("xmlsecurity:verify://xmlSignatureChecker?keySelector=#selectorKeyValue&xmlSignatureChecker=#envelopingSignatureChecker")
- .to("mock:result");
+ .to("xmlsecurity:verify://xmlSignatureChecker?keySelector=#selectorKeyValue&xmlSignatureChecker=#envelopingSignatureChecker")
+ .to("mock:result");
// END SNIPPET: xmlSignatureChecker
}
}, new RouteBuilder() {
public void configure() throws Exception { //
// START SNIPPET: properties
from("direct:props")
- .to("xmlsecurity:sign://properties?keyAccessor=#accessor&properties=#signatureProperties")
- .to("xmlsecurity:verify://properties?keySelector=#selector&xmlSignature2Message=#xmlSignature2MessageWithTimestampProperty")
- .to("mock:result");
+ .to("xmlsecurity:sign://properties?keyAccessor=#accessor&properties=#signatureProperties")
+ .to("xmlsecurity:verify://properties?keySelector=#selector&xmlSignature2Message=#xmlSignature2MessageWithTimestampProperty")
+ .to("mock:result");
// END SNIPPET: properties
}
}, new RouteBuilder() {
@@ -263,8 +267,9 @@ public class XmlSignatureTest extends CamelTestSupport {
onException(XmlSignatureException.class).handled(true).to(
"mock:exception");
from("direct:outputnodesearchelementname")
- .to("xmlsecurity:verify://outputnodesearchelementname?keySelector=#selectorKeyValue&outputNodeSearchType=ElementName&outputNodeSearch={http://test/test}root&removeSignatureElements=true")
- .to("mock:result");
+ .to("xmlsecurity:verify://outputnodesearchelementname?keySelector=#selectorKeyValue"
+ + "&outputNodeSearchType=ElementName&outputNodeSearch={http://test/test}root&removeSignatureElements=true")
+ .to("mock:result");
// END SNIPPET: verify output node search element name
}
}, new RouteBuilder() {
@@ -273,45 +278,43 @@ public class XmlSignatureTest extends CamelTestSupport {
onException(XmlSignatureException.class).handled(true).to(
"mock:exception");
from("direct:outputnodesearchxpath")
- .to("xmlsecurity:verify://outputnodesearchxpath?keySelector=#selectorKeyValue&outputNodeSearchType=XPath&outputNodeSearch=#nodesearchxpath&removeSignatureElements=true")
- .to("mock:result");
+ .to("xmlsecurity:verify://outputnodesearchxpath?keySelector=#selectorKeyValue&outputNodeSearchType=XPath&outputNodeSearch=#nodesearchxpath&removeSignatureElements=true")
+ .to("mock:result");
// END SNIPPET: verify output node search xpath
}
}, new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: validationFailedHandler
from("direct:validationFailedHandler")
- .to("xmlsecurity:verify://validationFailedHandler?keySelector=#selectorKeyValue&validationFailedHandler=validationFailedHandlerIgnoreManifestFailures")
- .to("mock:result");
+ .to("xmlsecurity:verify://validationFailedHandler?keySelector=#selectorKeyValue&validationFailedHandler=validationFailedHandlerIgnoreManifestFailures")
+ .to("mock:result");
// END SNIPPET: validationFailedHandler
}
}, new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: further parameters
from("direct:furtherparams")
- .to("xmlsecurity:sign://furtherparams?keyAccessor=#accessor&prefixForXmlSignatureNamespace=digsig&disallowDoctypeDecl=false")
- .to("xmlsecurity:verify://bfurtherparams?keySelector=#selector&disallowDoctypeDecl=false")
- .to("mock:result");
+ .to("xmlsecurity:sign://furtherparams?keyAccessor=#accessor&prefixForXmlSignatureNamespace=digsig&disallowDoctypeDecl=false")
+ .to("xmlsecurity:verify://bfurtherparams?keySelector=#selector&disallowDoctypeDecl=false")
+ .to("mock:result");
// END SNIPPET: further parameters
}
}, new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: signer invalid keyexception
- onException(XmlSignatureInvalidKeyException.class)
- .handled(true).to("mock:exception");
+ onException(XmlSignatureInvalidKeyException.class).handled(true).to("mock:exception");
from("direct:signexceptioninvalidkey")
- .to("xmlsecurity:sign://signexceptioninvalidkey?signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha512")
- .to("mock:result");
+ .to("xmlsecurity:sign://signexceptioninvalidkey?signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha512")
+ .to("mock:result");
// END SNIPPET: signer invalid keyexception
}
}, new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: signer exceptions
- onException(XmlSignatureException.class).handled(true).to(
- "mock:exception");
+ onException(XmlSignatureException.class).handled(true).to("mock:exception");
from("direct:signexceptions")
- .to("xmlsecurity:sign://signexceptions?keyAccessor=#accessor&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha512")
- .to("mock:result");
+ .to("xmlsecurity:sign://signexceptions?keyAccessor=#accessor&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha512")
+ .to("mock:result");
// END SNIPPET: signer exceptions
}
}, new RouteBuilder() {
@@ -320,8 +323,8 @@ public class XmlSignatureTest extends CamelTestSupport {
onException(XmlSignatureException.class).handled(true).to(
"mock:exception");
from("direct:noSuchAlgorithmException")
- .to("xmlsecurity:sign://noSuchAlgorithmException?keyAccessor=#accessor&signatureAlgorithm=wrongalgorithm&digestAlgorithm=http://www.w3.org/2001/04/xmlenc#sha512")
- .to("mock:result");
+ .to("xmlsecurity:sign://noSuchAlgorithmException?keyAccessor=#accessor&signatureAlgorithm=wrongalgorithm&digestAlgorithm=http://www.w3.org/2001/04/xmlenc#sha512")
+ .to("mock:result");
// END SNIPPET: NoSuchAlgorithmException
}
}, new RouteBuilder() {
@@ -330,28 +333,26 @@ public class XmlSignatureTest extends CamelTestSupport {
onException(XmlSignatureException.class).handled(false).to(
"mock:exception");
from("direct:verifyexceptions")
- .to("xmlsecurity:verify://verifyexceptions?keySelector=#selector")
- .to("mock:result");
+ .to("xmlsecurity:verify://verifyexceptions?keySelector=#selector")
+ .to("mock:result");
// END SNIPPET: verifier exceptions
}
}, new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: verifier InvalidKeyException
- onException(XmlSignatureException.class).handled(false).to(
- "mock:exception");
+ onException(XmlSignatureException.class).handled(false).to("mock:exception");
from("direct:verifyInvalidKeyException")
- .to("xmlsecurity:verify://verifyInvalidKeyException?keySelector=#selector")
- .to("mock:result");
+ .to("xmlsecurity:verify://verifyInvalidKeyException?keySelector=#selector")
+ .to("mock:result");
// END SNIPPET: verifier exceptions
}
}, new RouteBuilder() {
public void configure() throws Exception {
// START SNIPPET: verifier InvalidHashException
- onException(XmlSignatureException.class).handled(false).to(
- "mock:exception");
+ onException(XmlSignatureException.class).handled(false).to("mock:exception");
from("direct:invalidhash")
- .to("xmlsecurity:verify://invalidhash?keySelector=#selectorKeyValue&baseUri=#baseUri&secureValidation=false")
- .to("mock:result");
+ .to("xmlsecurity:verify://invalidhash?keySelector=#selectorKeyValue&baseUri=#baseUri&secureValidation=false")
+ .to("mock:result");
// END SNIPPET: verifier InvalidHashException
}
}
@@ -552,7 +553,8 @@ public class XmlSignatureTest extends CamelTestSupport {
throws Exception {
XmlVerifierEndpoint endpoint = context
.getEndpoint(
- "xmlsecurity:verify://outputnodesearchelementname?keySelector=#selectorKeyValue&outputNodeSearchType=ElementName&outputNodeSearch={http://test/test}root&removeSignatureElements=true",
+ "xmlsecurity:verify://outputnodesearchelementname?keySelector=#selectorKeyValue"
+ + "&outputNodeSearchType=ElementName&outputNodeSearch={http://test/test}root&removeSignatureElements=true",
XmlVerifierEndpoint.class);
endpoint.setOutputNodeSearch("{wrongformat"); // closing '}' missing
MockEndpoint mock = setupExceptionMock();
@@ -567,11 +569,10 @@ public class XmlSignatureTest extends CamelTestSupport {
@Test
public void testVerifyExceptionOutputNodeSearchElementNameInvalidFormat2()
throws Exception {
- context.getEndpoint(
- "xmlsecurity:verify://outputnodesearchelementname?keySelector=#selectorKeyValue&outputNodeSearchType=ElementName&outputNodeSearch={http://test/test}root&removeSignatureElements=true",
- XmlVerifierEndpoint.class).setOutputNodeSearch("{wrongformat}"); // local
- // name
- // missing
+ context.getEndpoint("xmlsecurity:verify://outputnodesearchelementname?keySelector=#selectorKeyValue"
+ + "&outputNodeSearchType=ElementName&outputNodeSearch={http://test/test}root&removeSignatureElements=true",
+ XmlVerifierEndpoint.class).setOutputNodeSearch("{wrongformat}");
+ // local name missing
MockEndpoint mock = setupExceptionMock();
InputStream payload = XmlSignatureTest.class
.getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml");
@@ -1037,15 +1038,8 @@ public class XmlSignatureTest extends CamelTestSupport {
}
static boolean algEquals(String algURI, String algName) {
- if (algName.equalsIgnoreCase("DSA")
- && algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) {
- return true;
- } else if (algName.equalsIgnoreCase("RSA")
- && algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1)) {
- return true;
- } else {
- return false;
- }
+ return (algName.equalsIgnoreCase("DSA") && algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1))
+ || (algName.equalsIgnoreCase("RSA") && algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1));
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/EnvelopingXmlSignatureChecker.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/EnvelopingXmlSignatureChecker.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/EnvelopingXmlSignatureChecker.java
index 3884c68..2f2c9b7 100644
--- a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/EnvelopingXmlSignatureChecker.java
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/EnvelopingXmlSignatureChecker.java
@@ -31,7 +31,7 @@ import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidException;
*/
public class EnvelopingXmlSignatureChecker implements XmlSignatureChecker {
- private static Set<String> ALLOWED_TRANSFORM_ALGORITHMS = new HashSet<String>(4);
+ private static final Set<String> ALLOWED_TRANSFORM_ALGORITHMS = new HashSet<String>(4);
static {
ALLOWED_TRANSFORM_ALGORITHMS.add(CanonicalizationMethod.INCLUSIVE);
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/SameDocumentUriDereferencer.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/SameDocumentUriDereferencer.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/SameDocumentUriDereferencer.java
index 267b2ee..025c14b 100644
--- a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/SameDocumentUriDereferencer.java
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/SameDocumentUriDereferencer.java
@@ -28,17 +28,19 @@ import javax.xml.crypto.dsig.XMLSignatureFactory;
/**
* URI Dereferencer which allows only same document URI references via ids.
*/
-public class SameDocumentUriDereferencer implements URIDereferencer {
+public final class SameDocumentUriDereferencer implements URIDereferencer {
private static final URIDereferencer INSTANCE = new SameDocumentUriDereferencer();
+
+ private SameDocumentUriDereferencer() {
+ // singelton
+ }
public static URIDereferencer getInstance() {
return INSTANCE;
}
- private SameDocumentUriDereferencer() {
- // singelton
- }
+
public Data dereference(URIReference uriReference, XMLCryptoContext context) throws URIReferenceException {
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java
index 6a7ae93..487ea42 100644
--- a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java
@@ -23,14 +23,14 @@ import java.security.KeyStore;
import javax.xml.crypto.KeySelector;
-import org.apache.camel.component.xmlsecurity.api.KeyAccessor;
import org.apache.camel.component.xmlsecurity.api.DefaultKeyAccessor;
import org.apache.camel.component.xmlsecurity.api.DefaultKeySelector;
+import org.apache.camel.component.xmlsecurity.api.KeyAccessor;
-public class TestKeystore {
-
- public TestKeystore() {
+public final class TestKeystore {
+ private TestKeystore() {
+ // helper class
}
http://git-wip-us.apache.org/repos/asf/camel/blob/54ce5a02/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TimestampProperty.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TimestampProperty.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TimestampProperty.java
index 099ed8d..ee12318 100644
--- a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TimestampProperty.java
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TimestampProperty.java
@@ -29,9 +29,11 @@ import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+import org.w3c.dom.Document;
+
import org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper;
import org.apache.camel.component.xmlsecurity.api.XmlSignatureProperties;
-import org.w3c.dom.Document;
+
/**
* Example for a XmlSignatureProperties implementation which adds a timestamp
[4/6] CAMEL-6339 Applied the patch with thanks to Franz
Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
new file mode 100644
index 0000000..120b81c
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
@@ -0,0 +1,680 @@
+/**
+ * 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.camel.component.xmlsecurity.processor;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import javax.xml.crypto.AlgorithmMethod;
+import javax.xml.crypto.KeySelector;
+import javax.xml.crypto.dom.DOMStructure;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.xmlsecurity.api.KeyAccessor;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureFormatException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidKeyException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureNoKeyException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureProperties;
+import org.apache.camel.util.IOHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * Creates from the message body a XML signature element which is returned in
+ * the message body of the output message. Enveloped and enveloping XML
+ * signatures are supported.
+ * <p>
+ * In the enveloped XML signature case, the method
+ * {@link XmlSignerConfiguration#getParentLocalName()} must not return
+ * <code>null</code>. In this case the parent element must be contained in the
+ * XML document provided by the message body and the signature element is added
+ * as last child element of the parent element. If a KeyInfo instance is
+ * provided by the {@link KeyAccessor} and
+ * {@link XmlSignerConfiguration#getAddKeyInfoReference()} is <code>true</code>,
+ * then also a reference to the KeyInfo element is added. The generated XML
+ * signature has the following structure:
+ *
+ * <pre>
+ * {@code
+ * <[parent element]>
+ * ...
+ * <Signature Id="[signature_id]">
+ * <SignedInfo>
+ * <Reference URI="">
+ * <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ * (<Transform>)*
+ * <DigestMethod>
+ * <DigestValue>
+ * </Reference>
+ * (<Reference URI="#[keyinfo_Id]">
+ * <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
+ * <DigestMethod>
+ * <DigestValue>
+ * </Reference>)?
+ * <!-- further references possible, see XmlSignerConfiguration#setProperties(XmlSignatureProperties) -->
+ * </SignedInfo>
+ * <SignatureValue>
+ * (<KeyInfo Id="[keyinfo_id]">)?
+ * <!-- Object elements possible, see XmlSignerConfiguration#setProperties(XmlSignatureProperties) -->
+ * </Signature>
+ * </[parent element]>
+ * }
+ * </pre>
+ * <p>
+ * In the enveloping XML signature case, the generated XML signature has the
+ * following structure:
+ *
+ * <pre>
+ * {@code
+ * <Signature Id="[signature_id]">
+ * <SignedInfo>
+ * <Reference URI="#[object_id]" type="[optional_type_value]">
+ * (<Transform>)*
+ * <DigestMethod>
+ * <DigestValue>
+ * </Reference>
+ * (<Reference URI="#[keyinfo_id]">
+ * <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
+ * <DigestMethod>
+ * <DigestValue>
+ * </Reference>)?
+ * <!-- further references possible, see XmlSignerConfiguration#setProperties(XmlSignatureProperties) -->
+ * </SignedInfo>
+ * <SignatureValue>
+ * (<KeyInfo Id="[keyinfo_id]">)?
+ * <Object Id="[object_id]"/>
+ * <!-- further Object elements possible, see XmlSignerConfiguration#setProperties(XmlSignatureProperties) -->
+ * </Signature>
+ * }
+ * </pre>
+ *
+ * In the enveloping XML signature case, also message bodies containing plain
+ * text are supported. This must be indicated via the header
+ * {@link XmlSignatureConstants#HEADER_MESSAGE_IS_PLAIN_TEXT} or via the
+ * configuration {@link XmlSignerConfiguration#getPlainText()}.
+ *
+ * <p>
+ * In both cases, the digest algorithm is either read from the configuration
+ * method {@link XmlSignerConfiguration#getDigestAlgorithm()} or calculated from
+ * the signature algorithm (
+ * {@link XmlSignerConfiguration#getSignatureAlgorithm()}. The optional
+ * transforms are read from {@link XmlSignerConfiguration#getTransformMethods()}
+ * .
+ * <p>
+ * In both cases, you can add additional references and objects which contain
+ * properties for the XML signature, see
+ * {@link XmlSignerConfiguration#setProperties(XmlSignatureProperties)}.
+ */
+
+public class XmlSignerProcessor extends XmlSignatureProcessor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(XmlSignerProcessor.class);
+
+ private static final String SHA512 = "sha512";
+
+ private static final String SHA384 = "sha384";
+
+ private static final String SHA256 = "sha256";
+
+ private static final String SHA1 = "sha1";
+
+ private static final String HTTP_WWW_W3_ORG_2001_04_XMLDSIG_MORE_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#sha384";
+
+ private final XmlSignerConfiguration config;
+
+ public XmlSignerProcessor(XmlSignerConfiguration config) {
+ super();
+ this.config = config;
+ }
+
+ @Override
+ public XmlSignerConfiguration getConfiguration() {
+ return config;
+ }
+
+ @Override
+ public void process(Exchange exchange) throws Exception { //NOPMD
+
+ try {
+ LOG.debug("XML signature generation started using algorithm {} and canonicalization method {}", getConfiguration()
+ .getSignatureAlgorithm(), getConfiguration().getCanonicalizationMethod().getAlgorithm());
+
+ // lets setup the out message before we invoke the signing
+ // so that it can mutate it if necessary
+ Message out = exchange.getOut();
+ out.copyFrom(exchange.getIn());
+
+ Document outputDoc = sign(out);
+
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ XmlSignatureHelper.transformNonTextNodeToOutputStream(outputDoc, outStream, omitXmlDeclaration(out));
+ byte[] data = outStream.toByteArray();
+ out.setBody(data);
+ clearMessageHeaders(out);
+ LOG.debug("XML signature generation finished");
+ } catch (Exception e) {
+ // remove OUT message, as an exception occurred
+ exchange.setOut(null);
+ throw e;
+ }
+ }
+
+ protected Document sign(final Message out) throws Exception { //NOPMD
+
+ try {
+ XMLSignatureFactory fac;
+ // Try to install the Santuario Provider - fall back to the JDK provider if this does
+ // not work
+ try {
+ fac = XMLSignatureFactory.getInstance("DOM", "ApacheXMLDSig");
+ } catch (NoSuchProviderException ex) {
+ fac = XMLSignatureFactory.getInstance("DOM");
+ }
+
+ final Node node = getMessageBodyNode(out);
+
+ Node parent = getParentOfSignature(out, node);
+
+ final KeySelector keySelector = getConfiguration().getKeyAccessor().getKeySelector(out);
+ if (keySelector == null) {
+ throw new XmlSignatureNoKeyException(
+ "Key selector is missing for XML signature generation. Specify a key selector in the configuration.");
+ }
+
+ // the method KeyAccessor.getKeyInfo must be called after the method KeyAccessor.getKeySelector, this is part of the interface contract!
+ final KeyInfo keyInfo = getConfiguration().getKeyAccessor().getKeyInfo(out, node, fac.getKeyInfoFactory());
+
+ final String signatureId = "_" + UUID.randomUUID().toString();
+ LOG.debug("Signature Id {}", signatureId);
+
+ XmlSignatureProperties.Input input = new InputBuilder().contentDigestAlgorithm(getDigestAlgorithmUri()).keyInfo(keyInfo)
+ .message(out).messageBodyNode(node).parent(parent).signatureAlgorithm(getConfiguration().getSignatureAlgorithm())
+ .signatureFactory(fac).signatureId(signatureId).build();
+
+ XmlSignatureProperties.Output properties = getSignatureProperties(input);
+
+ List<? extends XMLObject> objects = getObjects(input, properties);
+ List<? extends Reference> refs = getReferences(input, properties, getKeyInfoId(keyInfo));
+
+ SignedInfo si = createSignedInfo(fac, refs);
+
+ if (parent == null) {
+ // for enveloping signature, create new document
+ parent = XmlSignatureHelper.newDocumentBuilder(Boolean.TRUE).newDocument();
+ }
+
+ DOMSignContext dsc = createAndConfigureSignContext(parent, keySelector);
+
+ XMLSignature signature = fac.newXMLSignature(si, keyInfo, objects, signatureId, null);
+ // generate the signature
+ signature.sign(dsc);
+
+ return XmlSignatureHelper.getDocument(parent);
+
+ } catch (XMLSignatureException se) {
+ if (se.getCause() instanceof InvalidKeyException) {
+ throw new XmlSignatureInvalidKeyException(se.getMessage(), se);
+ } else {
+ throw new XmlSignatureException(se);
+ }
+ } catch (GeneralSecurityException e) {
+ // like NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchProviderException
+ throw new XmlSignatureException(e);
+ }
+
+ }
+
+ protected XmlSignatureProperties.Output getSignatureProperties(XmlSignatureProperties.Input input) throws Exception { //NOPMD
+ XmlSignatureProperties propGetter = getConfiguration().getProperties();
+ XmlSignatureProperties.Output propsOutput = null;
+ if (propGetter != null) {
+ propsOutput = propGetter.get(input);
+ }
+ return propsOutput;
+ }
+
+ private DOMSignContext createAndConfigureSignContext(Node parent, KeySelector keySelector) {
+ DOMSignContext dsc = new DOMSignContext(keySelector, parent);
+ // set namespace prefix for "http://www.w3.org/2000/09/xmldsig#" according to best practice described in http://www.w3.org/TR/xmldsig-bestpractices/#signing-xml-without-namespaces
+ if (getConfiguration().getPrefixForXmlSignatureNamespace() != null
+ && !getConfiguration().getPrefixForXmlSignatureNamespace().isEmpty()) {
+ dsc.putNamespacePrefix("http://www.w3.org/2000/09/xmldsig#", getConfiguration().getPrefixForXmlSignatureNamespace());
+ }
+ setCryptoContextProperties(dsc);
+ setUriDereferencerAndBaseUri(dsc);
+ return dsc;
+ }
+
+ protected Boolean omitXmlDeclaration(Message message) {
+ Boolean omitXmlDeclaration = message.getHeader(XmlSignatureConstants.HEADER_OMIT_XML_DECLARATION, Boolean.class);
+ if (omitXmlDeclaration == null) {
+ omitXmlDeclaration = getConfiguration().getOmitXmlDeclaration();
+ }
+ if (omitXmlDeclaration == null) {
+ omitXmlDeclaration = Boolean.FALSE;
+ }
+ LOG.debug("Omit XML declaration: {}", omitXmlDeclaration);
+ return omitXmlDeclaration;
+ }
+
+ protected SignedInfo createSignedInfo(XMLSignatureFactory fac, List<? extends Reference> refs) throws Exception { //NOPMD
+ return fac.newSignedInfo(fac.newCanonicalizationMethod(getConfiguration().getCanonicalizationMethod().getAlgorithm(),
+ (C14NMethodParameterSpec) getConfiguration().getCanonicalizationMethod().getParameterSpec()),
+ getSignatureMethod(getConfiguration().getSignatureAlgorithm(), fac), refs);
+ }
+
+ private SignatureMethod getSignatureMethod(String signatureAlgorithm, XMLSignatureFactory fac) throws NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException {
+ return fac.newSignatureMethod(signatureAlgorithm, null);
+ }
+
+ protected Node getMessageBodyNode(Message message) throws Exception { //NOPMD
+ InputStream is = message.getMandatoryBody(InputStream.class);
+
+ Boolean isPlainText = isPlainText(message);
+
+ Node node;
+ if (isPlainText != null && isPlainText) {
+ node = getTextNode(message, is);
+ } else {
+ Document doc = parseInput(is, getConfiguration().getDisallowDoctypeDecl());
+ node = doc.getDocumentElement();
+ LOG.debug("Root element of document to be signed: {}", node);
+ }
+ return node;
+ }
+
+ protected Boolean isPlainText(Message message) {
+ Boolean isPlainText = message.getHeader(XmlSignatureConstants.HEADER_MESSAGE_IS_PLAIN_TEXT, Boolean.class);
+ if (isPlainText == null) {
+ isPlainText = getConfiguration().getPlainText();
+ }
+ LOG.debug("Is plain text: {}", isPlainText);
+ return isPlainText;
+ }
+
+ protected Element getParentOfSignature(Message inMessage, Node messageBodyNode) throws Exception { //NOPMD
+ if (getConfiguration().getParentLocalName() == null) {
+ return null;
+ }
+ if (messageBodyNode.getParentNode() == null || messageBodyNode.getParentNode().getNodeType() != Node.DOCUMENT_NODE) {
+ throw new XmlSignatureFormatException(
+ "Incomming message has wrong format: It is not an XML document. Cannot create an enveloped XML signature.");
+ }
+
+ Document doc = (Document) messageBodyNode.getParentNode();
+ NodeList parents = doc.getElementsByTagNameNS(getConfiguration().getParentNamespace(), getConfiguration().getParentLocalName());
+
+ if (parents == null || parents.getLength() == 0) {
+ throw new XmlSignatureFormatException(
+ String.format(
+ "Incoming message has wrong format: The parent element with the local name %s and the namespace %s was not found in the message to build an enveloped XML signature.",
+ getConfiguration().getParentLocalName(), getConfiguration().getParentNamespace()));
+ }
+ // return the first element
+ return (Element) parents.item(0);
+
+ }
+
+ protected List<? extends Reference> getReferences(XmlSignatureProperties.Input input, XmlSignatureProperties.Output properties,
+ String keyInfoId) throws Exception { //NOPMD
+
+ // Create Reference with URI="#<objectId>" for enveloping signature or URI="" for enveloped signature and the transforms
+ Reference ref = createReference(input.getSignatureFactory(), getContentReferenceUri(input.getMessage()),
+ getContentReferenceType(input.getMessage()));
+ Reference keyInfoRef = createKeyInfoReference(input.getSignatureFactory(), keyInfoId, input.getContentDigestAlgorithm());
+
+ int propsRefsSize = properties == null || properties.getReferences() == null || properties.getReferences().isEmpty() ? 0
+ : properties.getReferences().size();
+ int size = keyInfoRef == null ? propsRefsSize + 1 : propsRefsSize + 2;
+ List<Reference> referenceList = new ArrayList<Reference>(size);
+ referenceList.add(ref);
+ if (keyInfoRef != null) {
+ referenceList.add(keyInfoRef);
+ }
+ if (properties != null && properties.getReferences() != null && !properties.getReferences().isEmpty()) {
+ referenceList.addAll(properties.getReferences());
+ }
+ return referenceList;
+ }
+
+ protected List<? extends XMLObject> getObjects(XmlSignatureProperties.Input input, XmlSignatureProperties.Output properties)
+ throws Exception { //NOPMD
+ if (isEnveloped()) {
+ if (properties == null || properties.getObjects() == null) {
+ return Collections.emptyList();
+ }
+ return properties.getObjects();
+ }
+
+ final String objectId = getConfiguration().getContentObjectId();
+ LOG.debug("Object Content Id {}", objectId);
+
+ XMLObject obj = createXMLObject(input.getSignatureFactory(), input.getMessageBodyNode(), objectId);
+ if (properties == null || properties.getObjects() == null || properties.getObjects().isEmpty()) {
+ return Collections.singletonList(obj);
+ }
+ List<XMLObject> result = new ArrayList<XMLObject>(properties.getObjects().size() + 1);
+ result.add(obj);
+ result.addAll(properties.getObjects());
+ return result;
+ }
+
+ private Node getTextNode(Message inMessage, InputStream is) throws IOException, ParserConfigurationException, XmlSignatureException {
+ LOG.debug("Message body to be signed is plain text");
+ String encoding = getMessageEncoding(inMessage);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOHelper.copyAndCloseInput(is, bos);
+ try {
+ String text = new String(bos.toByteArray(), encoding);
+ return XmlSignatureHelper.newDocumentBuilder(true).newDocument().createTextNode(text);
+ } catch (UnsupportedEncodingException e) {
+ throw new XmlSignatureException(String.format("The message encoding %s is not supported.", encoding), e);
+ }
+ }
+
+ protected String getMessageEncoding(Message inMessage) {
+ String encoding = inMessage.getHeader(XmlSignatureConstants.HEADER_PLAIN_TEXT_ENCODING, String.class);
+ if (encoding == null) {
+ encoding = getConfiguration().getPlainTextEncoding();
+ }
+ LOG.debug("Messge encoding: {}", encoding);
+ return encoding;
+ }
+
+ protected Document parseInput(InputStream is, Boolean disallowDoctypeDecl) throws XmlSignatureFormatException,
+ ParserConfigurationException, IOException {
+ try {
+ return XmlSignatureHelper.newDocumentBuilder(disallowDoctypeDecl).parse(is);
+ } catch (SAXException e) {
+ throw new XmlSignatureFormatException(
+ "XML signature generation not possible. Sent message is not an XML document. Check the sent message.", e);
+ } finally {
+ IOHelper.close(is, "input stream");
+ }
+ }
+
+ protected Reference createReference(XMLSignatureFactory fac, String uri, String type) throws InvalidAlgorithmParameterException,
+ XmlSignatureException {
+ try {
+ List<Transform> transforms = getTransforms(fac);
+ Reference ref = fac.newReference(uri, fac.newDigestMethod(getDigestAlgorithmUri(), null), transforms, type, null);
+ return ref;
+ } catch (NoSuchAlgorithmException e) {
+ throw new XmlSignatureException("Wrong algorithm specified in the configuration.", e);
+ }
+ }
+
+ protected String getContentReferenceType(Message message) {
+ String type = message.getHeader(XmlSignatureConstants.HEADER_CONTENT_REFERENCE_TYPE, String.class);
+ if (type == null) {
+ type = getConfiguration().getContentReferenceType();
+ }
+ LOG.debug("Content reference type: {}", type);
+ return type;
+ }
+
+ protected String getContentReferenceUri(Message message) {
+ String uri = message.getHeader(XmlSignatureConstants.HEADER_CONTENT_REFERENCE_URI, String.class);
+ if (uri == null) {
+ uri = getConfiguration().getContentReferenceUri();
+ }
+ if (uri == null) {
+ uri = isEnveloped() ? "" : "#" + getConfiguration().getContentObjectId();
+ }
+ LOG.debug("Content reference uri: {}", uri);
+ return uri;
+ }
+
+ protected XMLObject createXMLObject(XMLSignatureFactory fac, Node node, String id) {
+ return fac.newXMLObject(Collections.singletonList(new DOMStructure(node)), id, null, null);
+ }
+
+ private List<Transform> getTransforms(XMLSignatureFactory fac) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
+ boolean isEnveloped = isEnveloped();
+ List<AlgorithmMethod> configuredTrafos = getConfiguration().getTransformMethods();
+ if (isEnveloped) {
+ // add enveloped transform if necessary
+ if (configuredTrafos.size() > 0) {
+ if (!containsEnvelopedTransform(configuredTrafos)) {
+ configuredTrafos = new ArrayList<AlgorithmMethod>(configuredTrafos.size() + 1);
+ configuredTrafos.add(XmlSignatureHelper.getEnvelopedTransform());
+ configuredTrafos.addAll(getConfiguration().getTransformMethods());
+ }
+ } else {
+ // add enveloped and C14N trafo
+ configuredTrafos = new ArrayList<AlgorithmMethod>(2);
+ configuredTrafos.add(XmlSignatureHelper.getEnvelopedTransform());
+ configuredTrafos.add(XmlSignatureHelper.getCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE));
+ }
+ }
+
+ List<Transform> transforms = new ArrayList<Transform>(configuredTrafos.size());
+ for (AlgorithmMethod trafo : configuredTrafos) {
+ Transform transform = fac.newTransform(trafo.getAlgorithm(), (TransformParameterSpec) trafo.getParameterSpec());
+ transforms.add(transform);
+ LOG.debug("Transform method: {}", trafo.getAlgorithm());
+ }
+ return transforms;
+ }
+
+ protected boolean isEnveloped() {
+ return getConfiguration().getParentLocalName() != null;
+ }
+
+ private boolean containsEnvelopedTransform(List<AlgorithmMethod> configuredTrafos) {
+ for (AlgorithmMethod m : configuredTrafos) {
+ if (Transform.ENVELOPED.equals(m.getAlgorithm())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected String getDigestAlgorithmUri() throws XmlSignatureException {
+
+ String result = getConfiguration().getDigestAlgorithm();
+ if (result == null) {
+ String signatureAlgorithm = getConfiguration().getSignatureAlgorithm();
+ if (signatureAlgorithm != null) {
+ if (signatureAlgorithm.contains(SHA1)) {
+ result = DigestMethod.SHA1;
+ } else if (signatureAlgorithm.contains(SHA256)) {
+ result = DigestMethod.SHA256;
+ } else if (signatureAlgorithm.contains(SHA384)) {
+ result = HTTP_WWW_W3_ORG_2001_04_XMLDSIG_MORE_SHA384;
+ } else if (signatureAlgorithm.contains(SHA512)) {
+ result = DigestMethod.SHA512;
+ }
+ }
+ }
+ if (result != null) {
+ LOG.debug("Digest algorithm: {}", result);
+ return result;
+ }
+ throw new XmlSignatureException(
+ "Digest algorithm missing for XML signature generation. Specify the digest algorithm in the configuration.");
+ }
+
+ protected Reference createKeyInfoReference(XMLSignatureFactory fac, String keyInfoId, String digestAlgorithm) throws Exception { //NOPMD
+
+ if (keyInfoId == null) {
+ return null;
+ }
+ if (getConfiguration().getAddKeyInfoReference() == null) {
+ return null;
+ }
+
+ if (!getConfiguration().getAddKeyInfoReference()) {
+ return null;
+ }
+
+ LOG.debug("Creating reference to key info element with Id: {}", keyInfoId);
+ List<Transform> transforms = new ArrayList<Transform>(1);
+ Transform transform = fac.newTransform(CanonicalizationMethod.INCLUSIVE, (TransformParameterSpec) null);
+ transforms.add(transform);
+ return fac.newReference("#" + keyInfoId, fac.newDigestMethod(digestAlgorithm, null), transforms, null, null);
+ }
+
+ private String getKeyInfoId(KeyInfo keyInfo) throws Exception { //NOPMD
+ if (keyInfo == null) {
+ return null;
+ }
+ return keyInfo.getId();
+ }
+
+ private static class InputBuilder {
+
+ private XMLSignatureFactory signatureFactory;
+
+ private String signatureAlgorithm;
+
+ private Node parent;
+
+ private Node messageBodyNode;
+
+ private Message message;
+
+ private KeyInfo keyInfo;
+
+ private String contentDigestAlgorithm;
+
+ private String signatureId;
+
+ public InputBuilder signatureFactory(XMLSignatureFactory signatureFactory) {
+ this.signatureFactory = signatureFactory;
+ return this;
+ }
+
+ public InputBuilder signatureAlgorithm(String signatureAlgorithm) {
+ this.signatureAlgorithm = signatureAlgorithm;
+ return this;
+ }
+
+ public InputBuilder parent(Node parent) {
+ this.parent = parent;
+ return this;
+ }
+
+ public InputBuilder messageBodyNode(Node messageBodyNode) {
+ this.messageBodyNode = messageBodyNode;
+ return this;
+ }
+
+ public InputBuilder message(Message message) {
+ this.message = message;
+ return this;
+ }
+
+ public InputBuilder keyInfo(KeyInfo keyInfo) {
+ this.keyInfo = keyInfo;
+ return this;
+ }
+
+ public InputBuilder contentDigestAlgorithm(String contentDigestAlgorithm) {
+ this.contentDigestAlgorithm = contentDigestAlgorithm;
+ return this;
+ }
+
+ public InputBuilder signatureId(String signatureId) {
+ this.signatureId = signatureId;
+ return this;
+ }
+
+ public XmlSignatureProperties.Input build() {
+ return new XmlSignatureProperties.Input() {
+
+ @Override
+ public XMLSignatureFactory getSignatureFactory() {
+ return signatureFactory;
+ }
+
+ @Override
+ public String getSignatureAlgorithm() {
+ return signatureAlgorithm;
+ }
+
+ @Override
+ public Node getParent() {
+ return parent;
+ }
+
+ @Override
+ public Node getMessageBodyNode() {
+ return messageBodyNode;
+ }
+
+ @Override
+ public Message getMessage() {
+ return message;
+ }
+
+ @Override
+ public KeyInfo getKeyInfo() {
+ return keyInfo;
+ }
+
+ @Override
+ public String getContentDigestAlgorithm() {
+ return contentDigestAlgorithm;
+ }
+
+ @Override
+ public String getSignatureId() {
+ return signatureId;
+ }
+
+ };
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierConfiguration.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierConfiguration.java
new file mode 100644
index 0000000..869abad
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierConfiguration.java
@@ -0,0 +1,232 @@
+/**
+ * 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.camel.component.xmlsecurity.processor;
+
+import javax.xml.crypto.KeySelector;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.xmlsecurity.api.DefaultXmlSignature2Message;
+import org.apache.camel.component.xmlsecurity.api.DefaultValidationFailedHandler;
+import org.apache.camel.component.xmlsecurity.api.XmlSignature2Message;
+import org.apache.camel.component.xmlsecurity.api.ValidationFailedHandler;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureChecker;
+
+public class XmlVerifierConfiguration extends XmlSignatureConfiguration {
+
+ private KeySelector keySelector;
+
+ private String keySelectorName;
+
+ private XmlSignatureChecker xmlSignatureChecker;
+
+ private String xmlSignatureCheckerName;
+
+ private XmlSignature2Message xmlSignature2Message = new DefaultXmlSignature2Message();
+
+ private String xmlSignature2MessageName;
+
+ private ValidationFailedHandler validationFailedHandler = new DefaultValidationFailedHandler();
+
+ private String validationFailedHandlerName;
+
+ private Object outputNodeSearch;
+
+ private String outputNodeSearchType = DefaultXmlSignature2Message.OUTPUT_NODE_SEARCH_TYPE_DEFAULT;
+
+ private Boolean removeSignatureElements = Boolean.FALSE;
+
+ private Boolean secureValidation = Boolean.TRUE;
+
+ public XmlVerifierConfiguration() {
+ super();
+ }
+
+ public XmlVerifierConfiguration copy() {
+ try {
+ return (XmlVerifierConfiguration) clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeCamelException(e);
+ }
+ }
+
+ public void setCamelContext(CamelContext camelContext) {
+ super.setCamelContext(camelContext);
+ setKeySelector(keySelectorName);
+ setXmlSignatureChecker(xmlSignatureCheckerName);
+ setXmlSignature2Message(xmlSignature2MessageName);
+ setValidationFailedHandler(validationFailedHandlerName);
+ }
+
+ public void setKeySelector(KeySelector keySelector) {
+ this.keySelector = keySelector;
+ }
+
+ public KeySelector getKeySelector() {
+ return keySelector;
+ }
+
+ /**
+ * Sets the reference name for a KeySelector that can be found in the
+ * registry.
+ */
+ public void setKeySelector(String keySelectorName) {
+ if (getCamelContext() != null && keySelectorName != null) {
+ KeySelector selector = getCamelContext().getRegistry()
+ .lookupByNameAndType(keySelectorName, KeySelector.class);
+ if (selector != null) {
+ setKeySelector(selector);
+ }
+ }
+ if (keySelectorName != null) {
+ this.keySelectorName = keySelectorName;
+ }
+ }
+
+ public XmlSignatureChecker getXmlSignatureChecker() {
+ return xmlSignatureChecker;
+ }
+
+ public void setXmlSignatureChecker(XmlSignatureChecker xmlSignatureChecker) {
+ this.xmlSignatureChecker = xmlSignatureChecker;
+ }
+
+ /**
+ * Sets the reference name for a application checker that can be found in
+ * the registry.
+ */
+ public void setXmlSignatureChecker(String xmlSignatureCheckerName) {
+ if (getCamelContext() != null && xmlSignatureCheckerName != null) {
+ XmlSignatureChecker checker = getCamelContext().getRegistry()
+ .lookupByNameAndType(xmlSignatureCheckerName,
+ XmlSignatureChecker.class);
+ if (checker != null) {
+ setXmlSignatureChecker(checker);
+ }
+ }
+ if (xmlSignatureCheckerName != null) {
+ this.xmlSignatureCheckerName = xmlSignatureCheckerName;
+ }
+ }
+
+ public XmlSignature2Message getXmlSignature2Message() {
+ return xmlSignature2Message;
+ }
+
+ public void setXmlSignature2Message(XmlSignature2Message xmlSignature2Message) {
+ this.xmlSignature2Message = xmlSignature2Message;
+ }
+
+ /**
+ * Sets the reference name for the to-message instance that can be found in
+ * the registry.
+ */
+ public void setXmlSignature2Message(String xmlSignature2Message) {
+ if (getCamelContext() != null && xmlSignature2Message != null) {
+ XmlSignature2Message maper = getCamelContext().getRegistry()
+ .lookupByNameAndType(xmlSignature2Message,
+ XmlSignature2Message.class);
+ if (maper != null) {
+ setXmlSignature2Message(maper);
+ }
+ }
+ if (xmlSignature2Message != null) {
+ this.xmlSignature2MessageName = xmlSignature2Message;
+ }
+ }
+
+ public ValidationFailedHandler getValidationFailedHandler() {
+ return validationFailedHandler;
+ }
+
+ public void setValidationFailedHandler(ValidationFailedHandler validationFailedHandler) {
+ this.validationFailedHandler = validationFailedHandler;
+ }
+
+ public void setValidationFailedHandler(String validationFailedHandlerName) {
+ if (getCamelContext() != null && validationFailedHandlerName != null) {
+ ValidationFailedHandler vailFailedHandler = getCamelContext()
+ .getRegistry().lookupByNameAndType(validationFailedHandlerName,
+ ValidationFailedHandler.class);
+ if (vailFailedHandler != null) {
+ setValidationFailedHandler(vailFailedHandler);
+ }
+ }
+ if (validationFailedHandlerName != null) {
+ this.validationFailedHandlerName = validationFailedHandlerName;
+ }
+ }
+
+ public Object getOutputNodeSearch() {
+ return outputNodeSearch;
+ }
+
+ /**
+ * Sets the output node search value for determining the node from the XML
+ * signature document which shall be set to the output message body. The
+ * class of the value depends on the type of the output node search. The
+ * output node search is forwarded to {@link XmlSignature2Message}.
+ *
+ */
+ public void setOutputNodeSearch(Object outputNodeSearch) {
+ this.outputNodeSearch = outputNodeSearch;
+ }
+
+ public String getOutputNodeSearchType() {
+ return outputNodeSearchType;
+ }
+
+ /**
+ * Determines the search type for determining the output node which is
+ * serialized into the output message bodyF. See
+ * {@link #setOutputNodeSearch(String)}. The supported default search types
+ * you can find in {@link DefaultXmlSignature2Message}.
+ *
+ * @param outputNodeSearchType
+ */
+ public void setOutputNodeSearchType(String outputNodeSearchType) {
+ this.outputNodeSearchType = outputNodeSearchType;
+ }
+
+ public Boolean getRemoveSignatureElements() {
+ return removeSignatureElements;
+ }
+
+ /**
+ * Indicator whether the XML signature elements (elements with local name
+ * "Signature" and namesapce ""http://www.w3.org/2000/09/xmldsig#"") shall
+ * be removed from the document set to the output message. Normally, this is
+ * only necessary, if the XML signature is enveloped. The default value is
+ * {@link Boolean#FALSE}. This parameter is forwarded to
+ * {@link XmlSignature2Message}.
+ * <p>
+ * This indicator has no effect if the output node search is of type
+ * {@link DefaultXmlSignature2Message#OUTPUT_NODE_SEARCH_TYPE_DEFAULT}.F
+ */
+ public void setRemoveSignatureElements(Boolean removeSignatureElements) {
+ this.removeSignatureElements = removeSignatureElements;
+ }
+
+ public Boolean getSecureValidation() {
+ return secureValidation;
+ }
+
+ public void setSecureValidation(Boolean secureValidation) {
+ this.secureValidation = secureValidation;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierProcessor.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierProcessor.java
new file mode 100644
index 0000000..1fd40ee
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlVerifierProcessor.java
@@ -0,0 +1,324 @@
+/**
+ * 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.camel.component.xmlsecurity.processor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.NoSuchProviderException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.crypto.KeySelector;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dsig.Manifest;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignature.SignatureValue;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.xmlsecurity.api.ValidationFailedHandler;
+import org.apache.camel.component.xmlsecurity.api.XmlSignature2Message;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureChecker;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureFormatException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidException;
+import org.apache.camel.util.IOHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * XML signature verifier. Assumes that the input XML contains exactly one
+ * Signature element.
+ */
+public class XmlVerifierProcessor extends XmlSignatureProcessor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(XmlVerifierProcessor.class);
+
+ private final XmlVerifierConfiguration config;
+
+ public XmlVerifierProcessor(XmlVerifierConfiguration config) {
+ super();
+ this.config = config;
+ }
+
+ @Override
+ public XmlVerifierConfiguration getConfiguration() {
+ return config;
+ }
+
+ @Override
+ public void process(Exchange exchange) throws Exception {
+
+ InputStream stream = exchange.getIn().getMandatoryBody(InputStream.class);
+ try {
+ // lets setup the out message before we invoke the signing
+ // so that it can mutate it if necessary
+ Message out = exchange.getOut();
+ out.copyFrom(exchange.getIn());
+ verify(stream, out);
+ clearMessageHeaders(out);
+ } catch (Exception e) {
+ // remove OUT message, as an exception occurred
+ exchange.setOut(null);
+ throw e;
+ } finally {
+ IOHelper.close(stream, "input stream");
+ }
+ }
+
+ protected void verify(InputStream input, final Message out)
+ throws Exception {
+
+ LOG.debug("Verification of XML signature document started");
+ final Document doc = parseInput(input);
+
+ Node signatureNode = getSignatureNode(doc);
+
+ XMLSignatureFactory fac;
+ // Try to install the Santuario Provider - fall back to the JDK provider if this does
+ // not work
+ try {
+ fac = XMLSignatureFactory.getInstance("DOM", "ApacheXMLDSig");
+ } catch (NoSuchProviderException ex) {
+ fac = XMLSignatureFactory.getInstance("DOM");
+ }
+
+ KeySelector selector = getConfiguration().getKeySelector();
+ if (selector == null) {
+ throw new IllegalStateException("Wrong configuration. Key selector is missing.");
+ }
+
+ DOMValidateContext valContext = new DOMValidateContext(selector, signatureNode);
+ valContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
+ valContext.setProperty("org.jcp.xml.dsig.validateManifests", Boolean.TRUE);
+
+ if (getConfiguration().getSecureValidation() == Boolean.TRUE) {
+ valContext.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
+ valContext.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
+ }
+ setUriDereferencerAndBaseUri(valContext);
+
+ setCryptoContextProperties(valContext);
+
+ final XMLSignature signature = fac.unmarshalXMLSignature(valContext);
+
+ executeApplicationCheck(out, doc, signature);
+
+ boolean coreValidity;
+ try {
+ coreValidity = signature.validate(valContext);
+ } catch (XMLSignatureException se) {
+ throw getConfiguration().getValidationFailedHandler().onXMLSignatureException(se);
+ }
+ // Check core validation status
+ boolean goon = coreValidity;
+ if (coreValidity == false) {
+ goon = handleSignatureValidationFailed(valContext, signature);
+ }
+ if (goon) {
+ LOG.debug("XML signature verified");
+ map2Message(signature, out, doc);
+ } else {
+ throw new XmlSignatureInvalidException("");
+ }
+ }
+
+ private void executeApplicationCheck(final Message out, final Document doc,
+ final XMLSignature signature) throws Exception {
+ if (getConfiguration().getXmlSignatureChecker() != null) {
+ XmlSignatureChecker.Input checkerInput = new XmlSignatureChecker.Input() {
+
+ @Override
+ public SignedInfo getSignedInfo() {
+ return signature.getSignedInfo();
+ }
+
+ @Override
+ public SignatureValue getSignatureValue() {
+ return signature.getSignatureValue();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<? extends XMLObject> getObjects() {
+ return (List<? extends XMLObject>) signature.getObjects();
+ }
+
+ @Override
+ public Document getMessageBodyDocument() {
+ return doc;
+ }
+
+ @Override
+ public Message getMessage() {
+ return out;
+ }
+
+ @Override
+ public KeyInfo getKeyInfo() {
+ return signature.getKeyInfo();
+ }
+ };
+ getConfiguration().getXmlSignatureChecker().checkBeforeCoreValidation(checkerInput);
+ }
+ }
+
+ private void map2Message(XMLSignature signature, Message out,
+ final Document messageBodyDocument) throws Exception {
+ @SuppressWarnings("unchecked")
+ final List<Reference> refs = new ArrayList<Reference>(signature.getSignedInfo().getReferences());
+ @SuppressWarnings("unchecked")
+ final List<XMLObject> objs = new ArrayList<XMLObject>(signature.getObjects());
+ XmlSignature2Message.Input refsAndObjects = new XmlSignature2Message.Input() {
+
+ @Override
+ public List<Reference> getReferences() {
+ return refs;
+ }
+
+ @Override
+ public List<XMLObject> getObjects() {
+ return objs;
+ }
+
+ @Override
+ public Document getMessageBodyDocument() {
+ return messageBodyDocument;
+ }
+
+ @Override
+ public Boolean omitXmlDeclaration() {
+ return getConfiguration().getOmitXmlDeclaration();
+ }
+
+ @Override
+ public Object getOutputNodeSearch() {
+ return getConfiguration().getOutputNodeSearch();
+ }
+
+ @Override
+ public String getOutputNodeSearchType() {
+ return getConfiguration().getOutputNodeSearchType();
+ }
+
+ public Boolean getRemoveSignatureElements() {
+ return getConfiguration().getRemoveSignatureElements();
+ }
+
+ };
+ getConfiguration().getXmlSignature2Message().mapToMessage(refsAndObjects, out);
+ }
+
+ private Node getSignatureNode(Document doc) throws IOException,
+ ParserConfigurationException, XmlSignatureFormatException {
+
+ // Find Signature element
+ NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
+ if (nl.getLength() == 0) {
+ throw new XmlSignatureFormatException(
+ "Message is not a correct XML signature document: 'Signature' element is missing. Check the sent message.");
+ }
+
+ if (nl.getLength() != 1) {
+ throw new XmlSignatureFormatException(
+ "XML signature document is not supported; it contains more than one signature element. Check the sent message.");
+ }
+ Node signatureNode = nl.item(0);
+ LOG.debug("Signature element found");
+ return signatureNode;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected boolean handleSignatureValidationFailed(DOMValidateContext valContext,
+ XMLSignature signature) throws Exception {
+ ValidationFailedHandler handler = getConfiguration().getValidationFailedHandler();
+ LOG.debug("handleSignatureValidationFailed called");
+ try {
+ handler.start();
+
+ // first check signature value, see
+ // https://www.isecpartners.com/media/12012/XMLDSIG_Command_Injection.pdf
+ SignatureValue sigValue = signature.getSignatureValue();
+ boolean sv = sigValue.validate(valContext);
+ if (!sv) {
+ handler.signatureValueValidationFailed(sigValue);
+ }
+
+ // then the references!
+ // check the validation status of each Reference
+ for (Reference ref : (List<Reference>) signature.getSignedInfo().getReferences()) {
+ boolean refValid = ref.validate(valContext);
+ if (!refValid) {
+ handler.referenceValidationFailed(ref);
+ }
+ }
+
+ // validate Manifests, if property set
+ if (Boolean.TRUE.equals(valContext.getProperty("org.jcp.xml.dsig.validateManifests"))) {
+ for (XMLObject xo : (List<XMLObject>) signature.getObjects()) {
+ List<XMLStructure> content = xo.getContent();
+ for (XMLStructure xs : content) {
+ if (xs instanceof Manifest) {
+ Manifest man = (Manifest) xs;
+ for (Reference ref : (List<Reference>) man
+ .getReferences()) {
+ boolean refValid = ref.validate(valContext);
+ if (!refValid) {
+ handler.manifestReferenceValidationFailed(ref);
+ }
+ }
+ }
+ }
+ }
+ }
+ boolean goon = handler.ignoreCoreValidationFailure();
+ LOG.debug("Ignore Core Validation failure: {}", goon);
+ return goon;
+ } finally {
+ handler.end();
+ }
+
+ }
+
+ protected Document parseInput(InputStream is)
+ throws XmlSignatureFormatException, ParserConfigurationException,
+ IOException {
+ try {
+ Document doc =
+ XmlSignatureHelper.newDocumentBuilder(getConfiguration().getDisallowDoctypeDecl()).parse(is);
+ return doc;
+ } catch (SAXException e) {
+ throw new XmlSignatureFormatException(
+ "Message has wrong format, it is not a XML signature document. Check the sent message.",
+ e
+ );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/resources/META-INF/services/org/apache/camel/component/xmlsecurity
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/resources/META-INF/services/org/apache/camel/component/xmlsecurity b/components/camel-xmlsecurity/src/main/resources/META-INF/services/org/apache/camel/component/xmlsecurity
new file mode 100644
index 0000000..44f51fc
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/resources/META-INF/services/org/apache/camel/component/xmlsecurity
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.component.xmlsecurity.XmlSignatureComponent
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTest.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTest.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTest.java
new file mode 100644
index 0000000..aef1fba
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTest.java
@@ -0,0 +1,64 @@
+/**
+ * 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.camel.component.xmlsecurity;
+
+import java.security.KeyPair;
+
+import javax.xml.crypto.KeySelector;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.xmlsecurity.api.KeyAccessor;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.spring.SpringCamelContext;
+
+public class SpringXmlSignatureTest extends XmlSignatureTest {
+
+ private static KeyPair rsaPair;
+
+ protected CamelContext createCamelContext() throws Exception {
+ rsaPair = getKeyPair("RSA", 1024);
+ return SpringCamelContext.springCamelContext("/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTests.xml");
+ }
+
+ public static KeyAccessor getDsaKeyAccessor() {
+ return getKeyAccessor(getKeyPair("DSA", 1024).getPrivate());
+ }
+
+ public static KeyAccessor getRsaKeyAccessor() {
+ return getKeyAccessor(rsaPair.getPrivate());
+ }
+
+ public static KeySelector getDsaKeySelector() {
+ return KeySelector.singletonKeySelector(getKeyPair("DSA", 1024).getPublic());
+ }
+
+ public static KeySelector getRsaKeySelector() {
+ return KeySelector.singletonKeySelector(rsaPair.getPublic());
+ }
+
+ @Override
+ protected JndiRegistry createRegistry() throws Exception {
+ return super.createRegistry();
+ }
+
+ @Override
+ protected RouteBuilder[] createRouteBuilders() throws Exception {
+ return new RouteBuilder[] {};
+ }
+
+}
\ No newline at end of file
[3/6] CAMEL-6339 Applied the patch with thanks to Franz
Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
new file mode 100644
index 0000000..b1872a9
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
@@ -0,0 +1,1111 @@
+/**
+ * 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.camel.component.xmlsecurity;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.security.Key;
+import java.security.KeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.xml.crypto.AlgorithmMethod;
+import javax.xml.crypto.KeySelector;
+import javax.xml.crypto.KeySelectorException;
+import javax.xml.crypto.KeySelectorResult;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import javax.xml.crypto.dsig.keyinfo.KeyValue;
+import javax.xml.crypto.dsig.spec.XPathFilterParameterSpec;
+import javax.xml.crypto.dsig.spec.XPathType;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.xmlsecurity.api.KeyAccessor;
+import org.apache.camel.component.xmlsecurity.api.ValidationFailedHandler;
+import org.apache.camel.component.xmlsecurity.api.XmlSignature2Message;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureChecker;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureFormatException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper.XPathAndFilter;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidContentHashException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidKeyException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidValueException;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureProperties;
+import org.apache.camel.component.xmlsecurity.processor.XmlSignatureConfiguration;
+import org.apache.camel.component.xmlsecurity.util.EnvelopingXmlSignatureChecker;
+import org.apache.camel.component.xmlsecurity.util.SameDocumentUriDereferencer;
+import org.apache.camel.component.xmlsecurity.util.TestKeystore;
+import org.apache.camel.component.xmlsecurity.util.TimestampProperty;
+import org.apache.camel.component.xmlsecurity.util.ValidationFailedHandlerIgnoreManifestFailures;
+import org.apache.camel.component.xmlsecurity.util.XmlSignature2Message2MessageWithTimestampProperty;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Before;
+import org.junit.Test;
+import org.w3c.dom.Node;
+
+public class XmlSignatureTest extends CamelTestSupport {
+
+ private KeyPair keyPair;
+ private static String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root xmlns=\"http://test/test\"><test>Test Message</test></root>";
+
+ @Override
+ protected JndiRegistry createRegistry() throws Exception {
+ JndiRegistry registry = super.createRegistry();
+
+ registry.bind("accessor", getKeyAccessor(keyPair.getPrivate()));
+ registry.bind("canonicalizationMethod1", getCanonicalizationMethod());
+ registry.bind("selector", KeySelector.singletonKeySelector(keyPair.getPublic()));
+ registry.bind("selectorKeyValue", getKeyValueKeySelector());
+ registry.bind("transformsXPath2", getTransformsXPath2());
+ registry.bind("transformsXsltXPath", getTransformsXsltXpath());
+ registry.bind("uriDereferencer", getSameDocumentUriDereferencer());
+ registry.bind("baseUri", getBaseUri());
+ registry.bind("cryptoContextProperties", getCrytoContextProperties());
+ registry.bind("keyAccessorDefault", getDefaultKeyAccessor());
+ registry.bind("keySelectorDefault", getDefaultKeySelector());
+ registry.bind("envelopingSignatureChecker", getEnvelopingXmlSignatureChecker());
+ registry.bind("xmlSignature2MessageWithTimestampProperty",
+ getXmlSignature2MessageWithTimestampdProperty());
+ registry.bind("validationFailedHandlerIgnoreManifestFailures",
+ getValidationFailedHandlerIgnoreManifestFailures());
+ registry.bind("signatureProperties", getSignatureProperties());
+ registry.bind("nodesearchxpath", getNodeSerachXPath());
+
+ return registry;
+ }
+
+ @Override
+ protected RouteBuilder[] createRouteBuilders() throws Exception {
+ return new RouteBuilder[] { new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: enveloping XML signature
+ onException(XmlSignatureException.class).handled(true).to(
+ "mock:exception");
+ from("direct:enveloping")
+ .to("xmlsecurity:sign://enveloping?keyAccessor=#accessor")
+ .to("xmlsecurity:verify://enveloping?keySelector=#selector")
+ .to("mock:result");
+ // END SNIPPET: enveloping XML signature
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: enveloping XML signature with plain text
+ // message body
+ onException(XmlSignatureException.class).handled(true).to(
+ "mock:exception");
+ from("direct:plaintext")
+ .to("xmlsecurity:sign://plaintext?keyAccessor=#accessor&plainText=true&plainTextEncoding=UTF-8")
+ .to("xmlsecurity:verify://plaintext?keySelector=#selector")
+ .to("mock:result");
+ // END SNIPPET: enveloping XML signature with plain text message
+ // body
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: enveloped XML signature
+ onException(XmlSignatureException.class).handled(true).to(
+ "mock:exception");
+ from("direct:enveloped")
+ .to("xmlsecurity:sign://enveloped?keyAccessor=#accessor&parentLocalName=root&parentNamespace=http://test/test")
+ .to("xmlsecurity:verify://enveloped?keySelector=#selector")
+ .to("mock:result");
+ // END SNIPPET: enveloped XML signature
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: canonicalization
+ // we can set the configuration properties explicitly on the
+ // endpoint instances.
+ context.getEndpoint("xmlsecurity:sign://canonicalization?canonicalizationMethod=#canonicalizationMethod1",
+ XmlSignerEndpoint.class).setKeyAccessor(getKeyAccessor(keyPair.getPrivate()));
+ context.getEndpoint("xmlsecurity:sign://canonicalization?canonicalizationMethod=#canonicalizationMethod1",
+ XmlSignerEndpoint.class).setSignatureAlgorithm(
+ "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
+ context.getEndpoint("xmlsecurity:verify://canonicalization",
+ XmlVerifierEndpoint.class).setKeySelector(KeySelector.singletonKeySelector(keyPair.getPublic()));
+ from("direct:canonicalization")
+ .to("xmlsecurity:sign://canonicalization?canonicalizationMethod=#canonicalizationMethod1",
+ "xmlsecurity:verify://canonicalization",
+ "mock:result");
+ // END SNIPPET: canonicalization
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: signature and digest algorithm
+ from("direct:signaturedigestalgorithm")
+ .to("xmlsecurity:sign://signaturedigestalgorithm?keyAccessor=#accessor&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha512&digestAlgorithm=http://www.w3.org/2001/04/xmlenc#sha512",
+ "xmlsecurity:verify://signaturedigestalgorithm?keySelector=#selector")
+ .to("mock:result");
+ // END SNIPPET: signature and digest algorithm
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: transforms XPath2
+ from("direct:transformsXPath2")
+ .to("xmlsecurity:sign://transformsXPath2?keyAccessor=#accessor&transformMethods=#transformsXPath2",
+ "xmlsecurity:verify://transformsXPath2?keySelector=#selector")
+ .to("mock:result");
+ // END SNIPPET: transform XPath
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: transforms XSLT,XPath
+ onException(XmlSignatureException.class).handled(false)
+ .to("mock:exception");
+ from("direct:transformsXsltXPath")
+ .to("xmlsecurity:sign://transformsXsltXPath?keyAccessor=#accessor&transformMethods=#transformsXsltXPath",
+ "xmlsecurity:verify://transformsXsltXPath?keySelector=#selector")
+ .to("mock:result");
+ // END SNIPPET: transforms XSLT,XPath
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: transforms XSLT,XPath - secure Validation disabled
+ from("direct:transformsXsltXPathSecureValDisabled")
+ .to("xmlsecurity:sign://transformsXsltXPathSecureValDisabled?keyAccessor=#accessor&transformMethods=#transformsXsltXPath",
+ "xmlsecurity:verify://transformsXsltXPathSecureValDisabled?keySelector=#selector&secureValidation=false")
+ .to("mock:result");
+ // END SNIPPET: transforms XSLT,XPath - secure Validation disabled
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: cryptocontextprops
+ onException(XmlSignatureException.class).handled(false).to(
+ "mock:exception");
+ from("direct:cryptocontextprops")
+ .to("xmlsecurity:verify://cryptocontextprops?keySelector=#selectorKeyValue&cryptoContextProperties=#cryptoContextProperties")
+ .to("mock:result");
+ // END SNIPPET: cryptocontextprops
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: URI dereferencer
+ from("direct:uridereferencer")
+ .to("xmlsecurity:sign://uriderferencer?keyAccessor=#accessor&uriDereferencer=#uriDereferencer")
+ .to("xmlsecurity:verify://uridereferencer?keySelector=#selector&uriDereferencer=#uriDereferencer")
+ .to("mock:result");
+ // END SNIPPET: URI dereferencer
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: keyAccessorKeySelectorDefault
+ from("direct:keyAccessorKeySelectorDefault")
+ .to("xmlsecurity:sign://keyAccessorKeySelectorDefault?keyAccessor=#keyAccessorDefault&addKeyInfoReference=true")
+ .to("xmlsecurity:verify://keyAccessorKeySelectorDefault?keySelector=#keySelectorDefault")
+ .to("mock:result");
+ // END SNIPPET: keyAccessorKeySelectorDefault
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: xmlSignatureChecker
+ onException(XmlSignatureInvalidException.class).handled(false)
+ .to("mock:exception");
+ from("direct:xmlSignatureChecker")
+ .to("xmlsecurity:verify://xmlSignatureChecker?keySelector=#selectorKeyValue&xmlSignatureChecker=#envelopingSignatureChecker")
+ .to("mock:result");
+ // END SNIPPET: xmlSignatureChecker
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception { //
+ // START SNIPPET: properties
+ from("direct:props")
+ .to("xmlsecurity:sign://properties?keyAccessor=#accessor&properties=#signatureProperties")
+ .to("xmlsecurity:verify://properties?keySelector=#selector&xmlSignature2Message=#xmlSignature2MessageWithTimestampProperty")
+ .to("mock:result");
+ // END SNIPPET: properties
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: verify output node search element name
+ onException(XmlSignatureException.class).handled(true).to(
+ "mock:exception");
+ from("direct:outputnodesearchelementname")
+ .to("xmlsecurity:verify://outputnodesearchelementname?keySelector=#selectorKeyValue&outputNodeSearchType=ElementName&outputNodeSearch={http://test/test}root&removeSignatureElements=true")
+ .to("mock:result");
+ // END SNIPPET: verify output node search element name
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: verify output node search xpath
+ onException(XmlSignatureException.class).handled(true).to(
+ "mock:exception");
+ from("direct:outputnodesearchxpath")
+ .to("xmlsecurity:verify://outputnodesearchxpath?keySelector=#selectorKeyValue&outputNodeSearchType=XPath&outputNodeSearch=#nodesearchxpath&removeSignatureElements=true")
+ .to("mock:result");
+ // END SNIPPET: verify output node search xpath
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: validationFailedHandler
+ from("direct:validationFailedHandler")
+ .to("xmlsecurity:verify://validationFailedHandler?keySelector=#selectorKeyValue&validationFailedHandler=validationFailedHandlerIgnoreManifestFailures")
+ .to("mock:result");
+ // END SNIPPET: validationFailedHandler
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: further parameters
+ from("direct:furtherparams")
+ .to("xmlsecurity:sign://furtherparams?keyAccessor=#accessor&prefixForXmlSignatureNamespace=digsig&disallowDoctypeDecl=false")
+ .to("xmlsecurity:verify://bfurtherparams?keySelector=#selector&disallowDoctypeDecl=false")
+ .to("mock:result");
+ // END SNIPPET: further parameters
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: signer invalid keyexception
+ onException(XmlSignatureInvalidKeyException.class)
+ .handled(true).to("mock:exception");
+ from("direct:signexceptioninvalidkey")
+ .to("xmlsecurity:sign://signexceptioninvalidkey?signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha512")
+ .to("mock:result");
+ // END SNIPPET: signer invalid keyexception
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: signer exceptions
+ onException(XmlSignatureException.class).handled(true).to(
+ "mock:exception");
+ from("direct:signexceptions")
+ .to("xmlsecurity:sign://signexceptions?keyAccessor=#accessor&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha512")
+ .to("mock:result");
+ // END SNIPPET: signer exceptions
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: NoSuchAlgorithmException
+ onException(XmlSignatureException.class).handled(true).to(
+ "mock:exception");
+ from("direct:noSuchAlgorithmException")
+ .to("xmlsecurity:sign://noSuchAlgorithmException?keyAccessor=#accessor&signatureAlgorithm=wrongalgorithm&digestAlgorithm=http://www.w3.org/2001/04/xmlenc#sha512")
+ .to("mock:result");
+ // END SNIPPET: NoSuchAlgorithmException
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: verifier exceptions
+ onException(XmlSignatureException.class).handled(false).to(
+ "mock:exception");
+ from("direct:verifyexceptions")
+ .to("xmlsecurity:verify://verifyexceptions?keySelector=#selector")
+ .to("mock:result");
+ // END SNIPPET: verifier exceptions
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: verifier InvalidKeyException
+ onException(XmlSignatureException.class).handled(false).to(
+ "mock:exception");
+ from("direct:verifyInvalidKeyException")
+ .to("xmlsecurity:verify://verifyInvalidKeyException?keySelector=#selector")
+ .to("mock:result");
+ // END SNIPPET: verifier exceptions
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+ // START SNIPPET: verifier InvalidHashException
+ onException(XmlSignatureException.class).handled(false).to(
+ "mock:exception");
+ from("direct:invalidhash")
+ .to("xmlsecurity:verify://invalidhash?keySelector=#selectorKeyValue&baseUri=#baseUri&secureValidation=false")
+ .to("mock:result");
+ // END SNIPPET: verifier InvalidHashException
+ }
+ }
+
+ };
+ }
+
+ @Test
+ public void testEnvelopingSignature() throws Exception {
+ setupMock();
+ sendBody("direct:enveloping", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testEnvelopingSignatureWithPlainText() throws Exception {
+ String text = "plain test text";
+ setupMock(text);
+ sendBody("direct:plaintext", text);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testEnvelopingSignatureWithPlainTextSetByHeaders()
+ throws Exception {
+ String text = "plain test text";
+ setupMock(text);
+ Map<String, Object> headers = new TreeMap<String, Object>();
+ headers.put(XmlSignatureConstants.HEADER_MESSAGE_IS_PLAIN_TEXT,
+ Boolean.TRUE);
+ headers.put(XmlSignatureConstants.HEADER_PLAIN_TEXT_ENCODING, "UTF-8");
+ sendBody("direct:enveloping", text, headers);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testExceptionSignatureForPlainTextWithWrongEncoding()
+ throws Exception {
+ String text = "plain test text";
+ MockEndpoint mock = setupExceptionMock();
+ Map<String, Object> headers = new TreeMap<String, Object>();
+ headers.put(XmlSignatureConstants.HEADER_MESSAGE_IS_PLAIN_TEXT,
+ Boolean.TRUE);
+ headers.put(XmlSignatureConstants.HEADER_PLAIN_TEXT_ENCODING,
+ "wrongEncoding");
+ sendBody("direct:enveloping", text, headers);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureException.class,
+ UnsupportedEncodingException.class);
+ }
+
+ @Test
+ public void testEnvelopedSignature() throws Exception {
+ setupMock(payload);
+ sendBody("direct:enveloped", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testExceptionEnvelopedSignatureWithWrongParent()
+ throws Exception {
+ // payload root element renamed to a -> parent name in route definition
+ // does not fit
+ String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a xmlns=\"http://test/test\"><test>Test Message</test></a>";
+
+ MockEndpoint mock = setupExceptionMock();
+ sendBody("direct:enveloped", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureFormatException.class, null);
+ }
+
+ @Test
+ public void testExceptionEnvelopedSignatureWithPlainTextPayload()
+ throws Exception {
+ // payload root element renamed to a -> parent name in route definition
+ // does not fit
+ String payload = "plain text Message";
+ Map<String, Object> headers = new HashMap<String, Object>(1);
+ headers.put(XmlSignatureConstants.HEADER_MESSAGE_IS_PLAIN_TEXT,
+ Boolean.TRUE);
+ MockEndpoint mock = setupExceptionMock();
+ sendBody("direct:enveloped", payload, headers);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureFormatException.class, null);
+ }
+
+ /**
+ * The parameter can also be configured via
+ * {@link XmlSignatureConfiguration#setOmitXmlDeclaration(Boolean)}
+ */
+ @Test
+ public void testOmitXmlDeclarationViaHeader() throws Exception {
+ String payloadOut = "<root xmlns=\"http://test/test\"><test>Test Message</test></root>";
+ setupMock(payloadOut);
+ Map<String, Object> headers = new TreeMap<String, Object>();
+ headers.put(XmlSignatureConstants.HEADER_OMIT_XML_DECLARATION,
+ Boolean.TRUE);
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:outputnodesearchelementname", payload, headers);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testkeyAccessorKeySelectorDefault() throws Exception {
+ setupMock();
+ sendBody("direct:keyAccessorKeySelectorDefault", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testSetCanonicalizationMethodInRouteDefinition()
+ throws Exception {
+ setupMock();
+ sendBody("direct:canonicalization", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testSetDigestAlgorithmInRouteDefinition() throws Exception {
+
+ setupMock();
+ sendBody("direct:signaturedigestalgorithm", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testSetTransformMethodXpath2InRouteDefinition()
+ throws Exception {
+ // example from http://www.w3.org/TR/2002/REC-xmldsig-filter2-20021108/
+ String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<Document xmlns=\"http://test/test\"> "
+ + "<ToBeSigned> "
+ + " <!-- comment --> "
+ + " <Data>1</Data> "
+ + " <NotToBeSigned> "
+ + " <ReallyToBeSigned> "
+ + " <!-- comment --> "
+ + " <Data>2</Data> "
+ + " </ReallyToBeSigned> "
+ + " </NotToBeSigned> "
+ + " </ToBeSigned> "
+ + " <ToBeSigned> "
+ + " <Data>3</Data> "
+ + " <NotToBeSigned> "
+ + " <Data>4</Data> "
+ + " </NotToBeSigned> "
+ + " </ToBeSigned> "
+ + "</Document>";
+
+ setupMock(payload);
+ sendBody("direct:transformsXPath2", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ // Secure Validation is enabled and so this should fail
+ @Test
+ public void testSetTransformMethodXsltXpathInRouteDefinition()
+ throws Exception {
+ // byte[] encoded = Base64.encode("Test Message".getBytes("UTF-8"));
+ // String contentBase64 = new String(encoded, "UTF-8");
+ // String payload =
+ // "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root xmlns=\"http://test/test\"><test></test></root>";
+ MockEndpoint mock = setupExceptionMock();
+ sendBody("direct:transformsXsltXPath", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureException.class, null);
+ }
+
+ @Test
+ public void testSetTransformMethodXsltXpathInRouteDefinitionSecValDisabled()
+ throws Exception {
+ setupMock();
+ sendBody("direct:transformsXsltXPathSecureValDisabled", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testProperties() throws Exception {
+ setupMock();
+ sendBody("direct:props", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testVerifyOutputNodeSearchElementName() throws Exception {
+ setupMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:outputnodesearchelementname", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testVerifyExceptionOutputNodeSearchElementNameInvalidFormat1()
+ throws Exception {
+ XmlVerifierEndpoint endpoint = context
+ .getEndpoint(
+ "xmlsecurity:verify://outputnodesearchelementname?keySelector=#selectorKeyValue&outputNodeSearchType=ElementName&outputNodeSearch={http://test/test}root&removeSignatureElements=true",
+ XmlVerifierEndpoint.class);
+ endpoint.setOutputNodeSearch("{wrongformat"); // closing '}' missing
+ MockEndpoint mock = setupExceptionMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:outputnodesearchelementname", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureException.class, null);
+ }
+
+ @Test
+ public void testVerifyExceptionOutputNodeSearchElementNameInvalidFormat2()
+ throws Exception {
+ context.getEndpoint(
+ "xmlsecurity:verify://outputnodesearchelementname?keySelector=#selectorKeyValue&outputNodeSearchType=ElementName&outputNodeSearch={http://test/test}root&removeSignatureElements=true",
+ XmlVerifierEndpoint.class).setOutputNodeSearch("{wrongformat}"); // local
+ // name
+ // missing
+ MockEndpoint mock = setupExceptionMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:outputnodesearchelementname", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureException.class, null);
+ }
+
+ @Test
+ public void testExceptionVerifyOutputNodeSearchWrongElementName()
+ throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSig.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:outputnodesearchelementname", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureException.class, null);
+ }
+
+ @Test
+ public void testExceptionVerifyOutputNodeSearchElementNameMoreThanOneOutputElement()
+ throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSigWithSeveralElementsWithNameRoot.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:outputnodesearchelementname", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureException.class, null);
+ }
+
+ @Test
+ public void testVerifyOutputNodeSearchXPath() throws Exception {
+ setupMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:outputnodesearchxpath", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testExceptionVerifyOutputNodeSearchXPathWithNoResultNode()
+ throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSig.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:outputnodesearchxpath", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureException.class, null);
+ }
+
+ @Test
+ public void testExceptionVerifyOutputNodeSearchXPathMoreThanOneOutputElement()
+ throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSigWithSeveralElementsWithNameRoot.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:outputnodesearchxpath", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureException.class, null);
+ }
+
+ @Test
+ public void testInvalidKeyException() throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ // wrong key type
+ setUpKeys("DSA", 512);
+ context.getEndpoint("xmlsecurity:sign://signexceptioninvalidkey?signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha512",
+ XmlSignerEndpoint.class).setKeyAccessor(getKeyAccessor(keyPair.getPrivate()));
+ sendBody("direct:signexceptioninvalidkey", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureInvalidKeyException.class, null);
+ }
+
+ @Test
+ public void testSignatureFormatException() throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ sendBody("direct:signexceptions", "wrongFormatedPayload");
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureFormatException.class, null);
+ }
+
+ @Test
+ public void testNoSuchAlgorithmException() throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ sendBody("direct:noSuchAlgorithmException", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureException.class, NoSuchAlgorithmException.class);
+ }
+
+ @Test
+ public void testVerifyFormatExceptionNoXml() throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ sendBody("direct:verifyexceptions", "wrongFormatedPayload");
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureFormatException.class, null);
+ }
+
+ @Test
+ public void testVerifyFormatExceptionNoXmlWithoutSignatureElement()
+ throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ sendBody("direct:verifyexceptions",
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><NoSignature></NoSignature>");
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureFormatException.class, null);
+ }
+
+ @Test
+ public void testVerifyFormatExceptionMoreThanOneSignatureElement()
+ throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ sendBody("direct:verifyexceptions",
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root><Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"/><Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"/></root>");
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureFormatException.class, null);
+ }
+
+ @Test
+ public void testVerifyInvalidContentHashException() throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleDetached.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:invalidhash", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureInvalidContentHashException.class, null);
+ }
+
+ @Test
+ public void testVerifyMantifestInvalidContentHashException()
+ throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ManifestTest_TamperedContent.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:invalidhash", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureInvalidContentHashException.class, null);
+ }
+
+ @Test
+ public void testVerifySetCryptoContextProperties() throws Exception {
+ // although the content referenced by the manifest was tempered, this is
+ // not detected by
+ // the core validation because the manifest validation is switched off
+ // by the crypto context properties
+ setupMock("some text tampered");
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ManifestTest_TamperedContent.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:cryptocontextprops", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testVerifySignatureInvalidValueException() throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ setUpKeys("DSA", 512);
+ context.getEndpoint("xmlsecurity:verify://verifyexceptions?keySelector=#selector",
+ XmlVerifierEndpoint.class).setKeySelector(KeySelector.singletonKeySelector(keyPair.getPublic()));
+ // payload needs DSA key
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSig.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:verifyexceptions", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureInvalidValueException.class, null);
+ }
+
+ @Test
+ public void testVerifyInvalidKeyException() throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSig.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:verifyInvalidKeyException", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureInvalidKeyException.class, null);
+ }
+
+ @Test
+ public void testUriDereferencerAndBaseUri() throws Exception {
+ setupMock();
+ sendBody("direct:uridereferencer", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testVerifyXmlSignatureChecker() throws Exception {
+ MockEndpoint mock = setupExceptionMock();
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:xmlSignatureChecker", payload);
+ assertMockEndpointsSatisfied();
+ checkThrownException(mock, XmlSignatureInvalidException.class, null);
+ }
+
+ @Test
+ public void testVerifyValidationFailedHandler() throws Exception {
+ setupMock("some text tampered");
+ InputStream payload = XmlSignatureTest.class
+ .getResourceAsStream("/org/apache/camel/component/xmlsecurity/ManifestTest_TamperedContent.xml");
+ assertNotNull("Cannot load payload", payload);
+ sendBody("direct:validationFailedHandler", payload);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testFurtherParameters() throws Exception {
+ setupMock(payload);
+ String payloadWithDTDoctype = "<?xml version=\'1.0\'?>"
+ + "<!DOCTYPE Signature SYSTEM "
+ + "\"src/test/resources/org/apache/camel/component/xmlsecurity/xmldsig-core-schema.dtd\" [ <!ENTITY dsig "
+ + "\"http://www.w3.org/2000/09/xmldsig#\"> ]>"
+ + "<root xmlns=\"http://test/test\"><test>Test Message</test></root>";
+
+ sendBody("direct:furtherparams", payloadWithDTDoctype);
+ assertMockEndpointsSatisfied();
+ }
+
+ private void checkThrownException(MockEndpoint mock,
+ Class<? extends XmlSignatureException> cl,
+ Class<? extends Exception> expectedCauseClass) throws Exception {
+ Exception e = (Exception) mock.getExchanges().get(0)
+ .getProperty(Exchange.EXCEPTION_CAUGHT);
+ assertNotNull("Expected excpetion " + cl.getName() + " missing", e);
+ if (e.getClass() != cl) {
+ String stackTrace = getStrackTrace(e);
+ fail("Exception " + cl.getName() + " excpected, but was "
+ + e.getClass().getName() + ": " + stackTrace);
+ }
+ if (expectedCauseClass != null) {
+ Throwable cause = e.getCause();
+ assertNotNull(
+ "Expected cause exception" + expectedCauseClass.getName()
+ + " missing", cause);
+ if (expectedCauseClass != cause.getClass()) {
+ fail("Cause exception " + expectedCauseClass.getName()
+ + " expected, but was " + cause.getClass().getName()
+ + ": " + getStrackTrace(e));
+ }
+ }
+ }
+
+ private String getStrackTrace(Exception e)
+ throws UnsupportedEncodingException {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ PrintWriter w = new PrintWriter(os);
+ e.printStackTrace(w);
+ w.close();
+ String stackTrace = new String(os.toByteArray(), "UTF-8");
+ return stackTrace;
+ }
+
+ private MockEndpoint setupExceptionMock() {
+ MockEndpoint mock = getMockEndpoint("mock:exception");
+ mock.setExpectedMessageCount(1);
+ MockEndpoint mockResult = getMockEndpoint("mock:result");
+ mockResult.setExpectedMessageCount(0);
+ return mock;
+ }
+
+ private MockEndpoint setupMock() {
+ return setupMock(payload);
+ }
+
+ private MockEndpoint setupMock(String payload) {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedBodiesReceived(payload);
+ return mock;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Exchange doTestSignatureRoute(RouteBuilder builder) throws Exception {
+ return doSignatureRouteTest(builder, null, Collections.EMPTY_MAP);
+ }
+
+ public Exchange doSignatureRouteTest(RouteBuilder builder, Exchange e,
+ Map<String, Object> headers) throws Exception {
+ CamelContext context = new DefaultCamelContext();
+ try {
+ context.addRoutes(builder);
+ context.start();
+
+ MockEndpoint mock = context.getEndpoint("mock:result",
+ MockEndpoint.class);
+ mock.setExpectedMessageCount(1);
+
+ ProducerTemplate template = context.createProducerTemplate();
+ if (e != null) {
+ template.send("direct:in", e);
+ } else {
+ template.sendBodyAndHeaders("direct:in", payload, headers);
+ }
+ assertMockEndpointsSatisfied();
+ return mock.getReceivedExchanges().get(0);
+ } finally {
+ context.stop();
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ setUpKeys("RSA", 1024);
+ disableJMX();
+ super.setUp();
+ }
+
+ public void setUpKeys(String algorithm, int keylength) throws Exception {
+ keyPair = getKeyPair(algorithm, keylength);
+ }
+
+ public static KeyPair getKeyPair(String algorithm, int keylength) {
+ KeyPairGenerator keyGen;
+ try {
+ keyGen = KeyPairGenerator.getInstance(algorithm);
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ keyGen.initialize(keylength, new SecureRandom());
+ return keyGen.generateKeyPair();
+ }
+
+ public static KeyStore loadKeystore() throws Exception {
+ KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
+ InputStream in = XmlSignatureTest.class.getResourceAsStream("/bob.keystore");
+ keystore.load(in, "letmein".toCharArray());
+ return keystore;
+ }
+
+ public Certificate getCertificateFromKeyStore() throws Exception {
+ Certificate c = loadKeystore().getCertificate("bob");
+ return c;
+ }
+
+ public PrivateKey getKeyFromKeystore() throws Exception {
+ return (PrivateKey) loadKeystore().getKey("bob",
+ "letmein".toCharArray());
+ }
+
+ private AlgorithmMethod getCanonicalizationMethod() {
+ List<String> inclusivePrefixes = new ArrayList<String>(1);
+ inclusivePrefixes.add("ds");
+ return XmlSignatureHelper.getCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, inclusivePrefixes);
+ }
+
+ private List<AlgorithmMethod> getTransformsXPath2() {
+
+ List<XPathAndFilter> list = new ArrayList<XPathAndFilter>(3);
+ XPathAndFilter xpath1 = new XPathAndFilter("//n0:ToBeSigned",
+ XPathType.Filter.INTERSECT.toString());
+ list.add(xpath1);
+ XPathAndFilter xpath2 = new XPathAndFilter("//n0:NotToBeSigned",
+ XPathType.Filter.SUBTRACT.toString());
+ list.add(xpath2);
+ XPathAndFilter xpath3 = new XPathAndFilter("//n0:ReallyToBeSigned",
+ XPathType.Filter.UNION.toString());
+ list.add(xpath3);
+ List<AlgorithmMethod> result = new ArrayList<AlgorithmMethod>(2);
+ result.add(XmlSignatureHelper
+ .getCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE));
+ result.add(XmlSignatureHelper.getXPath2Transform(list, getNamespaceMap()));
+ return result;
+ }
+
+ private Map<String, String> getNamespaceMap() {
+ Map<String, String> result = new HashMap<String, String>(1);
+ result.put("n0", "http://test/test");
+ return result;
+ }
+
+ private List<AlgorithmMethod> getTransformsXsltXpath() {
+ try {
+ AlgorithmMethod transformXslt = XmlSignatureHelper
+ .getXslTransform("/org/apache/camel/component/xmlsecurity/xslt_test.xsl");
+ Map<String, String> namespaceMap = new HashMap<String, String>(1);
+ namespaceMap.put("n0", "https://org.apache/camel/xmlsecurity/test");
+ AlgorithmMethod transformXpath = XmlSignatureHelper
+ .getXPathTransform("//n0:XMLSecurity/n0:Content",
+ namespaceMap);
+ // I removed base 64 transform because the JDK implementation does
+ // not correctly support this transformation
+ // AlgorithmMethod transformBase64 = helper.getBase64Transform();
+ List<AlgorithmMethod> result = new ArrayList<AlgorithmMethod>(3);
+ result.add(XmlSignatureHelper
+ .getCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE));
+ result.add(transformXslt);
+ result.add(transformXpath);
+ // result.add(transformBase64);
+ return result;
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ static KeyAccessor getKeyAccessor(final PrivateKey privateKey) {
+ KeyAccessor accessor = new KeyAccessor() {
+
+ @Override
+ public KeySelector getKeySelector(Message message) throws Exception {
+ return KeySelector.singletonKeySelector(privateKey);
+ }
+
+ @Override
+ public KeyInfo getKeyInfo(Message mess, Node messageBody,
+ KeyInfoFactory keyInfoFactory) throws Exception {
+ return null;
+ }
+ };
+ return accessor;
+ }
+
+ public static String getBaseUri() {
+ String uri = "file:/" + System.getProperty("user.dir")
+ + "/src/test/resources/org/apache/camel/component/xmlsecurity/";
+ return uri.replace('\\', '/');
+ }
+
+ public static KeySelector getKeyValueKeySelector() {
+ return new KeyValueKeySelector();
+ }
+
+ /**
+ * KeySelector which retrieves the public key from the KeyValue element and
+ * returns it. NOTE: If the key algorithm doesn't match signature algorithm,
+ * then the public key will be ignored.
+ */
+ static class KeyValueKeySelector extends KeySelector {
+ public KeySelectorResult select(KeyInfo keyInfo,
+ KeySelector.Purpose purpose, AlgorithmMethod method,
+ XMLCryptoContext context) throws KeySelectorException {
+ if (keyInfo == null) {
+ throw new KeySelectorException("Null KeyInfo object!");
+ }
+
+ SignatureMethod sm = (SignatureMethod) method;
+ @SuppressWarnings("rawtypes")
+ List list = keyInfo.getContent();
+
+ for (int i = 0; i < list.size(); i++) {
+ XMLStructure xmlStructure = (XMLStructure) list.get(i);
+ if (xmlStructure instanceof KeyValue) {
+ PublicKey pk = null;
+ try {
+ pk = ((KeyValue) xmlStructure).getPublicKey();
+ } catch (KeyException ke) {
+ throw new KeySelectorException(ke);
+ }
+ // make sure algorithm is compatible with method
+ if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
+ return new SimpleKeySelectorResult(pk);
+ }
+ }
+ }
+ throw new KeySelectorException("No KeyValue element found!");
+ }
+
+ static boolean algEquals(String algURI, String algName) {
+ if (algName.equalsIgnoreCase("DSA")
+ && algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) {
+ return true;
+ } else if (algName.equalsIgnoreCase("RSA")
+ && algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ private static class SimpleKeySelectorResult implements KeySelectorResult {
+ private PublicKey pk;
+
+ SimpleKeySelectorResult(PublicKey pk) {
+ this.pk = pk;
+ }
+
+ public Key getKey() {
+ return pk;
+ }
+ }
+
+ public static Map<String, ? extends Object> getCrytoContextProperties() {
+ return Collections.singletonMap("org.jcp.xml.dsig.validateManifests",
+ Boolean.FALSE);
+ }
+
+ public static KeyAccessor getDefaultKeyAccessor() throws Exception {
+ return TestKeystore.getKeyAccessor("bob");
+ }
+
+ public static KeySelector getDefaultKeySelector() throws Exception {
+ return TestKeystore.getKeySelector("bob");
+ }
+
+ public static KeyAccessor getDefaultKeyAccessorDsa() throws Exception {
+ return TestKeystore.getKeyAccessor("bobdsa");
+ }
+
+ public static KeySelector getDefaultKeySelectorDsa() throws Exception {
+ return TestKeystore.getKeySelector("bobdsa");
+ }
+
+ public static XmlSignatureChecker getEnvelopingXmlSignatureChecker() {
+ return new EnvelopingXmlSignatureChecker();
+ }
+
+ public static XmlSignature2Message getXmlSignature2MessageWithTimestampdProperty() {
+ return new XmlSignature2Message2MessageWithTimestampProperty();
+ }
+
+ public static ValidationFailedHandler getValidationFailedHandlerIgnoreManifestFailures() {
+ return new ValidationFailedHandlerIgnoreManifestFailures();
+ }
+
+ public static XmlSignatureProperties getSignatureProperties() {
+ return new TimestampProperty();
+ }
+
+ public static XPathFilterParameterSpec getNodeSerachXPath() {
+ Map<String, String> prefix2Namespace = Collections.singletonMap("pre",
+ "http://test/test");
+ return XmlSignatureHelper.getXpathFilter("//pre:root", prefix2Namespace);
+ }
+
+ public static URIDereferencer getSameDocumentUriDereferencer() {
+ return SameDocumentUriDereferencer.getInstance();
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/EnvelopingXmlSignatureChecker.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/EnvelopingXmlSignatureChecker.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/EnvelopingXmlSignatureChecker.java
new file mode 100644
index 0000000..3884c68
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/EnvelopingXmlSignatureChecker.java
@@ -0,0 +1,52 @@
+/**
+ * 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.camel.component.xmlsecurity.util;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureChecker;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidException;
+
+/**
+ * Checks that root element local name is "Signature" and the root element
+ * namespace is "http://www.w3.org/2000/09/xmldsig#". If the checks fails then a
+ * {@link XmlSignatureInvalidException} is thrown.
+ */
+public class EnvelopingXmlSignatureChecker implements XmlSignatureChecker {
+
+ private static Set<String> ALLOWED_TRANSFORM_ALGORITHMS = new HashSet<String>(4);
+
+ static {
+ ALLOWED_TRANSFORM_ALGORITHMS.add(CanonicalizationMethod.INCLUSIVE);
+ ALLOWED_TRANSFORM_ALGORITHMS.add(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS);
+ ALLOWED_TRANSFORM_ALGORITHMS.add(CanonicalizationMethod.EXCLUSIVE);
+ ALLOWED_TRANSFORM_ALGORITHMS.add(CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS);
+ }
+
+ @Override
+ public void checkBeforeCoreValidation(Input input) throws Exception {
+
+ if (!"Signature".equals(input.getMessageBodyDocument().getDocumentElement().getLocalName())) {
+ throw new XmlSignatureInvalidException(
+ "XML signature is not enveloping. Only enveloping XML signatures are allowed.");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/SameDocumentUriDereferencer.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/SameDocumentUriDereferencer.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/SameDocumentUriDereferencer.java
new file mode 100644
index 0000000..267b2ee
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/SameDocumentUriDereferencer.java
@@ -0,0 +1,72 @@
+/**
+ * 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.camel.component.xmlsecurity.util;
+
+import javax.xml.crypto.Data;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.URIReference;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dom.DOMURIReference;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+
+/**
+ * URI Dereferencer which allows only same document URI references via ids.
+ */
+public class SameDocumentUriDereferencer implements URIDereferencer {
+
+ private static final URIDereferencer INSTANCE = new SameDocumentUriDereferencer();
+
+ public static URIDereferencer getInstance() {
+ return INSTANCE;
+ }
+
+ private SameDocumentUriDereferencer() {
+ // singelton
+ }
+
+ public Data dereference(URIReference uriReference, XMLCryptoContext context) throws URIReferenceException {
+
+ if (uriReference == null) {
+ throw new NullPointerException("Parameter 'uriReference' cannot be null.");
+ }
+
+ if (context == null) {
+ throw new NullPointerException("Parameter 'context' can notbe null.");
+ }
+
+ if (!(uriReference instanceof DOMURIReference && context instanceof DOMCryptoContext)) {
+ throw new IllegalArgumentException(String.format("This %s implementation supports the DOM XML mechanism only.",
+ URIDereferencer.class.getName()));
+ }
+
+ String uriString = uriReference.getURI();
+
+ if (uriString == null) {
+ throw new URIReferenceException("Cannot resolve a URI of value 'null'.");
+ }
+
+ if (uriString != null && ((uriString.length() != 0 && uriString.charAt(0) == '#') || uriString.isEmpty())) {
+ // same document uri
+ XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
+ return fac.getURIDereferencer().dereference(uriReference, context);
+ }
+
+ throw new URIReferenceException(String.format("URI reference %s not supported", uriString));
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java
new file mode 100644
index 0000000..6a7ae93
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java
@@ -0,0 +1,65 @@
+/**
+ * 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.camel.component.xmlsecurity.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+
+import javax.xml.crypto.KeySelector;
+
+import org.apache.camel.component.xmlsecurity.api.KeyAccessor;
+import org.apache.camel.component.xmlsecurity.api.DefaultKeyAccessor;
+import org.apache.camel.component.xmlsecurity.api.DefaultKeySelector;
+
+public class TestKeystore {
+
+ public TestKeystore() {
+
+ }
+
+
+ public static KeyAccessor getKeyAccessor(String alias) throws Exception {
+
+ DefaultKeyAccessor accessor = new DefaultKeyAccessor();
+ accessor.setKeyStore(getKeyStore());
+ accessor.setPassword(getPassword());
+ accessor.setAlias(alias);
+ return accessor;
+ }
+
+ public static KeySelector getKeySelector(String alias) throws Exception {
+ DefaultKeySelector selector = new DefaultKeySelector();
+ selector.setKeyStore(getKeyStore());
+ selector.setAlias(alias);
+ return selector;
+ }
+
+ private static char[] getPassword() {
+ return "abcd1234".toCharArray();
+ }
+
+ private static KeyStore getKeyStore() throws GeneralSecurityException, IOException {
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ InputStream is = TestKeystore.class.getClassLoader().getResourceAsStream("org/apache/camel/component/xmlsecurity/keystore.jks");
+ ks.load(is, null);
+
+ return ks;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TimestampProperty.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TimestampProperty.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TimestampProperty.java
new file mode 100644
index 0000000..099ed8d
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TimestampProperty.java
@@ -0,0 +1,68 @@
+/**
+ * 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.camel.component.xmlsecurity.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Collections;
+
+import javax.xml.crypto.dom.DOMStructure;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignatureProperties;
+import javax.xml.crypto.dsig.SignatureProperty;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureProperties;
+import org.w3c.dom.Document;
+
+/**
+ * Example for a XmlSignatureProperties implementation which adds a timestamp
+ * signature property.
+ */
+public class TimestampProperty implements XmlSignatureProperties {
+
+ @Override
+ public Output get(Input input) throws Exception {
+
+ Transform transform = input.getSignatureFactory().newTransform(CanonicalizationMethod.INCLUSIVE, (TransformParameterSpec) null);
+ Reference ref = input.getSignatureFactory().newReference("#propertiesObject",
+ input.getSignatureFactory().newDigestMethod(input.getContentDigestAlgorithm(), null), Collections.singletonList(transform),
+ null, null);
+
+ String doc2 = "<ts:timestamp xmlns:ts=\"http:/timestamp\">" + System.currentTimeMillis() + "</ts:timestamp>";
+ InputStream is = new ByteArrayInputStream(doc2.getBytes("UTF-8"));
+ Document doc = XmlSignatureHelper.newDocumentBuilder(Boolean.TRUE).parse(is);
+ DOMStructure structure = new DOMStructure(doc.getDocumentElement());
+
+ SignatureProperty prop = input.getSignatureFactory().newSignatureProperty(Collections.singletonList(structure),
+ input.getSignatureId(), "property");
+ SignatureProperties properties = input.getSignatureFactory().newSignatureProperties(Collections.singletonList(prop), "properties");
+ XMLObject propertiesObject = input.getSignatureFactory().newXMLObject(Collections.singletonList(properties), "propertiesObject",
+ null, null);
+
+ XmlSignatureProperties.Output result = new Output();
+ result.setReferences(Collections.singletonList(ref));
+ result.setObjects(Collections.singletonList(propertiesObject));
+
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/ValidationFailedHandlerIgnoreManifestFailures.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/ValidationFailedHandlerIgnoreManifestFailures.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/ValidationFailedHandlerIgnoreManifestFailures.java
new file mode 100644
index 0000000..53149ea
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/ValidationFailedHandlerIgnoreManifestFailures.java
@@ -0,0 +1,38 @@
+/**
+ * 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.camel.component.xmlsecurity.util;
+
+import javax.xml.crypto.dsig.Reference;
+
+import org.apache.camel.component.xmlsecurity.api.DefaultValidationFailedHandler;
+
+/**
+ * Validation failed handler which ignores manifest reference validation
+ * failures.
+ */
+public class ValidationFailedHandlerIgnoreManifestFailures extends DefaultValidationFailedHandler {
+
+ @Override
+ public void manifestReferenceValidationFailed(Reference ref) throws Exception {
+ // do nothing
+ }
+
+ @Override
+ public boolean ignoreCoreValidationFailure() throws Exception {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/XmlSignature2Message2MessageWithTimestampProperty.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/XmlSignature2Message2MessageWithTimestampProperty.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/XmlSignature2Message2MessageWithTimestampProperty.java
new file mode 100644
index 0000000..5d6e798
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/XmlSignature2Message2MessageWithTimestampProperty.java
@@ -0,0 +1,45 @@
+/**
+ * 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.camel.component.xmlsecurity.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.crypto.dsig.Reference;
+
+import org.apache.camel.component.xmlsecurity.api.DefaultXmlSignature2Message;
+
+/**
+ * Removes all references whose URIs contain "propert" from the relevant
+ * references for the mapping to the camel message.
+ */
+public class XmlSignature2Message2MessageWithTimestampProperty extends DefaultXmlSignature2Message {
+
+ protected List<Reference> getReferencesForMessageMapping(Input input) throws Exception {
+
+ List<Reference> result = new ArrayList<Reference>(1);
+ for (Reference ref : input.getReferences()) {
+ if (ref.getURI() != null && ref.getURI().contains("propert")) {
+ // do not add
+ } else {
+ result.add(ref);
+ }
+ }
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleDetached.xml
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleDetached.xml b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleDetached.xml
new file mode 100644
index 0000000..bcbaa6f
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleDetached.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/><Reference URI="testFile.txt"><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>LVzTET7OaeWAL3PmLnCAJ6xERYs=</DigestValue></Reference></SignedInfo><SignatureValue>lOEIqMmufeQjUmzfGBsiYkMTKlxSAUwyaXoFjHjNuNPvjltR9gj85Q==</SignatureValue><KeyInfo><KeyValue><DSAKeyValue><P>/KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxeEu0ImbzRMqzVDZkVG9
+xD7nN1kuFw==</P><Q>li7dzDacuo67Jg7mtqEm2TRuOMU=</Q><G>Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/XPaF5Bpsy4pNWMOHCBiNU0Nogps
+QW5QvnlMpA==</G><Y>mrGw6dac5y83egi3d9B9mUhaUMptjO2IyechEfR7D7tNItjZwALPTRwXPfSdqaMhLq4E4okSYmqf
+pDIB5xlH5A==</Y></DSAKeyValue></KeyValue></KeyInfo></Signature>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml
new file mode 100644
index 0000000..7803c43
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopedXmlSig.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><root xmlns="http://test/test"><test>Test Message</test><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>/dePBrnNR3mx6DKdsDFN2H4UarQ=</DigestValue></Reference></SignedInfo><SignatureValue>PGhKJFsDUeJkSl/kBto/4FTyWctPTIud8DWpAK1MYrdm2tW+5CIGzg==</SignatureValue><KeyInfo><KeyValue><DSAKeyValue><P>/KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxeEu0ImbzRMqzVDZkVG9
+xD7nN1kuFw==</P><Q>li7dzDacuo67Jg7mtqEm2TRuOMU=</Q><G>Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/XPaF5Bpsy4pNWMOHCBiNU0Nogps
+QW5QvnlMpA==</G><Y>VU3zFibvvHpAjBU//q9/Acqlrvk0z004XeokckhCRQbzndMPXwqBZiRzidAJ1rH7VWmzjgoYCXgo
+S75Mz34Kzg==</Y></DSAKeyValue></KeyValue></KeyInfo></Signature></root>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSig.xml
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSig.xml b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSig.xml
new file mode 100644
index 0000000..9d4a2f4
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSig.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/><Reference URI="#object"><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>7/XTsHaBSOnJ/jXD5v0zL6VKYsk=</DigestValue></Reference></SignedInfo><SignatureValue>lEVp+uRAR76ljIWOLLmRHCCg1yJEhkSbmrz7p4g7uKqGBqeDOxKyqA==</SignatureValue><KeyInfo><KeyValue><DSAKeyValue><P>/KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxeEu0ImbzRMqzVDZkVG9
+xD7nN1kuFw==</P><Q>li7dzDacuo67Jg7mtqEm2TRuOMU=</Q><G>Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/XPaF5Bpsy4pNWMOHCBiNU0Nogps
+QW5QvnlMpA==</G><Y>JogaxQp8IZaKJecuVRYb1m7/fse2Q6zoM+Bt6E/kG6X5AE273DzLEbvcPXt67MFyz7uvYlHEf+M5
+eD83vjhlpA==</Y></DSAKeyValue></KeyValue></KeyInfo><Object Id="object">some text</Object></Signature>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSigWithSeveralElementsWithNameRoot.xml
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSigWithSeveralElementsWithNameRoot.xml b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSigWithSeveralElementsWithNameRoot.xml
new file mode 100644
index 0000000..565333f
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ExampleEnvelopingDigSigWithSeveralElementsWithNameRoot.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/><Reference URI="#object"><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>Fi9k4CFY/3aj+9IiKjC2Q4yEFEU=</DigestValue></Reference></SignedInfo><SignatureValue>Pq8jDzMW1bUVnITLGJaE9y9t5CqV1bMdL9k26iIxsQAtjrCMRWSZvw==</SignatureValue><KeyInfo><KeyValue><DSAKeyValue><P>/KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxeEu0ImbzRMqzVDZkVG9
+xD7nN1kuFw==</P><Q>li7dzDacuo67Jg7mtqEm2TRuOMU=</Q><G>Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/XPaF5Bpsy4pNWMOHCBiNU0Nogps
+QW5QvnlMpA==</G><Y>8iwyFDURB8kQ1f+8wNEHXbRs9LqgBd8hGC4azGfaHfYnDnGf74jzrG+UVVe68ETKWmuX7tpkzC0y
+bgjaNIp8KQ==</Y></DSAKeyValue></KeyValue></KeyInfo><Object Id="object"><superroot xmlns="http://test/test" Id="superroot_id"><root Id="root1_id"><test Id="test_id">Test Message</test></root><root Id="root2_id">second root</root></superroot></Object></Signature>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ManifestTest_TamperedContent.xml
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ManifestTest_TamperedContent.xml b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ManifestTest_TamperedContent.xml
new file mode 100644
index 0000000..77bf7d2
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/ManifestTest_TamperedContent.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/><Reference URI="#myManifest"><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>Dn1qUwuTxEEY+mvIETwPpCzTSao=</DigestValue></Reference></SignedInfo><SignatureValue>Z8BjjJ1lVpd58a2pNafQVIVTIP4blaSdbqDnClB/TK8QMj93XY+ZdQ==</SignatureValue><KeyInfo><KeyValue><DSAKeyValue><P>/KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxeEu0ImbzRMqzVDZkVG9
+xD7nN1kuFw==</P><Q>li7dzDacuo67Jg7mtqEm2TRuOMU=</Q><G>Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/XPaF5Bpsy4pNWMOHCBiNU0Nogps
+QW5QvnlMpA==</G><Y>BtnkfZ+4ME+oz7cJTKHpwJErRQ7NkAJO0K4fO+sCzr/KO2TKbG1Jg69aZuuEnxtPIEV0HkDJkKu4
+N7vcAKk0yw==</Y></DSAKeyValue></KeyValue></KeyInfo><Object><Manifest Id="myManifest"><Reference URI="#content"><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>ABSEE2Q8T96qN9OIEvPyNaLx6kk=</DigestValue></Reference></Manifest></Object><Object Id="content">some text tampered</Object></Signature>
\ No newline at end of file
[2/6] CAMEL-6339 Applied the patch with thanks to Franz
Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTests.xml
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTests.xml b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTests.xml
new file mode 100644
index 0000000..bc0a6d1
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTests.xml
@@ -0,0 +1,389 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+ ">
+
+ <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+ <onException>
+ <exception>org.apache.camel.component.xmlsecurity.api.XmlSignatureException
+ </exception>
+ <handled>
+ <constant>false</constant>
+ </handled>
+ <to uri="mock:exception" />
+ </onException>
+
+ <!-- START SNIPPET: enveloping XML signature -->
+ <route>
+ <from uri="direct:enveloping" />
+ <to uri="xmlsecurity:sign://enveloping?keyAccessor=#accessorRsa" />
+ <to uri="xmlsecurity:verify://enveloping?keySelector=#selectorRsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: enveloping XML signature -->
+
+ <!-- START SNIPPET: enveloping XML signature with plain text -->
+ <route>
+ <from uri="direct:plaintext" />
+ <to
+ uri="xmlsecurity:sign://plaintext?keyAccessor=#accessorRsa&plainText=true&plainTextEncoding=UTF-8" />
+ <to uri="xmlsecurity:verify://plaintext?keySelector=#selectorRsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: enveloping XML signature with plain text -->
+
+ <!-- START SNIPPET: enveloped XML signature -->
+ <route>
+ <from uri="direct:enveloped" />
+ <to
+ uri="xmlsecurity:sign://enveloped?keyAccessor=#accessorRsa&parentLocalName=root&parentNamespace=http://test/test" />
+ <to uri="xmlsecurity:verify://enveloped?keySelector=#selectorRsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: enveloped XML signature -->
+
+ <!-- START SNIPPET: canonicalization -->
+ <route>
+ <from uri="direct:canonicalization" />
+ <to
+ uri="xmlsecurity:sign://canonicalization?keyAccessor=#accessorRsa&canonicalizationMethod=#canonicalizationMethod1" />
+ <to uri="xmlsecurity:verify://canonicalization?keySelector=#selectorRsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: canonicalization -->
+
+ <!-- START SNIPPET: digest and signature algorithm -->
+ <route>
+ <from uri="direct:signaturedigestalgorithm" />
+ <to
+ uri="xmlsecurity:sign://signaturedigestalgorithm?keyAccessor=#accessorRsa&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha384&digestAlgorithm=http://www.w3.org/2001/04/xmlenc#sha256" />
+ <to
+ uri="xmlsecurity:verify://signaturedigestalgorithm?keySelector=#selectorRsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: digest and signature algorithm -->
+
+ <!-- START SNIPPET: transforms XPath2 -->
+ <route>
+ <from uri="direct:transformsXPath2" />
+ <to
+ uri="xmlsecurity:sign://transformsXPath2?keyAccessor=#accessorRsa&transformMethods=#transformsXPath2" />
+ <to uri="xmlsecurity:verify://transformsXPath2?keySelector=#selectorRsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: transforms XPath2 -->
+
+ <!-- START SNIPPET: transforms XSLT, XPath -->
+ <route>
+ <from uri="direct:transformsXsltXPath" />
+ <to
+ uri="xmlsecurity:sign://transformsXsltXPath?keyAccessor=#accessorRsa&transformMethods=#transformsXsltXPath" />
+ <to
+ uri="xmlsecurity:verify://transformsXsltXPath?keySelector=#selectorRsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: transforms XSLT, XPath -->
+
+ <!-- START SNIPPET: transforms XSLT, XPath - secure Validation disabled -->
+ <route>
+ <from uri="direct:transformsXsltXPathSecureValDisabled" />
+ <to
+ uri="xmlsecurity:sign://transformsXsltXPathSecureValDisabled?keyAccessor=#accessorRsa&transformMethods=#transformsXsltXPath" />
+ <to
+ uri="xmlsecurity:verify://transformsXsltXPathSecureValDisabled?keySelector=#selectorRsa&secureValidation=false" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: transforms XSLT, XPath - secure Validation disabled -->
+
+
+ <!-- START SNIPPET: invalid key exception -->
+ <route>
+ <from uri="direct:signexceptioninvalidkey" />
+ <to
+ uri="xmlsecurity:sign://signexceptioninvalidkey?keyAccessor=#accessorDsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: invalid key exception -->
+
+ <!-- START SNIPPET: sign exceptions -->
+ <route>
+ <from uri="direct:signexceptions" />
+ <to
+ uri="xmlsecurity:sign://signexceptioninvalidkey?keyAccessor=#accessorRsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: sign exceptions -->
+
+ <!-- START SNIPPET: noSuchAlgorithmException -->
+ <route>
+ <from uri="direct:noSuchAlgorithmException" />
+ <to
+ uri="xmlsecurity:sign://noSuchAlgorithmException?keyAccessor=#accessorRsa&signatureAlgorithm=wrongalgorithm&digestAlgorithm=http://www.w3.org/2001/04/xmlenc#sha512" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: noSuchAlgorithmException -->
+
+ <!-- START SNIPPET: verify exceptions -->
+ <route>
+ <from uri="direct:verifyexceptions" />
+ <to uri="xmlsecurity:verify://verifyexceptions?keySelector=#selectorDsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: verify exceptions -->
+
+ <!-- START SNIPPET: verifier InvalidHashException -->
+ <route>
+ <from uri="direct:invalidhash" />
+ <to
+ uri="xmlsecurity:verify://invalidhash?keySelector=#selectorKeyValue&baseUri=#baseUri&secureValidation=false" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: verifier InvalidHashException -->
+
+ <!-- START SNIPPET: cryptoContextProperties -->
+ <route>
+ <from uri="direct:cryptocontextprops" />
+ <to
+ uri="xmlsecurity:verify://cryptocontextprops?keySelector=#selectorKeyValue&cryptoContextProperties=#cryptoContextProperties" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: cryptoContextProperties -->
+
+ <!-- START SNIPPET: verify InvalidKeyException -->
+ <route>
+ <from uri="direct:verifyInvalidKeyException" />
+ <to
+ uri="xmlsecurity:verify://verifyInvalidKeyException?keySelector=#selectorRsa" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: verify InvalidKeyException -->
+
+
+ <!-- START SNIPPET: uridereferencer -->
+ <route>
+ <from uri="direct:uridereferencer" />
+ <to
+ uri="xmlsecurity:sign://uridereferencer?keyAccessor=#accessorRsa&uriDereferencer=#uriDereferencer" />
+ <to
+ uri="xmlsecurity:verify://uridereferencer?keySelector=#selectorRsa&uriDereferencer=#uriDereferencer" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: uridereferencer -->
+
+ <!-- START SNIPPET: keyAccessorKeySelectorDefault -->
+ <route>
+ <from uri="direct:keyAccessorKeySelectorDefault" />
+ <to
+ uri="xmlsecurity:sign://keyAccessorKeySelectorDefault?keyAccessor=#keyAccessorDefault" />
+ <to
+ uri="xmlsecurity:verify://keyAccessorKeySelectorDefault?keySelector=#keySelectorDefault" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: keyAccessorKeySelectorDefault -->
+
+ <!-- START SNIPPET: xmlSignatureChecker -->
+ <route>
+ <from uri="direct:xmlSignatureChecker" />
+ <to
+ uri="xmlsecurity:verify://keyAccessorKeySelectorDefault?keySelector=#selectorKeyValue&xmlSignatureChecker=#envelopingSignatureChecker" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: xmlSignatureChecker -->
+
+ <!-- START SNIPPET: properties -->
+ <route>
+ <from uri="direct:props" />
+ <to
+ uri="xmlsecurity:sign://properties?keyAccessor=#accessorRsa&properties=#signatureProperties" />
+ <to
+ uri="xmlsecurity:verify://properties?keySelector=#selectorRsa&xmlSignature2Message=#xmlSignature2MessageWithTimestampPropertyy" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: properties -->
+
+ <!-- START SNIPPET: verify output node search element name -->
+ <route>
+ <from uri="direct:outputnodesearchelementname" />
+ <to
+ uri="xmlsecurity:verify://outputnodesearchelementname?keySelector=#selectorKeyValue&outputNodeSearchType=ElementName&outputNodeSearch={http://test/test}root&removeSignatureElements=true" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: verify output node search element name -->
+
+ <!-- START SNIPPET: verify output node search xpath -->
+ <route>
+ <from uri="direct:outputnodesearchxpath" />
+ <to
+ uri="xmlsecurity:verify://outputnodesearchxpath?keySelector=#selectorKeyValue&outputNodeSearchType=XPath&outputNodeSearch=#nodesearchxpath&removeSignatureElements=true" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: verify output node search xpath -->
+
+ <!-- START SNIPPET: validationFailedHandler -->
+ <route>
+ <from uri="direct:validationFailedHandler" />
+ <to
+ uri="xmlsecurity:verify://validationFailedHandler?keySelector=#selectorKeyValue&validationFailedHandler=validationFailedHandlerIgnoreManifestFailures" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: validationFailedHandler -->
+
+ <!-- START SNIPPET: further parameters -->
+ <route>
+ <from uri="direct:furtherparams" />
+ <to
+ uri="xmlsecurity:sign://furtherparams?keyAccessor=#accessorRsa&prefixForXmlSignatureNamespace=digsig&disallowDoctypeDecl=false" />
+ <to
+ uri="xmlsecurity:verify://furtherparams?keySelector=#selectorRsa&disallowDoctypeDecl=false" />
+ <to uri="mock:result" />
+ </route>
+ <!-- END SNIPPET: further parameters -->
+
+
+ </camelContext>
+
+ <bean id="accessorDsa"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getDsaKeyAccessor" />
+ <bean id="accessorRsa"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getRsaKeyAccessor" />
+ <bean id="selectorDsa"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getDsaKeySelector" />
+ <bean id="selectorRsa"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getRsaKeySelector" />
+
+ <bean id="keyAccessorDefault"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getDefaultKeyAccessor" />
+ <bean id="keySelectorDefault"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getDefaultKeySelector" />
+
+ <bean id="baseUri"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getBaseUri" />
+
+ <bean id="selectorKeyValue"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getKeyValueKeySelector" />
+
+ <bean id="cryptoContextProperties"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getCrytoContextProperties" />
+
+ <bean id="canonicalizationMethod1"
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper"
+ factory-method="getCanonicalizationMethod">
+ <constructor-arg type="java.lang.String"
+ value="http://www.w3.org/2001/10/xml-exc-c14n#" />
+ </bean>
+
+ <bean id="transformsXsltXPath"
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper"
+ factory-method="getTransforms">
+ <constructor-arg type="java.util.List">
+ <list>
+ <bean
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper"
+ factory-method="getCanonicalizationMethod">
+ <constructor-arg type="java.lang.String"
+ value="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
+ </bean>
+ <bean
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper"
+ factory-method="getXslTransform">
+ <constructor-arg type="java.lang.String"
+ value="/org/apache/camel/component/xmlsecurity/xslt_test.xsl" />
+ </bean>
+ <bean
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper"
+ factory-method="getXPathTransform">
+ <constructor-arg type="java.lang.String" value="//n0:XMLSecurity/n0:Content" />
+ <constructor-arg type="java.util.Map">
+ <map>
+ <entry key="n0" value="https://org.apache/camel/xmlsecurity/test" />
+ </map>
+ </constructor-arg>
+ </bean>
+ <!-- I removed base 64 transform because the JDK provider does not support
+ correctly this transform <bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper"
+ factory-method="getBase64Transform" /> -->
+ </list>
+ </constructor-arg>
+ </bean>
+
+
+ <bean id="transformsXPath2"
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper"
+ factory-method="getTransforms">
+ <constructor-arg type="java.util.List">
+ <list>
+ <bean
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper"
+ factory-method="getCanonicalizationMethod">
+ <constructor-arg type="java.lang.String"
+ value="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
+ </bean>
+ <bean
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper"
+ factory-method="getXPath2Transform">
+ <constructor-arg type="java.util.List">
+ <list>
+ <bean
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper.XPathAndFilter">
+ <property name="xpath" value="//n0:ToBeSigned" />
+ <property name="filter" value="intersect" />
+ </bean>
+ <bean
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper.XPathAndFilter">
+ <property name="xpath" value="//n0:NotToBeSigned" />
+ <property name="filter" value="subtract" />
+ </bean>
+ <bean
+ class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper.XPathAndFilter">
+ <property name="xpath" value="//n0:ReallyToBeSigned" />
+ <property name="filter" value="union" />
+ </bean>
+ </list>
+ </constructor-arg>
+ <constructor-arg type="java.util.Map">
+ <map>
+ <entry key="n0" value="http://test/test" />
+ </map>
+ </constructor-arg>
+ </bean>
+ </list>
+ </constructor-arg>
+ </bean>
+
+ <bean id="uriDereferencer"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getSameDocumentUriDereferencer" />
+
+ <bean id="envelopingSignatureChecker"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getEnvelopingXmlSignatureChecker" />
+
+ <bean id="xmlSignature2MessageWithTimestampPropertyy"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getXmlSignature2MessageWithTimestampdProperty" />
+
+ <bean id="signatureProperties"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getSignatureProperties" />
+
+ <bean id="validationFailedHandlerIgnoreManifestFailures"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getValidationFailedHandlerIgnoreManifestFailures" />
+
+ <bean id="nodesearchxpath"
+ class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest"
+ factory-method="getNodeSerachXPath" />
+
+</beans>
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/keystore.jks
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/keystore.jks b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/keystore.jks
new file mode 100644
index 0000000..de80bc0
Binary files /dev/null and b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/keystore.jks differ
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/testFile.txt
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/testFile.txt b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/testFile.txt
new file mode 100644
index 0000000..3214841
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/testFile.txt
@@ -0,0 +1 @@
+<root>Test Message Tampered</root>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xmldsig-core-schema.dtd
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xmldsig-core-schema.dtd b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xmldsig-core-schema.dtd
new file mode 100644
index 0000000..969dbb1
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xmldsig-core-schema.dtd
@@ -0,0 +1,171 @@
+<!-- DTD for XML Signatures
+ http://www.w3.org/2000/09/xmldsig#
+ Joseph Reagle $last changed 20001215$
+
+ http://www.w3.org/2000/09/xmldsig#
+ $Revision: 1.1 $ on $Date: 2002/02/08 20:32:26 $ by $Author: reagle $
+
+ Copyright 2001 The Internet Society and W3C (Massachusetts Institute
+ of Technology, Institut National de Recherche en Informatique et en
+ Automatique, Keio University). All Rights Reserved.
+ http://www.w3.org/Consortium/Legal/
+
+ This document is governed by the W3C Software License [1] as described
+ in the FAQ [2].
+
+ [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+ [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+-->
+
+
+<!--
+
+The following entity declarations enable external/flexible content in
+the Signature content model.
+
+#PCDATA emulates schema string; when combined with element types it
+emulates schema's mixed content type.
+
+%foo.ANY permits the user to include their own element types from
+other namespaces, for example:
+ <!ENTITY % KeyValue.ANY '| ecds:ECDSAKeyValue'>
+ ...
+ <!ELEMENT ecds:ECDSAKeyValue (#PCDATA) >
+
+-->
+
+<!ENTITY % Object.ANY ''>
+<!ENTITY % Method.ANY ''>
+<!ENTITY % Transform.ANY ''>
+<!ENTITY % SignatureProperty.ANY ''>
+<!ENTITY % KeyInfo.ANY ''>
+<!ENTITY % KeyValue.ANY ''>
+<!ENTITY % PGPData.ANY ''>
+<!ENTITY % X509Data.ANY ''>
+<!ENTITY % SPKIData.ANY ''>
+
+
+
+<!-- Start Core Signature declarations, these should NOT be altered -->
+
+<!ELEMENT Signature (SignedInfo, SignatureValue, KeyInfo?, Object*) >
+<!ATTLIST Signature
+ xmlns CDATA #FIXED 'http://www.w3.org/2000/09/xmldsig#'
+ Id ID #IMPLIED >
+
+<!ELEMENT SignatureValue (#PCDATA) >
+<!ATTLIST SignatureValue
+ Id ID #IMPLIED>
+
+<!ELEMENT SignedInfo (CanonicalizationMethod,
+ SignatureMethod, Reference+) >
+<!ATTLIST SignedInfo
+ Id ID #IMPLIED
+>
+
+<!ELEMENT CanonicalizationMethod (#PCDATA %Method.ANY;)* >
+<!ATTLIST CanonicalizationMethod
+ Algorithm CDATA #REQUIRED >
+
+<!ELEMENT SignatureMethod (#PCDATA|HMACOutputLength %Method.ANY;)* >
+<!ATTLIST SignatureMethod
+ Algorithm CDATA #REQUIRED >
+
+<!ELEMENT Reference (Transforms?, DigestMethod, DigestValue) >
+<!ATTLIST Reference
+ Id ID #IMPLIED
+ URI CDATA #IMPLIED
+ Type CDATA #IMPLIED>
+
+
+<!ELEMENT Transforms (Transform+)>
+
+<!ELEMENT Transform (#PCDATA|XPath %Transform.ANY;)* >
+<!ATTLIST Transform
+ Algorithm CDATA #REQUIRED >
+
+<!ELEMENT XPath (#PCDATA) >
+
+<!ELEMENT DigestMethod (#PCDATA %Method.ANY;)* >
+<!ATTLIST DigestMethod
+ Algorithm CDATA #REQUIRED >
+
+<!ELEMENT DigestValue (#PCDATA) >
+
+<!ELEMENT KeyInfo (#PCDATA|KeyName|KeyValue|RetrievalMethod|
+ X509Data|PGPData|SPKIData|MgmtData %KeyInfo.ANY;)* >
+<!ATTLIST KeyInfo
+ Id ID #IMPLIED >
+
+<!-- Key Information -->
+
+<!ELEMENT KeyName (#PCDATA) >
+<!ELEMENT KeyValue (#PCDATA|DSAKeyValue|RSAKeyValue %KeyValue.ANY;)* >
+<!ELEMENT MgmtData (#PCDATA) >
+
+<!ELEMENT RetrievalMethod (Transforms?) >
+<!ATTLIST RetrievalMethod
+ URI CDATA #REQUIRED
+ Type CDATA #IMPLIED >
+
+<!-- X.509 Data -->
+
+<!ELEMENT X509Data ((X509IssuerSerial | X509SKI | X509SubjectName |
+ X509Certificate | X509CRL )+ %X509Data.ANY;)>
+<!ELEMENT X509IssuerSerial (X509IssuerName, X509SerialNumber) >
+<!ELEMENT X509IssuerName (#PCDATA) >
+<!ELEMENT X509SubjectName (#PCDATA) >
+<!ELEMENT X509SerialNumber (#PCDATA) >
+<!ELEMENT X509SKI (#PCDATA) >
+<!ELEMENT X509Certificate (#PCDATA) >
+<!ELEMENT X509CRL (#PCDATA) >
+
+<!-- PGPData -->
+
+<!ELEMENT PGPData ((PGPKeyID, PGPKeyPacket?) | (PGPKeyPacket) %PGPData.ANY;) >
+<!ELEMENT PGPKeyPacket (#PCDATA) >
+<!ELEMENT PGPKeyID (#PCDATA) >
+
+<!-- SPKI Data -->
+
+<!ELEMENT SPKIData (SPKISexp %SPKIData.ANY;) >
+<!ELEMENT SPKISexp (#PCDATA) >
+
+<!-- Extensible Content -->
+
+<!ELEMENT Object (#PCDATA|Signature|SignatureProperties|Manifest %Object.ANY;)* >
+<!ATTLIST Object
+ Id ID #IMPLIED
+ MimeType CDATA #IMPLIED
+ Encoding CDATA #IMPLIED >
+
+<!ELEMENT Manifest (Reference+) >
+<!ATTLIST Manifest
+ Id ID #IMPLIED >
+
+<!ELEMENT SignatureProperties (SignatureProperty+) >
+<!ATTLIST SignatureProperties
+ Id ID #IMPLIED >
+
+<!ELEMENT SignatureProperty (#PCDATA %SignatureProperty.ANY;)* >
+<!ATTLIST SignatureProperty
+ Target CDATA #REQUIRED
+ Id ID #IMPLIED >
+
+<!-- Algorithm Parameters -->
+
+<!ELEMENT HMACOutputLength (#PCDATA) >
+
+<!ELEMENT DSAKeyValue ((P, Q)?, G?, Y, J?, (Seed, PgenCounter)?) >
+<!ELEMENT P (#PCDATA) >
+<!ELEMENT Q (#PCDATA) >
+<!ELEMENT G (#PCDATA) >
+<!ELEMENT Y (#PCDATA) >
+<!ELEMENT J (#PCDATA) >
+<!ELEMENT Seed (#PCDATA) >
+<!ELEMENT PgenCounter (#PCDATA) >
+
+<!ELEMENT RSAKeyValue (Modulus, Exponent) >
+<!ELEMENT Modulus (#PCDATA) >
+<!ELEMENT Exponent (#PCDATA) >
+
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xslt_test.xsl
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xslt_test.xsl b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xslt_test.xsl
new file mode 100644
index 0000000..6220480
--- /dev/null
+++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xslt_test.xsl
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+ <xsl:template match="/">
+ <n0:XMLSecurity xmlns:n0="https://org.apache/camel/xmlsecurity/test"
+ xmlns:nn0="http://www.w3.org/2000/09/xmldsig#" xmlns:n1="http://test/test">
+ <n0:Content>
+ <!-- must start with the Object element! -->
+ <xsl:value-of select="//n1:root/n1:test" />
+ </n0:Content>
+ </n0:XMLSecurity>
+ </xsl:template>
+</xsl:stylesheet>
[5/6] CAMEL-6339 Applied the patch with thanks to Franz
Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
new file mode 100644
index 0000000..216ae98
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
@@ -0,0 +1,65 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+public final class XmlSignatureConstants {
+
+ private XmlSignatureConstants() {
+ // no instance
+ }
+
+ /**
+ * Header for indicating that the message body contains non-xml plain text.
+ * This header is used in the XML signature generator. If the value is set
+ * to {@link Boolean#TRUE} then the message body is treated as plain text
+ * Overwrites the configuration parameter
+ * XmlSignerConfiguration#setPlainText(Boolean)
+ */
+ public static final String HEADER_MESSAGE_IS_PLAIN_TEXT = "CamelXmlSignatureMessageIsPlainText";
+
+ /**
+ * Header indicating the encoding of the plain text message body. Used in
+ * the XML signature generator if the header
+ * {@link #HEADER_MESSAGE_IS_PLAIN_TEXT} is set to {@link Boolean#TRUE}.
+ * Overwrites the configuration parameter
+ * XmlSignerConfiguration#setPlainTextEncoding(String).
+ */
+ public static final String HEADER_PLAIN_TEXT_ENCODING = "CamelXmlSignaturePlainTextEncoding";
+
+ /**
+ * Header which indicates that either the resulting signature document in
+ * the signature generation case or the resulting output of the verifier
+ * should not contain an XML declaration. If the header is not specified
+ * then a XML declaration is created.
+ * <p>
+ * There is one exception: If the verifier result is a plain text this
+ * header has no effect.
+ * <p>
+ * Possible values of the header are {@link Boolean#TRUE} or
+ * {@link Boolean#FALSE}.
+ * <p>
+ * Overwrites the configuration parameter
+ * XmlSignatureConfiguration#setOmitXmlDeclaration(Boolean).
+ *
+ */
+ public static final String HEADER_OMIT_XML_DECLARATION = "CamelXmlSignatureOmitXmlDeclaration";
+
+ public static final String HEADER_CONTENT_REFERENCE_URI = "CamelXmlSignatureContentReferenceUri";
+
+ public static final String HEADER_CONTENT_REFERENCE_TYPE = "CamelXmlSignatureContentReferenceType";
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureException.java
new file mode 100644
index 0000000..5685ea2
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureException.java
@@ -0,0 +1,45 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+/**
+ * Exception thrown when a configuration failure or a failure caused by the
+ * input message in the XML signature generation or validation process occurs.
+ *
+ * The route developer can catch these exception in an error handler to react on
+ * such failures.
+ */
+public class XmlSignatureException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public XmlSignatureException() {
+ }
+
+ public XmlSignatureException(String message) {
+ super(message);
+ }
+
+ public XmlSignatureException(Throwable cause) {
+ super(cause);
+ }
+
+ public XmlSignatureException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureFormatException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureFormatException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureFormatException.java
new file mode 100644
index 0000000..afbdaa8
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureFormatException.java
@@ -0,0 +1,38 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureException;
+
+/**
+ * Exception thrown when the input for signing or verifying does not have the correct
+ * format.
+ */
+public class XmlSignatureFormatException extends XmlSignatureException {
+
+ private static final long serialVersionUID = 1L;
+
+ public XmlSignatureFormatException(String message) {
+ super(message);
+ }
+
+ public XmlSignatureFormatException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureHelper.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureHelper.java
new file mode 100644
index 0000000..9657fac
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureHelper.java
@@ -0,0 +1,476 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.XMLConstants;
+import javax.xml.crypto.AlgorithmMethod;
+import javax.xml.crypto.dom.DOMStructure;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;
+import javax.xml.crypto.dsig.spec.XPathFilter2ParameterSpec;
+import javax.xml.crypto.dsig.spec.XPathFilterParameterSpec;
+import javax.xml.crypto.dsig.spec.XPathType;
+import javax.xml.crypto.dsig.spec.XSLTTransformParameterSpec;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * Helps to construct the transformations and the canonicalization methods for
+ * the XML Signature generator.
+ */
+public class XmlSignatureHelper {
+
+ /**
+ * Returns a configuration for a canonicalization algorithm.
+ *
+ * @param algorithm
+ * algorithm URI
+ * @return canonicalization
+ * @throws IllegalArgumentException
+ * if <tt>algorithm</tt> is <code>null</code>
+ */
+ public static AlgorithmMethod getCanonicalizationMethod(String algorithm) {
+ return getCanonicalizationMethod(algorithm, null);
+ }
+
+ /**
+ * Returns a configuration for a canonicalization algorithm.
+ *
+ * @param algorithm
+ * algorithm URI
+ * @param inclusiveNamespacePrefixes
+ * namespace prefixes which should be treated like in the
+ * inclusive canonicalization, only relevant if the algorithm is
+ * exclusive
+ * @return canonicalization
+ * @throws IllegalArgumentException
+ * if <tt>algorithm</tt> is <code>null</code>
+ */
+ public static AlgorithmMethod getCanonicalizationMethod(String algorithm, List<String> inclusiveNamespacePrefixes) {
+ if (algorithm == null) {
+ throw new IllegalArgumentException("algorithm is null");
+ }
+ XmlSignatureTransform canonicalizationMethod = new XmlSignatureTransform(algorithm);
+ if (inclusiveNamespacePrefixes != null) {
+ ExcC14NParameterSpec parameters = new ExcC14NParameterSpec(inclusiveNamespacePrefixes);
+ canonicalizationMethod.setParameterSpec(parameters);
+ }
+ return canonicalizationMethod;
+ }
+
+ public static AlgorithmMethod getEnvelopedTransform() {
+ return new XmlSignatureTransform(Transform.ENVELOPED);
+ }
+
+ /**
+ * Returns a configuration for a base64 transformation.
+ *
+ * @return Base64 transformation
+ */
+ public static AlgorithmMethod getBase64Transform() {
+ return new XmlSignatureTransform(Transform.BASE64);
+ }
+
+ /**
+ * Returns a configuration for an XPATH transformation.
+ *
+ * @param xpath
+ * XPATH expression
+ * @return XPATH transformation
+ * @throws IllegalArgumentException
+ * if <tt>xpath</tt> is <code>null</code>
+ */
+ public static AlgorithmMethod getXPathTransform(String xpath) {
+ return getXPathTransform(xpath, null);
+ }
+
+ /**
+ * Returns a configuration for an XPATH transformation which needs a
+ * namespace map.
+ *
+ * @param xpath
+ * XPATH expression
+ * @param namespaceMap
+ * namespace map, key is the prefix, value is the namespace, can
+ * be <code>null</code>
+ * @throws IllegalArgumentException
+ * if <tt>xpath</tt> is <code>null</code>
+ * @return XPATH transformation
+ */
+ public static AlgorithmMethod getXPathTransform(String xpath, Map<String, String> namespaceMap) {
+ if (xpath == null) {
+ throw new IllegalArgumentException("xpath is null");
+ }
+ XmlSignatureTransform transformXPath = new XmlSignatureTransform();
+ transformXPath.setAlgorithm(Transform.XPATH);
+ XPathFilterParameterSpec params = getXpathFilter(xpath, namespaceMap);
+ transformXPath.setParameterSpec(params);
+ return transformXPath;
+ }
+
+ public static XPathFilterParameterSpec getXpathFilter(String xpath, Map<String, String> namespaceMap) {
+ XPathFilterParameterSpec params = namespaceMap == null ? new XPathFilterParameterSpec(xpath) : new XPathFilterParameterSpec(xpath,
+ namespaceMap);
+ return params;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static XPathExpression getXPathExpression(XPathFilterParameterSpec xpathFilter) throws XPathExpressionException {
+
+ XPathFactory factory = XPathFactory.newInstance();
+ XPath xpath = factory.newXPath();
+ if (xpathFilter.getNamespaceMap() != null) {
+ xpath.setNamespaceContext(new XPathNamespaceContext(xpathFilter.getNamespaceMap()));
+ }
+ return xpath.compile(xpathFilter.getXPath());
+ }
+
+ private static class XPathNamespaceContext implements NamespaceContext {
+
+ private final Map<String, String> prefix2Namespace;
+
+ XPathNamespaceContext(Map<String, String> prefix2Namespace) {
+ this.prefix2Namespace = prefix2Namespace;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ if (prefix == null) {
+ throw new NullPointerException("Null prefix");
+ }
+ if ("xml".equals(prefix)) {
+ return XMLConstants.XML_NS_URI;
+ }
+ String ns = prefix2Namespace.get(prefix);
+ if (ns != null) {
+ return ns;
+ }
+ return XMLConstants.NULL_NS_URI;
+ }
+
+ // This method isn't necessary for XPath processing.
+ public String getPrefix(String uri) {
+ throw new UnsupportedOperationException();
+ }
+
+ // This method isn't necessary for XPath processing either.
+ @SuppressWarnings("rawtypes")
+ public Iterator getPrefixes(String uri) {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+ /**
+ * Returns a configuration for an XPATH2 transformation.
+ *
+ * @param xpath
+ * XPATH expression
+ * @param filter
+ * possible values are "intersect", "subtract", "union"
+ * @throws IllegalArgumentException
+ * if <tt>xpath</tt> or <tt>filter</tt> is <code>null</code>, or
+ * is neither "intersect", nor "subtract", nor "union"
+ * @return XPATH transformation
+ */
+ public static AlgorithmMethod getXPath2Transform(String xpath, String filter) {
+ return getXPath2Transform(xpath, filter, null);
+ }
+
+ /**
+ * Returns a configuration for an XPATH2 transformation which consists of
+ * several XPATH expressions.
+ *
+ * @param xpathAndFilterList
+ * list of XPATH expressions with their filters
+ * @param namespaceMap
+ * namespace map, key is the prefix, value is the namespace, can
+ * be <code>null</code>
+ * @throws IllegalArgumentException
+ * if <tt>xpathAndFilterList</tt> is <code>null</code> or empty,
+ * or the specified filter values are neither "intersect", nor
+ * "subtract", nor "union"
+ * @return XPATH transformation
+ */
+ public static AlgorithmMethod getXPath2Transform(String xpath, String filter, Map<String, String> namespaceMap) {
+ XPathAndFilter xpathAndFilter = new XPathAndFilter();
+ xpathAndFilter.setXpath(xpath);
+ xpathAndFilter.setFilter(filter);
+ List<XPathAndFilter> list = new ArrayList<XmlSignatureHelper.XPathAndFilter>(1);
+ list.add(xpathAndFilter);
+ return getXPath2Transform(list, namespaceMap);
+ }
+
+ /**
+ * Returns a configuration for an XPATH2 transformation which consists of
+ * several XPATH expressions.
+ *
+ * @param xpathAndFilterList
+ * list of XPATH expressions with their filters
+ * @param namespaceMap
+ * namespace map, key is the prefix, value is the namespace, can
+ * be <code>null</code>
+ * @throws IllegalArgumentException
+ * if <tt>xpathAndFilterList</tt> is <code>null</code> or empty,
+ * or the specified filter values are neither "intersect", nor
+ * "subtract", nor "union"
+ * @return XPATH transformation
+ */
+ public static AlgorithmMethod getXPath2Transform(List<XPathAndFilter> xpathAndFilterList, Map<String, String> namespaceMap) {
+ if (xpathAndFilterList == null) {
+ throw new IllegalArgumentException("xpathAndFilterList is null");
+ }
+ if (xpathAndFilterList.isEmpty()) {
+ throw new IllegalArgumentException("XPath and filter list is empty");
+ }
+ List<XPathType> list = getXPathTypeList(xpathAndFilterList, namespaceMap);
+ XmlSignatureTransform transformXPath = new XmlSignatureTransform(Transform.XPATH2);
+ transformXPath.setParameterSpec(new XPathFilter2ParameterSpec(list));
+ return transformXPath;
+ }
+
+ private static List<XPathType> getXPathTypeList(List<XPathAndFilter> xpathAndFilterList, Map<String, String> namespaceMap) {
+ List<XPathType> list = new ArrayList<XPathType>(xpathAndFilterList.size());
+ for (XPathAndFilter xpathAndFilter : xpathAndFilterList) {
+ XPathType.Filter xpathFilter;
+ if (XPathType.Filter.INTERSECT.toString().equals(xpathAndFilter.getFilter())) {
+ xpathFilter = XPathType.Filter.INTERSECT;
+ } else if (XPathType.Filter.SUBTRACT.toString().equals(xpathAndFilter.getFilter())) {
+ xpathFilter = XPathType.Filter.SUBTRACT;
+ } else if (XPathType.Filter.UNION.toString().equals(xpathAndFilter.getFilter())) {
+ xpathFilter = XPathType.Filter.UNION;
+ } else {
+ throw new IllegalStateException(String.format("XPATH %s has a filter %s not supported", xpathAndFilter.getXpath(),
+ xpathAndFilter.getFilter()));
+ }
+
+ XPathType xpathtype = namespaceMap == null ? new XPathType(xpathAndFilter.getXpath(), xpathFilter) : new XPathType(
+ xpathAndFilter.getXpath(), xpathFilter, namespaceMap);
+ list.add(xpathtype);
+ }
+ return list;
+ }
+
+ /**
+ * Returns a configuration for an XPATH2 transformation which consists of
+ * several XPATH expressions.
+ *
+ * @param xpathAndFilterList
+ * list of XPATH expressions with their filters
+ * @throws IllegalArgumentException
+ * if <tt>xpathAndFilterList</tt> is <code>null</code> or empty,
+ * or the specified filte values are neither "intersect", nor
+ * "subtract", nor "union"
+ * @return XPATH transformation
+ */
+ public static AlgorithmMethod getXPath2Transform(List<XPathAndFilter> xpathAndFilterList) {
+ return getXPath2Transform(xpathAndFilterList, null);
+ }
+
+ /**
+ * Returns a configuration for an XSL transformation.
+ *
+ * @param path
+ * path to the XSL file in the classpath
+ * @return XSL transform
+ * @throws IllegalArgumentException
+ * if <tt>path</tt> is <code>null</code>
+ * @throws IllegalStateException
+ * if the XSL file cannot be found
+ * @throws Exception
+ * if an error during the reading of the XSL file occurs
+ */
+ public static AlgorithmMethod getXslTransform(String path) throws Exception {
+ InputStream is = readXslTransform(path);
+ if (is == null) {
+ throw new IllegalStateException(String.format("XSL file %s not found", path));
+ }
+ return getXslTranform(is);
+ }
+
+ /**
+ * Returns a configuration for an XSL transformation.
+ *
+ * @param is
+ * input stream of the XSL
+ * @return XSL transform
+ * @throws IllegalArgumentException
+ * if <tt>is</tt> is <code>null</code>
+ * @throws Exception
+ * if an error during the reading of the XSL file occurs
+ */
+ public static AlgorithmMethod getXslTranform(InputStream is) throws SAXException, IOException, ParserConfigurationException {
+ if (is == null) {
+ throw new IllegalArgumentException("is must not be null");
+ }
+ Document doc = parseInput(is);
+ DOMStructure stylesheet = new DOMStructure(doc.getDocumentElement());
+ XSLTTransformParameterSpec spec = new XSLTTransformParameterSpec(stylesheet);
+ XmlSignatureTransform transformXslt = new XmlSignatureTransform();
+ transformXslt.setAlgorithm(Transform.XSLT);
+ transformXslt.setParameterSpec(spec);
+ return transformXslt;
+ }
+
+ protected static InputStream readXslTransform(String path) throws Exception {
+ if (path == null) {
+ throw new IllegalArgumentException("path is null");
+ }
+ return XmlSignatureHelper.class.getResourceAsStream(path);
+ }
+
+ public static List<AlgorithmMethod> getTransforms(List<AlgorithmMethod> list) {
+ return list;
+ }
+
+ private static Document parseInput(InputStream is) throws SAXException, IOException, ParserConfigurationException {
+ return newDocumentBuilder(Boolean.TRUE).parse(is);
+ }
+
+ public static List<Node> getTextAndElementChildren(Node node) {
+ List<Node> result = new LinkedList<Node>();
+ NodeList children = node.getChildNodes();
+ if (children == null) {
+ return result;
+ }
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if (Node.ELEMENT_NODE == child.getNodeType() || Node.TEXT_NODE == child.getNodeType()) {
+ result.add(child);
+ }
+ }
+ return result;
+ }
+
+ public static DocumentBuilder newDocumentBuilder(Boolean disallowDoctypeDecl) throws ParserConfigurationException {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ dbf.setValidating(false);
+ // avoid external entity attacks
+ dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
+ dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+ boolean isDissalowDoctypeDecl = disallowDoctypeDecl == null ? true : disallowDoctypeDecl;
+ dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", isDissalowDoctypeDecl);
+ // avoid overflow attacks
+ dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+
+ return dbf.newDocumentBuilder();
+ }
+
+ public static void transformToOutputStream(Node node, OutputStream os, boolean omitXmlDeclaration)
+ throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException, IOException {
+ if (node.getNodeType() == Node.TEXT_NODE) {
+ byte[] bytes = tranformTextNodeToByteArray(node);
+ os.write(bytes);
+ } else {
+ transformNonTextNodeToOutputStream(node, os, omitXmlDeclaration);
+ }
+ }
+
+ public static void transformNonTextNodeToOutputStream(Node node, OutputStream os, boolean omitXmlDeclaration)
+ throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException {
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer trans = tf.newTransformer();
+ if (omitXmlDeclaration) {
+ trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ }
+ trans.transform(new DOMSource(node), new StreamResult(os));
+ }
+
+ public static byte[] tranformTextNodeToByteArray(Node node) {
+ String text = node.getTextContent();
+ if (text != null) {
+ try {
+ return text.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // should not happen
+ throw new IllegalStateException(e);
+ }
+ } else {
+ return null;
+ }
+ }
+
+ public static Document getDocument(Node node) {
+ if (node.getNodeType() == Node.DOCUMENT_NODE) {
+ return (Document) node;
+ }
+ return node.getOwnerDocument();
+ }
+
+ public static class XPathAndFilter {
+
+ private String xpath;
+
+ private String filter;
+
+ public XPathAndFilter(String xpath, String filter) {
+ this.xpath = xpath;
+ this.filter = filter;
+ }
+
+ public XPathAndFilter() {
+
+ }
+
+ public String getXpath() {
+ return xpath;
+ }
+
+ public void setXpath(String xpath) {
+ this.xpath = xpath;
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public void setFilter(String filter) {
+ this.filter = filter;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidContentHashException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidContentHashException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidContentHashException.java
new file mode 100644
index 0000000..5476d9c
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidContentHashException.java
@@ -0,0 +1,38 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidException;
+
+/**
+ * This exception is thrown if the verification of a XML signature fails because
+ * the hash calculated over the content does not match the value in the
+ * signature.
+ */
+public class XmlSignatureInvalidContentHashException extends XmlSignatureInvalidException {
+
+ private static final long serialVersionUID = 1L;
+
+ public XmlSignatureInvalidContentHashException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public XmlSignatureInvalidContentHashException(String message) {
+ super(message);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidException.java
new file mode 100644
index 0000000..c5d132f
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidException.java
@@ -0,0 +1,35 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureException;
+
+/**
+ * This exception is thrown if XML signature verification fails.
+ */
+public class XmlSignatureInvalidException extends XmlSignatureException {
+
+ private static final long serialVersionUID = 1L;
+
+ public XmlSignatureInvalidException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public XmlSignatureInvalidException(String message) {
+ super(message);
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidKeyException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidKeyException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidKeyException.java
new file mode 100644
index 0000000..eaedb65
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidKeyException.java
@@ -0,0 +1,37 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureException;
+
+/**
+ * Exception thrown during signing or verifying if the key type does not fit to
+ * the signature algorithm.
+ */
+public class XmlSignatureInvalidKeyException extends XmlSignatureException {
+
+ private static final long serialVersionUID = 1L;
+
+ public XmlSignatureInvalidKeyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public XmlSignatureInvalidKeyException(Throwable cause) {
+ super(cause);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidValueException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidValueException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidValueException.java
new file mode 100644
index 0000000..b635917
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureInvalidValueException.java
@@ -0,0 +1,37 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureInvalidException;
+
+/**
+ * This exception is thrown if the verification of an XML signature fails
+ * because the signature value is invalid.
+ */
+public class XmlSignatureInvalidValueException extends XmlSignatureInvalidException {
+
+ private static final long serialVersionUID = 1L;
+
+ public XmlSignatureInvalidValueException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public XmlSignatureInvalidValueException(String message) {
+ super(message);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureNoKeyException.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureNoKeyException.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureNoKeyException.java
new file mode 100644
index 0000000..0933a8f
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureNoKeyException.java
@@ -0,0 +1,45 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureException;
+
+/**
+ * Exception thrown when no key for signing is found.
+ */
+public class XmlSignatureNoKeyException extends XmlSignatureException {
+
+ private static final long serialVersionUID = 1L;
+
+ public XmlSignatureNoKeyException() {
+
+ }
+
+ public XmlSignatureNoKeyException(String message) {
+ super(message);
+ }
+
+ public XmlSignatureNoKeyException(Throwable cause) {
+ super(cause);
+ }
+
+ public XmlSignatureNoKeyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureProperties.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureProperties.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureProperties.java
new file mode 100644
index 0000000..9f24215
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureProperties.java
@@ -0,0 +1,119 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import java.util.List;
+
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+
+import org.apache.camel.Message;
+import org.w3c.dom.Node;
+
+/**
+ * You can provide further XML objects and references which will be added by the
+ * XML signature generator to the XML signature.
+ */
+public interface XmlSignatureProperties {
+
+ /**
+ * Returns further configuration objects for the XML signature
+ *
+ * @param input
+ * input
+ * @return output must not be <code>null</code>
+ * @throws Exception
+ * if an error occurs during creating the output
+ */
+ Output get(Input input) throws Exception;
+
+ public static interface Input {
+
+ /** Input message for reading header data */
+ Message getMessage();
+
+ /**
+ * The message body as DOM node. If the message body is plain text then
+ * the node will be a text node. If the message body is a XML document,
+ * then the node is the root element.
+ */
+ Node getMessageBodyNode();
+
+ /**
+ * Returns the parent node of the signature element in the case of
+ * enveloped XML signature. <code>null</code> is returned in the case of
+ * enveloping XML signature.
+ *
+ * @return parent node or <code>null</code>
+ */
+ Node getParent();
+
+ /** Key info. */
+ KeyInfo getKeyInfo();
+
+ /**
+ * XML signature factory which can be used to create Reference and
+ * XMLObject instances.
+ *
+ * @return factory
+ */
+ XMLSignatureFactory getSignatureFactory();
+
+ /**
+ * Signature algorithm. Example:
+ * "http://www.w3.org/2000/09/xmldsig#dsa-sha1".
+ */
+ String getSignatureAlgorithm();
+
+ /**
+ * Digest algorithm which is used for the digest calculation of the
+ * message body.
+ */
+ String getContentDigestAlgorithm();
+
+ /** Signature Id. Can be <code>null</code>. */
+ String getSignatureId();
+
+ }
+
+ public static class Output {
+
+ private List<? extends XMLObject> objects;
+
+ private List<? extends Reference> references;
+
+ public List<? extends XMLObject> getObjects() {
+ return objects;
+ }
+
+ public void setObjects(List<? extends XMLObject> objects) {
+ this.objects = objects;
+ }
+
+ public List<? extends Reference> getReferences() {
+ return references;
+ }
+
+ public void setReferences(List<? extends Reference> references) {
+ this.references = references;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureTransform.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureTransform.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureTransform.java
new file mode 100644
index 0000000..8e5f52d
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureTransform.java
@@ -0,0 +1,58 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.xml.crypto.AlgorithmMethod;
+
+/**
+ * Transform and canonicalization algorithms with their parameters.
+ */
+public class XmlSignatureTransform implements AlgorithmMethod {
+
+ private String algorithm;
+
+ private AlgorithmParameterSpec parameterSpec;
+
+ public XmlSignatureTransform() {
+
+ }
+
+ public XmlSignatureTransform(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
+ @Override
+ public AlgorithmParameterSpec getParameterSpec() {
+ return parameterSpec;
+ }
+
+ @Override
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
+ public void setParameterSpec(AlgorithmParameterSpec parameterSpec) {
+ this.parameterSpec = parameterSpec;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureConfiguration.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureConfiguration.java
new file mode 100644
index 0000000..5a0d444
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureConfiguration.java
@@ -0,0 +1,164 @@
+/**
+ * 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.camel.component.xmlsecurity.processor;
+
+import java.util.Map;
+
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dsig.XMLSignContext;
+import javax.xml.crypto.dsig.XMLValidateContext;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants;
+
+public abstract class XmlSignatureConfiguration implements Cloneable, CamelContextAware {
+
+ private CamelContext context;
+
+ private URIDereferencer uriDereferencer;
+
+ private String baseUri;
+
+ private Map<String, ? extends Object> cryptoContextProperties;
+
+ private Boolean disallowDoctypeDecl = Boolean.TRUE;
+
+ private Boolean omitXmlDeclaration = Boolean.FALSE;
+
+ private Boolean clearHeaders = Boolean.TRUE;
+
+ public XmlSignatureConfiguration() {
+ }
+
+ public CamelContext getCamelContext() {
+ return context;
+ }
+
+ public void setCamelContext(CamelContext camelContext) {
+ this.context = camelContext;
+ }
+
+ public URIDereferencer getUriDereferencer() {
+ return uriDereferencer;
+ }
+
+ /**
+ * If you want to restrict the remote access via reference URIs, you can set
+ * an own dereferencer. Optional parameter. If not set the provider default
+ * dereferencer is used which can resolve URI fragments, HTTP, file and
+ * XPpointer URIs.
+ * <p>
+ * Attention: The implementation is provider dependent!
+ *
+ * @param uriDereferencer
+ * @see XMLCryptoContext#setURIDereferencer(URIDereferencer)
+ */
+ public void setUriDereferencer(URIDereferencer uriDereferencer) {
+ this.uriDereferencer = uriDereferencer;
+ }
+
+ public String getBaseUri() {
+ return baseUri;
+ }
+
+ /**
+ * You can set a base URI which is used in the URI dereferencing. Relative
+ * URIs are then concatenated with the base URI.
+ *
+ * @param baseUri
+ * base URI
+ *
+ * @see XMLCryptoContext#setBaseURI(String)
+ */
+ public void setBaseUri(String baseUri) {
+ this.baseUri = baseUri;
+ }
+
+ public Map<String, ? extends Object> getCryptoContextProperties() {
+ return cryptoContextProperties;
+ }
+
+ /**
+ * Sets the crypto context properties. See
+ * {@link XMLCryptoContext#setProperty(String, Object)}. Possible properties
+ * are defined in {@link XMLSignContext} an {@link XMLValidateContext} (see
+ * Supported Properties).
+ * <p>
+ * The following properties are set by default to the value
+ * {@link Boolean#TRUE} for the XML validation. If you want to switch these
+ * features off you must set the property value to {@link Boolean#FALSE}.
+ * <ul>
+ * <li><code>"org.jcp.xml.dsig.validateManifests"</code></li>
+ * <li><code>"javax.xml.crypto.dsig.cacheReference"</code></li>
+ * </ul>
+ *
+ * @param cryptoContextProperties
+ */
+ public void setCryptoContextProperties(Map<String, ? extends Object> cryptoContextProperties) {
+ this.cryptoContextProperties = cryptoContextProperties;
+ }
+
+ public Boolean getDisallowDoctypeDecl() {
+ return disallowDoctypeDecl;
+ }
+
+ /**
+ * Disallows that the incoming XML document contains DTD DOCTYPE
+ * declaration. The default value is {@link Boolean#TRUE}.
+ *
+ * @param disallowDoctypeDecl
+ * if set to {@link Boolean#FALSE} then DOCTYPE declaration is
+ * allowed, otherwise not
+ */
+ public void setDisallowDoctypeDecl(Boolean disallowDoctypeDecl) {
+ this.disallowDoctypeDecl = disallowDoctypeDecl;
+ }
+
+ public Boolean getOmitXmlDeclaration() {
+ return omitXmlDeclaration;
+ }
+
+ /**
+ * Indicator whether the XML declaration in the outgoing message body should
+ * be omitted. Default value is <code>false</code>. Can be overwritten by
+ * the header {@link XmlSignatureConstants#HEADER_OMIT_XML_DECLARATION}.
+ */
+ public void setOmitXmlDeclaration(Boolean omitXmlDeclaration) {
+ this.omitXmlDeclaration = omitXmlDeclaration;
+ }
+
+ /**
+ * Determines if the XML signature specific headers be cleared after signing
+ * and verification. Defaults to true.
+ *
+ * @return true if the Signature headers should be unset, false otherwise
+ */
+ public Boolean getClearHeaders() {
+ return clearHeaders;
+ }
+
+ /**
+ * Determines if the XML signature specific headers be cleared after signing
+ * and verification. Defaults to true.
+ */
+ public void setClearHeaders(Boolean clearHeaders) {
+ this.clearHeaders = clearHeaders;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureProcessor.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureProcessor.java
new file mode 100644
index 0000000..9a6fd5c
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureProcessor.java
@@ -0,0 +1,82 @@
+/**
+ * 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.camel.component.xmlsecurity.processor;
+
+import java.lang.reflect.Field;
+import java.util.Map;
+
+import javax.xml.crypto.XMLCryptoContext;
+
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.component.xmlsecurity.SantuarioUtil;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class XmlSignatureProcessor implements Processor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(XmlSignatureProcessor.class);
+
+ static {
+ SantuarioUtil.initializeSantuario();
+ SantuarioUtil.addSantuarioJSR105Provider();
+ }
+
+ public abstract XmlSignatureConfiguration getConfiguration();
+
+ void setUriDereferencerAndBaseUri(XMLCryptoContext context) {
+ setUriDereferencer(context);
+ setBaseUri(context);
+ }
+
+ private void setUriDereferencer(XMLCryptoContext context) {
+ if (getConfiguration().getUriDereferencer() != null) {
+ context.setURIDereferencer(getConfiguration().getUriDereferencer());
+ LOG.debug("URI dereferencer set");
+ }
+ }
+
+ private void setBaseUri(XMLCryptoContext context) {
+ if (getConfiguration().getBaseUri() != null) {
+ context.setBaseURI(getConfiguration().getBaseUri());
+ LOG.debug("Base URI {} set", context.getBaseURI());
+ }
+ }
+
+ protected void setCryptoContextProperties(XMLCryptoContext cryptoContext) {
+ Map<String, ? extends Object> props = getConfiguration().getCryptoContextProperties();
+ if (props == null) {
+ return;
+ }
+ for (String prop : props.keySet()) {
+ Object val = props.get(prop);
+ cryptoContext.setProperty(prop, val);
+ LOG.debug("Context property {} set to value {}", prop, val);
+ }
+ }
+
+ protected void clearMessageHeaders(Message message) {
+ if (getConfiguration().getClearHeaders() != null && getConfiguration().getClearHeaders()) {
+ Map<String, Object> headers = message.getHeaders();
+ for (Field f : XmlSignatureConstants.class.getFields()) {
+ headers.remove(ObjectHelper.lookupConstantFieldValue(XmlSignatureConstants.class, f.getName()));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerConfiguration.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerConfiguration.java
new file mode 100644
index 0000000..cb8fdde
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerConfiguration.java
@@ -0,0 +1,364 @@
+/**
+ * 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.camel.component.xmlsecurity.processor;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import javax.xml.crypto.AlgorithmMethod;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.xmlsecurity.api.KeyAccessor;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureProperties;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureTransform;
+
+public class XmlSignerConfiguration extends XmlSignatureConfiguration {
+
+ private KeyAccessor keyAccessor;
+
+ /**
+ * Optional canonicalization method for SignerInfo. Default value is
+ * {@link CanonicalizationMethod#INCLUSIVE}.
+ *
+ */
+ private AlgorithmMethod canonicalizationMethod = new XmlSignatureTransform(CanonicalizationMethod.INCLUSIVE);
+
+ /**
+ * Optional transform methods. Default value is
+ * {@link CanonicalizationMethod#INCLUSIVE}.
+ */
+ private List<AlgorithmMethod> transformMethods = Collections.singletonList(XmlSignatureHelper
+ .getCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE));
+
+ private String signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
+
+ /**
+ * Digest algorithm URI. Optional parameter. This digest algorithm is used
+ * for calculating the digest of the input message. If this digest algorithm
+ * is not specified then the digest algorithm is calculated from the
+ * signature algorithm. Example: "http://www.w3.org/2001/04/xmlenc#sha256"
+ */
+ private String digestAlgorithm;
+
+ private Boolean addKeyInfoReference = Boolean.TRUE;
+
+ private String prefixForXmlSignatureNamespace = "ds";
+
+ private String contentObjectId;
+
+ /**
+ * The URI of the content reference. If <code>null</code> then the URI will
+ * be set to "" in the enveloped XML signature case or set to "#[object_id]"
+ * in the enveloping XML signature case. This value can be overwritten by
+ * the header {@link XmlSignatureConstants#HEADER_CONTENT_REFERENCE_URI}.
+ */
+ private String contentReferenceUri;
+
+ /**
+ * Type of the content reference. The default value is <code>null</code>.
+ * This value can be overwritten by the header
+ * {@link XmlSignatureConstants#HEADER_CONTENT_REFERENCE_TYPE}.
+ */
+ private String contentReferenceType;
+
+ private String parentLocalName;
+
+ private String parentNamespace;
+
+ /**
+ * Indicator whether the message body contains plain text. The default value
+ * is <code>false</code>, indicating that the message body contains XML. The
+ * value can be overwritten by the header
+ * {@link XmlSignatureConstants#HEADER_MESSAGE_IS_PLAIN_TEXT}.
+ */
+ private Boolean plainText = Boolean.FALSE;
+
+ /**
+ * Encoding of the plain text. Only relevant if the message body is plain
+ * text (see parameter {@link #plainText}. Default value is "UTF-8".
+ *
+ */
+ private String plainTextEncoding = "UTF-8";
+
+ private XmlSignatureProperties properties;
+
+ /* references that should be resolved when the context changes */
+ private String keyAccessorName;
+ private String canonicalizationMethodName;
+ private String transformMethodsName;
+ private String propertiesName;
+
+ public XmlSignerConfiguration() {
+ super();
+ }
+
+ public XmlSignerConfiguration copy() {
+ try {
+ return (XmlSignerConfiguration) clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeCamelException(e);
+ }
+ }
+
+ @Override
+ public void setCamelContext(CamelContext camelContext) {
+ super.setCamelContext(camelContext);
+ // try to retrieve the references once the context is available.
+ setTransformMethods(transformMethodsName);
+ setCanonicalizationMethod(canonicalizationMethodName);
+ setKeyAccessor(keyAccessorName);
+ setProperties(propertiesName);
+ }
+
+ public KeyAccessor getKeyAccessor() {
+ return keyAccessor;
+ }
+
+ public void setKeyAccessor(KeyAccessor keyAccessor) {
+ this.keyAccessor = keyAccessor;
+ }
+
+ /**
+ * Sets the reference name for a KeyAccessor that can be found in the
+ * registry.
+ */
+ public void setKeyAccessor(String keyAccessorName) {
+ if (getCamelContext() != null && keyAccessorName != null) {
+ KeyAccessor accessor = getCamelContext().getRegistry().lookupByNameAndType(keyAccessorName, KeyAccessor.class);
+ if (accessor != null) {
+ setKeyAccessor(accessor);
+ }
+ }
+ if (keyAccessorName != null) {
+ this.keyAccessorName = keyAccessorName;
+ }
+ }
+
+ public AlgorithmMethod getCanonicalizationMethod() {
+ return canonicalizationMethod;
+ }
+
+ public void setCanonicalizationMethod(AlgorithmMethod canonicalizationMethod) {
+ this.canonicalizationMethod = canonicalizationMethod;
+ }
+
+ /**
+ * Sets the reference name for a AlgorithmMethod that can be found in the
+ * registry.
+ */
+ public void setCanonicalizationMethod(String canonicalizationMethodName) {
+ if (getCamelContext() != null && canonicalizationMethodName != null) {
+ AlgorithmMethod method = getCamelContext().getRegistry().lookupByNameAndType(canonicalizationMethodName, AlgorithmMethod.class);
+ if (method != null) {
+ setCanonicalizationMethod(method);
+ }
+ }
+ if (canonicalizationMethodName != null) {
+ this.canonicalizationMethodName = canonicalizationMethodName;
+ }
+ }
+
+ public List<AlgorithmMethod> getTransformMethods() {
+ return transformMethods;
+ }
+
+ public void setTransformMethods(List<AlgorithmMethod> transformMethods) {
+ this.transformMethods = transformMethods;
+ }
+
+ /**
+ * Sets the reference name for a List<AlgorithmMethod> that can be found in
+ * the registry.
+ */
+ public void setTransformMethods(String transformMethodsName) {
+ if (getCamelContext() != null && transformMethodsName != null) {
+ @SuppressWarnings("unchecked")
+ List<AlgorithmMethod> list = getCamelContext().getRegistry().lookupByNameAndType(transformMethodsName, List.class);
+ if (list != null) {
+ setTransformMethods(list);
+ }
+ }
+ if (transformMethodsName != null) {
+ this.transformMethodsName = transformMethodsName;
+ }
+ }
+
+ public String getSignatureAlgorithm() {
+ return signatureAlgorithm;
+ }
+
+ /**
+ * Signature algorithm. Default value is
+ * "http://www.w3.org/2000/09/xmldsig#rsa-sha1".
+ *
+ * @param signatureAlgorithm
+ * signature algorithm
+ */
+ public void setSignatureAlgorithm(String signatureAlgorithm) {
+ this.signatureAlgorithm = signatureAlgorithm;
+ }
+
+ public String getDigestAlgorithm() {
+ return digestAlgorithm;
+ }
+
+ public void setDigestAlgorithm(String digestAlgorithm) {
+ this.digestAlgorithm = digestAlgorithm;
+ }
+
+ public Boolean getAddKeyInfoReference() {
+ return addKeyInfoReference;
+ }
+
+ /**
+ * In order to protect the KeyInfo element from tampering you can add a
+ * reference to the signed info element so that it is protected via the
+ * signature value. The default value is <tt>true</tt>.
+ * <p>
+ * Only relevant when a KeyInfo is returned by {@link KeyAccessor}. and
+ * {@link KeyInfo#getId()} is not <code>null</code>.
+ *
+ * @param addKeyInfoReference
+ * boolean value
+ */
+ public void setAddKeyInfoReference(Boolean addKeyInfoReference) {
+ this.addKeyInfoReference = addKeyInfoReference;
+ }
+
+ public String getPrefixForXmlSignatureNamespace() {
+ return prefixForXmlSignatureNamespace;
+ }
+
+ /**
+ * Namespace prefix for the XML signature namespace
+ * "http://www.w3.org/2000/09/xmldsig#". Default value is "ds".
+ *
+ * If <code>null</code> or an empty value is set then no prefix is used for
+ * the XML signature namespace.
+ * <p>
+ * See best practice
+ * http://www.w3.org/TR/xmldsig-bestpractices/#signing-xml-
+ * without-namespaces
+ *
+ * @param prefixForXmlSignatureNamespace
+ * prefix
+ */
+ public void setPrefixForXmlSignatureNamespace(String prefixForXmlSignatureNamespace) {
+ this.prefixForXmlSignatureNamespace = prefixForXmlSignatureNamespace;
+ }
+
+ public String getParentLocalName() {
+ return parentLocalName;
+ }
+
+ public String getContentObjectId() {
+ if (contentObjectId == null) {
+ contentObjectId = "_" + UUID.randomUUID().toString();
+ }
+ return contentObjectId;
+ }
+
+ /**
+ * Local name of the parent element to which the XML signature element will
+ * be added. Only relevant for enveloped XML signature. Default value is
+ * <code>null</code>. The value must be <code>null</code> for enveloping XML
+ * signature.
+ *
+ * @param parentLocalName
+ * local name
+ */
+ public void setParentLocalName(String parentLocalName) {
+ this.parentLocalName = parentLocalName;
+ }
+
+ public String getParentNamespace() {
+ return parentNamespace;
+ }
+
+ /**
+ * Namespace of the parent element to which the XML signature element will
+ * be added. See {@link #setEnvelopedParentLocalName(String)}.
+ *
+ * @param parentNamespace
+ */
+ public void setParentNamespace(String parentNamespace) {
+ this.parentNamespace = parentNamespace;
+ }
+
+ public String getContentReferenceUri() {
+ return contentReferenceUri;
+ }
+
+ public void setContentReferenceUri(String referenceUri) {
+ this.contentReferenceUri = referenceUri;
+ }
+
+ public String getContentReferenceType() {
+ return contentReferenceType;
+ }
+
+ public void setContentReferenceType(String referenceType) {
+ this.contentReferenceType = referenceType;
+ }
+
+ public Boolean getPlainText() {
+ return plainText;
+ }
+
+ public void setPlainText(Boolean plainText) {
+ this.plainText = plainText;
+ }
+
+ public String getPlainTextEncoding() {
+ return plainTextEncoding;
+ }
+
+ public void setPlainTextEncoding(String plainTextEncoding) {
+ this.plainTextEncoding = plainTextEncoding;
+ }
+
+ public XmlSignatureProperties getProperties() {
+ return properties;
+ }
+
+ public void setProperties(XmlSignatureProperties properties) {
+ this.properties = properties;
+ }
+
+ /**
+ * Sets the reference name for a XmlSignatureProperties that can be found in
+ * the registry.
+ */
+ public void setProperties(String propertiesName) {
+ if (getCamelContext() != null && propertiesName != null) {
+ XmlSignatureProperties props = getCamelContext().getRegistry().lookupByNameAndType(propertiesName, XmlSignatureProperties.class);
+ if (props != null) {
+ setProperties(props);
+ }
+ }
+ if (propertiesName != null) {
+ this.propertiesName = propertiesName;
+ }
+ }
+
+}
[6/6] git commit: CAMEL-6339 Applied the patch with thanks to Franz
Posted by ni...@apache.org.
CAMEL-6339 Applied the patch with thanks to Franz
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/a8265a2c
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/a8265a2c
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/a8265a2c
Branch: refs/heads/master
Commit: a8265a2cfba7a7bd5a0d42301ba7aef371c23330
Parents: db9fb33
Author: Willem Jiang <ni...@apache.org>
Authored: Tue Aug 27 18:00:21 2013 +0800
Committer: Willem Jiang <ni...@apache.org>
Committed: Tue Aug 27 21:51:44 2013 +0800
----------------------------------------------------------------------
components/camel-xmlsecurity/pom.xml | 12 +-
.../component/xmlsecurity/SantuarioUtil.java | 80 ++
.../xmlsecurity/XmlSignatureComponent.java | 104 ++
.../xmlsecurity/XmlSignatureEndpoint.java | 97 ++
.../xmlsecurity/XmlSignatureProducer.java | 46 +
.../xmlsecurity/XmlSignerEndpoint.java | 163 +++
.../xmlsecurity/XmlVerifierEndpoint.java | 107 ++
.../xmlsecurity/api/DefaultKeyAccessor.java | 97 ++
.../xmlsecurity/api/DefaultKeySelector.java | 131 +++
.../api/DefaultValidationFailedHandler.java | 88 ++
.../api/DefaultXmlSignature2Message.java | 523 +++++++++
.../component/xmlsecurity/api/KeyAccessor.java | 73 ++
.../xmlsecurity/api/KeyStoreAndAlias.java | 53 +
.../api/ValidationFailedHandler.java | 94 ++
.../xmlsecurity/api/XmlSignature2Message.java | 91 ++
.../xmlsecurity/api/XmlSignatureChecker.java | 73 ++
.../xmlsecurity/api/XmlSignatureConstants.java | 65 +
.../xmlsecurity/api/XmlSignatureException.java | 45 +
.../api/XmlSignatureFormatException.java | 38 +
.../xmlsecurity/api/XmlSignatureHelper.java | 476 ++++++++
...XmlSignatureInvalidContentHashException.java | 38 +
.../api/XmlSignatureInvalidException.java | 35 +
.../api/XmlSignatureInvalidKeyException.java | 37 +
.../api/XmlSignatureInvalidValueException.java | 37 +
.../api/XmlSignatureNoKeyException.java | 45 +
.../xmlsecurity/api/XmlSignatureProperties.java | 119 ++
.../xmlsecurity/api/XmlSignatureTransform.java | 58 +
.../processor/XmlSignatureConfiguration.java | 164 +++
.../processor/XmlSignatureProcessor.java | 82 ++
.../processor/XmlSignerConfiguration.java | 364 ++++++
.../processor/XmlSignerProcessor.java | 680 +++++++++++
.../processor/XmlVerifierConfiguration.java | 232 ++++
.../processor/XmlVerifierProcessor.java | 324 +++++
.../org/apache/camel/component/xmlsecurity | 18 +
.../xmlsecurity/SpringXmlSignatureTest.java | 64 +
.../component/xmlsecurity/XmlSignatureTest.java | 1111 ++++++++++++++++++
.../util/EnvelopingXmlSignatureChecker.java | 52 +
.../util/SameDocumentUriDereferencer.java | 72 ++
.../xmlsecurity/util/TestKeystore.java | 65 +
.../xmlsecurity/util/TimestampProperty.java | 68 ++
...tionFailedHandlerIgnoreManifestFailures.java | 38 +
...re2Message2MessageWithTimestampProperty.java | 45 +
.../component/xmlsecurity/ExampleDetached.xml | 4 +
.../xmlsecurity/ExampleEnvelopedXmlSig.xml | 4 +
.../xmlsecurity/ExampleEnvelopingDigSig.xml | 4 +
...ingDigSigWithSeveralElementsWithNameRoot.xml | 4 +
.../ManifestTest_TamperedContent.xml | 4 +
.../xmlsecurity/SpringXmlSignatureTests.xml | 389 ++++++
.../camel/component/xmlsecurity/keystore.jks | Bin 0 -> 2343 bytes
.../camel/component/xmlsecurity/testFile.txt | 1 +
.../xmlsecurity/xmldsig-core-schema.dtd | 171 +++
.../camel/component/xmlsecurity/xslt_test.xsl | 13 +
52 files changed, 6795 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/pom.xml b/components/camel-xmlsecurity/pom.xml
index d3749d1..05bfa9a 100755
--- a/components/camel-xmlsecurity/pom.xml
+++ b/components/camel-xmlsecurity/pom.xml
@@ -28,11 +28,17 @@
<artifactId>camel-xmlsecurity</artifactId>
<packaging>bundle</packaging>
<name>Camel :: XML Security</name>
- <description>Camel Partial XML Encryption/Decryption support</description>
+ <description>Camel Partial XML Encryption/Decryption and XML Signature support</description>
<properties>
- <camel.osgi.export.pkg>org.apache.camel.dataformat.xmlsecurity.*</camel.osgi.export.pkg>
- <camel.osgi.export.service>org.apache.camel.spi.DataFormatResolver;dataformat=secureXML</camel.osgi.export.service>
+ <camel.osgi.export.pkg>
+ org.apache.camel.component.xmlsecurity.*;${camel.osgi.version},
+ org.apache.camel.dataformat.xmlsecurity.*
+ </camel.osgi.export.pkg>
+ <camel.osgi.export.service>
+ org.apache.camel.spi.ComponentResolver;component=xmlsecurity,
+ org.apache.camel.spi.DataFormatResolver;dataformat=secureXML
+ </camel.osgi.export.service>
</properties>
<dependencies>
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/SantuarioUtil.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/SantuarioUtil.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/SantuarioUtil.java
new file mode 100644
index 0000000..89ec52d
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/SantuarioUtil.java
@@ -0,0 +1,80 @@
+/**
+ * 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.camel.component.xmlsecurity;
+
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.Provider;
+import java.security.Security;
+
+import org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI;
+import org.apache.xml.security.utils.XMLUtils;
+
+
+public final class SantuarioUtil {
+
+ public static void initializeSantuario() {
+ // Set ignoreLineBreaks to true
+ boolean wasSet = false;
+ try {
+ // Don't override if it was set explicitly
+ wasSet = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+ public Boolean run() {
+ String lineBreakPropName = "org.apache.xml.security.ignoreLineBreaks";
+ if (System.getProperty(lineBreakPropName) == null) {
+ System.setProperty(lineBreakPropName, "true");
+ return false;
+ }
+ return true;
+ }
+ });
+ } catch (Throwable t) { //NOPMD
+ //ignore
+ }
+ org.apache.xml.security.Init.init();
+ if (!wasSet) {
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() {
+ public Boolean run() throws Exception {
+ Field f = XMLUtils.class.getDeclaredField("ignoreLineBreaks");
+ f.setAccessible(true);
+ f.set(null, Boolean.TRUE);
+ return false;
+ }
+ });
+ } catch (Throwable t) { //NOPMD
+ //ignore
+ }
+ }
+ }
+
+ public static void addSantuarioJSR105Provider() {
+ AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+ public Boolean run() {
+ String providerName = "ApacheXMLDSig";
+ Provider currentProvider = Security.getProvider(providerName);
+ if (currentProvider == null) {
+ Security.addProvider(new XMLDSigRI());
+ }
+ return true;
+ }
+ });
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureComponent.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureComponent.java
new file mode 100644
index 0000000..886a695
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureComponent.java
@@ -0,0 +1,104 @@
+/**
+ * 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.camel.component.xmlsecurity;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.component.xmlsecurity.processor.XmlSignerConfiguration;
+import org.apache.camel.component.xmlsecurity.processor.XmlVerifierConfiguration;
+import org.apache.camel.impl.DefaultComponent;
+import org.apache.camel.util.ObjectHelper;
+
+
+public class XmlSignatureComponent extends DefaultComponent {
+
+ private XmlSignerConfiguration signerConfiguration;
+
+ private XmlVerifierConfiguration verifierConfiguration;
+
+ public XmlSignatureComponent() {
+ }
+
+ public XmlSignatureComponent(CamelContext context) {
+ super(context);
+ }
+
+ @Override
+ protected Endpoint createEndpoint(String uri, String remaining,
+ Map<String, Object> parameters) throws Exception {
+ ObjectHelper.notNull(getCamelContext(), "CamelContext");
+
+ String scheme;
+ try {
+ scheme = new URI(remaining).getScheme();
+ } catch (Exception e) {
+ throw new MalformedURLException(
+ String.format(
+ "An invalid xmlsecurity uri was provided '%s'."
+ + " Check the uri matches the format xmlsecurity:sign://<name> or xmlsecurity:verify://<name>",
+ uri
+ )
+ );
+ }
+ XmlSignatureEndpoint endpoint;
+ if ("sign".equals(scheme)) {
+ XmlSignerConfiguration config = getSignerConfiguration().copy();
+ endpoint = new XmlSignerEndpoint(uri, this, config);
+ } else if ("verify".equals(scheme)) {
+ XmlVerifierConfiguration config = getVerifierConfiguration().copy();
+ endpoint = new XmlVerifierEndpoint(uri, this, config);
+ } else {
+ throw new IllegalStateException(
+ String.format(
+ "Endpoint uri '%s'" + " is wrong configured. Operation '%s'"
+ + " is not supported. Supported operations are: sign, verify",
+ uri, scheme
+ )
+ );
+ }
+ setProperties(endpoint.getConfiguration(), parameters);
+ endpoint.getConfiguration().setCamelContext(getCamelContext());
+ return endpoint;
+ }
+
+ public XmlSignerConfiguration getSignerConfiguration() {
+ if (signerConfiguration == null) {
+ signerConfiguration = new XmlSignerConfiguration();
+ }
+ return signerConfiguration;
+ }
+
+ public void setSignerConfiguration(XmlSignerConfiguration signerConfiguration) {
+ this.signerConfiguration = signerConfiguration;
+ }
+
+ public XmlVerifierConfiguration getVerifierConfiguration() {
+ if (verifierConfiguration == null) {
+ verifierConfiguration = new XmlVerifierConfiguration();
+ }
+ return verifierConfiguration;
+ }
+
+ public void setVerifierConfiguration(XmlVerifierConfiguration verifierConfiguration) {
+ this.verifierConfiguration = verifierConfiguration;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureEndpoint.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureEndpoint.java
new file mode 100644
index 0000000..5b35139
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureEndpoint.java
@@ -0,0 +1,97 @@
+/**
+ * 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.camel.component.xmlsecurity;
+
+import java.util.Map;
+
+import javax.xml.crypto.URIDereferencer;
+
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.component.xmlsecurity.processor.XmlSignatureConfiguration;
+import org.apache.camel.impl.DefaultEndpoint;
+
+public abstract class XmlSignatureEndpoint extends DefaultEndpoint {
+
+ public XmlSignatureEndpoint(String uri, XmlSignatureComponent component) {
+ super(uri, component);
+ }
+
+ @Override
+ public Producer createProducer() {
+ return new XmlSignatureProducer(this, createProcessor());
+ }
+
+ abstract Processor createProcessor();
+
+ @Override
+ public Consumer createConsumer(Processor processor) {
+ throw new UnsupportedOperationException("XML Signature endpoints are not meant to be consumed from.");
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public Object getManagedObject(XmlSignatureEndpoint endpoint) {
+ return this;
+ }
+
+ public abstract XmlSignatureConfiguration getConfiguration();
+
+ public URIDereferencer getUriDereferencer() {
+ return getConfiguration().getUriDereferencer();
+ }
+
+ public void setUriDereferencer(URIDereferencer uriDereferencer) {
+ getConfiguration().setUriDereferencer(uriDereferencer);
+ }
+
+ public String getBaseUri() {
+ return getConfiguration().getBaseUri();
+ }
+
+ public void setBaseUri(String baseUri) {
+ getConfiguration().setBaseUri(baseUri);
+ }
+
+ public Map<String, ? extends Object> getCryptoContextProperties() {
+ return getConfiguration().getCryptoContextProperties();
+ }
+
+ public void setCryptoContextProperties(Map<String, ? extends Object> cryptoContextProperties) {
+ getConfiguration().setCryptoContextProperties(cryptoContextProperties);
+ }
+
+ public Boolean getDisallowDoctypeDecl() {
+ return getConfiguration().getDisallowDoctypeDecl();
+ }
+
+ public void setDisallowDoctypeDecl(Boolean disallowDoctypeDecl) {
+ getConfiguration().setDisallowDoctypeDecl(disallowDoctypeDecl);
+ }
+
+ public Boolean getOmitXmlDeclaration() {
+ return getConfiguration().getOmitXmlDeclaration();
+ }
+
+ public void setOmitXmlDeclaration(Boolean omitXmlDeclaration) {
+ getConfiguration().setOmitXmlDeclaration(omitXmlDeclaration);
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureProducer.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureProducer.java
new file mode 100644
index 0000000..74dede1
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignatureProducer.java
@@ -0,0 +1,46 @@
+/**
+ * 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.camel.component.xmlsecurity;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.impl.DefaultProducer;
+
+/**
+ *
+ */
+public class XmlSignatureProducer extends DefaultProducer {
+
+ private Processor processor;
+
+ public XmlSignatureProducer(Endpoint endpoint, Processor processor) {
+ super(endpoint);
+ this.processor = processor;
+ }
+
+ @Override
+ public void process(Exchange exchange) throws Exception { //NOPMD a processor can throw any exception
+ try {
+ processor.process(exchange);
+ } catch (Exception e) {
+ exchange.setException(e);
+ }
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignerEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignerEndpoint.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignerEndpoint.java
new file mode 100644
index 0000000..f35d512
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignerEndpoint.java
@@ -0,0 +1,163 @@
+/**
+ * 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.camel.component.xmlsecurity;
+
+import java.util.List;
+
+import javax.xml.crypto.AlgorithmMethod;
+
+import org.apache.camel.Processor;
+import org.apache.camel.component.xmlsecurity.api.KeyAccessor;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureProperties;
+import org.apache.camel.component.xmlsecurity.processor.XmlSignerConfiguration;
+import org.apache.camel.component.xmlsecurity.processor.XmlSignerProcessor;
+
+public class XmlSignerEndpoint extends XmlSignatureEndpoint {
+
+ private XmlSignerConfiguration configuration;
+
+ public XmlSignerEndpoint(String uri, XmlSignatureComponent component, XmlSignerConfiguration configuration) {
+ super(uri, component);
+ this.configuration = configuration;
+ }
+
+ @Override
+ Processor createProcessor() {
+ return new XmlSignerProcessor(getConfiguration());
+ }
+
+ public XmlSignerConfiguration getConfiguration() {
+ return configuration;
+ }
+
+ public void setConfiguration(XmlSignerConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ public KeyAccessor getKeyAccessor() {
+ return getConfiguration().getKeyAccessor();
+ }
+
+ public void setKeyAccessor(KeyAccessor keyAccessor) {
+ getConfiguration().setKeyAccessor(keyAccessor);
+ }
+
+ public String getSignatureAlgorithm() {
+ return getConfiguration().getSignatureAlgorithm();
+ }
+
+ public void setSignatureAlgorithm(String signatureAlgorithm) {
+ getConfiguration().setSignatureAlgorithm(signatureAlgorithm);
+ }
+
+ public String getDigestAlgorithm() {
+ return getConfiguration().getDigestAlgorithm();
+ }
+
+ public void setDigestAlgorithm(String digestAlgorithm) {
+ getConfiguration().setDigestAlgorithm(digestAlgorithm);
+ }
+
+ public AlgorithmMethod getCanonicalizationMethod() {
+ return getConfiguration().getCanonicalizationMethod();
+ }
+
+ public void setCanonicalizationMethod(AlgorithmMethod canonicalizationMethod) {
+ getConfiguration().setCanonicalizationMethod(canonicalizationMethod);
+ }
+
+ public List<AlgorithmMethod> getTransformMethods() {
+ return getConfiguration().getTransformMethods();
+ }
+
+ public void setTransformMethods(List<AlgorithmMethod> transformMethods) {
+ getConfiguration().setTransformMethods(transformMethods);
+ }
+
+ public Boolean getAddKeyInfoReference() {
+ return getConfiguration().getAddKeyInfoReference();
+ }
+
+ public void setAddKeyInfoReference(Boolean addKeyInfoReference) {
+ getConfiguration().setAddKeyInfoReference(addKeyInfoReference);
+ }
+
+ public String getPrefixForXmlSignatureNamespace() {
+ return getConfiguration().getPrefixForXmlSignatureNamespace();
+ }
+
+ public void setPrefixForXmlSignatureNamespace(String prefixForXmlSignatureNamespace) {
+ getConfiguration().setPrefixForXmlSignatureNamespace(prefixForXmlSignatureNamespace);
+ }
+
+ public String getParentLocalName() {
+ return getConfiguration().getParentLocalName();
+ }
+
+ public void setParentLocalName(String parentLocalName) {
+ getConfiguration().setParentLocalName(parentLocalName);
+ }
+
+ public String getParentNamespace() {
+ return getConfiguration().getParentNamespace();
+ }
+
+ public void setParentNamespace(String parentNamespace) {
+ getConfiguration().setParentNamespace(parentNamespace);
+ }
+
+ public String getContentReferenceUri() {
+ return getConfiguration().getContentReferenceUri();
+ }
+
+ public void setContentReferenceUri(String referenceUri) {
+ getConfiguration().setContentReferenceUri(referenceUri);
+ }
+
+ public String getContentReferenceType() {
+ return getConfiguration().getContentReferenceType();
+ }
+
+ public void setContentReferenceType(String referenceType) {
+ getConfiguration().setContentReferenceType(referenceType);
+ }
+
+ public Boolean getPlainText() {
+ return getConfiguration().getPlainText();
+ }
+
+ public void setPlainText(Boolean plainText) {
+ getConfiguration().setPlainText(plainText);
+ }
+
+ public String getMessageEncoding() {
+ return getConfiguration().getPlainTextEncoding();
+ }
+
+ public void setMessageEncoding(String messageEncoding) {
+ getConfiguration().setPlainTextEncoding(messageEncoding);
+ }
+
+ public XmlSignatureProperties getProperties() {
+ return getConfiguration().getProperties();
+ }
+
+ public void setProperties(XmlSignatureProperties properties) {
+ getConfiguration().setProperties(properties);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
new file mode 100644
index 0000000..2f2ee7f
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
@@ -0,0 +1,107 @@
+/**
+ * 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.camel.component.xmlsecurity;
+
+import javax.xml.crypto.KeySelector;
+
+import org.apache.camel.Processor;
+import org.apache.camel.component.xmlsecurity.api.XmlSignature2Message;
+import org.apache.camel.component.xmlsecurity.api.ValidationFailedHandler;
+import org.apache.camel.component.xmlsecurity.api.XmlSignatureChecker;
+import org.apache.camel.component.xmlsecurity.processor.XmlVerifierConfiguration;
+import org.apache.camel.component.xmlsecurity.processor.XmlVerifierProcessor;
+
+public class XmlVerifierEndpoint extends XmlSignatureEndpoint {
+
+ private XmlVerifierConfiguration configuration;
+
+ public XmlVerifierEndpoint(String uri, XmlSignatureComponent component,
+ XmlVerifierConfiguration configuration) {
+ super(uri, component);
+ this.configuration = configuration;
+ }
+
+ @Override
+ Processor createProcessor() {
+ return new XmlVerifierProcessor(getConfiguration());
+ }
+
+ public XmlVerifierConfiguration getConfiguration() {
+ return configuration;
+ }
+
+ public void setConfiguration(XmlVerifierConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ public void setKeySelector(KeySelector keySelector) {
+ getConfiguration().setKeySelector(keySelector);
+ }
+
+ public KeySelector getKeySelector() {
+ return getConfiguration().getKeySelector();
+ }
+
+ public XmlSignatureChecker getXmlSignatureChecker() {
+ return getConfiguration().getXmlSignatureChecker();
+ }
+
+ public void setXmlSignatureChecker(XmlSignatureChecker xmlSignatureChecker) {
+ getConfiguration().setXmlSignatureChecker(xmlSignatureChecker);
+ }
+
+ public XmlSignature2Message getXmlSignature2Message() {
+ return getConfiguration().getXmlSignature2Message();
+ }
+
+ public void setXmlSignature2Message(XmlSignature2Message xmlSignature2Message) {
+ getConfiguration().setXmlSignature2Message(xmlSignature2Message);
+ }
+
+ public ValidationFailedHandler getValidationFailedHandler() {
+ return getConfiguration().getValidationFailedHandler();
+ }
+
+ public void setValidationFailedHandler(ValidationFailedHandler validationFailedHandler) {
+ getConfiguration().setValidationFailedHandler(validationFailedHandler);
+ }
+
+ public Object getOutputNodeSearch() {
+ return getConfiguration().getOutputNodeSearch();
+ }
+
+ public void setOutputNodeSearch(Object outputNodeSearch) {
+ getConfiguration().setOutputNodeSearch(outputNodeSearch);
+ }
+
+ public String getOutputNodeSearchType() {
+ return getConfiguration().getOutputNodeSearchType();
+ }
+
+ public void setOutputNodeSearchType(String outputNodeSearchType) {
+ getConfiguration().setOutputNodeSearchType(outputNodeSearchType);
+ }
+
+ public Boolean getRemoveSignatureElements() {
+ return getConfiguration().getRemoveSignatureElements();
+ }
+
+ public void setRemoveSignatureElements(Boolean removeSignatureElements) {
+ getConfiguration().setRemoveSignatureElements(removeSignatureElements);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeyAccessor.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeyAccessor.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeyAccessor.java
new file mode 100644
index 0000000..5142a9e
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeyAccessor.java
@@ -0,0 +1,97 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.UUID;
+
+import javax.xml.crypto.KeySelector;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import javax.xml.crypto.dsig.keyinfo.X509Data;
+
+import org.apache.camel.Message;
+import org.w3c.dom.Node;
+
+/**
+ * Accesses the private key from a key-store and returns a KeyInfo which
+ * contains the X.509 certificate chain corresponding to the private key.
+ */
+public class DefaultKeyAccessor extends DefaultKeySelector implements KeyAccessor {
+
+ private String provider;
+
+ public DefaultKeyAccessor() {
+
+ }
+
+ public String getProvider() {
+ return provider;
+ }
+
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
+
+ @Override
+ public KeySelector getKeySelector(Message message) throws Exception {
+ return this;
+ }
+
+ @Override
+ public KeyInfo getKeyInfo(Message message, Node messageBody, KeyInfoFactory factory) throws Exception {
+ return createKeyInfo(factory);
+ }
+
+ private KeyInfo createKeyInfo(KeyInfoFactory kif) throws Exception {
+
+ X509Certificate[] chain = getCertificateChain();
+ if (chain == null) {
+ return null;
+ }
+ X509Data x509D = kif.newX509Data(Arrays.asList(chain));
+ return kif.newKeyInfo(Collections.singletonList(x509D), "_" + UUID.randomUUID().toString());
+ }
+
+ private X509Certificate[] getCertificateChain() throws Exception {
+ KeyStore keystore = getKeyStore();
+ if (keystore == null) {
+ return null;
+ }
+ String alias = getAlias();
+ if (alias == null) {
+ return null;
+ }
+ Certificate[] certs = keystore.getCertificateChain(alias);
+ if (certs == null) {
+ return null;
+ }
+ ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>(certs.length);
+ for (Certificate cert : certs) {
+ if (cert instanceof X509Certificate) {
+ certList.add((X509Certificate) cert);
+ }
+ }
+ return certList.toArray(new X509Certificate[certList.size()]);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeySelector.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeySelector.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeySelector.java
new file mode 100644
index 0000000..1999e40
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultKeySelector.java
@@ -0,0 +1,131 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+
+import javax.xml.crypto.AlgorithmMethod;
+import javax.xml.crypto.KeySelector;
+import javax.xml.crypto.KeySelectorException;
+import javax.xml.crypto.KeySelectorResult;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+
+/**
+ * Default implementation for the key selector. The key is read from a key-store
+ * for a given alias. Depending on the purpose a private or public key is
+ * returned.
+ */
+public class DefaultKeySelector extends KeySelector {
+
+ private final KeyStoreAndAlias keyStoreAndAlias = new KeyStoreAndAlias();
+
+ private KeySelectorResult nullKeyResult;
+
+ public void setKeyStore(KeyStore keyStore) {
+ keyStoreAndAlias.setKeyStore(keyStore);
+ }
+
+ public void setAlias(String alias) {
+ keyStoreAndAlias.setAlias(alias);
+ }
+
+ public void setPassword(String password) {
+ if (password == null) {
+ keyStoreAndAlias.setPassword(null);
+ } else {
+ keyStoreAndAlias.setPassword(password.toCharArray());
+ }
+ }
+
+ public void setPassword(char[] password) {
+ keyStoreAndAlias.setPassword(password);
+ }
+
+ public KeySelectorResult select(KeyInfo keyInfo, KeySelector.Purpose purpose, AlgorithmMethod method, XMLCryptoContext context)
+ throws KeySelectorException {
+ if (keyStoreAndAlias.getKeyStore() == null) {
+ return getNullKeyResult();
+ }
+ if (keyStoreAndAlias.getAlias() == null) {
+ return getNullKeyResult();
+ }
+ if (KeySelector.Purpose.VERIFY.equals(purpose)) {
+ Certificate cert;
+ try {
+ cert = keyStoreAndAlias.getKeyStore().getCertificate(keyStoreAndAlias.getAlias());
+ } catch (KeyStoreException e) {
+ throw new KeySelectorException(e);
+ }
+ if (cert == null) {
+ return getNullKeyResult();
+ }
+ final Key key = cert.getPublicKey();
+ return getKeySelectorResult(key);
+ } else if (KeySelector.Purpose.SIGN.equals(purpose)) {
+ if (keyStoreAndAlias.getPassword() == null) {
+ return getNullKeyResult();
+ }
+ Key key;
+ try {
+ key = keyStoreAndAlias.getKeyStore().getKey(keyStoreAndAlias.getAlias(), keyStoreAndAlias.getPassword());
+ } catch (UnrecoverableKeyException e) {
+ throw new KeySelectorException(e);
+ } catch (KeyStoreException e) {
+ throw new KeySelectorException(e);
+ } catch (NoSuchAlgorithmException e) {
+ throw new KeySelectorException(e);
+ }
+ return getKeySelectorResult(key);
+ } else {
+ throw new IllegalStateException("Purpose " + purpose + " not supported");
+ }
+ }
+
+ KeyStore getKeyStore() {
+ return keyStoreAndAlias.getKeyStore();
+ }
+
+ String getAlias() {
+ return keyStoreAndAlias.getAlias();
+ }
+
+ private KeySelectorResult getKeySelectorResult(final Key key) {
+ return new KeySelectorResult() {
+ public Key getKey() {
+ return key;
+ }
+ };
+ }
+
+ private KeySelectorResult getNullKeyResult() {
+ if (nullKeyResult == null) {
+ nullKeyResult = new KeySelectorResult() {
+ public Key getKey() {
+ return null;
+ }
+ };
+ }
+ return nullKeyResult;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultValidationFailedHandler.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultValidationFailedHandler.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultValidationFailedHandler.java
new file mode 100644
index 0000000..abb8585
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultValidationFailedHandler.java
@@ -0,0 +1,88 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import java.security.InvalidKeyException;
+
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLSignature.SignatureValue;
+
+/**
+ * Interrupts the validation by throwing an exception as soon as a validation
+ * failure occurs and gives specific error messages.
+ */
+public class DefaultValidationFailedHandler implements ValidationFailedHandler {
+
+ private StringBuilder error;
+
+ @Override
+ public Exception onXMLSignatureException(XMLSignatureException se) {
+ if (se.getCause() instanceof InvalidKeyException) {
+ return new XmlSignatureInvalidKeyException(se);
+ } else {
+ return new XmlSignatureException(se);
+ }
+ }
+
+ @Override
+ public void start() {
+ error = new StringBuilder();
+ error.append("Signature validation failed. ");
+ }
+
+ @Override
+ public void signatureValueValidationFailed(SignatureValue value) throws Exception { //NOPMD
+ error.append("The signature value could not be validated by the public key. Either the message has been tampered or the public key is not correct.");
+ throw new XmlSignatureInvalidValueException(error.toString());
+ }
+
+ @Override
+ public void referenceValidationFailed(Reference ref) throws Exception { //NOPMD
+ error.append(String
+ .format("The calculated digest value of the document %s is not equal to the value specified in the XML signature. The document may have been tampered.",
+ getReferenceUriOrId(ref)));
+ throw new XmlSignatureInvalidContentHashException(error.toString());
+ }
+
+ @Override
+ public void manifestReferenceValidationFailed(Reference ref) throws Exception { //NOPMD
+ error.append(String
+ .format("The calculated digest value of the manifest %s is not equal to the value specified in the XML signature. The document may have been tampered.",
+ getReferenceUriOrId(ref)));
+ throw new XmlSignatureInvalidContentHashException(error.toString());
+ }
+
+ @Override
+ public void end() throws Exception { //NOPMD
+ error = null;
+ }
+
+ private String getReferenceUriOrId(Reference ref) {
+ String docId = ref.getURI();
+ if (docId == null) {
+ docId = ref.getId();
+ }
+ return docId;
+ }
+
+ @Override
+ public boolean ignoreCoreValidationFailure() throws Exception { //NOPMD
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultXmlSignature2Message.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultXmlSignature2Message.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultXmlSignature2Message.java
new file mode 100644
index 0000000..095487f
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/DefaultXmlSignature2Message.java
@@ -0,0 +1,523 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMStructure;
+import javax.xml.crypto.dsig.Manifest;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.spec.XPathFilterParameterSpec;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+
+import org.apache.camel.Message;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Maps the XML signature to a camel message. A output node is determined from
+ * the XML signature document via a node search and then serialized and set to
+ * the output message body.
+ * <p>
+ * There are three output node search types supported: "Default", "ElementName",
+ * and "XPath". All these search types support enveloped XML signature or
+ * enveloping XML signature.
+ * <p>
+ * <ul>
+ * <li>The "ElementName" search uses the local name and namespace specified in
+ * the search value to determine the output element from the XML signature
+ * document. With the input parameter 'RemoveSignatureElements", you can specify
+ * whether the signature elements should be removed from the resulting output
+ * document. This flag shall be used for enveloped XML signatures.
+ * <li>The "XPath" search uses an XPath expression to evaluate the output node.
+ * In this case the output node can be of type Element, TextNode, or Document.
+ * With the input parameter 'RemoveSignatureElements", you can specify whether
+ * the signature elements should be removed from the resulting output document.
+ * This flag shall be used for enveloped XML signatures.
+ * <li>The "Default" search is explained in more detail below.
+ * </ul>
+ * <p>
+ * Default Output Node Search:
+ * <ul>
+ * In the enveloped XML signature case, the XML document without the signature
+ * part is returned in the message body.
+ * <p>
+ * In the enveloping XML signature case, the message body is determined from a
+ * referenced Object element in the following way:
+ * <ul>
+ * <li>Only same document references are taken into account (URI must start with
+ * '#').
+ * <li>Also indirect same document references to an object via manifest are
+ * taken into account.
+ * <li>The resulting number of object references must be 1.
+ * <li>The referenced object must contain exactly 1 {@link DOMStructure}.
+ * <li>The node of the DOMStructure is serialized to a byte array and added as
+ * body to the message.
+ * </ul>
+ * This does mean that the enveloping XML signature must have either the
+ * structure
+ *
+ * <pre>
+ * {@code
+ * <Signature>
+ * <SignedInfo>
+ * <Reference URI="#object"/>
+ * <!-- further references possible but they must not point to an Object or Manifest containing an object reference -->
+ * ...
+ * </SignedInfo>
+ *
+ * <Object Id="object">
+ * <!-- contains the DOM node which should be extracted to the message body -->
+ * <Object>
+ * <!-- further object elements possible which are not referenced-->
+ * ...
+ * (<KeyInfo>)?
+ * </Signature>
+ * }
+ * </pre>
+ *
+ * or the structure
+ *
+ * <pre>
+ * {@code
+ * <Signature>
+ * <SignedInfo>
+ * <Reference URI="#manifest"/>
+ * <!-- further references are possible but they must not point to an Object or other manifest containing an object reference -->
+ * ...
+ * </SignedInfo>
+ *
+ * <Object >
+ * <Manifest Id="manifest">
+ * <Reference URI=#object/>
+ * </Manifest>
+ * </Objet>
+ * <Object Id="object">
+ * <!-- contains the DOM node which should be extracted to the message body -->
+ * </Object>
+ * <!-- further object elements possible which are not referenced -->
+ * ...
+ * (<KeyInfo>)?
+ * </Signature>
+ * }
+ * </pre>
+ * </ul>
+ */
+public class DefaultXmlSignature2Message implements XmlSignature2Message {
+
+ /**
+ * Search type 'Default' for determining the output node.
+ *
+ */
+ public static final String OUTPUT_NODE_SEARCH_TYPE_DEFAULT = "Default";
+
+ /**
+ * Search type 'ElementName' for determining the output element.
+ *
+ */
+ public static final String OUTPUT_NODE_SEARCH_TYPE_ELEMENT_NAME = "ElementName";
+
+ /**
+ * Search type 'XPath' for determining the output node. Search value must be
+ * of type {@link XPathFilterParameterSpec}.
+ *
+ */
+ public static final String OUTPUT_NODE_SEARCH_TYPE_XPATH = "XPath";
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultXmlSignature2Message.class);
+
+ @Override
+ public void mapToMessage(Input input, Message output) throws Exception { //NOPMD
+
+ Node node;
+ boolean removeSignatureElements = false;
+ if (OUTPUT_NODE_SEARCH_TYPE_DEFAULT.equals(input.getOutputNodeSearchType())) {
+ LOG.debug("Searching for output node via default search");
+ if (isEnveloped(input)) {
+ // enveloped XML signature --> remove signature element
+ node = input.getMessageBodyDocument().getDocumentElement();
+ removeSignatureElements = true;
+ } else {
+ node = getNodeForMessageBodyInNonEnvelopedCase(input);
+ }
+ } else if (OUTPUT_NODE_SEARCH_TYPE_ELEMENT_NAME.equals(input.getOutputNodeSearchType())) {
+ node = getOutputElementViaLocalNameAndNamespace(input);
+ } else if (OUTPUT_NODE_SEARCH_TYPE_XPATH.equals(input.getOutputNodeSearchType())) {
+ node = getOutputNodeViaXPath(input);
+ } else {
+ throw new XmlSignatureException(String.format("Wrong configuration: The output node search type %s is not supported.",
+ input.getOutputNodeSearchType()));
+ }
+
+ LOG.debug("Output node with local name {} and namespace {} found", node.getLocalName(), node.getNamespaceURI());
+
+ if (!removeSignatureElements) {
+ removeSignatureElements = input.getRemoveSignatureElements() != null && input.getRemoveSignatureElements();
+ }
+
+ if (removeSignatureElements) {
+ removeSignatureElements(node);
+ }
+
+ transformNodeToByteArrayAndSetToOutputMessage(input, output, node);
+ }
+
+ protected void transformNodeToByteArrayAndSetToOutputMessage(Input input, Message output, Node node)
+ throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException, IOException {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ XmlSignatureHelper.transformToOutputStream(node, os, omitXmlDeclaration(output, input));
+ output.setBody(os.toByteArray());
+ }
+
+ protected Node getOutputNodeViaXPath(Input input) throws Exception { //NOPMD
+ checkSearchValueNotNull(input);
+ checkSearchValueOfType(XPathFilterParameterSpec.class, input);
+ XPathFilterParameterSpec xpathFilter = (XPathFilterParameterSpec) input.getOutputNodeSearch();
+ XPathExpression expr = XmlSignatureHelper.getXPathExpression(xpathFilter);
+ NodeList nodes = (NodeList) expr.evaluate(input.getMessageBodyDocument(), XPathConstants.NODESET);
+ if (nodes == null || nodes.getLength() == 0) {
+ throw new XmlSignatureException(
+ String.format(
+ "Cannot extract root node for the output document from the XML signature document. No node found for XPATH %s as specified in the output node search.",
+ xpathFilter.getXPath()));
+ }
+ if (nodes.getLength() > 1) {
+ throw new XmlSignatureException(
+ String.format(
+ "Cannot extract root node for the output document from the XML signature document. XPATH %s as specified in the output node search results into more than one child.",
+ xpathFilter.getXPath()));
+
+ }
+ Node result = nodes.item(0);
+ if (Node.ELEMENT_NODE == result.getNodeType() || Node.TEXT_NODE == result.getNodeType()
+ || Node.DOCUMENT_NODE == result.getNodeType()) {
+ return result;
+ }
+ throw new XmlSignatureException(
+ String.format(
+ "Cannot extract root node for the output document from the XML signature document. XPATH %s as specified in the output node search results into a node which has the wrong type.",
+ xpathFilter.getXPath()));
+ }
+
+ protected Node getOutputElementViaLocalNameAndNamespace(Input input) throws Exception { //NOPMD
+ String search = getNonEmptyStringSearchValue(input);
+ String namespace;
+ String localName;
+ if ('{' == search.charAt(0)) {
+ // namespace
+ int index = search.indexOf('}');
+ if (index < 1) {
+ throw new XmlSignatureException(
+ String.format(
+ "Wrong configuration: Value %s for the output node search %s has wrong format. Value must have the form '{<namespace>}<element local name>' or '<element local name>' if no the element has no namespace.",
+ search, input.getOutputNodeSearchType()));
+ }
+ namespace = search.substring(1, index);
+ if (search.length() < index + 1) {
+ throw new XmlSignatureException(
+ String.format(
+ "Wrong configuration: Value %s for the output node search %s has wrong format. Value must have the form '{<namespace>}<element local name>' or '<element local name>' if no the element has no namespace.",
+ search, input.getOutputNodeSearchType()));
+ }
+ localName = search.substring(index + 1);
+ } else {
+ namespace = null;
+ localName = search;
+ }
+ NodeList nodeList = input.getMessageBodyDocument().getElementsByTagNameNS(namespace, localName);
+ if (nodeList.getLength() == 0) {
+ throw new XmlSignatureException(
+ String.format(
+ "Cannot extract root element for the output document from the XML signature document. Element with local name %s and namespace %s does not exist.",
+ namespace, localName));
+ }
+ if (nodeList.getLength() > 1) {
+ throw new XmlSignatureException(
+ String.format(
+ "Cannot extract root element for the output document from the XML signature document. More than one element found with local name %s and namespace %s.",
+ namespace, localName));
+ }
+ return nodeList.item(0);
+ }
+
+ protected String getNonEmptyStringSearchValue(Input input) throws Exception { //NOPMD
+ checkSearchValueNotNull(input);
+ checkSearchValueOfType(String.class, input);
+ String search = (String) input.getOutputNodeSearch();
+ checkStringSarchValueNotEmpty(search, input.getOutputNodeSearchType());
+ return search;
+ }
+
+ protected void checkSearchValueOfType(Class<?> cl, Input input) throws Exception { //NOPMD
+ if (!cl.isAssignableFrom(input.getOutputNodeSearch().getClass())) {
+ throw new XMLSignatureException(String.format(
+ "Wrong configruation: Search value is of class %s, the output node search %s requires class %s.", input
+ .getOutputNodeSearch().getClass().getName(), input.getOutputNodeSearchType(), cl.getName()));
+ }
+
+ }
+
+ protected void checkStringSarchValueNotEmpty(String searchValue, String outputNodeSearchType) throws Exception { //NOPMD
+ if (searchValue.isEmpty()) {
+ throw new XMLSignatureException(String.format("Wrong configruation: Value for output node search %s is empty.",
+ outputNodeSearchType));
+ }
+ }
+
+ protected void checkSearchValueNotNull(Input input) throws Exception { //NOPMD
+ LOG.debug("Searching for output element with search value '{}' and sarch type {}", input.getOutputNodeSearch(),
+ input.getOutputNodeSearchType());
+ if (input.getOutputNodeSearch() == null) {
+ throw new XMLSignatureException(String.format("Wrong configruation: Value is missing for output node search %s.",
+ input.getOutputNodeSearchType()));
+ }
+ }
+
+ protected Node getNodeForMessageBodyInNonEnvelopedCase(Input input) throws Exception { //NOPMD
+ Node node;
+ List<Reference> relevantReferences = getReferencesForMessageMapping(input);
+
+ List<XMLObject> relevantObjects = getObjectsForMessageMapping(input);
+
+ DOMStructure domStruc = getDomStructureForMessageBody(relevantReferences, relevantObjects);
+ node = domStruc.getNode();
+ return node;
+ }
+
+ /**
+ * Removes the Signature elements from the document.
+ *
+ * @param doc
+ * document
+ */
+ protected void removeSignatureElements(Node node) {
+ Document doc = XmlSignatureHelper.getDocument(node);
+ NodeList nl = doc.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Signature");
+ for (int i = 0; i < nl.getLength(); i++) {
+ Node n = nl.item(i);
+ Node parent = n.getParentNode();
+ if (parent != null) {
+ parent.removeChild(n);
+ }
+ }
+ }
+
+ /**
+ * Returns the enveloped data in case of an enveloped XML signature.
+ *
+ * @param input
+ * references of signed info and objects
+ * @return <code>true</code> if there exists a reference with URI = "" and
+ * with {@link Transform#ENVELOPED} transform; otherwise
+ * <code>false</code>
+ * @throws Exception
+ */
+ @SuppressWarnings("unchecked")
+ protected boolean isEnveloped(Input input) throws Exception { //NOPMD
+ for (Reference ref : input.getReferences()) {
+ if ("".equals(ref.getURI())) {
+ for (Transform t : ((List<Transform>) ref.getTransforms())) {
+ if (Transform.ENVELOPED.equals(t.getAlgorithm())) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ protected Boolean omitXmlDeclaration(Message message, Input input) {
+ Boolean omitXmlDeclaration = message.getHeader(XmlSignatureConstants.HEADER_OMIT_XML_DECLARATION, Boolean.class);
+ if (omitXmlDeclaration == null) {
+ omitXmlDeclaration = input.omitXmlDeclaration();
+ }
+ if (omitXmlDeclaration == null) {
+ omitXmlDeclaration = Boolean.FALSE;
+ }
+ return omitXmlDeclaration;
+ }
+
+ /**
+ * Returns the references whose referenced objects are taken into account
+ * for the message body. This message you can use to filter the relevant
+ * references from the references provided by the input parameter.
+ *
+ *
+ * @param input
+ * references and objects
+ * @return relevant references for the mapping to the camel message
+ * @throws Exception
+ * if an error occurs
+ */
+ protected List<Reference> getReferencesForMessageMapping(Input input) throws Exception { //NOPMD
+ return input.getReferences();
+ }
+
+ /**
+ * Returns the objects which must be taken into account for the mapping to
+ * the camel message.
+ *
+ * @param input
+ * references and objects
+ * @return relevant objects for the mapping to camel message
+ * @throws Exception
+ * if an error occurs
+ */
+ protected List<XMLObject> getObjectsForMessageMapping(Input input) throws Exception { //NOPMD
+ return input.getObjects();
+ }
+
+ /**
+ * Returns the DOM structure which is transformed to a byte array and set to
+ * the camel message body.
+ *
+ * @param relevantReferences
+ * input from method
+ * {@link #getReferencesForMessageMapping(ReferencesAndObjects)}
+ * @param relevantObjects
+ * input from method
+ * {@link #getObjectsForMessageMapping(ReferencesAndObjects)}
+ * @return dom structure
+ * @throws Exception
+ * if an error occurs
+ */
+ protected DOMStructure getDomStructureForMessageBody(List<Reference> relevantReferences, List<XMLObject> relevantObjects)
+ throws Exception { //NOPMD
+ List<XMLObject> referencedObjects = getReferencedSameDocumentObjects(relevantReferences, relevantObjects);
+
+ if (referencedObjects.isEmpty()) {
+ throw new XmlSignatureException(
+ String.format("Unsupported XML signature document: Content object not found in the XML signature. Detached or enveloped signatures are not supported."));
+ }
+
+ if (referencedObjects.size() > 1) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < referencedObjects.size(); i++) {
+ XMLObject xmlOb = referencedObjects.get(i);
+ sb.append(xmlOb.getId());
+ if (i < referencedObjects.size() - 1) {
+ sb.append(", ");
+ }
+ }
+ throw new XmlSignatureException(String.format(
+ "Unsupported XML signature document: More than one content objects found. Object IDs: %s", sb.toString()));
+ }
+
+ @SuppressWarnings("unchecked")
+ List<XMLStructure> structures = referencedObjects.get(0).getContent();
+ if (structures.size() == 0) {
+ throw new XmlSignatureException(
+ "Unsupported XML signature: XML signature is not enveloping; content not found in XML signature: structure list is empty.");
+ }
+ if (structures.size() > 1) {
+ throw new XmlSignatureException("Unsupported XML signature: more than one structure elements in referenced content object.");
+ }
+ XMLStructure structure = structures.get(0);
+ // only dom currently supported
+ DOMStructure domStruc = (DOMStructure) structure;
+ return domStruc;
+ }
+
+ protected List<XMLObject> getReferencedSameDocumentObjects(List<Reference> relevantReferences, List<XMLObject> relevantObjects) {
+ List<XMLObject> referencedObjects = new ArrayList<XMLObject>(1);
+
+ for (Reference ref : relevantReferences) {
+ String refUri = getSameDocumentReferenceUri(ref);
+ if (refUri == null) {
+ continue;
+ }
+ XMLObject referencedOb = getReferencedObject(relevantObjects, refUri);
+ if (referencedOb != null) {
+ referencedObjects.add(referencedOb);
+ continue;
+ }
+ // content could also be indirectly referenced via manifest
+ addManifestReferencedObjects(relevantObjects, referencedObjects, refUri);
+ }
+ return referencedObjects;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void addManifestReferencedObjects(List<XMLObject> allObjects, List<XMLObject> referencedObjects, String manifestId) {
+ Manifest manifest = getReferencedManifest(allObjects, manifestId);
+ if (manifest == null) {
+ return;
+ }
+ for (Reference manifestRef : (List<Reference>) manifest.getReferences()) {
+ String manifestRefUri = getSameDocumentReferenceUri(manifestRef);
+ if (manifestRefUri == null) {
+ continue;
+ }
+ XMLObject manifestReferencedOb = getReferencedObject(allObjects, manifestRefUri);
+ if (manifestReferencedOb != null) {
+ referencedObjects.add(manifestReferencedOb);
+ }
+ }
+ }
+
+ protected String getSameDocumentReferenceUri(Reference ref) {
+ String refUri = ref.getURI();
+ if (refUri == null) {
+ LOG.warn("Ignoring reference {} which has no URI", ref);
+ return null;
+ }
+ if (!refUri.startsWith("#")) {
+ LOG.warn("Ignoring non-same document reference {}", refUri);
+ return null;
+ }
+ return refUri.substring(1);
+ }
+
+ protected Manifest getReferencedManifest(List<XMLObject> objects, String id) {
+ for (XMLObject xo : objects) {
+ @SuppressWarnings("unchecked")
+ List<XMLStructure> content = xo.getContent();
+ for (XMLStructure xs : content) {
+ if (xs instanceof Manifest) {
+ Manifest man = (Manifest) xs;
+ if (id.equals(man.getId())) {
+ return man;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ protected XMLObject getReferencedObject(List<XMLObject> objects, String id) {
+ for (XMLObject ob : objects) {
+ if (id.equals(ob.getId())) {
+ return ob;
+ }
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyAccessor.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyAccessor.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyAccessor.java
new file mode 100644
index 0000000..4f74da4
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyAccessor.java
@@ -0,0 +1,73 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import javax.xml.crypto.KeySelector;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+
+import org.apache.camel.Message;
+import org.w3c.dom.Node;
+
+/**
+ * Returns the key selector and the optional KeyInfo instance for signing an XML
+ * document. There is a default implementation {@link DefaultKeySelector}.
+ * <p>
+ * The XML signature generator will first call {@link #getKeySelector(Message)}
+ * and then {@link KeyAccessor#getKeyInfo(Message, Node, KeyInfoFactory)}.
+ */
+public interface KeyAccessor {
+
+ /**
+ * Returns the key selector which determines the key for signing the XML
+ * document. The method is called every time a XML document is signed.
+ *
+ * If <code>null</code> is returned the XML signature generator will throw a
+ * {@link XmlSignatureNoKeyException}.
+ *
+ * @param message
+ * the incoming message, from which you can read headers to
+ * configure the key selector, for example, a header could
+ * contain a private key for the key selector
+ * @return key selector, must not be <code>null</code>
+ * @throws Exception
+ * if an error occurs
+ */
+ KeySelector getKeySelector(Message message) throws Exception;
+
+ /**
+ * Returns the optional key info to be incorporated into the XML signature.
+ * If <code>null</code> is returned, no key info element is created. You can
+ * create a key info instance via the key info factory.
+ *
+ * @param message
+ * incoming message, from which you can read headers, for
+ * example, there could be a header which contains the public key
+ * or certificate for the key info
+ * @param messageBody
+ * the message body as DOM node. If the message body is plain
+ * text then the node will be a text node. If the message body is
+ * a XML document, then the node is the root element.
+ * @param keyInfoFactory
+ * key info factory for creating the KeyInfo instance
+ * @return key info, can be <code>null</code>
+ * @throws Exception
+ * if an error occurs
+ */
+ KeyInfo getKeyInfo(Message message, Node messageBody, KeyInfoFactory keyInfoFactory) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyStoreAndAlias.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyStoreAndAlias.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyStoreAndAlias.java
new file mode 100644
index 0000000..dd9ed02
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/KeyStoreAndAlias.java
@@ -0,0 +1,53 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import java.security.KeyStore;
+
+public class KeyStoreAndAlias {
+
+ private KeyStore keyStore;
+
+ private String alias;
+
+ private char[] password;
+
+ public KeyStore getKeyStore() {
+ return keyStore;
+ }
+
+ public void setKeyStore(KeyStore keyStore) {
+ this.keyStore = keyStore;
+ }
+
+ public String getAlias() {
+ return alias;
+ }
+
+ public void setAlias(String alias) {
+ this.alias = alias;
+ }
+
+ public char[] getPassword() {
+ return password;
+ }
+
+ public void setPassword(char[] password) {
+ this.password = password;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/ValidationFailedHandler.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/ValidationFailedHandler.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/ValidationFailedHandler.java
new file mode 100644
index 0000000..dfe669e
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/ValidationFailedHandler.java
@@ -0,0 +1,94 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignature.SignatureValue;
+import javax.xml.crypto.dsig.XMLSignatureException;
+
+/**
+ * Handler for handling the case when the core signature validation fails or a
+ * {@link XMLSignatureException} occurs during calling
+ * {@link XMLSignature#validate(javax.xml.crypto.dsig.XMLValidateContext)}.
+ *
+ * This handler can be used to react in a specific way on validation failures.
+ * For example, the handler could write logs or may even ignore certain
+ * validation failures.
+ * <p>
+ * Typically the handler throws an exception when a validation failure occurs.
+ *
+ * There is a certain order how the methods are called.
+ * <ul>
+ * <li>First, the method {@link #start()} is called when a core validation
+ * fails.
+ * <li>Then {@link #signatureValueValidationFailed(SignatureValue)} is called if
+ * the signature validation fails.
+ * <li>Then, for each reference in the signed info whose validation fails
+ * {@link #referenceValidationFailed(Reference)} is called.
+ * <li>Then, for each reference in the manifests whose validation fails, the
+ * method {@link #manifestReferenceValidationFailed(Reference)} is called.
+ * <li>Then, the method {@link #ignoreCoreValidationFailure()} is called where
+ * you can finally decide whether the processing should go on or be interrupted.
+ * <li>It is ensured that the method {@link #end()} is called at the end of the
+ * validation, even if the methods called before have thrown an exception. This
+ * allows you to hold state between the start and end of the validation handling
+ * process.
+ * </ul>
+ * If you throw an exception then the validation checking is interrupted and
+ * after that only the {@link #end()} method is called in a finally block. Best
+ * practice is to interrupt the validation at the first occurrence of a
+ * validation error.
+ */
+public interface ValidationFailedHandler {
+
+ /**
+ * Method called when an XMLSignatureException is thrown by the method
+ * {@link XMLSignature#validate(javax.xml.crypto.dsig.XMLValidateContext)}.
+ * <p>
+ * You can return more specific exceptions which are useful for your
+ * use-case.
+ *
+ * @param e exception
+ * @return exception exception which is then thrown by XmlSignerProcessor.
+ */
+ Exception onXMLSignatureException(XMLSignatureException e);
+
+ void start();
+
+ void signatureValueValidationFailed(SignatureValue value) throws Exception; // NOPMD
+
+ void referenceValidationFailed(Reference ref) throws Exception; // NOPMD
+
+ void manifestReferenceValidationFailed(Reference ref) throws Exception; // NOPMD
+
+ /**
+ * If <tt>true</tt> is returned then the verifier will go-on as if there was
+ * no validation failure. If <tt>false</tt> is returned than the verifier
+ * will throw an {@link XmlSignatureInvalidException}.
+ * <p>
+ * Best practice is to return <code>false</code> to ensure that after a core
+ * validation failure, the verification fails.
+ *
+ * @return true or false
+ * @throws Exception
+ */
+ boolean ignoreCoreValidationFailure() throws Exception; // NOPMD
+
+ void end() throws Exception; // NOPMD
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignature2Message.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignature2Message.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignature2Message.java
new file mode 100644
index 0000000..5d8c743
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignature2Message.java
@@ -0,0 +1,91 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import java.util.List;
+
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.XMLObject;
+
+import org.apache.camel.Message;
+import org.w3c.dom.Document;
+
+/**
+ * Used in the signature verifier to map the references and objects of the XML
+ * signature to the output message.
+ */
+public interface XmlSignature2Message {
+
+ /**
+ * Maps the references and objects of an XML signature to the camel message.
+ *
+ * @param input
+ * input
+ * @param output
+ * output message
+ * @throws Exception
+ */
+ void mapToMessage(Input input, Message output) throws Exception;
+
+ public static interface Input {
+
+ /**
+ * Returns the references.
+ *
+ * @return list of references, cannot be <code>null</code>
+ */
+ List<Reference> getReferences();
+
+ /**
+ * Returns the objects.
+ *
+ * @return objects, cannot be <code>null</code>
+ */
+ List<XMLObject> getObjects();
+
+ /** Message body containing the XML signature as DOM. */
+ Document getMessageBodyDocument();
+
+ /**
+ * Indicator whether XML declaration should be omitted. Configured in
+ * the endpoint URI.
+ *
+ * @return {@link Boolean#TRUE} if the XML declaration shall be omitted
+ * in the output document.
+ */
+ Boolean omitXmlDeclaration();
+
+ /**
+ * Output node search value for determining the node from the XML
+ * signature document which shall be set to the output message body.
+ */
+ Object getOutputNodeSearch();
+
+ /**
+ * Search type. Which determines the class and meaning of
+ * {@link #getOutputNodeSearch()}.
+ */
+ String getOutputNodeSearchType();
+
+ /**
+ * Indicator whether the XML signature elements should be removed from
+ * the document set to the output message.
+ */
+ Boolean getRemoveSignatureElements();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a8265a2c/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureChecker.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureChecker.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureChecker.java
new file mode 100644
index 0000000..a6982a2
--- /dev/null
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureChecker.java
@@ -0,0 +1,73 @@
+/**
+ * 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.camel.component.xmlsecurity.api;
+
+import java.util.List;
+
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignature.SignatureValue;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+
+import org.apache.camel.Message;
+import org.w3c.dom.Document;
+
+/**
+ * This interface gives the application the possibility to check whether the
+ * expected parts are signed.
+ * <p>
+ * Only relevant for the XML signature verifier.
+ * <p>
+ * See http://www.w3.org/TR/xmldsig-bestpractices/#check-what-is-signed
+ */
+public interface XmlSignatureChecker {
+
+ /**
+ * Checks whether the signature document has the expected structure and
+ * contains the expected transformations and references. See
+ * http://www.w3.org/TR/xmldsig-bestpractices/#check-what-is-signed
+ *
+ * @param input
+ * input parameters
+ * @throws Exception
+ * when XML signature does not pass the check
+ */
+ void checkBeforeCoreValidation(Input input) throws Exception;
+
+ public static interface Input {
+
+ /** Signed info instance. */
+ SignedInfo getSignedInfo();
+
+ /** Signature value instance. */
+ SignatureValue getSignatureValue();
+
+ /** XML objects list. */
+ List<? extends XMLObject> getObjects();
+
+ /** Key info. */
+ KeyInfo getKeyInfo();
+
+ /** Message body containing the XML signature as DOM. */
+ Document getMessageBodyDocument();
+
+ /** Message. */
+ Message getMessage();
+
+ }
+
+}