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

Reply via email to