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:34 UTC
[6/6] git commit: CAMEL-6339 Applied the patch with thanks to Franz
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();
+
+ }
+
+}