You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by fo...@apache.org on 2017/07/25 08:20:03 UTC

[1/4] camel git commit: CAMEL-11438 new component crypto-cms

Repository: camel
Updated Branches:
  refs/heads/master cf96ff477 -> b831203b8


http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/TestOriginatorInformationProvider.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/TestOriginatorInformationProvider.java b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/TestOriginatorInformationProvider.java
new file mode 100644
index 0000000..f5037de
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/TestOriginatorInformationProvider.java
@@ -0,0 +1,49 @@
+/**
+ * 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.crypto.cms.util;
+
+import java.security.cert.X509Certificate;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.common.OriginatorInformationProvider;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.util.jsse.KeyStoreParameters;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cms.OriginatorInfoGenerator;
+import org.bouncycastle.cms.OriginatorInformation;
+
+import static org.junit.Assert.assertNotNull;
+
+public class TestOriginatorInformationProvider implements OriginatorInformationProvider {
+
+    @Override
+    public OriginatorInformation getOriginatorInformation(Exchange exchange) throws CryptoCmsException {
+
+        try {
+            KeyStoreParameters keyStorePas = KeystoreUtil.getKeyStoreParameters("test.jks");
+            assertNotNull(keyStorePas);
+            X509Certificate cert = (X509Certificate)keyStorePas.createKeyStore().getCertificate("test user keystore test");
+            assertNotNull(cert);
+            X509CertificateHolder origCert = new X509CertificateHolder(cert.getEncoded());
+            return new OriginatorInfoGenerator(origCert).generate();
+        } catch (Exception e) {
+            throw new CryptoCmsException(e);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/resources/detached_signature.base64
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/resources/detached_signature.base64 b/components/camel-crypto-cms/src/test/resources/detached_signature.base64
new file mode 100644
index 0000000..e5c305e
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/resources/detached_signature.base64
@@ -0,0 +1,8 @@
+MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAMYIBXDCCAVgC
+AQEwKzAjMQ4wDAYDVQQKDAVDYW1lbDERMA8GA1UEAwwIdGVzdHVzZXICBFlWR2QwCQYFKw4DAhoF
+AKCBiDAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNzA2MzAxOTE1
+NDhaMCMGCSqGSIb3DQEJBDEWBBQ9I0wDF2KKttiOpt/51oW/SEI7LTApBgkqhkiG9w0BCTQxHDAa
+MAkGBSsOAwIaBQChDQYJKoZIhvcNAQEBBQAwDQYJKoZIhvcNAQEBBQAEgYBi94gFvsL7B2vFqO/S
+AylXrTVcDhGgQQDicRiOIB5XXOXbXbIvI32d3OA7px0XaiW7EvMBLAF9wsQ9yM4XuNE5R6VPV8l+
+4siE23HqjNkZHeapVsr1tarBzpOuxpa+PDksdHDpaGQgtdWjLGPZwgIx0CP3E8KJwZjcBs63ua2c
+QgAAAAAAAA==

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/resources/detached_signature.binary
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/resources/detached_signature.binary b/components/camel-crypto-cms/src/test/resources/detached_signature.binary
new file mode 100644
index 0000000..619ae53
Binary files /dev/null and b/components/camel-crypto-cms/src/test/resources/detached_signature.binary differ

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/resources/keystore/system.jks
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/resources/keystore/system.jks b/components/camel-crypto-cms/src/test/resources/keystore/system.jks
new file mode 100644
index 0000000..c9f894e
Binary files /dev/null and b/components/camel-crypto-cms/src/test/resources/keystore/system.jks differ

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/resources/keystore/test.jks
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/resources/keystore/test.jks b/components/camel-crypto-cms/src/test/resources/keystore/test.jks
new file mode 100644
index 0000000..4bd2c95
Binary files /dev/null and b/components/camel-crypto-cms/src/test/resources/keystore/test.jks differ

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/resources/log4j2.properties
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/resources/log4j2.properties b/components/camel-crypto-cms/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..c55bc31
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/resources/log4j2.properties
@@ -0,0 +1,29 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-crypto-cms-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+rootLogger.level = DEBUG
+#rootLogger.appenderRef.file.ref = file
+rootLogger.appenderRef.out.ref = out

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/resources/signed_enveloped_other_CMS_vendor.binary
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/resources/signed_enveloped_other_CMS_vendor.binary b/components/camel-crypto-cms/src/test/resources/signed_enveloped_other_CMS_vendor.binary
new file mode 100644
index 0000000..27006c9
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/resources/signed_enveloped_other_CMS_vendor.binary
@@ -0,0 +1,28 @@
+MIAGCSqGSIb3DQEHA6CAMIACAQAxgcUwgcICAQAwKzAjMQ4wDAYDVQQKDAVDYW1l
+bDERMA8GA1UEAwwIdGVzdHVzZXICBFlWR2QwDQYJKoZIhvcNAQEBBQAEgYArqASJ
+Bo7XOI05zGJ3C4q8tczaYhsRm+2z9LBIFPAsHulwhDG8xMwZya/wP6fT7pdr+NR/
+ZT8tIbMWEedhYYifHDZ/VRIl8TNPg5heeE9QV+u398+FyZ3wZUKJyTy+wzkoAa76
+qWnYQYm81kzIBaPWYF+HT9wUMvOW+GeWfBJ04DCABgkqhkiG9w0BBwEwFAYIKoZI
+hvcNAwcECA8w3syXyAyboIAEggQYSFu9z7gvX1cKdq4+fS0HFHr960mNNB/vu/ve
+kldLLIAsXDI7tIvTyyMJ3lUR2ly8xA1H73AkC+hX2tnsrjp9W8VzpRPaMYXleJX/
+nVWX4ZC3aFLh7FsaalcUvg/z6l9/xW3aTm/kcon890ghlmLQ1gnxogvgGlezZq4+
+BZ9e686cQJydjuheJRk2FJkKXkjxD2BOaZrRhiXLYf7BI83XVgN1lEXngQmTK32b
+OQ6oHYfcuMPTN3FghTx4v9A4Vm7QuH+UeUsywAhSGPjW7hzZ2HF0QM5psxlwqAmp
+i6xOje9qUVXzc9aRxZFwawtLP51jVEewm7FZgs0zd1fz79SWP5YP3FXsYEiw3tf9
+Dq25lGy7Rt5Dh7HDRn+CcIaBnOZiD9ydG13iEd2rx+jZc/tG0zy+BrLyKOR+Ohf1
+WJvYUo+4TnrJToc6IVqCtxwCFLM6Yt9WMtL//Fc1rDTtbOPtPRpTMkoxHw7zARiR
+rFSUd4gFxQjg3nvi8BkNxy2Vhwdhzy1HwMJWijmvlWZ27UH+knXdi0zmwjSiIQ8A
+/VobUzpLhd9PoTaoaWp2w0u1NSHC4TH9M1FoCs0AGaIvfJDpbvzvswjRxpS0d6Tw
+PK6Qe+KBA/lGJpMM+IeA7cwulLxfSQ8PQHaeo3G+ZZOr0ZYjkzc4cBjm9GtaN8ip
+E35Z3+gqCecyJM0O5jxSM6PrxCA1AWFvA9H+mIadLStgQ9cG3svQqEG6lVJQPgzu
+hd4C5vIvt68MkCNJD16EBID+COYH40IjM97BI8N+t/Ni+ziNcDKWQiqWwLD8/ljL
+7YXePtJChaUv2EO5sSKTjBM2tJ+RMoDQr9kgMFQ8J1NahRtQmGRIH6SUAJXD5ptf
+ls53ad6R6bBto9wV0ErVebxkjQKQSNUnyBeyf+w6+RJ4QnidLBKieRlMplNLUlnm
+DNGbts1/0v7fIovMMr5lKVA9eLCMClUS6WQiN84EZV+1JQwHcTQ0yEOgz06bpssz
+gK/9mFDv7PLZbnMa4cjkH3JZqEnVGLEv1hJEgiwkVruzHH+Q7dSTOGkRBbdbQDoe
+0HDZGk0/urSe9yAbREbh8zb1DqO4bilySXWpivtLFk49IyEccYwnZJiN2la9BQFK
+6A6BNZF8d8yMezeRddybHPIZkHD5r9DfLDgrKo9T0+oSefvGjDntS8AjrdsaPgm8
+dWXjjOAO9OhNxNa2dJF6Zxr/Z7bmbgFgVFkWr3K72bCEr/RfIbob5kwfkZ6IkKCg
+kQxdj30HeFWTBalhxp61IkB1ySGI8MKQtH0/A71IbKyhX+YdvmEQFAoUSvhz3/FN
+zZRDvc73SARqRpTuVMHLqZMdZ641o1EfXsKpwgTnbX5EExkp43ydQUiJRG4cS8+h
+dK2sBu8z17apihJrLgAAAAAAAAAAAAA=
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/pom.xml
----------------------------------------------------------------------
diff --git a/components/pom.xml b/components/pom.xml
index 72a1fd0..5a72166 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -102,6 +102,7 @@
     <module>camel-couchbase</module>
     <module>camel-couchdb</module>
     <module>camel-crypto</module>
+    <module>camel-crypto-cms</module>
     <module>camel-csv</module>
     <module>camel-digitalocean</module>
     <module>camel-disruptor</module>

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/pom.xml
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-crypto-cms-starter/pom.xml b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/pom.xml
new file mode 100644
index 0000000..e92c1f4
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>components-starter</artifactId>
+    <version>2.20.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>camel-crypto-cms-starter</artifactId>
+  <packaging>jar</packaging>
+  <name>Spring-Boot Starter :: Camel :: Crypto</name>
+  <description>Spring-Boot Starter for Camel Cryptographic Support</description>
+  <dependencies>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter</artifactId>
+      <version>${spring-boot-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-crypto-cms</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <!--START OF GENERATED CODE-->
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-core-starter</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-spring-boot-starter</artifactId>
+    </dependency>
+    <!--END OF GENERATED CODE-->
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/java/org/apache/camel/component/crypto/cms/springboot/CryptoCmsComponentAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/java/org/apache/camel/component/crypto/cms/springboot/CryptoCmsComponentAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/java/org/apache/camel/component/crypto/cms/springboot/CryptoCmsComponentAutoConfiguration.java
new file mode 100644
index 0000000..e8d5e55
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/java/org/apache/camel/component/crypto/cms/springboot/CryptoCmsComponentAutoConfiguration.java
@@ -0,0 +1,128 @@
+/**
+ * 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.crypto.cms.springboot;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Generated;
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.crypto.cms.CryptoCmsComponent;
+import org.apache.camel.spi.ComponentCustomizer;
+import org.apache.camel.spi.HasId;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.spring.boot.ComponentConfigurationProperties;
+import org.apache.camel.spring.boot.util.ConditionalOnCamelContextAndAutoConfigurationBeans;
+import org.apache.camel.spring.boot.util.GroupCondition;
+import org.apache.camel.spring.boot.util.HierarchicalPropertiesEvaluator;
+import org.apache.camel.util.IntrospectionSupport;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+
+/**
+ * Generated by camel-package-maven-plugin - do not edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.SpringBootAutoConfigurationMojo")
+@Configuration
+@Conditional({ConditionalOnCamelContextAndAutoConfigurationBeans.class,
+        CryptoCmsComponentAutoConfiguration.GroupConditions.class})
+@AutoConfigureAfter(CamelAutoConfiguration.class)
+@EnableConfigurationProperties({ComponentConfigurationProperties.class,
+        CryptoCmsComponentConfiguration.class})
+public class CryptoCmsComponentAutoConfiguration {
+
+    private static final Logger LOGGER = LoggerFactory
+            .getLogger(CryptoCmsComponentAutoConfiguration.class);
+    @Autowired
+    private ApplicationContext applicationContext;
+    @Autowired
+    private CamelContext camelContext;
+    @Autowired
+    private CryptoCmsComponentConfiguration configuration;
+    @Autowired(required = false)
+    private List<ComponentCustomizer<CryptoCmsComponent>> customizers;
+
+    static class GroupConditions extends GroupCondition {
+        public GroupConditions() {
+            super("camel.component", "camel.component.crypto-cms");
+        }
+    }
+
+    @Lazy
+    @Bean(name = "crypto-cms-component")
+    @ConditionalOnMissingBean(CryptoCmsComponent.class)
+    public CryptoCmsComponent configureCryptoCmsComponent() throws Exception {
+        CryptoCmsComponent component = new CryptoCmsComponent();
+        component.setCamelContext(camelContext);
+        Map<String, Object> parameters = new HashMap<>();
+        IntrospectionSupport.getProperties(configuration, parameters, null,
+                false);
+        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
+            Object value = entry.getValue();
+            Class<?> paramClass = value.getClass();
+            if (paramClass.getName().endsWith("NestedConfiguration")) {
+                Class nestedClass = null;
+                try {
+                    nestedClass = (Class) paramClass.getDeclaredField(
+                            "CAMEL_NESTED_CLASS").get(null);
+                    HashMap<String, Object> nestedParameters = new HashMap<>();
+                    IntrospectionSupport.getProperties(value, nestedParameters,
+                            null, false);
+                    Object nestedProperty = nestedClass.newInstance();
+                    IntrospectionSupport.setProperties(camelContext,
+                            camelContext.getTypeConverter(), nestedProperty,
+                            nestedParameters);
+                    entry.setValue(nestedProperty);
+                } catch (NoSuchFieldException e) {
+                }
+            }
+        }
+        IntrospectionSupport.setProperties(camelContext,
+                camelContext.getTypeConverter(), component, parameters);
+        if (ObjectHelper.isNotEmpty(customizers)) {
+            for (ComponentCustomizer<CryptoCmsComponent> customizer : customizers) {
+                boolean useCustomizer = (customizer instanceof HasId)
+                        ? HierarchicalPropertiesEvaluator.evaluate(
+                                applicationContext.getEnvironment(),
+                                "camel.component.customizer",
+                                "camel.component.crypto-cms.customizer",
+                                ((HasId) customizer).getId())
+                        : HierarchicalPropertiesEvaluator.evaluate(
+                                applicationContext.getEnvironment(),
+                                "camel.component.customizer",
+                                "camel.component.crypto-cms.customizer");
+                if (useCustomizer) {
+                    LOGGER.debug("Configure component {}, with customizer {}",
+                            component, customizer);
+                    customizer.customize(component);
+                }
+            }
+        }
+        return component;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/java/org/apache/camel/component/crypto/cms/springboot/CryptoCmsComponentConfiguration.java
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/java/org/apache/camel/component/crypto/cms/springboot/CryptoCmsComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/java/org/apache/camel/component/crypto/cms/springboot/CryptoCmsComponentConfiguration.java
new file mode 100644
index 0000000..8993427
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/java/org/apache/camel/component/crypto/cms/springboot/CryptoCmsComponentConfiguration.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.crypto.cms.springboot;
+
+import javax.annotation.Generated;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataDecryptorConfiguration;
+import org.apache.camel.component.crypto.cms.sig.SignedDataVerifierConfiguration;
+import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+
+/**
+ * Camel Cryptographic Message Syntax Support
+ * 
+ * Generated by camel-package-maven-plugin - do not edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.SpringBootAutoConfigurationMojo")
+@ConfigurationProperties(prefix = "camel.component.crypto-cms")
+public class CryptoCmsComponentConfiguration
+        extends
+            ComponentConfigurationPropertiesCommon {
+
+    /**
+     * To configure the shared SignedDataVerifierConfiguration which determines
+     * the uri parameters for the verify operation.
+     */
+    @NestedConfigurationProperty
+    private SignedDataVerifierConfiguration signedDataVerifierConfiguration;
+    /**
+     * To configure the shared EnvelopedDataDecryptorConfiguration which
+     * determines the uri parameters for the decrypt operation.
+     */
+    @NestedConfigurationProperty
+    private EnvelopedDataDecryptorConfiguration envelopedDataDecryptorConfiguration;
+    /**
+     * Whether the component should resolve property placeholders on itself when
+     * starting. Only properties which are of String type can use property
+     * placeholders.
+     */
+    private Boolean resolvePropertyPlaceholders = true;
+
+    public SignedDataVerifierConfiguration getSignedDataVerifierConfiguration() {
+        return signedDataVerifierConfiguration;
+    }
+
+    public void setSignedDataVerifierConfiguration(
+            SignedDataVerifierConfiguration signedDataVerifierConfiguration) {
+        this.signedDataVerifierConfiguration = signedDataVerifierConfiguration;
+    }
+
+    public EnvelopedDataDecryptorConfiguration getEnvelopedDataDecryptorConfiguration() {
+        return envelopedDataDecryptorConfiguration;
+    }
+
+    public void setEnvelopedDataDecryptorConfiguration(
+            EnvelopedDataDecryptorConfiguration envelopedDataDecryptorConfiguration) {
+        this.envelopedDataDecryptorConfiguration = envelopedDataDecryptorConfiguration;
+    }
+
+    public Boolean getResolvePropertyPlaceholders() {
+        return resolvePropertyPlaceholders;
+    }
+
+    public void setResolvePropertyPlaceholders(
+            Boolean resolvePropertyPlaceholders) {
+        this.resolvePropertyPlaceholders = resolvePropertyPlaceholders;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/LICENSE.txt
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/LICENSE.txt b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/LICENSE.txt
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/LICENSE.txt
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/NOTICE.txt
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/NOTICE.txt b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/NOTICE.txt
new file mode 100644
index 0000000..2e215bf
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/NOTICE.txt
@@ -0,0 +1,11 @@
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the Apache Camel distribution.                    ==
+   =========================================================================
+
+   This product includes software developed by
+   The Apache Software Foundation (http://www.apache.org/).
+
+   Please read the different LICENSE files present in the licenses directory of
+   this distribution.

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/spring.factories
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/spring.factories b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..106227d
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,19 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.apache.camel.component.crypto.cms.springboot.CryptoCmsComponentAutoConfiguration

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/spring.provides
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/spring.provides b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/spring.provides
new file mode 100644
index 0000000..a2f9dec
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-crypto-cms-starter/src/main/resources/META-INF/spring.provides
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+provides: camel-crypto-cms

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/platforms/spring-boot/components-starter/pom.xml
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/pom.xml b/platforms/spring-boot/components-starter/pom.xml
index 50a345a..279a009 100644
--- a/platforms/spring-boot/components-starter/pom.xml
+++ b/platforms/spring-boot/components-starter/pom.xml
@@ -17,326 +17,327 @@
     limitations under the License.
 
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.camel</groupId>
-    <artifactId>camel-starter-parent</artifactId>
-    <version>2.20.0-SNAPSHOT</version>
-    <relativePath>../../../platforms/spring-boot/spring-boot-dm/camel-starter-parent</relativePath>
-  </parent>
-  <artifactId>components-starter</artifactId>
-  <packaging>pom</packaging>
-  <name>Camel :: Components :: Starter</name>
-  <description>Camel Components Starter</description>
-  <!-- to support spring-boot auto configuration in the Camel components -->
-  <dependencies>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot</artifactId>
-      <version>${spring-boot-version}</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-autoconfigure</artifactId>
-      <version>${spring-boot-version}</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-configuration-processor</artifactId>
-      <version>${spring-boot-version}</version>
-      <scope>provided</scope>
-    </dependency>
-    <!-- Test dependencies -->
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-test</artifactId>
-      <version>${spring-boot-version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.camel</groupId>
-      <artifactId>camel-test-spring</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <failIfNoTests>false</failIfNoTests>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-  <!-- WARNING: do not edit the modules section, it is update automatically by the camel-package plugin -->
-  <modules>
-    <module>camel-ahc-starter</module>
-    <module>camel-ahc-ws-starter</module>
-    <module>camel-amqp-starter</module>
-    <module>camel-apns-starter</module>
-    <module>camel-asterisk-starter</module>
-    <module>camel-atmos-starter</module>
-    <module>camel-atmosphere-websocket-starter</module>
-    <module>camel-atom-starter</module>
-    <module>camel-atomix-starter</module>
-    <module>camel-avro-starter</module>
-    <module>camel-aws-starter</module>
-    <module>camel-azure-starter</module>
-    <module>camel-bam-starter</module>
-    <module>camel-barcode-starter</module>
-    <module>camel-base64-starter</module>
-    <module>camel-bean-validator-starter</module>
-    <module>camel-beanio-starter</module>
-    <module>camel-beanstalk-starter</module>
-    <module>camel-bindy-starter</module>
-    <module>camel-bonita-starter</module>
-    <module>camel-boon-starter</module>
-    <module>camel-box-starter</module>
-    <module>camel-braintree-starter</module>
-    <module>camel-cache-starter</module>
-    <module>camel-caffeine-starter</module>
-    <module>camel-cassandraql-starter</module>
-    <module>camel-castor-starter</module>
-    <module>camel-chronicle-starter</module>
-    <module>camel-chunk-starter</module>
-    <module>camel-cm-sms-starter</module>
-    <module>camel-cmis-starter</module>
-    <module>camel-coap-starter</module>
-    <module>camel-cometd-starter</module>
-    <module>camel-consul-starter</module>
-    <module>camel-context-starter</module>
-    <module>camel-core-starter</module>
-    <module>camel-couchbase-starter</module>
-    <module>camel-couchdb-starter</module>
-    <module>camel-crypto-starter</module>
-    <module>camel-csv-starter</module>
-    <module>camel-cxf-starter</module>
-    <module>camel-cxf-transport-starter</module>
-    <module>camel-digitalocean-starter</module>
-    <module>camel-disruptor-starter</module>
-    <module>camel-dns-starter</module>
-    <module>camel-docker-starter</module>
-    <module>camel-dozer-starter</module>
-    <module>camel-drill-starter</module>
-    <module>camel-dropbox-starter</module>
-    <module>camel-eclipse-starter</module>
-    <module>camel-ehcache-starter</module>
-    <module>camel-elasticsearch-starter</module>
-    <module>camel-elasticsearch5-starter</module>
-    <module>camel-elsql-starter</module>
-    <module>camel-etcd-starter</module>
-    <module>camel-exec-starter</module>
-    <module>camel-facebook-starter</module>
-    <module>camel-fastjson-starter</module>
-    <module>camel-flatpack-starter</module>
-    <module>camel-flink-starter</module>
-    <module>camel-fop-starter</module>
-    <module>camel-freemarker-starter</module>
-    <module>camel-ftp-starter</module>
-    <module>camel-ganglia-starter</module>
-    <module>camel-geocoder-starter</module>
-    <module>camel-git-starter</module>
-    <module>camel-github-starter</module>
-    <module>camel-google-calendar-starter</module>
-    <module>camel-google-drive-starter</module>
-    <module>camel-google-mail-starter</module>
-    <module>camel-google-pubsub-starter</module>
-    <module>camel-gora-starter</module>
-    <module>camel-grape-starter</module>
-    <module>camel-groovy-starter</module>
-    <module>camel-grpc-starter</module>
-    <module>camel-gson-starter</module>
-    <module>camel-guava-eventbus-starter</module>
-    <module>camel-guice-starter</module>
-    <module>camel-hawtdb-starter</module>
-    <module>camel-hazelcast-starter</module>
-    <module>camel-hbase-starter</module>
-    <module>camel-hdfs-starter</module>
-    <module>camel-hdfs2-starter</module>
-    <module>camel-headersmap-starter</module>
-    <module>camel-hessian-starter</module>
-    <module>camel-hipchat-starter</module>
-    <module>camel-hl7-starter</module>
-    <module>camel-http-common-starter</module>
-    <module>camel-http-starter</module>
-    <module>camel-http4-starter</module>
-    <module>camel-hystrix-starter</module>
-    <module>camel-ical-starter</module>
-    <module>camel-ignite-starter</module>
-    <module>camel-infinispan-starter</module>
-    <module>camel-influxdb-starter</module>
-    <module>camel-irc-starter</module>
-    <module>camel-ironmq-starter</module>
-    <module>camel-jackson-starter</module>
-    <module>camel-jacksonxml-starter</module>
-    <module>camel-jasypt-starter</module>
-    <module>camel-javaspace-starter</module>
-    <module>camel-jaxb-starter</module>
-    <module>camel-jbpm-starter</module>
-    <module>camel-jcache-starter</module>
-    <module>camel-jcr-starter</module>
-    <module>camel-jdbc-starter</module>
-    <module>camel-jetty-common-starter</module>
-    <module>camel-jetty-starter</module>
-    <module>camel-jetty9-starter</module>
-    <module>camel-jgroups-starter</module>
-    <module>camel-jibx-starter</module>
-    <module>camel-jing-starter</module>
-    <module>camel-jira-starter</module>
-    <module>camel-jms-starter</module>
-    <module>camel-jmx-starter</module>
-    <module>camel-johnzon-starter</module>
-    <module>camel-jolt-starter</module>
-    <module>camel-josql-starter</module>
-    <module>camel-jpa-starter</module>
-    <module>camel-jsch-starter</module>
-    <module>camel-jsonpath-starter</module>
-    <module>camel-jt400-starter</module>
-    <module>camel-juel-starter</module>
-    <module>camel-jxpath-starter</module>
-    <module>camel-kafka-starter</module>
-    <module>camel-kestrel-starter</module>
-    <module>camel-krati-starter</module>
-    <module>camel-kubernetes-starter</module>
-    <module>camel-kura-starter</module>
-    <module>camel-ldap-starter</module>
-    <module>camel-leveldb-starter</module>
-    <module>camel-linkedin-starter</module>
-    <module>camel-lucene-starter</module>
-    <module>camel-lumberjack-starter</module>
-    <module>camel-lzf-starter</module>
-    <module>camel-mail-starter</module>
-    <module>camel-metrics-starter</module>
-    <module>camel-milo-starter</module>
-    <module>camel-mina2-starter</module>
-    <module>camel-mllp-starter</module>
-    <module>camel-mongodb-gridfs-starter</module>
-    <module>camel-mongodb-starter</module>
-    <module>camel-mongodb3-starter</module>
-    <module>camel-mqtt-starter</module>
-    <module>camel-msv-starter</module>
-    <module>camel-mustache-starter</module>
-    <module>camel-mvel-starter</module>
-    <module>camel-mybatis-starter</module>
-    <module>camel-nagios-starter</module>
-    <module>camel-nats-starter</module>
-    <module>camel-netty-http-starter</module>
-    <module>camel-netty-starter</module>
-    <module>camel-netty4-http-starter</module>
-    <module>camel-netty4-starter</module>
-    <module>camel-ognl-starter</module>
-    <module>camel-olingo2-starter</module>
-    <module>camel-olingo4-starter</module>
-    <module>camel-openshift-starter</module>
-    <module>camel-openstack-starter</module>
-    <module>camel-opentracing-starter</module>
-    <module>camel-optaplanner-starter</module>
-    <module>camel-paho-starter</module>
-    <module>camel-pdf-starter</module>
-    <module>camel-pgevent-starter</module>
-    <module>camel-printer-starter</module>
-    <module>camel-protobuf-starter</module>
-    <module>camel-pubnub-starter</module>
-    <module>camel-quartz2-starter</module>
-    <module>camel-quickfix-starter</module>
-    <module>camel-rabbitmq-starter</module>
-    <module>camel-reactive-streams-starter</module>
-    <module>camel-reactor-starter</module>
-    <module>camel-rest-swagger-starter</module>
-    <module>camel-restlet-starter</module>
-    <module>camel-ribbon-starter</module>
-    <module>camel-rmi-starter</module>
-    <module>camel-routebox-starter</module>
-    <module>camel-rss-starter</module>
-    <module>camel-ruby-starter</module>
-    <module>camel-rx-starter</module>
-    <module>camel-salesforce-starter</module>
-    <module>camel-sap-netweaver-starter</module>
-    <module>camel-saxon-starter</module>
-    <module>camel-schematron-starter</module>
-    <module>camel-script-starter</module>
-    <module>camel-servicenow-starter</module>
-    <module>camel-servlet-starter</module>
-    <module>camel-servletlistener-starter</module>
-    <module>camel-shiro-starter</module>
-    <module>camel-sip-starter</module>
-    <module>camel-sjms-starter</module>
-    <module>camel-sjms2-starter</module>
-    <module>camel-slack-starter</module>
-    <module>camel-smpp-starter</module>
-    <module>camel-snakeyaml-starter</module>
-    <module>camel-snmp-starter</module>
-    <module>camel-soap-starter</module>
-    <module>camel-solr-starter</module>
-    <module>camel-spark-starter</module>
-    <module>camel-splunk-starter</module>
-    <module>camel-spring-batch-starter</module>
-    <module>camel-spring-boot-starter</module>
-    <module>camel-spring-cloud-netflix-starter</module>
-    <module>camel-spring-cloud-starter</module>
-    <module>camel-spring-integration-starter</module>
-    <module>camel-spring-javaconfig-starter</module>
-    <module>camel-spring-ldap-starter</module>
-    <module>camel-spring-redis-starter</module>
-    <module>camel-spring-security-starter</module>
-    <module>camel-spring-starter</module>
-    <module>camel-spring-ws-starter</module>
-    <module>camel-sql-starter</module>
-    <module>camel-ssh-starter</module>
-    <module>camel-stax-starter</module>
-    <module>camel-stomp-starter</module>
-    <module>camel-stream-starter</module>
-    <module>camel-stringtemplate-starter</module>
-    <module>camel-swagger-java-starter</module>
-    <module>camel-syslog-starter</module>
-    <module>camel-tagsoup-starter</module>
-    <module>camel-tarfile-starter</module>
-    <module>camel-telegram-starter</module>
-    <module>camel-thrift-starter</module>
-    <module>camel-tika-starter</module>
-    <module>camel-twilio-starter</module>
-    <module>camel-twitter-starter</module>
-    <module>camel-undertow-starter</module>
-    <module>camel-univocity-parsers-starter</module>
-    <module>camel-urlrewrite-starter</module>
-    <module>camel-velocity-starter</module>
-    <module>camel-vertx-starter</module>
-    <module>camel-weather-starter</module>
-    <module>camel-websocket-starter</module>
-    <module>camel-xmlbeans-starter</module>
-    <module>camel-xmljson-starter</module>
-    <module>camel-xmlrpc-starter</module>
-    <module>camel-xmlsecurity-starter</module>
-    <module>camel-xmpp-starter</module>
-    <module>camel-xstream-starter</module>
-    <module>camel-yammer-starter</module>
-    <module>camel-zendesk-starter</module>
-    <module>camel-zipfile-starter</module>
-    <module>camel-zipkin-starter</module>
-    <module>camel-zookeeper-master-starter</module>
-    <module>camel-zookeeper-starter</module>
-  </modules>
-  <profiles>
-    <profile>
-      <id>jdk9-build</id>
-      <activation>
-        <jdk>9</jdk>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <artifactId>maven-surefire-plugin</artifactId>
-            <configuration>
-              <argLine>--add-modules java.xml.bind --add-opens java.base/java.lang=ALL-UNNAMED</argLine>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-</project>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-starter-parent</artifactId>
+    <version>2.20.0-SNAPSHOT</version>
+    <relativePath>../../../platforms/spring-boot/spring-boot-dm/camel-starter-parent</relativePath>
+  </parent>
+  <artifactId>components-starter</artifactId>
+  <packaging>pom</packaging>
+  <name>Camel :: Components :: Starter</name>
+  <description>Camel Components Starter</description>
+  <!-- to support spring-boot auto configuration in the Camel components -->
+  <dependencies>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot</artifactId>
+      <version>${spring-boot-version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-autoconfigure</artifactId>
+      <version>${spring-boot-version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-configuration-processor</artifactId>
+      <version>${spring-boot-version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <!-- Test dependencies -->
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-test</artifactId>
+      <version>${spring-boot-version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-test-spring</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <failIfNoTests>false</failIfNoTests>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <!-- WARNING: do not edit the modules section, it is update automatically by the camel-package plugin -->
+  <modules>
+    <module>camel-ahc-starter</module>
+    <module>camel-ahc-ws-starter</module>
+    <module>camel-amqp-starter</module>
+    <module>camel-apns-starter</module>
+    <module>camel-asterisk-starter</module>
+    <module>camel-atmos-starter</module>
+    <module>camel-atmosphere-websocket-starter</module>
+    <module>camel-atom-starter</module>
+    <module>camel-atomix-starter</module>
+    <module>camel-avro-starter</module>
+    <module>camel-aws-starter</module>
+    <module>camel-azure-starter</module>
+    <module>camel-bam-starter</module>
+    <module>camel-barcode-starter</module>
+    <module>camel-base64-starter</module>
+    <module>camel-bean-validator-starter</module>
+    <module>camel-beanio-starter</module>
+    <module>camel-beanstalk-starter</module>
+    <module>camel-bindy-starter</module>
+    <module>camel-bonita-starter</module>
+    <module>camel-boon-starter</module>
+    <module>camel-box-starter</module>
+    <module>camel-braintree-starter</module>
+    <module>camel-cache-starter</module>
+    <module>camel-caffeine-starter</module>
+    <module>camel-cassandraql-starter</module>
+    <module>camel-castor-starter</module>
+    <module>camel-chronicle-starter</module>
+    <module>camel-chunk-starter</module>
+    <module>camel-cm-sms-starter</module>
+    <module>camel-cmis-starter</module>
+    <module>camel-coap-starter</module>
+    <module>camel-cometd-starter</module>
+    <module>camel-consul-starter</module>
+    <module>camel-context-starter</module>
+    <module>camel-core-starter</module>
+    <module>camel-couchbase-starter</module>
+    <module>camel-couchdb-starter</module>
+    <module>camel-crypto-cms-starter</module>
+    <module>camel-crypto-starter</module>
+    <module>camel-csv-starter</module>
+    <module>camel-cxf-starter</module>
+    <module>camel-cxf-transport-starter</module>
+    <module>camel-digitalocean-starter</module>
+    <module>camel-disruptor-starter</module>
+    <module>camel-dns-starter</module>
+    <module>camel-docker-starter</module>
+    <module>camel-dozer-starter</module>
+    <module>camel-drill-starter</module>
+    <module>camel-dropbox-starter</module>
+    <module>camel-eclipse-starter</module>
+    <module>camel-ehcache-starter</module>
+    <module>camel-elasticsearch-starter</module>
+    <module>camel-elasticsearch5-starter</module>
+    <module>camel-elsql-starter</module>
+    <module>camel-etcd-starter</module>
+    <module>camel-exec-starter</module>
+    <module>camel-facebook-starter</module>
+    <module>camel-fastjson-starter</module>
+    <module>camel-flatpack-starter</module>
+    <module>camel-flink-starter</module>
+    <module>camel-fop-starter</module>
+    <module>camel-freemarker-starter</module>
+    <module>camel-ftp-starter</module>
+    <module>camel-ganglia-starter</module>
+    <module>camel-geocoder-starter</module>
+    <module>camel-git-starter</module>
+    <module>camel-github-starter</module>
+    <module>camel-google-calendar-starter</module>
+    <module>camel-google-drive-starter</module>
+    <module>camel-google-mail-starter</module>
+    <module>camel-google-pubsub-starter</module>
+    <module>camel-gora-starter</module>
+    <module>camel-grape-starter</module>
+    <module>camel-groovy-starter</module>
+    <module>camel-grpc-starter</module>
+    <module>camel-gson-starter</module>
+    <module>camel-guava-eventbus-starter</module>
+    <module>camel-guice-starter</module>
+    <module>camel-hawtdb-starter</module>
+    <module>camel-hazelcast-starter</module>
+    <module>camel-hbase-starter</module>
+    <module>camel-hdfs-starter</module>
+    <module>camel-hdfs2-starter</module>
+    <module>camel-headersmap-starter</module>
+    <module>camel-hessian-starter</module>
+    <module>camel-hipchat-starter</module>
+    <module>camel-hl7-starter</module>
+    <module>camel-http-common-starter</module>
+    <module>camel-http-starter</module>
+    <module>camel-http4-starter</module>
+    <module>camel-hystrix-starter</module>
+    <module>camel-ical-starter</module>
+    <module>camel-ignite-starter</module>
+    <module>camel-infinispan-starter</module>
+    <module>camel-influxdb-starter</module>
+    <module>camel-irc-starter</module>
+    <module>camel-ironmq-starter</module>
+    <module>camel-jackson-starter</module>
+    <module>camel-jacksonxml-starter</module>
+    <module>camel-jasypt-starter</module>
+    <module>camel-javaspace-starter</module>
+    <module>camel-jaxb-starter</module>
+    <module>camel-jbpm-starter</module>
+    <module>camel-jcache-starter</module>
+    <module>camel-jcr-starter</module>
+    <module>camel-jdbc-starter</module>
+    <module>camel-jetty-common-starter</module>
+    <module>camel-jetty-starter</module>
+    <module>camel-jetty9-starter</module>
+    <module>camel-jgroups-starter</module>
+    <module>camel-jibx-starter</module>
+    <module>camel-jing-starter</module>
+    <module>camel-jira-starter</module>
+    <module>camel-jms-starter</module>
+    <module>camel-jmx-starter</module>
+    <module>camel-johnzon-starter</module>
+    <module>camel-jolt-starter</module>
+    <module>camel-josql-starter</module>
+    <module>camel-jpa-starter</module>
+    <module>camel-jsch-starter</module>
+    <module>camel-jsonpath-starter</module>
+    <module>camel-jt400-starter</module>
+    <module>camel-juel-starter</module>
+    <module>camel-jxpath-starter</module>
+    <module>camel-kafka-starter</module>
+    <module>camel-kestrel-starter</module>
+    <module>camel-krati-starter</module>
+    <module>camel-kubernetes-starter</module>
+    <module>camel-kura-starter</module>
+    <module>camel-ldap-starter</module>
+    <module>camel-leveldb-starter</module>
+    <module>camel-linkedin-starter</module>
+    <module>camel-lucene-starter</module>
+    <module>camel-lumberjack-starter</module>
+    <module>camel-lzf-starter</module>
+    <module>camel-mail-starter</module>
+    <module>camel-metrics-starter</module>
+    <module>camel-milo-starter</module>
+    <module>camel-mina2-starter</module>
+    <module>camel-mllp-starter</module>
+    <module>camel-mongodb-gridfs-starter</module>
+    <module>camel-mongodb-starter</module>
+    <module>camel-mongodb3-starter</module>
+    <module>camel-mqtt-starter</module>
+    <module>camel-msv-starter</module>
+    <module>camel-mustache-starter</module>
+    <module>camel-mvel-starter</module>
+    <module>camel-mybatis-starter</module>
+    <module>camel-nagios-starter</module>
+    <module>camel-nats-starter</module>
+    <module>camel-netty-http-starter</module>
+    <module>camel-netty-starter</module>
+    <module>camel-netty4-http-starter</module>
+    <module>camel-netty4-starter</module>
+    <module>camel-ognl-starter</module>
+    <module>camel-olingo2-starter</module>
+    <module>camel-olingo4-starter</module>
+    <module>camel-openshift-starter</module>
+    <module>camel-openstack-starter</module>
+    <module>camel-opentracing-starter</module>
+    <module>camel-optaplanner-starter</module>
+    <module>camel-paho-starter</module>
+    <module>camel-pdf-starter</module>
+    <module>camel-pgevent-starter</module>
+    <module>camel-printer-starter</module>
+    <module>camel-protobuf-starter</module>
+    <module>camel-pubnub-starter</module>
+    <module>camel-quartz2-starter</module>
+    <module>camel-quickfix-starter</module>
+    <module>camel-rabbitmq-starter</module>
+    <module>camel-reactive-streams-starter</module>
+    <module>camel-reactor-starter</module>
+    <module>camel-rest-swagger-starter</module>
+    <module>camel-restlet-starter</module>
+    <module>camel-ribbon-starter</module>
+    <module>camel-rmi-starter</module>
+    <module>camel-routebox-starter</module>
+    <module>camel-rss-starter</module>
+    <module>camel-ruby-starter</module>
+    <module>camel-rx-starter</module>
+    <module>camel-salesforce-starter</module>
+    <module>camel-sap-netweaver-starter</module>
+    <module>camel-saxon-starter</module>
+    <module>camel-schematron-starter</module>
+    <module>camel-script-starter</module>
+    <module>camel-servicenow-starter</module>
+    <module>camel-servlet-starter</module>
+    <module>camel-servletlistener-starter</module>
+    <module>camel-shiro-starter</module>
+    <module>camel-sip-starter</module>
+    <module>camel-sjms-starter</module>
+    <module>camel-sjms2-starter</module>
+    <module>camel-slack-starter</module>
+    <module>camel-smpp-starter</module>
+    <module>camel-snakeyaml-starter</module>
+    <module>camel-snmp-starter</module>
+    <module>camel-soap-starter</module>
+    <module>camel-solr-starter</module>
+    <module>camel-spark-starter</module>
+    <module>camel-splunk-starter</module>
+    <module>camel-spring-batch-starter</module>
+    <module>camel-spring-boot-starter</module>
+    <module>camel-spring-cloud-netflix-starter</module>
+    <module>camel-spring-cloud-starter</module>
+    <module>camel-spring-integration-starter</module>
+    <module>camel-spring-javaconfig-starter</module>
+    <module>camel-spring-ldap-starter</module>
+    <module>camel-spring-redis-starter</module>
+    <module>camel-spring-security-starter</module>
+    <module>camel-spring-starter</module>
+    <module>camel-spring-ws-starter</module>
+    <module>camel-sql-starter</module>
+    <module>camel-ssh-starter</module>
+    <module>camel-stax-starter</module>
+    <module>camel-stomp-starter</module>
+    <module>camel-stream-starter</module>
+    <module>camel-stringtemplate-starter</module>
+    <module>camel-swagger-java-starter</module>
+    <module>camel-syslog-starter</module>
+    <module>camel-tagsoup-starter</module>
+    <module>camel-tarfile-starter</module>
+    <module>camel-telegram-starter</module>
+    <module>camel-thrift-starter</module>
+    <module>camel-tika-starter</module>
+    <module>camel-twilio-starter</module>
+    <module>camel-twitter-starter</module>
+    <module>camel-undertow-starter</module>
+    <module>camel-univocity-parsers-starter</module>
+    <module>camel-urlrewrite-starter</module>
+    <module>camel-velocity-starter</module>
+    <module>camel-vertx-starter</module>
+    <module>camel-weather-starter</module>
+    <module>camel-websocket-starter</module>
+    <module>camel-xmlbeans-starter</module>
+    <module>camel-xmljson-starter</module>
+    <module>camel-xmlrpc-starter</module>
+    <module>camel-xmlsecurity-starter</module>
+    <module>camel-xmpp-starter</module>
+    <module>camel-xstream-starter</module>
+    <module>camel-yammer-starter</module>
+    <module>camel-zendesk-starter</module>
+    <module>camel-zipfile-starter</module>
+    <module>camel-zipkin-starter</module>
+    <module>camel-zookeeper-master-starter</module>
+    <module>camel-zookeeper-starter</module>
+  </modules>
+  <profiles>
+    <profile>
+      <id>jdk9-build</id>
+      <activation>
+        <jdk>9</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <argLine>--add-modules java.xml.bind --add-opens java.base/java.lang=ALL-UNNAMED</argLine>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

[2/4] camel git commit: CAMEL-11438 new component crypto-cms

Posted by fo...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifierConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifierConfiguration.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifierConfiguration.java
new file mode 100644
index 0000000..209c304
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifierConfiguration.java
@@ -0,0 +1,55 @@
+/**
+ * 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.crypto.cms.sig;
+
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsConstants;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsUnMarshallerConfiguration;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+
+public interface SignedDataVerifierConfiguration extends CryptoCmsUnMarshallerConfiguration {
+
+    /**
+     * Indicates whether the value in the Signed Data header (given by
+     * {@link CryptoCmsConstants#CAMEL_CRYPTO_CMS_SIGNED_DATA} is base64
+     * encoded.
+     */
+    Boolean isSignedDataHeaderBase64(Exchange exchange) throws CryptoCmsException;
+
+    /**
+     * If <code>true</code> then the signatures of all signers are checked. If
+     * <code>false</code> then the verifier searches for a signer which matches
+     * with one of the specified certificates and verifies only the signature of
+     * the first found signer.
+     */
+    Boolean isVerifySignaturesOfAllSigners(Exchange exchange) throws CryptoCmsException;
+
+    /**
+     * Returns the collection of certificates whose public keys are used to
+     * verify the signatures contained in the Signed Data object if the
+     * certificates match the signer information given in the Signed Data
+     * object.
+     */
+    Collection<X509Certificate> getCertificates(Exchange exchange) throws CryptoCmsException;
+
+    /** Creates a copy of this instance. For example by cloning. */
+    SignedDataVerifierConfiguration copy();
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifierFromHeader.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifierFromHeader.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifierFromHeader.java
new file mode 100644
index 0000000..8ddbf30
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifierFromHeader.java
@@ -0,0 +1,117 @@
+/**
+ * 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.crypto.cms.sig;
+
+import java.io.InputStream;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsConstants;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsFormatException;
+import org.apache.camel.util.IOHelper;
+import org.apache.commons.codec.binary.Base64InputStream;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.CMSSignedDataParser;
+import org.bouncycastle.cms.CMSTypedStream;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Verifies the signature contained in the header
+ * {@link CryptoCmsConstants#CAMEL_CRYPTO_CMS_SIGNED_DATA}.
+ */
+public class SignedDataVerifierFromHeader extends SignedDataVerifier {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SignedDataVerifierFromHeader.class);
+
+    private SignedDataVerifierConfiguration conf;
+
+    public SignedDataVerifierFromHeader(SignedDataVerifierConfiguration conf) {
+        super(conf);
+        this.conf = conf;
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception { // NOPMD see
+                                                              // method
+                                                              // processSignedDataHader
+
+        InputStream signature = exchange.getIn().getHeader(CryptoCmsConstants.CAMEL_CRYPTO_CMS_SIGNED_DATA, InputStream.class);
+        if (signature == null) {
+            LOG.debug("No signed data found in header {}. Assuming signed data contained in message body", CryptoCmsConstants.CAMEL_CRYPTO_CMS_SIGNED_DATA);
+            super.process(exchange);
+        } else {
+            LOG.debug("Signed data header {} found.", CryptoCmsConstants.CAMEL_CRYPTO_CMS_SIGNED_DATA);
+            processSignedDataHeader(exchange, signature);
+
+            // remove header
+            exchange.getIn().removeHeader(CryptoCmsConstants.CAMEL_CRYPTO_CMS_SIGNED_DATA);
+        }
+    }
+
+    protected void processSignedDataHeader(Exchange exchange, InputStream signature) throws Exception { // NOPMD
+        // all exceptions must be caught and re-thrown in order to make a
+        // clean-up, see code below
+        if (conf.isSignedDataHeaderBase64(exchange)) {
+            signature = new Base64InputStream(signature);
+        }
+
+        InputStream stream = exchange.getIn().getMandatoryBody(InputStream.class);
+        try {
+            // lets setup the out message before we invoke the dataFormat
+            // so that it can mutate it if necessary
+            Message out = exchange.getOut();
+            out.copyFrom(exchange.getIn());
+
+            if (conf.isFromBase64(exchange)) {
+                stream = new Base64InputStream(stream);
+            }
+            unmarshalInternal(stream, signature, exchange);
+        } catch (Exception e) {
+            // remove OUT message, as an exception occurred
+            exchange.setOut(null);
+            throw e;
+        } finally {
+            IOHelper.close(stream, "input stream");
+        }
+    }
+
+    protected void unmarshalInternal(InputStream is, InputStream signature, Exchange exchange) throws Exception {
+
+        CMSSignedDataParser sp;
+        try {
+            sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME).build(), new CMSTypedStream(is), signature);
+        } catch (CMSException e) {
+            throw new CryptoCmsFormatException(getFormatErrorMessage(), e);
+        }
+        try {
+            // content must be read in order to calculate the hash for the
+            // signature
+            sp.getSignedContent().drain();
+        } catch (NullPointerException e) { // nullpointer exception is thrown
+                                           // when the signed content is missing
+            throw getContentMissingException(e);
+        }
+
+        LOG.debug("Signed data found");
+        debugLog(sp);
+        verify(sp, exchange);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignerInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignerInfo.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignerInfo.java
new file mode 100644
index 0000000..b7da85a
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignerInfo.java
@@ -0,0 +1,57 @@
+/**
+ * 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.crypto.cms.sig;
+
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.bouncycastle.cms.CMSAttributeTableGenerator;
+
+/**
+ * Signer information.
+ */
+public interface SignerInfo {
+
+    String getSignatureAlgorithm(Exchange exchange) throws CryptoCmsException;
+
+    PrivateKey getPrivateKey(Exchange exchange) throws CryptoCmsException;
+
+    X509Certificate getCertificate(Exchange exchange) throws CryptoCmsException;
+
+    /**
+     * Certificates which should be added to the certificate list of the Signed
+     * Data instance which belong to the private key. Return an empty array if
+     * you do not want that the certificate chain of the private key to be added
+     * to the signature certificates.
+     */
+    Certificate[] getCertificateChain(Exchange exchange) throws CryptoCmsException;
+
+    /**
+     * Returns the generator for the signed attributes.
+     */
+    CMSAttributeTableGenerator getSignedAttributeGenerator(Exchange exchange) throws CryptoCmsException;
+
+    /**
+     * Returns the generator for the unsigned attributes. Can be
+     * <code>null</code>, then no unsigned attribute is generated.
+     */
+    CMSAttributeTableGenerator getUnsignedAttributeGenerator(Exchange exchange) throws CryptoCmsException;
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/resources/META-INF/LICENSE.txt
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/resources/META-INF/LICENSE.txt b/components/camel-crypto-cms/src/main/resources/META-INF/LICENSE.txt
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/resources/META-INF/LICENSE.txt
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/resources/META-INF/NOTICE.txt
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/resources/META-INF/NOTICE.txt b/components/camel-crypto-cms/src/main/resources/META-INF/NOTICE.txt
new file mode 100644
index 0000000..2e215bf
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/resources/META-INF/NOTICE.txt
@@ -0,0 +1,11 @@
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the Apache Camel distribution.                    ==
+   =========================================================================
+
+   This product includes software developed by
+   The Apache Software Foundation (http://www.apache.org/).
+
+   Please read the different LICENSE files present in the licenses directory of
+   this distribution.

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/resources/META-INF/services/org/apache/camel/component/crypto-cms
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/resources/META-INF/services/org/apache/camel/component/crypto-cms b/components/camel-crypto-cms/src/main/resources/META-INF/services/org/apache/camel/component/crypto-cms
new file mode 100644
index 0000000..542d209
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/resources/META-INF/services/org/apache/camel/component/crypto-cms
@@ -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.crypto.cms.CryptoCmsComponent

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/ComponentTest.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/ComponentTest.java b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/ComponentTest.java
new file mode 100644
index 0000000..497aa70
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/ComponentTest.java
@@ -0,0 +1,170 @@
+/**
+ * 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.crypto.cms;
+
+import java.io.InputStream;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.crypto.cms.crypt.DefaultKeyTransRecipientInfo;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsVerifierCertificateNotValidException;
+import org.apache.camel.component.crypto.cms.sig.DefaultSignerInfo;
+import org.apache.camel.component.crypto.cms.util.KeystoreUtil;
+import org.apache.camel.component.crypto.cms.util.TestAttributesGeneratorProvider;
+import org.apache.camel.component.crypto.cms.util.TestOriginatorInformationProvider;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.SimpleRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.camel.util.jsse.KeyStoreParameters;
+import org.junit.Test;
+
+public class ComponentTest extends CamelTestSupport {
+
+    private SimpleRegistry simpleReg;
+
+    @Test
+    public void execute() throws Exception {
+
+        String message = "Testmessage";
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedBodiesReceived(message);
+        sendBody("direct:start", message.getBytes("UTF-8"));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void signedWithOutdatedCert() throws Exception {
+
+        String message = "Testmessage";
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(0);
+        MockEndpoint mockException = getMockEndpoint("mock:exception");
+        mockException.expectedMessageCount(1);
+
+        sendBody("direct:outdated", message.getBytes("UTF-8"));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void decryptAndVerify() throws Exception {
+
+        InputStream input = this.getClass().getClassLoader().getResourceAsStream("signed_enveloped_other_CMS_vendor.binary");
+        assertNotNull(input);
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedBodiesReceived("Testmessage");
+        sendBody("direct:decryptAndVerify", input);
+
+        assertMockEndpointsSatisfied();
+
+        input.close();
+
+    }
+
+    @Test
+    public void orignatorUnprotectedAttributes() throws Exception {
+
+        String message = "Testmessage";
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedBodiesReceived(message);
+        sendBody("direct:encryptDecryptOriginatorAttributes", message.getBytes("UTF-8"));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    protected CamelContext createCamelContext() throws Exception {
+        simpleReg = new SimpleRegistry();
+        CamelContext context = new DefaultCamelContext(simpleReg);
+        return context;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                context.setTracing(true);
+                context.setStreamCaching(true);
+
+                KeyStoreParameters keystore = KeystoreUtil.getKeyStoreParameters("system.jks");
+
+                DefaultKeyTransRecipientInfo recipient = new DefaultKeyTransRecipientInfo();
+                recipient.setCertificateAlias("rsa");
+                recipient.setKeyStoreParameters(keystore);
+
+                DefaultSignerInfo signerInfo = new DefaultSignerInfo();
+                signerInfo.setIncludeCertificates(true); // optional default
+                                                         // value is true
+                signerInfo.setSignatureAlgorithm("SHA256withRSA"); // mandatory
+                signerInfo.setPrivateKeyAlias("rsa");
+                signerInfo.setKeyStoreParameters(keystore);
+
+                DefaultSignerInfo signerInfo2 = new DefaultSignerInfo();
+                signerInfo2.setSignatureAlgorithm("SHA256withDSA"); // mandatory
+                signerInfo2.setPrivateKeyAlias("dsa");
+                signerInfo2.setKeyStoreParameters(keystore);
+
+                getContext().addComponent("crypto-cms", new CryptoCmsComponent(getContext()));
+
+                simpleReg.put("keyStoreParameters", keystore);
+                simpleReg.put("signer1", signerInfo);
+                simpleReg.put("signer2", signerInfo2);
+                simpleReg.put("recipient1", recipient);
+
+                onException(CryptoCmsVerifierCertificateNotValidException.class).handled(false).to("mock:exception");
+
+                from("direct:start").to("crypto-cms:sign://testsign?signer=#signer1&signer=#signer2&includeContent=true")
+                    .to("crypto-cms:encrypt://testencrpyt?toBase64=true&recipient=#recipient1&contentEncryptionAlgorithm=DESede/CBC/PKCS5Padding&secretKeyLength=128")
+                    // .to("file:target/test_signed_encrypted.base64")
+                    .to("crypto-cms:decrypt://testdecrypt?fromBase64=true&keyStoreParameters=#keyStoreParameters")
+                    .to("crypto-cms:verify://testverify?keyStoreParameters=#keyStoreParameters").convertBodyTo(String.class).to("log:after").to("mock:result");
+
+                DefaultSignerInfo signerOutdated = new DefaultSignerInfo();
+                signerOutdated.setIncludeCertificates(false);
+                signerOutdated.setSignatureAlgorithm("SHA1withRSA");
+                signerOutdated.setPrivateKeyAlias("outdated");
+                signerOutdated.setKeyStoreParameters(keystore);
+                simpleReg.put("signerOutdated", signerOutdated);
+
+                from("direct:outdated").to("crypto-cms:sign://outdated?signer=#signerOutdated&includeContent=true")
+                    .to("crypto-cms:verify://outdated?keyStoreParameters=#keyStoreParameters").to("mock:result");
+
+                from("direct:decryptAndVerify").to("crypto-cms:decrypt://testdecrypt?fromBase64=true&keyStoreParameters=#keyStoreParameters")
+                    .to("crypto-cms:verify://testverify?keyStoreParameters=#keyStoreParameters").to("mock:result");
+
+                TestOriginatorInformationProvider originatorInformationProvider = new TestOriginatorInformationProvider();
+                TestAttributesGeneratorProvider attributesGeneratorProvider = new TestAttributesGeneratorProvider();
+                simpleReg.put("originatorInformationProvider1", originatorInformationProvider);
+                simpleReg.put("attributesGeneratorProvider1", attributesGeneratorProvider);
+
+                from("direct:encryptDecryptOriginatorAttributes")
+                    .to("crypto-cms:encrypt://testencrpyt?toBase64=true&recipient=#recipient1&contentEncryptionAlgorithm=DESede/CBC/PKCS5Padding&secretKeyLength=128&"
+                        + "originatorInformationProvider=#originatorInformationProvider1&unprotectedAttributesGeneratorProvider=#attributesGeneratorProvider1")
+                    .to("crypto-cms:decrypt://testdecrypt?fromBase64=true&keyStoreParameters=#keyStoreParameters").to("mock:result");
+            }
+        };
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void wrongOperation() throws Exception {
+        CryptoCmsComponent c = new CryptoCmsComponent(new DefaultCamelContext());
+        c.createEndpoint("uri", "wrongoperation", null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/EnvelopedDataTest.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/EnvelopedDataTest.java b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/EnvelopedDataTest.java
new file mode 100644
index 0000000..49579bd
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/EnvelopedDataTest.java
@@ -0,0 +1,430 @@
+/**
+ * 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.crypto.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.crypt.DefaultEnvelopedDataDecryptorConfiguration;
+import org.apache.camel.component.crypto.cms.crypt.DefaultKeyTransRecipientInfo;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataDecryptor;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataEncryptor;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataEncryptorConfiguration;
+import org.apache.camel.component.crypto.cms.crypt.RecipientInfo;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsFormatException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsNoCertificateForRecipientsException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsNoKeyOrCertificateForAliasException;
+import org.apache.camel.component.crypto.cms.util.ExchangeUtil;
+import org.apache.camel.component.crypto.cms.util.KeystoreUtil;
+import org.apache.camel.util.jsse.KeyStoreParameters;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class EnvelopedDataTest {
+
+    @BeforeClass
+    public static void setUpProvider() {
+        Security.addProvider(new BouncyCastleProvider());
+    }
+
+    @Test
+    public void executeDESedeCBClength192() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "DESede/CBC/PKCS5Padding", 192);
+    }
+
+    @Test
+    public void executeDESedeCBClength128() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "DESede/CBC/PKCS5Padding", 128);
+    }
+
+    @Test
+    public void executeDESCBCkeyLength64() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "DES/CBC/PKCS5Padding", 64);
+    }
+
+    @Test
+    public void executeDESCBCkeyLength56() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "DES/CBC/PKCS5Padding", 56);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength128() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 128);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength120() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 120);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength112() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 112);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength104() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 104);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength96() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 96);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength88() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 88);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength80() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 80);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength72() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 72);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength64() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 64);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength56() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 56);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength48() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 48);
+    }
+
+    @Test
+    public void executeCAST5CBCkeyLength40() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "CAST5/CBC/PKCS5Padding", 40);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength128() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 128);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength120() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 120);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength112() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 112);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength104() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 104);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength96() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 96);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength88() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 88);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength80() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 80);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength72() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 72);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength64() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 64);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength56() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 56);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength48() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 48);
+    }
+
+    @Test
+    public void executeRC2CBCkeyLength40() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC2/CBC/PKCS5Padding", 40);
+    }
+
+    @Test
+    public void executeCamelliaCBCKeySize128() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "Camellia/CBC/PKCS5Padding", 128);
+    }
+
+    /** Works if strong encryption policy jars are installed. */
+    @Ignore
+    @Test(expected = CryptoCmsException.class)
+    public void executeCamelliaCBCKeySize256() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "Camellia/CBC/PKCS5Padding", 256);
+    }
+
+    /** Works if strong encryption policy jars are installed. */
+    @Ignore
+    @Test(expected = CryptoCmsException.class)
+    public void executeCamelliaCBCKeySize192() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "Camellia/CBC/PKCS5Padding", 192);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNoInWhiteListCamellia256CBC() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "Camellia256/CBC/PKCS5Padding", 256);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListCamellia192CBC() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "Camellia192/CBC/PKCS5Padding", 192);
+    }
+
+    /** Works if strong encryption policy jars are installed. */
+    @Ignore
+    @Test(expected = CryptoCmsException.class)
+    public void executeAESCBCKeySize256() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES/CBC/PKCS5Padding", 256);
+    }
+
+    /** Works if strong encryption policy jars are installed. */
+    @Ignore
+    @Test(expected = CryptoCmsException.class)
+    public void executeAESCBCKeySize192() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES/CBC/PKCS5Padding", 192);
+    }
+
+    @Test
+    public void executeAESCBCKeySize128() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES/CBC/PKCS5Padding", 128);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListAES256CBC() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES256/CBC/PKCS5Padding", 256);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListAES192CBC() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES192/CBC/PKCS5Padding", 192);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executerNoImplRSAECB() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RSA/ECB/OAEP", 0);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListAESGCM() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES/GCM/NoPadding", 128);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListAES192GCM() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES192/GCM/NoPadding", 192);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListAES256GCM() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES256/GCM/NoPadding", 256);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListAES256CCM() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES256/CCM/NoPadding", 256);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListIDEACBC() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "IDEA/CBC/PKCS5Padding", 128);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListAESCCM() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES/CCM/NoPadding", 128);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListAES192CCM() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "AES192/CCM/NoPadding", 192);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void executeNotInWhiteListRC5CBC() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "RC5/CBC/PKCS5Padding", 0);
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void wrongSecretKeyLength() throws Exception {
+        encrypt("system.jks", "DESede/CBC/PKCS5Padding", 200, "testMessage", "rsa");
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void wrongContentEncryptionAlgorithm() throws Exception {
+        encryptDecrypt("system.jks", "rsa", "WrongDESede/CBC/PKCS5Padding", 200);
+    }
+
+    @Test(expected = CryptoCmsNoKeyOrCertificateForAliasException.class)
+    public void wrongEncryptAlias() throws Exception {
+        encrypt("system.jks", "DESede/CBC/PKCS5Padding", 128, "testMessage", "wrongAlias");
+    }
+
+    @Test(expected = CryptoCmsNoKeyOrCertificateForAliasException.class)
+    public void encryptWrongAliasAndCorrectAlias() throws Exception {
+        encrypt("system.jks", "DESede/CBC/PKCS5Padding", 128, "testMessage", "wrongAlias", "rsa");
+    }
+
+    @Test(expected = CryptoCmsNoKeyOrCertificateForAliasException.class)
+    public void encryptTwoWrongAliases() throws Exception {
+        encrypt("system.jks", "DESede/CBC/PKCS5Padding", 128, "testMessage", "wrongAlias", "wrongAlias2");
+    }
+
+    @Test
+    public void encryptTwoCorrectAliases() throws Exception {
+        encrypt("system.jks", "DESede/CBC/PKCS5Padding", 128, "testMessage", "rsa2", "rsa");
+    }
+
+    @Test(expected = CryptoCmsFormatException.class)
+    public void wrongEncryptedMessage() throws Exception {
+        decrypt("system.jks", "TestMessage".getBytes());
+    }
+
+    @Test(expected = CryptoCmsFormatException.class)
+    public void wrongEncryptedEmptyMessage() throws Exception {
+        decrypt("system.jks", new byte[0]);
+    }
+
+    @Test
+    public void decryptionWithEmptyAlias() throws Exception {
+
+        byte[] bytes = null;
+        try {
+            bytes = encrypt("system.jks", "DESede/CBC/PKCS5Padding", 192, "Test Message", "rsa");
+        } catch (Exception e) {
+            Assert.fail("Unexpected exception: " + e.getMessage());
+        }
+        decrypt("system.jks", bytes);
+    }
+
+    @Test(expected = CryptoCmsNoCertificateForRecipientsException.class)
+    public void decryptionWithNullAliasWrongKeystore() throws Exception {
+
+        byte[] bytes = null;
+        try {
+            bytes = encrypt("system.jks", "DESede/CBC/PKCS5Padding", 192, "Test Message", "rsa");
+        } catch (Exception e) {
+            Assert.fail("Unexpected exception: " + e.getMessage());
+        }
+        decrypt("test.jks", bytes);
+    }
+
+    // @Test
+    // public void invalidContentTypeEnvelopedData() throws Exception {
+    // try {
+    // encryptDecrypt("system.jks", "rsa", "DESede/CBC/PKCS5Padding", 192,
+    // CmsEnvelopedDataDecryptorConfiguration.SIGNEDANDENVELOPEDDATA);
+    // } catch (CmsException e) {
+    // Assert.assertTrue(e.getMessage().contains("The PKCS#7/CMS decryptor step
+    // does not accept PKCS#7/CMS messages of content type 'Enveloped Data'"));
+    // return;
+    // }
+    // Assert.fail("Exception expected");
+    // }
+
+    private void encryptDecrypt(String keystoreName, String alias, String contentEncryptionAlgorithm, int secretKeyLength) throws Exception {
+        String message = "Test Message";
+
+        byte[] encrypted = encrypt(keystoreName, contentEncryptionAlgorithm, secretKeyLength, message, alias);
+        byte[] decrypted = decrypt(keystoreName, encrypted);
+
+        String actual = new String(decrypted, "UTF-8");
+        Assert.assertEquals(message, actual);
+    }
+
+    private byte[] encrypt(String keystoreName, String contentEncryptionAlgorithm, int secretKeyLength, String message, String... aliases)
+        throws UnsupportedEncodingException, Exception {
+        KeyStoreParameters keystorePas = KeystoreUtil.getKeyStoreParameters(keystoreName);
+
+        List<RecipientInfo> recipients = new ArrayList<RecipientInfo>(aliases.length);
+        for (String alias : aliases) {
+            DefaultKeyTransRecipientInfo recipient = new DefaultKeyTransRecipientInfo();
+            recipient.setCertificateAlias(alias);
+            recipient.setKeyStoreParameters(keystorePas);
+            recipients.add(recipient);
+        }
+
+        EnvelopedDataEncryptorConfiguration enConf = new EnvelopedDataEncryptorConfiguration(null);
+        enConf.setContentEncryptionAlgorithm(contentEncryptionAlgorithm);
+        for (RecipientInfo recipient : recipients) {
+            enConf.setRecipient(recipient);
+        }
+        enConf.setSecretKeyLength(secretKeyLength); // optional
+        // enConf.setBlockSize(2048); // optional
+        enConf.init();
+        EnvelopedDataEncryptor encryptor = new EnvelopedDataEncryptor(enConf);
+
+        Exchange exchange = ExchangeUtil.getExchange();
+        exchange.getIn().setBody(new ByteArrayInputStream(message.getBytes("UTF-8")));
+        encryptor.process(exchange);
+        byte[] encrypted = (byte[])exchange.getOut().getBody();
+        return encrypted;
+    }
+
+    private byte[] decrypt(String keystoreName, byte[] encrypted) throws UnsupportedEncodingException, Exception, IOException {
+
+        KeyStoreParameters keystore = KeystoreUtil.getKeyStoreParameters(keystoreName);
+
+        Exchange exchangeDecrypt = ExchangeUtil.getExchange();
+        exchangeDecrypt.getIn().setBody(new ByteArrayInputStream(encrypted));
+
+        DefaultEnvelopedDataDecryptorConfiguration conf = new DefaultEnvelopedDataDecryptorConfiguration();
+        conf.setKeyStoreParameters(keystore);
+        EnvelopedDataDecryptor decryptor = new EnvelopedDataDecryptor(conf);
+
+        decryptor.process(exchangeDecrypt);
+
+        byte[] decrypted = (byte[])exchangeDecrypt.getOut().getBody();
+
+        return decrypted;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/ProcessorsTest.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/ProcessorsTest.java b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/ProcessorsTest.java
new file mode 100644
index 0000000..4aefdfa
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/ProcessorsTest.java
@@ -0,0 +1,120 @@
+/**
+ * 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.crypto.cms;
+
+import java.security.Security;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.crypto.cms.crypt.DefaultEnvelopedDataDecryptorConfiguration;
+import org.apache.camel.component.crypto.cms.crypt.DefaultKeyTransRecipientInfo;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataDecryptor;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataEncryptor;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataEncryptorConfiguration;
+import org.apache.camel.component.crypto.cms.sig.DefaultSignedDataVerifierConfiguration;
+import org.apache.camel.component.crypto.cms.sig.DefaultSignerInfo;
+import org.apache.camel.component.crypto.cms.sig.SignedDataCreator;
+import org.apache.camel.component.crypto.cms.sig.SignedDataCreatorConfiguration;
+import org.apache.camel.component.crypto.cms.sig.SignedDataVerifier;
+import org.apache.camel.component.crypto.cms.util.KeystoreUtil;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.SimpleRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.camel.util.jsse.KeyStoreParameters;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class ProcessorsTest extends CamelTestSupport {
+
+    private SimpleRegistry simpleReg;
+
+    @BeforeClass
+    public static void setUpProvider() {
+        Security.addProvider(new BouncyCastleProvider());
+    }
+
+    @Test
+    public void execute() throws Exception {
+
+        String message = "Testmessage";
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedBodiesReceived(message);
+        sendBody("direct:start", message);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    protected CamelContext createCamelContext() throws Exception {
+        simpleReg = new SimpleRegistry();
+        CamelContext context = new DefaultCamelContext(simpleReg);
+        return context;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                context.setTracing(true);
+
+                String keystoreName = "system.jks";
+                KeyStoreParameters keystore = KeystoreUtil.getKeyStoreParameters(keystoreName);
+
+                DefaultKeyTransRecipientInfo recipient = new DefaultKeyTransRecipientInfo();
+                recipient.setCertificateAlias("rsa");
+                recipient.setKeyStoreParameters(keystore);
+
+                EnvelopedDataEncryptorConfiguration enConf = new EnvelopedDataEncryptorConfiguration(context);
+                enConf.setContentEncryptionAlgorithm("DESede/CBC/PKCS5Padding");
+                enConf.setRecipient(recipient);
+                enConf.setSecretKeyLength(192); // mandatory
+                enConf.init();
+                EnvelopedDataEncryptor encryptor = new EnvelopedDataEncryptor(enConf);
+
+                DefaultEnvelopedDataDecryptorConfiguration conf = new DefaultEnvelopedDataDecryptorConfiguration();
+                conf.setKeyStoreParameters(keystore);
+                EnvelopedDataDecryptor decryptor = new EnvelopedDataDecryptor(conf);
+
+                DefaultSignerInfo signerInfo = new DefaultSignerInfo();
+
+                signerInfo.setIncludeCertificates(true); // optional default
+                                                         // value is true
+                signerInfo.setSignatureAlgorithm("SHA256withRSA"); // mandatory
+                signerInfo.setPrivateKeyAlias("rsa");
+                signerInfo.setKeyStoreParameters(keystore);
+
+                SignedDataCreatorConfiguration config = new SignedDataCreatorConfiguration(new DefaultCamelContext());
+                config.setSigner(signerInfo);
+                config.setIncludeContent(true); // optional default value is
+                                                // true
+                config.init();
+                SignedDataCreator signer = new SignedDataCreator(config);
+
+                DefaultSignedDataVerifierConfiguration verifierConf = new DefaultSignedDataVerifierConfiguration();
+                verifierConf.setKeyStoreParameters(keystore);
+
+                SignedDataVerifier verifier = new SignedDataVerifier(verifierConf);
+
+                from("direct:start").to("log:before").process(signer).process(encryptor).to("log:signed_encrypted").process(decryptor).process(verifier).convertBodyTo(String.class)
+                    .to("log:after").to("mock:result");
+
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/SignedDataTest.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/SignedDataTest.java b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/SignedDataTest.java
new file mode 100644
index 0000000..9d4b448
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/SignedDataTest.java
@@ -0,0 +1,483 @@
+/**
+ * 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.crypto.cms;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsConstants;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsFormatException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsInvalidKeyException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsNoCertificateForSignerInfoException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsNoCertificateForSignerInfosException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsNoKeyOrCertificateForAliasException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsSignatureInvalidContentHashException;
+import org.apache.camel.component.crypto.cms.sig.DefaultSignedDataVerifierConfiguration;
+import org.apache.camel.component.crypto.cms.sig.DefaultSignerInfo;
+import org.apache.camel.component.crypto.cms.sig.SignedDataCreator;
+import org.apache.camel.component.crypto.cms.sig.SignedDataCreatorConfiguration;
+import org.apache.camel.component.crypto.cms.sig.SignedDataVerifier;
+import org.apache.camel.component.crypto.cms.sig.SignedDataVerifierFromHeader;
+import org.apache.camel.component.crypto.cms.sig.SignerInfo;
+import org.apache.camel.component.crypto.cms.util.ExchangeUtil;
+import org.apache.camel.component.crypto.cms.util.KeystoreUtil;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.jsse.KeyStoreParameters;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+public class SignedDataTest {
+
+    @BeforeClass
+    public static void setUpProvider() {
+        Security.addProvider(new BouncyCastleProvider());
+    }
+
+    @Test
+    public void testWithCertificatesIncluded() throws Exception {
+        signAndVerify("Test Message", "system.jks", "SHA1withRSA", "rsa", true, true);
+    }
+
+    @Test
+    public void testWithCertificatesIncludedNoSignedAttributes() throws Exception {
+        signAndVerify("Test Message", "system.jks", "SHA1withRSA", "rsa", true, true);
+    }
+
+    @Test
+    public void testWithCertificatesIncludedTimestampSignedAttribute() throws Exception {
+        signAndVerify("Test Message", "system.jks", "SHA1withRSA", "rsa", true, true);
+    }
+
+    @Test
+    public void testWithCertificatesIncludedCertificateSignedAttribute() throws Exception {
+        signAndVerify("Test Message", "system.jks", "SHA1withRSA", "rsa", true, true);
+    }
+
+    @Test
+    public void testWithoutCertificatesIncludedAndDigestAlgorithmSHA1andSignatureAlgorithm() throws Exception {
+        signAndVerify("Test Message", "system.jks", "SHA1withDSA", "dsa", true, false);
+    }
+
+    private void signAndVerify(String message, String keystoreName, String signatureAlgorithm, String alias, boolean includeContent, boolean includeCertificates)
+        throws UnsupportedEncodingException, Exception {
+
+        byte[] signed = sign(message, keystoreName, signatureAlgorithm, includeContent, includeCertificates, alias);
+        byte[] result = verify(keystoreName, alias, signed, false);
+
+        Assert.assertEquals(message, new String(result, "UTF-8"));
+    }
+
+    private byte[] sign(String message, String keystoreName, String signatureAlgorithm, boolean includeContent, boolean includeCertificates, String... aliases)
+        throws UnsupportedEncodingException, Exception {
+        KeyStoreParameters keystore = KeystoreUtil.getKeyStoreParameters(keystoreName);
+
+        List<SignerInfo> signers = new ArrayList<SignerInfo>(aliases.length);
+        for (String alias : aliases) {
+            DefaultSignerInfo signerInfo = new DefaultSignerInfo();
+            signerInfo.setIncludeCertificates(includeCertificates); // without
+                                                                    // certificates,
+                                                                    // optional
+                                                                    // default
+                                                                    // value is
+                                                                    // true
+            signerInfo.setSignatureAlgorithm(signatureAlgorithm); // mandatory
+            signerInfo.setPrivateKeyAlias(alias);
+            signerInfo.setKeyStoreParameters(keystore);
+            signers.add(signerInfo);
+        }
+
+        SignedDataCreatorConfiguration config = new SignedDataCreatorConfiguration(new DefaultCamelContext());
+        for (SignerInfo signer : signers) {
+            config.setSigner(signer);
+        }
+        // config.setBlockSize(blockSize); // optional
+        config.setIncludeContent(includeContent); // optional default value is
+                                                  // true
+        config.init();
+        SignedDataCreator signer = new SignedDataCreator(config);
+
+        Exchange exchange = ExchangeUtil.getExchange();
+        exchange.getIn().setBody(new ByteArrayInputStream(message.getBytes("UTF-8")));
+        signer.process(exchange);
+        byte[] signed = (byte[])exchange.getOut().getBody();
+        return signed;
+    }
+
+    private byte[] verify(String keystoreName, String alias, byte[] signed, boolean base64) throws Exception, UnsupportedEncodingException {
+        DefaultSignedDataVerifierConfiguration verifierConf = getCryptoCmsSignedDataVerifierConf(keystoreName, Collections.singletonList(alias), base64);
+
+        SignedDataVerifier verifier = new SignedDataVerifier(verifierConf);
+
+        InputStream is = new BufferedInputStream(new ByteArrayInputStream(signed));
+        Exchange exchangeVeri = ExchangeUtil.getExchange();
+        exchangeVeri.getIn().setBody(is);
+        verifier.process(exchangeVeri);
+        byte[] result = (byte[])exchangeVeri.getOut().getBody();
+        return result;
+    }
+
+    DefaultSignedDataVerifierConfiguration getCryptoCmsSignedDataVerifierConf(String keystoreName, Collection<String> aliases, boolean base64)
+        throws GeneralSecurityException, IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
+        KeyStoreParameters keystorePas = KeystoreUtil.getKeyStoreParameters(keystoreName);
+        KeyStore keystore = keystorePas.createKeyStore();
+
+        KeyStore verifierKeystore = KeyStore.getInstance("JCEKS");
+        verifierKeystore.load(null, "".toCharArray());
+        // add only verifier certs
+        for (String alias : aliases) {
+            Certificate verifierCert = keystore.getCertificate(alias);
+            if (verifierCert != null) {
+                verifierKeystore.setCertificateEntry(alias, verifierCert);
+            }
+        }
+        DefaultSignedDataVerifierConfiguration verifierConf = new DefaultSignedDataVerifierConfiguration();
+
+        verifierConf.setKeyStore(verifierKeystore);
+        verifierConf.setFromBase64(base64);
+        return verifierConf;
+    }
+
+    @Test
+    public void signWithTwoAliases() throws Exception {
+        sign("", "system.jks", "SHA1withRSA", true, false, "rsa", "rsa2");
+    }
+
+    @Test(expected = CryptoCmsNoKeyOrCertificateForAliasException.class)
+    public void signWithTwoAliasesOneWithNoPrivateKeyInKeystore() throws Exception {
+        sign("Test Message", "system.jks", "SHA1withDSA", true, false, "dsa", "noEntry");
+    }
+
+    @Test(expected = CryptoCmsNoKeyOrCertificateForAliasException.class)
+    public void signWrongAlias() throws Exception {
+        sign("Test Message", "system.jks", "SHA1withDSA", true, false, "wrong");
+
+    }
+
+    @Test
+    public void signEmptyContent() throws Exception {
+        sign("", "system.jks", "SHA1withDSA", true, false, "dsa");
+    }
+
+    @Test(expected = CryptoCmsInvalidKeyException.class)
+    public void signSignatureAlgorithmNotCorrespondingToPrivateKey() throws Exception {
+        sign("testMessage", "system.jks", "MD5withRSA", true, false, "dsa");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void signWrongSignatureAlgorithm() throws Exception {
+        sign("testMessage", "system.jks", "wrongRSA", true, false, "rsa");
+    }
+
+    @Test
+    public void verifySignedDataWithoutSignedContent() throws Exception {
+        InputStream is = SignedDataTest.class.getClassLoader().getResourceAsStream("detached_signature.binary");
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        IOHelper.copy(is, os);
+        byte[] signed = os.toByteArray();
+        try {
+            verify("system.jks", "rsa", signed, false);
+        } catch (CryptoCmsException e) {
+            String message = e.getMessage();
+            assertEquals("PKCS7/CMS signature validation not possible: The content for which the hash-value must be calculated is missing in the PKCS7/CMS signed data instance. "
+                         + "Please check the configuration of the sender of the PKCS7/CMS signature.", message);
+            return;
+        }
+        fail("Exception expected");
+    }
+
+    @Test(expected = CryptoCmsNoCertificateForSignerInfosException.class)
+    public void verifyNoVerifierCerts() throws Exception {
+
+        byte[] signed = sign("Test Message", "system.jks", "SHA1withRSA", true, true, "rsa");
+
+        verify("system.jks", "wrongAlias", signed, false); // wrongAlias means
+                                                           // that no
+                                                           // certificates are
+                                                           // added to the
+                                                           // verifier keystore
+    }
+
+    @Test(expected = CryptoCmsFormatException.class)
+    public void verifyWrongFormat() throws Exception {
+
+        verify("system.jks", "rsa", "test".getBytes(), false);
+    }
+
+    @Test(expected = CryptoCmsFormatException.class)
+    public void verifyWrongFormatInHeader() throws Exception {
+
+        verifyContentWithSeparateSignature(new ByteArrayInputStream("ABCDEFG1ABCDEFG1ABCDEFG1".getBytes()), new ByteArrayInputStream("ABCDEFG1ABCDEFG1ABCDEFG1".getBytes()), "rsa");
+    }
+
+    @Test
+    public void verifyContentWithSeparateSignature() throws Exception {
+
+        InputStream message = new ByteArrayInputStream("Test Message".getBytes(StandardCharsets.UTF_8));
+
+        InputStream signature = this.getClass().getClassLoader().getResourceAsStream("detached_signature.binary");
+        assertNotNull(signature);
+
+        verifyContentWithSeparateSignature(message, signature, "rsa");
+    }
+
+    @Test(expected = CryptoCmsSignatureInvalidContentHashException.class)
+    public void verifyContentWithSeparateSignatureWrongContent() throws Exception {
+
+        InputStream message = new ByteArrayInputStream("Wrong Message".getBytes());
+
+        InputStream signature = this.getClass().getClassLoader().getResourceAsStream("detached_signature.binary");
+        assertNotNull(signature);
+
+        verifyContentWithSeparateSignature(message, signature, "rsa");
+
+    }
+
+    private void verifyContentWithSeparateSignature(InputStream content, InputStream signature, String alias) throws Exception {
+
+        DefaultSignedDataVerifierConfiguration verifierConf = getCryptoCmsSignedDataVerifierConf("system.jks", Collections.singletonList(alias), Boolean.FALSE);
+        SignedDataVerifier verifier = new SignedDataVerifierFromHeader(verifierConf);
+
+        Exchange exchange = ExchangeUtil.getExchange();
+        exchange.getIn().setBody(content);
+        exchange.getIn().setHeader(CryptoCmsConstants.CAMEL_CRYPTO_CMS_SIGNED_DATA, signature);
+        verifier.process(exchange);
+    }
+
+    @Test
+    public void verifyWithServeralAliases() throws Exception {
+        verifyDetachedSignatureWithKeystore("system.jks", "rsa", "rsa2");
+    }
+
+    @Test
+    public void verifyWithServeralAliasesOneWithNoEntryInKeystore() throws Exception {
+        verifyDetachedSignatureWithKeystore("system.jks", "noEntry", "rsa");
+    }
+
+    @Test(expected = CryptoCmsException.class)
+    public void verifyWithEmptyAlias() throws Exception {
+        verifyDetachedSignatureWithKeystore("system.jks", "");
+    }
+
+    @Test(expected = CryptoCmsNoCertificateForSignerInfoException.class)
+    public void verifyDetachedSignatureWithAliasNotFittingToSigner() throws Exception {
+        verifyDetachedSignatureWithKeystore("system.jks", "rsa2");
+    }
+
+    @Test(expected = CryptoCmsNoCertificateForSignerInfosException.class)
+    public void verifyDetachedSignatureWithAliasNotFittingToSignerWithVerifiyAllSignaturesFalse() throws Exception {
+        verifyDetachedSignatureWithKeystore("system.jks", Boolean.FALSE, "rsa2");
+    }
+
+    private void verifyDetachedSignatureWithKeystore(String keystoreName, String... aliases) throws FileNotFoundException, CryptoCmsException, Exception {
+        verifyDetachedSignatureWithKeystore(keystoreName, Boolean.TRUE, aliases);
+    }
+
+    private void verifyDetachedSignatureWithKeystore(String keystoreName, Boolean verifyAllSignatures, String... aliases)
+        throws FileNotFoundException, CryptoCmsException, Exception {
+
+        InputStream message = new ByteArrayInputStream("Test Message".getBytes(StandardCharsets.UTF_8));
+
+        assertNotNull(message);
+
+        DefaultSignedDataVerifierConfiguration verifierConf = getCryptoCmsSignedDataVerifierConf(keystoreName, Arrays.asList(aliases), Boolean.FALSE);
+        verifierConf.setVerifySignaturesOfAllSigners(verifyAllSignatures);
+
+        verifierConf.setSignedDataHeaderBase64(Boolean.TRUE);
+
+        SignedDataVerifier verifier = new SignedDataVerifierFromHeader(verifierConf);
+
+        InputStream signature = this.getClass().getClassLoader().getResourceAsStream("detached_signature.base64");
+        assertNotNull(signature);
+
+        Exchange exchange = ExchangeUtil.getExchange();
+        exchange.getIn().setBody(message);
+        exchange.getIn().setHeader(CryptoCmsConstants.CAMEL_CRYPTO_CMS_SIGNED_DATA, signature);
+        verifier.process(exchange);
+    }
+
+    @Test
+    public void signatureAndContentSeparatedExplicitMode() throws Exception {
+        String keystoreName = "system.jks";
+        String alias = "rsa";
+        KeyStoreParameters keystore = KeystoreUtil.getKeyStoreParameters(keystoreName);
+
+        DefaultSignerInfo signerInfo = new DefaultSignerInfo();
+        signerInfo.setIncludeCertificates(false); // without certificates,
+                                                  // optional default value is
+                                                  // true
+        signerInfo.setSignatureAlgorithm("SHA1withRSA"); // mandatory
+        signerInfo.setPrivateKeyAlias(alias);
+        signerInfo.setKeyStoreParameters(keystore);
+
+        SignedDataCreatorConfiguration config = new SignedDataCreatorConfiguration(new DefaultCamelContext());
+        config.setSigner(signerInfo);
+        config.setIncludeContent(false); // optional default value is true
+        config.setToBase64(Boolean.TRUE);
+        config.init();
+        SignedDataCreator signer = new SignedDataCreator(config);
+
+        String message = "Test Message";
+
+        Exchange exchange = ExchangeUtil.getExchange();
+
+        exchange.getIn().setBody(new ByteArrayInputStream(message.getBytes(StandardCharsets.UTF_8)));
+        signer.process(exchange);
+
+        byte[] signature = exchange.getOut().getHeader(CryptoCmsConstants.CAMEL_CRYPTO_CMS_SIGNED_DATA, byte[].class);
+
+        DefaultSignedDataVerifierConfiguration verifierConf = getCryptoCmsSignedDataVerifierConf(keystoreName, Collections.singleton(alias), Boolean.FALSE);
+        verifierConf.setSignedDataHeaderBase64(Boolean.TRUE);
+
+        SignedDataVerifier verifier = new SignedDataVerifierFromHeader(verifierConf);
+
+        exchange = ExchangeUtil.getExchange();
+        exchange.getIn().setBody(new ByteArrayInputStream(message.getBytes(StandardCharsets.UTF_8)));
+        exchange.getIn().setHeader(CryptoCmsConstants.CAMEL_CRYPTO_CMS_SIGNED_DATA, new ByteArrayInputStream(signature));
+        verifier.process(exchange);
+    }
+
+    private void signAndVerifyByDSASigAlgorithm(String sigAlgorithm) throws UnsupportedEncodingException, Exception {
+        // digest algorithm is calculated
+        signAndVerify("Test Message", "system.jks", sigAlgorithm, "dsa", true, false);
+    }
+
+    private void signAndVerifyByRSASigAlgorithm(String sigAlgorithm) throws UnsupportedEncodingException, Exception {
+        // digest algorithm is calculated
+        signAndVerify("Test Message", "system.jks", sigAlgorithm, "rsa", true, false);
+    }
+
+    @Test
+    public void testSigAlgorithmSHADSA() throws Exception {
+        signAndVerifyByDSASigAlgorithm("SHA1withDSA");
+    }
+
+    // SHA224withDSA
+    @Test
+    public void testSigAlgorithmSHA224withDSA() throws Exception {
+        signAndVerifyByDSASigAlgorithm("SHA224withDSA");
+    }
+
+    // SHA256withDSA
+    @Test
+    public void testSigAlgorithmSHA256withDSA() throws Exception {
+        signAndVerifyByDSASigAlgorithm("SHA256withDSA");
+    }
+
+    // SHA1withECDSA // ECSDSA keys not supported
+    @Test(expected = CryptoCmsException.class)
+    public void testSigAlgorithmSHA1withECDSA() throws Exception {
+        signAndVerifyByDSASigAlgorithm("SHA1withECDSA");
+    }
+
+    // MD2withRSA
+    @Test
+    public void testSigAlgorithmMD2withRSA() throws Exception {
+        signAndVerifyByRSASigAlgorithm("MD2withRSA");
+    }
+
+    // MD5/RSA
+    // MD2withRSA
+    @Test
+    public void testSigAlgorithmMD5withRSA() throws Exception {
+        signAndVerifyByRSASigAlgorithm("MD5withRSA");
+    }
+
+    // SHA/RSA
+    @Test
+    public void testSigAlgorithmSHAwithRSA() throws Exception {
+        signAndVerifyByRSASigAlgorithm("SHA1withRSA"); // SHA/RSA");
+    }
+
+    // SHA224/RSA
+    @Test
+    public void testSigAlgorithmSHA224withRSA() throws Exception {
+        signAndVerifyByRSASigAlgorithm("SHA224withRSA");
+    }
+
+    // SHA256/RSA
+    @Test
+    public void testSigAlgorithmSHA256withRSA() throws Exception {
+        signAndVerifyByRSASigAlgorithm("SHA256withRSA");
+    }
+
+    // SHA384/RSA
+    @Test
+    public void testSigAlgorithmSHA384withRSA() throws Exception {
+        signAndVerifyByRSASigAlgorithm("SHA384withRSA");
+    }
+
+    // SHA512/RSA
+    @Test
+    public void testSigAlgorithmSHA512withRSA() throws Exception {
+        signAndVerifyByRSASigAlgorithm("SHA512withRSA");
+    }
+
+    // RIPEMD160/RSA
+    @Test
+    public void testSigAlgorithmRIPEMD160withRSA() throws Exception {
+        signAndVerifyByRSASigAlgorithm("RIPEMD160withRSA");
+    }
+
+    // RIPEMD128/RSA
+    @Test
+    public void testSigAlgorithmRIPEMD128withRSA() throws Exception {
+        signAndVerifyByRSASigAlgorithm("RIPEMD128withRSA");
+    }
+
+    // RIPEMD256/RSA
+    @Test
+    public void testSigAlgorithmRIPEMD256withRSA() throws Exception {
+        signAndVerifyByRSASigAlgorithm("RIPEMD256withRSA");
+    }
+
+    @Test(expected = CryptoCmsInvalidKeyException.class)
+    public void testSigAlgorithmDoesnotFitToDSAPrivateKey() throws Exception {
+        signAndVerifyByDSASigAlgorithm("RIPEMD128withRSA");
+    }
+
+    @Test(expected = CryptoCmsInvalidKeyException.class)
+    public void testSigAlgorithmDoesnotFitToRSAPrivateKey() throws Exception {
+        signAndVerifyByRSASigAlgorithm("SHA224withDSA");
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/ExchangeUtil.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/ExchangeUtil.java b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/ExchangeUtil.java
new file mode 100644
index 0000000..f4eb11f
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/ExchangeUtil.java
@@ -0,0 +1,40 @@
+/**
+ * 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.crypto.cms.util;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.DefaultExchange;
+import org.apache.camel.impl.DefaultMessage;
+
+public final class ExchangeUtil {
+
+    private ExchangeUtil() {
+    }
+
+    public static Exchange getExchange() {
+        CamelContext context = new DefaultCamelContext();
+        Message in = new DefaultMessage(context);
+        Message out = new DefaultMessage(context);
+        Exchange exchange = new DefaultExchange(context);
+        exchange.setIn(in);
+        exchange.setOut(out);
+        return exchange;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/KeystoreUtil.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/KeystoreUtil.java b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/KeystoreUtil.java
new file mode 100644
index 0000000..4381229
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/KeystoreUtil.java
@@ -0,0 +1,42 @@
+/**
+ * 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.crypto.cms.util;
+
+import org.apache.camel.util.jsse.KeyStoreParameters;
+
+public final class KeystoreUtil {
+
+    private KeystoreUtil() {
+
+    }
+
+    public static KeyStoreParameters getKeyStoreParameters(String keystoreName) {
+        KeyStoreParameters keystorePas = new KeyStoreParameters();
+        keystorePas.setType("JCEKS");
+        keystorePas.setResource("keystore/" + keystoreName);
+        String pw;
+        if (keystoreName.startsWith("test")) {
+            pw = "abcd1234";
+        } else {
+            pw = "";
+        }
+        keystorePas.setPassword(pw);
+        return keystorePas;
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/TestAttributesGeneratorProvider.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/TestAttributesGeneratorProvider.java b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/TestAttributesGeneratorProvider.java
new file mode 100644
index 0000000..e7f60f0
--- /dev/null
+++ b/components/camel-crypto-cms/src/test/java/org/apache/camel/component/crypto/cms/util/TestAttributesGeneratorProvider.java
@@ -0,0 +1,48 @@
+/**
+ * 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.crypto.cms.util;
+
+import java.util.Hashtable;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.common.AttributesGeneratorProvider;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.DERSet;
+import org.bouncycastle.asn1.DERUTF8String;
+import org.bouncycastle.asn1.cms.Attribute;
+import org.bouncycastle.asn1.cms.AttributeTable;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.cms.CMSAttributeTableGenerator;
+import org.bouncycastle.cms.SimpleAttributeTableGenerator;
+
+public class TestAttributesGeneratorProvider implements AttributesGeneratorProvider {
+    
+
+    @Override
+    public CMSAttributeTableGenerator getAttributesGenerator(Exchange excange) throws CryptoCmsException {
+        Hashtable<ASN1ObjectIdentifier, Attribute> attrs = new Hashtable<>();
+
+        attrs.put(PKCSObjectIdentifiers.id_aa_contentHint, new Attribute(PKCSObjectIdentifiers.id_aa_contentHint, new DERSet(new DERUTF8String("Hint"))));
+        attrs.put(PKCSObjectIdentifiers.id_aa_receiptRequest, new Attribute(PKCSObjectIdentifiers.id_aa_receiptRequest, new DERSet(new DERUTF8String("Request"))));
+
+        AttributeTable attrTable = new AttributeTable(attrs);
+
+        return new SimpleAttributeTableGenerator(attrTable);
+    }
+
+}

[4/4] camel git commit: CAMEL-11438 new component crypto-cms

Posted by fo...@apache.org.
CAMEL-11438 new component crypto-cms 

Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/b831203b
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/b831203b
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/b831203b

Branch: refs/heads/master
Commit: b831203b8e124dc7414a6aa0aba476aee79c2421
Parents: cf96ff4
Author: Franz Forsthofer <fr...@sap.com>
Authored: Tue Jul 25 10:16:54 2017 +0200
Committer: Franz Forsthofer <fr...@sap.com>
Committed: Tue Jul 25 10:16:54 2017 +0200

----------------------------------------------------------------------
 components/camel-crypto-cms/pom.xml             | 103 +++
 .../src/main/docs/crypto-cms-component.adoc     |  60 ++
 .../crypto/cms/CryptoCmsComponent.java          | 162 +++++
 .../component/crypto/cms/CryptoCmsEndpoint.java | 111 ++++
 .../component/crypto/cms/CryptoCmsProducer.java |  47 ++
 .../component/crypto/cms/CryptoOperation.java   |  22 +
 .../cms/common/AttributesGeneratorProvider.java |  32 +
 .../crypto/cms/common/CryptoCmsConstants.java   |  33 +
 .../cms/common/CryptoCmsMarshallerAbstract.java |  88 +++
 .../CryptoCmsMarshallerConfiguration.java       |  59 ++
 .../CryptoCmsUnMarshallerConfiguration.java     |  27 +
 .../cms/common/CryptoCmsUnmarshaller.java       | 117 ++++
 .../common/DefaultCryptoCmsConfiguration.java   |  72 +++
 ...faultCryptoCmsUnMarshallerConfiguration.java |  45 ++
 .../common/OriginatorInformationProvider.java   |  32 +
 ...aultEnvelopedDataDecryptorConfiguration.java | 121 ++++
 .../cms/crypt/DefaultKeyTransRecipientInfo.java |  94 +++
 .../cms/crypt/EnvelopedDataDecryptor.java       | 275 ++++++++
 .../EnvelopedDataDecryptorConfiguration.java    |  38 ++
 .../cms/crypt/EnvelopedDataEncryptor.java       | 122 ++++
 .../EnvelopedDataEncryptorConfiguration.java    | 283 ++++++++
 .../cms/crypt/PrivateKeyWithCertificate.java    |  44 ++
 .../crypto/cms/crypt/RecipientInfo.java         |  54 ++
 .../crypto/cms/crypt/TransRecipientInfo.java    |  45 ++
 .../cms/exception/CryptoCmsException.java       |  40 ++
 .../cms/exception/CryptoCmsFormatException.java |  37 ++
 .../exception/CryptoCmsInvalidKeyException.java |  33 +
 ...oCmsNoCertificateForRecipientsException.java |  31 +
 ...oCmsNoCertificateForSignerInfoException.java |  34 +
 ...CmsNoCertificateForSignerInfosException.java |  35 +
 ...oCmsNoKeyOrCertificateForAliasException.java |  45 ++
 .../exception/CryptoCmsSignatureException.java  |  33 +
 ...CmsSignatureInvalidContentHashException.java |  33 +
 ...CmsVerifierCertificateNotValidException.java |  31 +
 .../component/crypto/cms/exception/packageinfo  |   1 +
 .../DefaultSignedDataVerifierConfiguration.java | 105 +++
 .../crypto/cms/sig/DefaultSignerInfo.java       | 198 ++++++
 .../crypto/cms/sig/SignedDataCreator.java       | 129 ++++
 .../cms/sig/SignedDataCreatorConfiguration.java |  94 +++
 .../crypto/cms/sig/SignedDataVerifier.java      | 286 ++++++++
 .../sig/SignedDataVerifierConfiguration.java    |  55 ++
 .../cms/sig/SignedDataVerifierFromHeader.java   | 117 ++++
 .../component/crypto/cms/sig/SignerInfo.java    |  57 ++
 .../src/main/resources/META-INF/LICENSE.txt     | 203 ++++++
 .../src/main/resources/META-INF/NOTICE.txt      |  11 +
 .../org/apache/camel/component/crypto-cms       |  18 +
 .../component/crypto/cms/ComponentTest.java     | 170 +++++
 .../component/crypto/cms/EnvelopedDataTest.java | 430 ++++++++++++
 .../component/crypto/cms/ProcessorsTest.java    | 120 ++++
 .../component/crypto/cms/SignedDataTest.java    | 483 ++++++++++++++
 .../component/crypto/cms/util/ExchangeUtil.java |  40 ++
 .../component/crypto/cms/util/KeystoreUtil.java |  42 ++
 .../util/TestAttributesGeneratorProvider.java   |  48 ++
 .../util/TestOriginatorInformationProvider.java |  49 ++
 .../test/resources/detached_signature.base64    |   8 +
 .../test/resources/detached_signature.binary    | Bin 0 -> 406 bytes
 .../src/test/resources/keystore/system.jks      | Bin 0 -> 5697 bytes
 .../src/test/resources/keystore/test.jks        | Bin 0 -> 1245 bytes
 .../src/test/resources/log4j2.properties        |  29 +
 .../signed_enveloped_other_CMS_vendor.binary    |  28 +
 components/pom.xml                              |   1 +
 .../camel-crypto-cms-starter/pom.xml            |  53 ++
 .../CryptoCmsComponentAutoConfiguration.java    | 128 ++++
 .../CryptoCmsComponentConfiguration.java        |  82 +++
 .../src/main/resources/META-INF/LICENSE.txt     | 203 ++++++
 .../src/main/resources/META-INF/NOTICE.txt      |  11 +
 .../main/resources/META-INF/spring.factories    |  19 +
 .../src/main/resources/META-INF/spring.provides |  17 +
 .../spring-boot/components-starter/pom.xml      | 647 ++++++++++---------
 69 files changed, 5997 insertions(+), 323 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/pom.xml b/components/camel-crypto-cms/pom.xml
new file mode 100644
index 0000000..d68b7b5
--- /dev/null
+++ b/components/camel-crypto-cms/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.apache.camel</groupId>
+		<artifactId>components</artifactId>
+		<version>2.20.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>camel-crypto-cms</artifactId>
+	<packaging>jar</packaging>
+	<name>Camel :: Crypto CMS</name>
+	<description>Camel Cryptographic Message Syntax Support</description>
+
+	<properties>
+		<camel.osgi.export.pkg>
+			org.apache.camel.component.crypto.cms.*;${camel.osgi.version},
+		</camel.osgi.export.pkg>
+		<camel.osgi.import.pkg>
+			!org.apache.camel.component.crypto.cms.*,
+			${camel.osgi.import.defaults},
+			*
+		</camel.osgi.import.pkg>
+		<camel.osgi.export.service>
+			org.apache.camel.spi.ComponentResolver;component=crypto-cms,
+		</camel.osgi.export.service>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.camel</groupId>
+			<artifactId>camel-core</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>commons-codec</groupId>
+			<artifactId>commons-codec</artifactId>
+		</dependency>
+ 		<dependency>
+			<groupId>org.bouncycastle</groupId>
+			<artifactId>bcpkix-jdk15on</artifactId>
+			<version>${bouncycastle-version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.bouncycastle</groupId>
+			<artifactId>bcprov-jdk15on</artifactId>
+			<version>${bouncycastle-version}</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<!--  <version>${commons-io-version}</version> -->
+		</dependency> 
+
+		<!-- for testing -->
+		<dependency>
+			<groupId>org.apache.camel</groupId>
+			<artifactId>camel-test-spring</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+	</dependencies>
+
+</project>
+

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/docs/crypto-cms-component.adoc
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/docs/crypto-cms-component.adoc b/components/camel-crypto-cms/src/main/docs/crypto-cms-component.adoc
new file mode 100644
index 0000000..95f14d0
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/docs/crypto-cms-component.adoc
@@ -0,0 +1,60 @@
+## Crypto CMS Component
+
+*Available as of Camel version 2.20*
+
+
+### Options
+
+// component options: START
+The Crypto CMS component supports 3 options which are listed below.
+
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|=======================================================================
+| Name | Description | Default | Type
+| **signedDataVerifier Configuration** (advanced) | To configure the shared SignedDataVerifierConfiguration which determines the uri parameters for the verify operation. |  | SignedDataVerifier Configuration
+| **envelopedDataDecryptor Configuration** (advanced) | To configure the shared EnvelopedDataDecryptorConfiguration which determines the uri parameters for the decrypt operation. |  | EnvelopedDataDecryptor Configuration
+| **resolveProperty Placeholders** (advanced) | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | boolean
+|=======================================================================
+// component options: END
+
+// endpoint options: START
+The Crypto CMS endpoint is configured using URI syntax:
+
+    crypto-cms:cryptoOperation:name
+
+with the following path and query parameters:
+
+#### Path Parameters (2 parameters):
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|=======================================================================
+| Name | Description | Default | Type
+| **cryptoOperation** | *Required* Set the Crypto operation from that supplied after the crypto scheme in the endpoint uri e.g. crypto-cms:sign sets sign as the operation. Possible values: sign verify encrypt or decrypt. |  | CryptoOperation
+| **name** | *Required* The name part in the URI can be chosen by the user to distinguish between different signer/verifier/encryptor/decryptor endpoints within the camel context. |  | String
+|=======================================================================
+
+#### Query Parameters (15 parameters):
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|=======================================================================
+| Name | Description | Default | Type
+| **keyStore** (common) | Keystore which contains signer private keys verifier public keys encryptor public keys decryptor private keys depending on the operation. Use either this parameter or the parameter 'keyStoreParameters'. |  | KeyStore
+| **keyStoreParameters** (common) | Keystore containing signer private keys verifier public keys encryptor public keys decryptor private keys depending on the operation. Use either this parameter or the parameter 'keystore'. |  | KeyStoreParameters
+| **synchronous** (advanced) | Sets whether synchronous processing should be strictly used or Camel is allowed to use asynchronous processing (if supported). | false | boolean
+| **password** (decrypt) | Sets the password of the private keys. It is assumed that all private keys in the keystore have the same password. If not set then it is assumed that the password of the private keys is given by the keystore password given in the KeyStoreParameters. |  | Char[]
+| **fromBase64** (decrypt_verify) | If true then the CMS message is base 64 encoded and must be decoded during the processing. Default value is false. | false | Boolean
+| **contentEncryptionAlgorithm** (encrypt) | Encryption algorithm for example DESede/CBC/PKCS5Padding. Further possible values: DESede/CBC/PKCS5Padding AES/CBC/PKCS5Padding Camellia/CBC/PKCS5Padding CAST5/CBC/PKCS5Padding. |  | String
+| **originatorInformation Provider** (encrypt) | Provider for the originator info. See https://tools.ietf.org/html/rfc5652section-6.1. The default value is null. |  | OriginatorInformation Provider
+| **recipient** (encrypt) | Recipient Info: reference to a bean which implements the interface org.apache.camel.component.crypto.cms.api.TransRecipientInfo |  | List
+| **secretKeyLength** (encrypt) | Key length for the secret symmetric key used for the content encryption. Only used if the specified content-encryption algorithm allows keys of different sizes. If contentEncryptionAlgorithm=AES/CBC/PKCS5Padding or Camellia/CBC/PKCS5Padding then 128; if contentEncryptionAlgorithm=DESede/CBC/PKCS5Padding then 192 128; if strong encryption is enabled then for AES/CBC/PKCS5Padding and Camellia/CBC/PKCS5Padding also the key lengths 192 and 256 are possible. |  | int
+| **unprotectedAttributes GeneratorProvider** (encrypt) | Provider of the generator for the unprotected attributes. The default value is null which means no unprotected attribute is added to the Enveloped Data object. See https://tools.ietf.org/html/rfc5652section-6.1. |  | AttributesGenerator Provider
+| **toBase64** (encrypt_sign) | Indicates whether the Signed Data or Enveloped Data instance shall be base 64 encoded. Default value is false. | false | Boolean
+| **includeContent** (sign) | Indicates whether the signed content should be included into the Signed Data instance. If false then a detached Signed Data instance is created in the header CamelCryptoCmsSignedData. | true | Boolean
+| **signer** (sign) | Signer information: reference to a bean which implements org.apache.camel.component.crypto.cms.api.SignerInfo |  | List
+| **signedDataHeaderBase64** (verify) | Indicates whether the value in the header CamelCryptoCmsSignedData is base64 encoded. Default value is false. Only relevant for detached signatures. In the detached signature case the header contains the Signed Data object. | false | Boolean
+| **verifySignaturesOfAll Signers** (verify) | If true then the signatures of all signers contained in the Signed Data object are verified. If false then only one signature whose signer info matches with one of the specified certificates is verified. Default value is true. | true | Boolean
+|=======================================================================
+// endpoint options: END
+

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsComponent.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsComponent.java
new file mode 100644
index 0000000..e8cd77a
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsComponent.java
@@ -0,0 +1,162 @@
+/**
+ * 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.crypto.cms;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.security.Security;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Processor;
+import org.apache.camel.component.crypto.cms.crypt.DefaultEnvelopedDataDecryptorConfiguration;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataDecryptor;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataDecryptorConfiguration;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataEncryptor;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataEncryptorConfiguration;
+import org.apache.camel.component.crypto.cms.sig.DefaultSignedDataVerifierConfiguration;
+import org.apache.camel.component.crypto.cms.sig.SignedDataCreator;
+import org.apache.camel.component.crypto.cms.sig.SignedDataCreatorConfiguration;
+import org.apache.camel.component.crypto.cms.sig.SignedDataVerifierConfiguration;
+import org.apache.camel.component.crypto.cms.sig.SignedDataVerifierFromHeader;
+import org.apache.camel.impl.UriEndpointComponent;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.util.ObjectHelper;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CryptoCmsComponent extends UriEndpointComponent {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CryptoCmsComponent.class);
+
+    @Metadata(label = "advanced")
+    private SignedDataVerifierConfiguration signedDataVerifierConfiguration;
+
+    @Metadata(label = "advanced")
+    private EnvelopedDataDecryptorConfiguration envelopedDataDecryptorConfiguration;
+
+    public CryptoCmsComponent() {
+        super(CryptoCmsEndpoint.class);
+    }
+
+    public CryptoCmsComponent(CamelContext context) {
+        super(context, CryptoCmsEndpoint.class);
+    }
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { // NOPMD
+                                                                                                                       // called
+                                                                                                                       // method
+                                                                                                                       // setProperties
+                                                                                                                       // throws
+                                                                                                                       // Exception
+        ObjectHelper.notNull(getCamelContext(), "CamelContext");
+
+        String scheme;
+        String name;
+        try {
+            URI u = new URI(remaining);
+            scheme = u.getScheme();
+            name = u.getPath();
+        } catch (Exception e) {
+            throw new MalformedURLException(// NOPMD -- the stack trace does not
+                                            // help in this case.
+                                            String.format("An invalid crypto-cms uri was provided '%s'."
+                                                          + " Check that the uri matches the format crypto-cms:sign://<name>, crypto-cms:verify://<name>, "
+                                                          + "crypto-cms:encrypt://<name>, or crypto-cms:decrpyt://<name>", uri));
+        }
+        Processor processor;
+        CryptoOperation operation;
+        if (CryptoOperation.sign.name().equals(scheme)) {
+            operation = CryptoOperation.sign;
+            SignedDataCreatorConfiguration config = new SignedDataCreatorConfiguration(getCamelContext());
+            // properties must be set to config before processor is initialized
+            setProperties(config, parameters);
+            config.init();
+            processor = new SignedDataCreator(config);
+        } else if (CryptoOperation.verify.name().equals(scheme)) {
+            operation = CryptoOperation.verify;
+            SignedDataVerifierConfiguration config = getSignedDataVerifierConfiguration().copy();
+            // properties must be set to config before processor is initialized
+            setProperties(config, parameters);
+            processor = new SignedDataVerifierFromHeader(config);
+        } else if (CryptoOperation.encrypt.name().equals(scheme)) {
+            operation = CryptoOperation.encrypt;
+            EnvelopedDataEncryptorConfiguration config = new EnvelopedDataEncryptorConfiguration(getCamelContext());
+            // properties must be set to config before processor is initialized
+            setProperties(config, parameters);
+            config.init();
+            processor = new EnvelopedDataEncryptor(config);
+        } else if (CryptoOperation.decrypt.name().equals(scheme)) {
+            operation = CryptoOperation.decrypt;
+            EnvelopedDataDecryptorConfiguration config = getEnvelopedDataDecryptorConfiguration().copy();
+            // properties must be set to config before processor is initialized
+            setProperties(config, parameters);
+            processor = new EnvelopedDataDecryptor(config);
+        } else {
+            String error = "Endpoint uri " + uri + " is wrong configured. Operation " + scheme + " is not supported. Supported operations are: sign, verify, encrypt, decrypt";
+            LOG.error(error);
+            throw new IllegalStateException(error);
+        }
+        CryptoCmsEndpoint endpoint = new CryptoCmsEndpoint(uri, this, processor);
+        endpoint.setCryptoOperation(operation);
+        endpoint.setName(name);
+        return endpoint;
+    }
+
+    /**
+     * To configure the shared SignedDataVerifierConfiguration, which determines
+     * the uri parameters for the verify operation.
+     */
+    public void setSignedDataVerifierConfiguration(SignedDataVerifierConfiguration signedDataVerifierConfiguration) {
+        this.signedDataVerifierConfiguration = signedDataVerifierConfiguration;
+    }
+
+    public SignedDataVerifierConfiguration getSignedDataVerifierConfiguration() {
+        if (signedDataVerifierConfiguration == null) {
+            signedDataVerifierConfiguration = new DefaultSignedDataVerifierConfiguration();
+        }
+        return signedDataVerifierConfiguration;
+    }
+
+    public EnvelopedDataDecryptorConfiguration getEnvelopedDataDecryptorConfiguration() {
+        if (envelopedDataDecryptorConfiguration == null) {
+            envelopedDataDecryptorConfiguration = new DefaultEnvelopedDataDecryptorConfiguration();
+        }
+        return envelopedDataDecryptorConfiguration;
+    }
+
+    /**
+     * To configure the shared EnvelopedDataDecryptorConfiguration, which
+     * determines the uri parameters for the decrypt operation.
+     */
+    public void setEnvelopedDataDecryptorConfiguration(EnvelopedDataDecryptorConfiguration envelopedDataDecryptorConfiguration) {
+        this.envelopedDataDecryptorConfiguration = envelopedDataDecryptorConfiguration;
+    }
+
+    @Override
+    protected void doStart() throws Exception { // NOPMD
+        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
+            LOG.debug("Adding BouncyCastleProvider as security provider");
+            Security.addProvider(new BouncyCastleProvider());
+        }
+        super.doStart();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsEndpoint.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsEndpoint.java
new file mode 100644
index 0000000..1966062
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsEndpoint.java
@@ -0,0 +1,111 @@
+/**
+ * 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.crypto.cms;
+
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.component.crypto.cms.crypt.DefaultEnvelopedDataDecryptorConfiguration;
+import org.apache.camel.component.crypto.cms.crypt.EnvelopedDataEncryptorConfiguration;
+import org.apache.camel.component.crypto.cms.sig.DefaultSignedDataVerifierConfiguration;
+import org.apache.camel.component.crypto.cms.sig.SignedDataCreatorConfiguration;
+import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriPath;
+
+@UriEndpoint(firstVersion = "2.20.0", scheme = "crypto-cms", title = "Crypto CMS", syntax = "crypto-cms:cryptoOperation:name", producerOnly = true, label = "security,transformation")
+public class CryptoCmsEndpoint extends DefaultEndpoint {
+    private final Processor processor;
+
+    @UriPath
+    @Metadata(required = "true")
+    private CryptoOperation cryptoOperation;
+    @UriPath
+    @Metadata(required = "true")
+    private String name;
+
+    // to include different kind of configuration params
+    @UriParam
+    private SignedDataCreatorConfiguration signConfig;
+    @UriParam
+    private DefaultSignedDataVerifierConfiguration verifyConfig;
+    @UriParam
+    private EnvelopedDataEncryptorConfiguration encryptConfig;
+    @UriParam
+    private DefaultEnvelopedDataDecryptorConfiguration decryptConfig;
+
+    public CryptoCmsEndpoint(String uri, CryptoCmsComponent component, Processor processor) {
+        super(uri, component);
+        this.processor = processor;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Set the Crypto operation from that supplied after the crypto scheme in
+     * the endpoint uri e.g. crypto-cms:sign sets sign as the operation.
+     * Possible values: "sign", "verify", "encrypt", or "decrypt".
+     */
+    public void setCryptoOperation(String operation) {
+        this.cryptoOperation = CryptoOperation.valueOf(operation);
+    }
+
+    public void setCryptoOperation(CryptoOperation operation) {
+        this.cryptoOperation = operation;
+    }
+
+    /**
+     * Gets the Crypto operation that was supplied in the the crypto scheme in
+     * the endpoint uri
+     */
+    public CryptoOperation getCryptoOperation() {
+        return cryptoOperation;
+    }
+
+    /**
+     * The name part in the URI can be chosen by the user to distinguish between
+     * different signer/verifier/encryptor/decryptor endpoints within the camel
+     * context.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public Producer createProducer() {
+        return new CryptoCmsProducer(this, processor);
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) {
+        throw new UnsupportedOperationException("Crypto CMS endpoints are not meant to be consumed from. They are meant be used as intermediate endpoints");
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+
+    public Object getManagedObject(CryptoCmsEndpoint endpoint) {
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsProducer.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsProducer.java
new file mode 100644
index 0000000..072a3a3
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoCmsProducer.java
@@ -0,0 +1,47 @@
+/**
+ * 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.crypto.cms;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.impl.DefaultProducer;
+
+public class CryptoCmsProducer extends DefaultProducer {
+    // private static final Logger LOG =
+    // LoggerFactory.getLogger(CmsProducer.class);
+
+    private Processor processor;
+
+    public CryptoCmsProducer(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/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoOperation.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoOperation.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoOperation.java
new file mode 100644
index 0000000..7771359
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/CryptoOperation.java
@@ -0,0 +1,22 @@
+/**
+ * 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.crypto.cms;
+
+public enum CryptoOperation {
+
+    sign, verify, encrypt, decrypt
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/AttributesGeneratorProvider.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/AttributesGeneratorProvider.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/AttributesGeneratorProvider.java
new file mode 100644
index 0000000..8614810
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/AttributesGeneratorProvider.java
@@ -0,0 +1,32 @@
+/**
+ * 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.crypto.cms.common;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.bouncycastle.cms.CMSAttributeTableGenerator;
+
+/**
+ * Provides a exchange dependent attribute table generator. Used in
+ * EnvelopedDataEncryptorConfiguration for the unprotected attributes.
+ */
+public interface AttributesGeneratorProvider {
+
+    CMSAttributeTableGenerator getAttributesGenerator(Exchange excange) throws CryptoCmsException;
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsConstants.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsConstants.java
new file mode 100644
index 0000000..ab86697
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsConstants.java
@@ -0,0 +1,33 @@
+/**
+ * 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.crypto.cms.common;
+
+public final class CryptoCmsConstants {
+
+    /**
+     * Camel message header name for the CMS Signed Data. If in the camel
+     * component uri like "crypto-cms:sign://basic?includeContent=false"
+     * contains the option includeContent=false. Then the CMS Signed Data object
+     * is written into the CamelCryptoCmsSignedData header.
+     */
+    public static final String CAMEL_CRYPTO_CMS_SIGNED_DATA = "CamelCryptoCmsSignedData";
+
+    private CryptoCmsConstants() {
+        // no instance
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsMarshallerAbstract.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsMarshallerAbstract.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsMarshallerAbstract.java
new file mode 100644
index 0000000..c78c381
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsMarshallerAbstract.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.crypto.cms.common;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.converter.stream.OutputStreamBuilder;
+import org.apache.camel.util.IOHelper;
+import org.apache.commons.codec.binary.Base64OutputStream;
+
+public abstract class CryptoCmsMarshallerAbstract implements Processor {
+
+    private final CryptoCmsMarshallerConfiguration config;
+
+    public CryptoCmsMarshallerAbstract(CryptoCmsMarshallerConfiguration config) {
+        this.config = config;
+    }
+
+    // @Override
+    public CryptoCmsMarshallerConfiguration getConfiguration() {
+        return config;
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception { // NOPMD all
+        // exceptions must be caught to react on exception case and re-thrown,
+        // see code below
+
+        OutputStreamBuilder output = OutputStreamBuilder.withExchange(exchange);
+        OutputStream outStream;
+        if (config.getToBase64()) {
+            outStream = new Base64OutputStream(output);
+        } else {
+            outStream = output;
+        }
+
+        InputStream body = exchange.getIn().getMandatoryBody(InputStream.class);
+
+        // lets setup the out message before we invoke the processing
+        // so that it can mutate it if necessary
+        Message out = exchange.getOut();
+        out.copyFrom(exchange.getIn());
+
+        try {
+            try {
+                marshalInternal(body, outStream, exchange);
+            } finally {
+                IOHelper.close(outStream); // base64 stream must be closed,
+                                           // before we fetch the bytes
+            }
+
+            setBodyAndHeader(out, output.build());
+        } catch (Throwable e) {
+            // remove OUT message, as an exception occurred
+            exchange.setOut(null);
+            throw e;
+        }
+    }
+
+    /**
+     * Intended for overwriting in order to set headers and body for the out
+     * message.
+     */
+    protected void setBodyAndHeader(Message out, Object encodedDataObject) {
+        out.setBody(encodedDataObject);
+    }
+
+    protected abstract void marshalInternal(InputStream is, OutputStream os, Exchange exchange) throws Exception; // NOPMD
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsMarshallerConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsMarshallerConfiguration.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsMarshallerConfiguration.java
new file mode 100644
index 0000000..203c185
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsMarshallerConfiguration.java
@@ -0,0 +1,59 @@
+/**
+ * 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.crypto.cms.common;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.slf4j.Logger;
+
+@UriParams
+public abstract class CryptoCmsMarshallerConfiguration {
+
+    private final CamelContext context;
+
+    @UriParam(label = "encrypt_sign", defaultValue = "false")
+    private Boolean toBase64 = Boolean.FALSE;
+
+    public CryptoCmsMarshallerConfiguration(CamelContext context) {
+        super();
+        this.context = context;
+    }
+
+    public Boolean getToBase64() {
+        return toBase64;
+    }
+
+    /**
+     * Indicates whether the Signed Data or Enveloped Data instance shall be
+     * base 64 encoded. Default value is <code>false</code>.
+     */
+    public void setToBase64(Boolean toBase64) {
+        this.toBase64 = toBase64;
+    }
+
+    protected CamelContext getContext() {
+        return context;
+    }
+
+    protected void logErrorAndThrow(final Logger log, String message) throws CryptoCmsException {
+        log.error(message);
+        throw new CryptoCmsException(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsUnMarshallerConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsUnMarshallerConfiguration.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsUnMarshallerConfiguration.java
new file mode 100644
index 0000000..744b8e2
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsUnMarshallerConfiguration.java
@@ -0,0 +1,27 @@
+/**
+ * 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.crypto.cms.common;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+
+public interface CryptoCmsUnMarshallerConfiguration {
+
+    /** Indicates whether the message in-body is base 64 encocded. */
+    Boolean isFromBase64(Exchange exchange) throws CryptoCmsException;
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsUnmarshaller.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsUnmarshaller.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsUnmarshaller.java
new file mode 100644
index 0000000..3b8ef28
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/CryptoCmsUnmarshaller.java
@@ -0,0 +1,117 @@
+/**
+ * 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.crypto.cms.common;
+
+import java.io.InputStream;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.util.IOHelper;
+import org.apache.commons.codec.binary.Base64InputStream;
+import org.bouncycastle.cert.X509CertificateHolder;
+
+public abstract class CryptoCmsUnmarshaller implements Processor {
+
+    private final CryptoCmsUnMarshallerConfiguration config;
+
+    public CryptoCmsUnmarshaller(CryptoCmsUnMarshallerConfiguration config) {
+        this.config = config;
+    }
+
+    // @Override
+    public CryptoCmsUnMarshallerConfiguration getConfiguration() {
+        return config;
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception { // NOPMD all
+                                                              // exceptions must
+                                                              // be caught to
+                                                              // react on
+                                                              // exception case
+                                                              // and re-thrown,
+                                                              // see code below
+
+        InputStream stream = exchange.getIn().getMandatoryBody(InputStream.class);
+        try {
+            // lets setup the out message before we invoke the dataFormat
+            // so that it can mutate it if necessary
+            Message out = exchange.getOut();
+            out.copyFrom(exchange.getIn());
+
+            if (config.isFromBase64(exchange)) {
+                stream = new Base64InputStream(stream);
+            }
+            Object result = unmarshalInternal(stream, exchange);
+            out.setBody(result);
+        } catch (Throwable e) {
+            // remove OUT message, as an exception occurred
+            exchange.setOut(null);
+            throw e;
+        } finally {
+            IOHelper.close(stream, "input stream");
+        }
+    }
+
+    protected abstract Object unmarshalInternal(InputStream is, Exchange exchange) throws Exception;
+
+    protected String certsToString(Collection<X509Certificate> certs) {
+        if (certs == null) {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        int size = certs.size();
+        int counter = 0;
+        for (X509Certificate cert : certs) {
+            counter++;
+            sb.append('[');
+            certToString(sb, cert);
+            sb.append("]");
+            if (counter < size) {
+                sb.append("; ");
+            }
+        }
+
+        return sb.toString();
+    }
+
+    protected String issuerSerialNumberSubject(X509CertificateHolder cert) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Issuer=(");
+        sb.append(cert.getIssuer());
+        sb.append("), SerialNumber=");
+        sb.append(cert.getSerialNumber());
+        sb.append(", Subject=(");
+        sb.append(cert.getSubject());
+        sb.append(')');
+        return sb.toString();
+    }
+
+    protected void certToString(StringBuilder sb, X509Certificate cert) {
+        sb.append("Issuer=(");
+        sb.append(cert.getIssuerX500Principal().getName());
+        sb.append("), SerialNumber=");
+        sb.append(cert.getSerialNumber());
+        sb.append(", Subject=(");
+        sb.append(cert.getSubjectX500Principal().getName());
+        sb.append(')');
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/DefaultCryptoCmsConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/DefaultCryptoCmsConfiguration.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/DefaultCryptoCmsConfiguration.java
new file mode 100644
index 0000000..120ee22
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/DefaultCryptoCmsConfiguration.java
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.crypto.cms.common;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.util.jsse.KeyStoreParameters;
+
+@UriParams
+public abstract class DefaultCryptoCmsConfiguration {
+
+    @UriParam(label = "common")
+    private KeyStoreParameters keyStoreParameters;
+
+    @UriParam(label = "common")
+    private KeyStore keyStore;
+
+    /**
+     * Keystore containing signer private keys verifier public keys, encryptor
+     * public keys, decryptor private keys depending on the operation. Use
+     * either this parameter or the parameter 'keystore'.
+     */
+    public void setKeyStoreParameters(KeyStoreParameters keyStoreParameters) throws CryptoCmsException {
+        this.keyStoreParameters = keyStoreParameters;
+        if (keyStoreParameters != null) {
+            try {
+                this.keyStore = keyStoreParameters.createKeyStore();
+            } catch (GeneralSecurityException | IOException e) {
+                throw new CryptoCmsException("Problem during generating the keystore", e);
+            }
+        }
+    }
+
+    /**
+     * Keystore which contains signer private keys, verifier public keys,
+     * encryptor public keys, decryptor private keys depending on the operation.
+     * Use either this parameter or the parameter 'keyStoreParameters'.
+     */
+    public void setKeyStore(KeyStore keyStore) {
+        this.keyStore = keyStore;
+    }
+
+    protected KeyStore getKeyStore() throws CryptoCmsException {
+        if (keyStore == null) {
+            throw new CryptoCmsException("Keystore not configured");
+        }
+        return keyStore;
+    }
+
+    protected KeyStoreParameters getKeyStoreParameters() {
+        return keyStoreParameters;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/DefaultCryptoCmsUnMarshallerConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/DefaultCryptoCmsUnMarshallerConfiguration.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/DefaultCryptoCmsUnMarshallerConfiguration.java
new file mode 100644
index 0000000..b362985
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/DefaultCryptoCmsUnMarshallerConfiguration.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.crypto.cms.common;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+
+@UriParams
+public class DefaultCryptoCmsUnMarshallerConfiguration extends DefaultCryptoCmsConfiguration implements CryptoCmsUnMarshallerConfiguration {
+
+    @UriParam(label = "decrypt_verify", defaultValue = "false")
+    private Boolean fromBase64 = Boolean.FALSE;
+
+    public DefaultCryptoCmsUnMarshallerConfiguration() {
+        super();
+    }
+
+    @Override
+    public Boolean isFromBase64(Exchange exchange) {
+        return fromBase64;
+    }
+
+    /**
+     * If <tt>true</tt> then the CMS message is base 64 encoded and must be
+     * decoded during the processing. Default value is <code>false</code>.
+     */
+    public void setFromBase64(Boolean base64) {
+        this.fromBase64 = base64;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/OriginatorInformationProvider.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/OriginatorInformationProvider.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/OriginatorInformationProvider.java
new file mode 100644
index 0000000..df64ba4
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/common/OriginatorInformationProvider.java
@@ -0,0 +1,32 @@
+/**
+ * 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.crypto.cms.common;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.bouncycastle.cms.OriginatorInformation;
+
+/**
+ * Provides originator information. Used in Enveloped Data object. See
+ * EnvelopedDataEncryptorConfiguration.
+ */
+public interface OriginatorInformationProvider {
+
+    OriginatorInformation getOriginatorInformation(Exchange exchange) throws CryptoCmsException;
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/DefaultEnvelopedDataDecryptorConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/DefaultEnvelopedDataDecryptorConfiguration.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/DefaultEnvelopedDataDecryptorConfiguration.java
new file mode 100644
index 0000000..6c09d2a
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/DefaultEnvelopedDataDecryptorConfiguration.java
@@ -0,0 +1,121 @@
+/**
+ * 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.crypto.cms.crypt;
+
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.crypto.cms.common.DefaultCryptoCmsUnMarshallerConfiguration;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.util.jsse.KeyStoreParameters;
+
+/**
+ * The defualt implementation fetches the private key and certificate from a
+ * keystore.
+ */
+@UriParams
+public class DefaultEnvelopedDataDecryptorConfiguration extends DefaultCryptoCmsUnMarshallerConfiguration implements EnvelopedDataDecryptorConfiguration, Cloneable {
+
+    @UriParam(label = "decrypt")
+    private char[] password;
+
+    public DefaultEnvelopedDataDecryptorConfiguration() {
+        super();
+    }
+
+    /**
+     * Sets the password of the private keys. It is assumed that all private
+     * keys in the keystore have the same password. If not set then it is
+     * assumed that the password of the private keys is given by the keystore
+     * password given in the {@link KeyStoreParameters}.
+     */
+    public void setPassword(char[] password) {
+        this.password = password;
+    }
+
+    protected char[] getPassword(Exchange exchange) throws CryptoCmsException {
+        if (password == null) {
+            if (getKeyStoreParameters() != null) {
+                String passwordS = getKeyStoreParameters().getPassword();
+                if (passwordS == null) {
+                    throw new CryptoCmsException("Password for private keys not configured");
+                } else {
+                    return passwordS.toCharArray();
+                }
+            } else {
+                throw new CryptoCmsException("Password for private keys not configured");
+            }
+        } else {
+            return password;
+        }
+
+    }
+
+    @Override
+    public Collection<PrivateKeyWithCertificate> getPrivateKeyCertificateCollection(Exchange exchange) throws CryptoCmsException {
+
+        KeyStore keystore = getKeyStore();
+        try {
+            List<PrivateKeyWithCertificate> privateKeys = new ArrayList<>(keystore.size());
+            for (Enumeration<String> aliases = keystore.aliases(); aliases.hasMoreElements();) {
+                String alias = aliases.nextElement();
+                if (!keystore.isKeyEntry(alias)) {
+                    // only key entries are relevant!
+                    continue;
+                }
+                Key privateKey = keystore.getKey(alias, getPassword(exchange));
+                if (privateKey instanceof PrivateKey) { // we currently only
+                                                        // support
+                                                        // assymmetric keys
+                    Certificate cert = keystore.getCertificate(alias);
+                    if (cert instanceof X509Certificate) {
+                        privateKeys.add(new PrivateKeyWithCertificate((PrivateKey)privateKey, (X509Certificate)cert));
+                    }
+                }
+            }
+            if (privateKeys.isEmpty()) {
+                throw new CryptoCmsException("No private keys in keystore found. Check your configuration.");
+            }
+            return privateKeys;
+        } catch (KeyStoreException | UnrecoverableKeyException | NoSuchAlgorithmException e) {
+            throw new CryptoCmsException("Problem during reading the private keys from the keystore", e);
+        }
+    }
+
+    public DefaultEnvelopedDataDecryptorConfiguration copy() {
+        try {
+            return (DefaultEnvelopedDataDecryptorConfiguration)clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeCamelException(e); // should never happen
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/DefaultKeyTransRecipientInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/DefaultKeyTransRecipientInfo.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/DefaultKeyTransRecipientInfo.java
new file mode 100644
index 0000000..32fa078
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/DefaultKeyTransRecipientInfo.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.crypto.cms.crypt;
+
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.common.DefaultCryptoCmsConfiguration;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsNoKeyOrCertificateForAliasException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+
+/**
+ * Information about the receiver of an encrypted message. The encryption public
+ * key is defined via an alias referencing an entry in a keystore.
+ */
+@UriParams
+public class DefaultKeyTransRecipientInfo extends DefaultCryptoCmsConfiguration implements TransRecipientInfo {
+
+    @UriParam(label = "encrypt")
+    private String certificateAlias;
+
+    private String keyEncryptionAlgorithm = "RSA";
+
+    protected String getCertificateAlias() throws CryptoCmsException {
+        if (certificateAlias == null) {
+            throw new CryptoCmsException("Certificate alias not configured in recipient " + this);
+        }
+        return certificateAlias;
+    }
+
+    /**
+     * Keytstore alias for looking up the X.509 certificate whose public key is
+     * used to encrypt the secret symmetric encryption key.
+     * 
+     * @param certificateAlias alias
+     */
+    public void setCertificateAlias(String certificateAlias) {
+        this.certificateAlias = certificateAlias;
+    }
+
+    // /**
+    // * Encryption Algorithm used for encrypting the secret key in
+    // * {@link CmsEnvelopedDataEncryptor}.
+    // *
+    // * @param keyEncryptionAlgorithm algorithm, for example "RSA"
+    // */
+    // public void setKeyEncryptionAlgorithm(String keyEncryptionAlgorithm) {
+    // this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+    // }
+
+    public String toString() {
+        return "certificate alias=" + certificateAlias + ", key encryption algorithm=" + keyEncryptionAlgorithm;
+    }
+
+    /** Currently, the key encryption algorithm is fixed to "RSA". */
+    @Override
+    public String getKeyEncryptionAlgorithm(Exchange exchange) throws CryptoCmsException {
+        return keyEncryptionAlgorithm;
+    }
+
+    @Override
+    public X509Certificate getCertificate(Exchange exchange) throws CryptoCmsException {
+        String alias = getCertificateAlias();
+        Certificate cert;
+        try {
+            cert = getKeyStore().getCertificate(alias);
+        } catch (KeyStoreException e) {
+            throw new CryptoCmsException("Problem during reading the certificate with the alias '" + alias + "' from the keystore of the recipient " + this);
+        }
+        if (cert instanceof X509Certificate) {
+            return (X509Certificate)cert;
+        }
+        throw new CryptoCmsNoKeyOrCertificateForAliasException("No X509 certificate found for the alias '" + alias + "' in the keystore of the recipient " + this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataDecryptor.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataDecryptor.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataDecryptor.java
new file mode 100644
index 0000000..657b653
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataDecryptor.java
@@ -0,0 +1,275 @@
+/**
+ * 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.crypto.cms.crypt;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsUnmarshaller;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsFormatException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsNoCertificateForRecipientsException;
+import org.apache.camel.converter.stream.OutputStreamBuilder;
+import org.apache.camel.util.IOHelper;
+import org.bouncycastle.asn1.cms.Attribute;
+import org.bouncycastle.asn1.cms.AttributeTable;
+import org.bouncycastle.cert.X509CRLEntryHolder;
+import org.bouncycastle.cert.X509CRLHolder;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cms.CMSEnvelopedDataParser;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.KeyTransRecipientId;
+import org.bouncycastle.cms.KeyTransRecipientInformation;
+import org.bouncycastle.cms.OriginatorInformation;
+import org.bouncycastle.cms.Recipient;
+import org.bouncycastle.cms.RecipientInformation;
+import org.bouncycastle.cms.RecipientInformationStore;
+import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
+import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId;
+import org.bouncycastle.util.Store;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Processor for decrypting CMS EnvelopedData content.
+ */
+public class EnvelopedDataDecryptor extends CryptoCmsUnmarshaller {
+    private static final Logger LOG = LoggerFactory.getLogger(EnvelopedDataDecryptor.class);
+
+    private final EnvelopedDataDecryptorConfiguration conf;
+
+    // private final PublicKeyFinder finder;
+
+    public EnvelopedDataDecryptor(EnvelopedDataDecryptorConfiguration conf) {
+        super(conf);
+        this.conf = conf;
+    }
+
+    @Override
+    protected Object unmarshalInternal(InputStream is, Exchange exchange) throws Exception {
+        CMSEnvelopedDataParser parser;
+        try {
+            parser = new CMSEnvelopedDataParser(is);
+        } catch (CMSException e) {
+            throw new CryptoCmsFormatException(getFormatErrorMessage(), e);
+        } catch (NullPointerException e) {
+            // occurs with an empty payloud
+            throw new CryptoCmsFormatException(getFormatErrorMessage(), e);
+        }
+        return unmarshal(parser, exchange);
+    }
+
+    String getFormatErrorMessage() {
+        return "Message has invalid format. It was not possible to parse the message into a PKCS7/CMS enveloped data object.";
+    }
+
+    private Object unmarshal(CMSEnvelopedDataParser parser, Exchange exchange) throws Exception {
+        LOG.debug("Decrypting CMS Enveloped Data started");
+        debugLog(parser);
+        RecipientInformationStore recipientsStore = parser.getRecipientInfos();
+
+        if (recipientsStore.size() == 0) {
+            throw new CryptoCmsException("PKCS7/CMS enveloped data message is incorrect. No recipient information found in enveloped data.");
+        }
+
+        // we loop over the key-pairs in the keystore and use the first entry
+        // which fits to a recipient info
+        RecipientInformation recipientInformation = null;
+        Collection<PrivateKeyWithCertificate> privateKeyCerts = conf.getPrivateKeyCertificateCollection(exchange);
+        if (privateKeyCerts.isEmpty()) {
+            throw new CryptoCmsNoCertificateForRecipientsException("Cannot decrypt PKCS7/CMS enveloped data object. No private key for the decryption configured.");
+
+        }
+        PrivateKey foundPrivateKey = null;
+        for (PrivateKeyWithCertificate privateKeyCert : privateKeyCerts) {
+            X509Certificate cert = privateKeyCert.getCertificate();
+            JceKeyTransRecipientId recipientId = new JceKeyTransRecipientId(cert);
+            recipientInformation = recipientsStore.get(recipientId);
+            if (recipientInformation != null) {
+
+                LOG.debug("Recipient found for certificate with subjectDN={}, issuerDN={}, and serial number={}",
+                          new Object[] {cert.getSubjectDN(), cert.getIssuerDN(), cert.getSerialNumber()});
+                foundPrivateKey = privateKeyCert.getPrivateKey();
+                break; // use the first found private key
+            }
+        }
+        if (recipientInformation == null) {
+            List<X509Certificate> certs = new ArrayList<>(privateKeyCerts.size());
+            for (PrivateKeyWithCertificate pc : privateKeyCerts) {
+                certs.add(pc.getCertificate());
+            }
+            throw new CryptoCmsNoCertificateForRecipientsException("Cannot decrypt PKCS7/CMS enveloped data object. No certificate found among the configured certificates "
+                                                                   + "which fit to one of the recipients in the enveloped data object. The recipients in the enveloped data object are: "
+                                                                   + recipientsToString(recipientsStore.getRecipients()) + "The configured certificates are: "
+                                                                   + certsToString(certs)
+                                                                   + ". Specify a certificate with private key which fits to one of the recipients in the configruation or"
+                                                                   + " check whether the encrypted message is encrypted with the correct key.");
+        }
+
+        Recipient recipient = new JceKeyTransEnvelopedRecipient(foundPrivateKey);
+
+        // get the InputStream with the decrypted data, here the decryption
+        // takes place
+        InputStream is;
+        try {
+            is = recipientInformation.getContentStream(recipient).getContentStream();
+        } catch (CMSException | IOException e) {
+            throw new CryptoCmsException("Error during decrypting an enveloped data object", e);
+        }
+
+        Object result;
+        try {
+            result = transformToStreamCacheOrByteArray(exchange, is);
+        } finally {
+            IOHelper.close(is);
+        }
+        if (LOG.isDebugEnabled()) {
+            // unprotected attributes can only be read after the parsing is
+            // finished.
+            AttributeTable unprotectedAttsTable = parser.getUnprotectedAttributes();
+            if (unprotectedAttsTable != null) {
+                LOG.debug("Unprotected attributes size {}", unprotectedAttsTable.size());
+                @SuppressWarnings("unchecked")
+                Hashtable<String, Attribute> unprotectedAtts = unprotectedAttsTable.toHashtable();
+                if (unprotectedAtts != null) {
+                    LOG.debug("Unprotected attributes: {}", attributesToString(unprotectedAtts));
+                }
+            }
+        }
+        return result;
+
+    }
+
+    protected void debugLog(CMSEnvelopedDataParser parser) {
+        if (!LOG.isDebugEnabled()) {
+            return;
+        }
+        OriginatorInformation originatorInfo = parser.getOriginatorInfo();
+        if (originatorInfo != null) {
+            LOG.debug("Enveloped Data has originator information");
+            @SuppressWarnings("unchecked")
+            Store<X509CertificateHolder> certStore = originatorInfo.getCertificates();
+            Collection<X509CertificateHolder> certs = certStore.getMatches(null);
+            if (certs != null && certs.size() > 0) {
+                LOG.debug("Certificates in the originator information:");
+                for (X509CertificateHolder cert : certs) {
+                    LOG.debug("    subject=" + cert.getSubject() + ", issuer=" + cert.getIssuer() + ", serial number=" + cert.getSerialNumber());
+                }
+            }
+            @SuppressWarnings("unchecked")
+            Store<X509CRLHolder> crlsStore = originatorInfo.getCRLs();
+            Collection<X509CRLHolder> crls = crlsStore.getMatches(null);
+            if (crls != null && crls.size() > 0) {
+                LOG.debug("CRLs in the originator information:");
+                for (X509CRLHolder crl : crls) {
+                    LOG.debug("    CRL issuer={}", crl.getIssuer());
+                    @SuppressWarnings("unchecked")
+                    Collection<X509CRLEntryHolder> revokedCerts = crl.getRevokedCertificates();
+                    for (X509CRLEntryHolder revokedCert : revokedCerts) {
+                        LOG.debug("        Revoked Certificate: issuer=" + revokedCert.getCertificateIssuer() + ", serial number=" + revokedCert.getSerialNumber() + ", date="
+                                  + revokedCert.getRevocationDate());
+                    }
+                }
+            }
+        }
+        LOG.debug("Content encryption algorithm OID: {}", parser.getEncryptionAlgOID());
+
+        LOG.debug("Recipient Infos:");
+        RecipientInformationStore recipientStore = parser.getRecipientInfos();
+        Collection<RecipientInformation> recipients = recipientStore.getRecipients();
+        int counter = 0;
+        for (RecipientInformation recipient : recipients) {
+            counter++;
+            LOG.debug("   Recipient Info {}: {}", counter, recipientToString(recipient));
+        }
+    }
+
+    protected String recipientsToString(Collection<RecipientInformation> recipients) {
+        StringBuilder sb = new StringBuilder();
+        int counter = 0;
+        int size = recipients.size();
+        for (RecipientInformation recipient : recipients) {
+            counter++;
+            sb.append('[');
+            sb.append(recipientToString(recipient));
+            sb.append(']');
+            if (counter < size) {
+                sb.append(';');
+            }
+        }
+        return sb.toString();
+    }
+
+    protected String recipientToString(RecipientInformation recipient) {
+        if (recipient instanceof KeyTransRecipientInformation) {
+            KeyTransRecipientId rid = (KeyTransRecipientId)recipient.getRID();
+            return "Issuer=" + rid.getIssuer() + ", serial number=" + rid.getSerialNumber() + ", key encryption algorithm OID=" + recipient.getKeyEncryptionAlgOID();
+        } else {
+            return "not a KeyTransRecipientInformation: " + recipient.getRID().getType();
+        }
+    }
+
+    protected String attributesToString(Hashtable<String, Attribute> attributes) {
+        if (attributes == null) {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        int size = attributes.size();
+        int counter = 0;
+        for (Attribute attr : attributes.values()) {
+            counter++;
+            sb.append(attr.getAttrType());
+            // we do not print out the attribute value because the value may
+            // contain sensitive information
+            if (counter < size) {
+                sb.append(",");
+            }
+        }
+        return sb.toString();
+    }
+
+    private Object transformToStreamCacheOrByteArray(Exchange exchange, InputStream is) throws CryptoCmsException {
+        // the input stream must be completely read, outherwise you will get
+        // errors when your use as next component the file adapter.
+        OutputStreamBuilder output = OutputStreamBuilder.withExchange(exchange);
+        try {
+            // data can be null in the case of explicit Signed Data
+            if (is != null) {
+                try {
+                    IOHelper.copy(is, output);
+                } finally {
+                    IOHelper.close(is);
+                }
+            }
+
+            LOG.debug("CMS Enveloped Data decryption successful");
+            return output.build();
+        } catch (IOException e) {
+            throw new CryptoCmsException("Error during reading the unencrypted content of the enveloped data object", e);
+        } finally {
+            IOHelper.close(output);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataDecryptorConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataDecryptorConfiguration.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataDecryptorConfiguration.java
new file mode 100644
index 0000000..75a43a4
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataDecryptorConfiguration.java
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.crypto.cms.crypt;
+
+import java.util.Collection;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsUnMarshallerConfiguration;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+
+public interface EnvelopedDataDecryptorConfiguration extends CryptoCmsUnMarshallerConfiguration {
+
+    /**
+     * Returns the private keys with their public keys in the X.509 certificate
+     * which can be used for the decryption. The certificate is used for finding
+     * the corresponding Key Transport Recipient Info in the Enveloped Data
+     * object.
+     */
+    Collection<PrivateKeyWithCertificate> getPrivateKeyCertificateCollection(Exchange exchange) throws CryptoCmsException;
+
+    /** Creates a copy of the current instance, for example by cloning. */
+    EnvelopedDataDecryptorConfiguration copy();
+
+}


[3/4] camel git commit: CAMEL-11438 new component crypto-cms

Posted by fo...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataEncryptor.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataEncryptor.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataEncryptor.java
new file mode 100644
index 0000000..147d819
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataEncryptor.java
@@ -0,0 +1,122 @@
+/**
+ * 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.crypto.cms.crypt;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.X509Certificate;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.common.AttributesGeneratorProvider;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsMarshallerAbstract;
+import org.apache.camel.component.crypto.cms.common.OriginatorInformationProvider;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.util.IOHelper;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.cms.CMSEnvelopedDataStreamGenerator;
+import org.bouncycastle.cms.OriginatorInformation;
+import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
+import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.OutputEncryptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Processor for creating an enveloped data object.
+ */
+public class EnvelopedDataEncryptor extends CryptoCmsMarshallerAbstract {
+    private static final Logger LOG = LoggerFactory.getLogger(EnvelopedDataEncryptor.class);
+
+    private final EnvelopedDataEncryptorConfiguration conf;
+
+    public EnvelopedDataEncryptor(EnvelopedDataEncryptorConfiguration conf) {
+        super(conf);
+        this.conf = conf;
+    }
+
+    @Override
+    protected void marshalInternal(InputStream is, OutputStream os, Exchange exchange) throws Exception {
+
+        LOG.debug("Content encryption algorithm: {}", conf.getAlgorithmID());
+        LOG.debug("Parameter secretKeyLength: {}", conf.getSecretKeyLength());
+
+        OutputStream encryptingStream = null;
+        try {
+            CMSEnvelopedDataStreamGenerator gen = new CMSEnvelopedDataStreamGenerator();
+            OriginatorInformationProvider originatorInformationProvider = conf.getOriginatorInformationProvider();
+            if (originatorInformationProvider != null) {
+                LOG.debug("originatorInformationProvider found");
+                OriginatorInformation originatorInformation = originatorInformationProvider.getOriginatorInformation(exchange);
+                if (originatorInformation != null) {
+                    LOG.debug("originatorInformation found");
+                    gen.setOriginatorInfo(originatorInformation);
+                }
+            }
+            AttributesGeneratorProvider attributeGeneratorProvider = conf.getUnprotectedAttributesGeneratorProvider();
+            if (attributeGeneratorProvider != null) {
+                LOG.debug("attributeGeneratorProvider found");
+                gen.setUnprotectedAttributeGenerator(attributeGeneratorProvider.getAttributesGenerator(exchange));
+            }
+
+            if (conf.getRecipient().isEmpty()) {
+                throw new CryptoCmsException("No recipient configured.");
+            }
+
+            for (RecipientInfo recipientInfo : conf.getRecipient()) {
+                // currently we only support key transport alternative, in
+                // future there maybe others
+                TransRecipientInfo keyTransrecipientInfo = (TransRecipientInfo)recipientInfo;
+                LOG.debug("Recipient info: {}", keyTransrecipientInfo);
+                X509Certificate encryptCert = keyTransrecipientInfo.getCertificate(exchange);
+                LOG.debug("Encryption certificate for recipient with '{}' : {}", keyTransrecipientInfo, encryptCert);
+
+                AlgorithmIdentifier keyEncryptionAlgorithm = determineKeyEncryptionAlgorithmIdentifier(keyTransrecipientInfo.getKeyEncryptionAlgorithm(exchange),
+                                                                                                       keyTransrecipientInfo);
+                JceKeyTransRecipientInfoGenerator keyTransRecipeintInfoGen = new JceKeyTransRecipientInfoGenerator(encryptCert, keyEncryptionAlgorithm);
+
+                keyTransRecipeintInfoGen.setProvider(BouncyCastleProvider.PROVIDER_NAME);
+                gen.addRecipientInfoGenerator(keyTransRecipeintInfoGen);
+            }
+
+            OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(conf.getAlgorithmID()).setProvider(BouncyCastleProvider.PROVIDER_NAME).build();
+
+            encryptingStream = gen.open(os, encryptor);
+
+            IOHelper.copy(is, encryptingStream);
+
+            LOG.debug("CMS Enveloped Data creation successful");
+
+        } finally {
+            IOHelper.close(is);
+            IOHelper.close(encryptingStream);
+        }
+
+    }
+
+    private AlgorithmIdentifier determineKeyEncryptionAlgorithmIdentifier(String keyEncryptionAlgorithm, TransRecipientInfo keyTransRecipient) throws CryptoCmsException {
+
+        if (keyEncryptionAlgorithm == null) {
+            throw new CryptoCmsException("Key encryption algorithm  of recipient info '" + keyTransRecipient + "' is missing");
+        }
+        if ("RSA".equals(keyEncryptionAlgorithm)) {
+            return new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption);
+        }
+        throw new CryptoCmsException("Key encryption algorithm '" + keyEncryptionAlgorithm + "' of recipient info '" + keyTransRecipient + "' is not supported");
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataEncryptorConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataEncryptorConfiguration.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataEncryptorConfiguration.java
new file mode 100644
index 0000000..50f3fc8
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/EnvelopedDataEncryptorConfiguration.java
@@ -0,0 +1,283 @@
+/**
+ * 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.crypto.cms.crypt;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.crypto.cms.common.AttributesGeneratorProvider;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsMarshallerConfiguration;
+import org.apache.camel.component.crypto.cms.common.OriginatorInformationProvider;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.cms.CMSAlgorithm;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@UriParams
+public class EnvelopedDataEncryptorConfiguration extends CryptoCmsMarshallerConfiguration {
+
+    private static final String CAST5_CBC_PKCS5_PADDING = "CAST5/CBC/PKCS5Padding";
+
+    private static final String RC2_CBC_PKCS5_PADDING = "RC2/CBC/PKCS5Padding";
+
+    private static final String CAMELLIA_CBC_PKCS5_PADDING = "Camellia/CBC/PKCS5Padding";
+
+    private static final String AES_CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";
+
+    private static final String DES_CBC_PKCS5_PADDING = "DES/CBC/PKCS5Padding";
+
+    private static final String DESEDE_CBC_PKCS5_PADDING = "DESede/CBC/PKCS5Padding";
+
+    private static final Logger LOG = LoggerFactory.getLogger(EnvelopedDataEncryptorConfiguration.class);
+
+    private static final Map<String, List<Integer>> SUPPORTED_ENCRYPTION_ALGORITHMS = new HashMap<String, List<Integer>>(7);
+
+    static {
+
+        List<Integer> allowedKeyLengthForAESandCamellia;
+        if (isLimitedEncryptionStrength()) {
+            allowedKeyLengthForAESandCamellia = Arrays.asList(new Integer[] {128});
+        } else {
+            allowedKeyLengthForAESandCamellia = Arrays.asList(new Integer[] {256, 192, 128});
+        }
+
+        SUPPORTED_ENCRYPTION_ALGORITHMS.put(DESEDE_CBC_PKCS5_PADDING, Arrays.asList(new Integer[] {192, 128}));
+        SUPPORTED_ENCRYPTION_ALGORITHMS.put(DES_CBC_PKCS5_PADDING, Arrays.asList(new Integer[] {64, 56}));
+        SUPPORTED_ENCRYPTION_ALGORITHMS.put(AES_CBC_PKCS5_PADDING, allowedKeyLengthForAESandCamellia);
+        SUPPORTED_ENCRYPTION_ALGORITHMS.put(CAMELLIA_CBC_PKCS5_PADDING, allowedKeyLengthForAESandCamellia);
+        SUPPORTED_ENCRYPTION_ALGORITHMS.put(RC2_CBC_PKCS5_PADDING, Arrays.asList(new Integer[] {128, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40}));
+        SUPPORTED_ENCRYPTION_ALGORITHMS.put(CAST5_CBC_PKCS5_PADDING, Arrays.asList(new Integer[] {128, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40}));
+    }
+
+    @UriParam(label = "encrypt", multiValue = true, description = "Recipient Info: reference to a bean which implements the interface org.apache.camel.component.crypto.cms.api.TransRecipientInfo")
+    private final List<RecipientInfo> recipient = new ArrayList<RecipientInfo>(3);
+
+    @UriParam(label = "encrypt", enums = "AES/CBC/PKCS5Padding,DESede/CBC/PKCS5Padding,Camellia/CBC/PKCS5Padding,CAST5/CBC/PKCS5Padding")
+    private String contentEncryptionAlgorithm;
+
+    @UriParam(label = "encrypt")
+    private int secretKeyLength;
+
+    @UriParam(label = "encrypt", defaultValue = "null")
+    private AttributesGeneratorProvider unprotectedAttributesGeneratorProvider;
+
+    @UriParam(label = "encrypt", defaultValue = "null")
+    private OriginatorInformationProvider originatorInformationProvider;
+
+    // calculated parameters
+    private ASN1ObjectIdentifier algorithmId;
+
+    public EnvelopedDataEncryptorConfiguration(CamelContext context) {
+        super(context);
+    }
+
+    private static boolean isLimitedEncryptionStrength() {
+        // limited encryption strength
+        boolean limitedEncryptionStrength;
+        try {
+            limitedEncryptionStrength = Cipher.getMaxAllowedKeyLength("AES") < 256;
+        } catch (NoSuchAlgorithmException e) {
+            // should never occur
+            throw new IllegalStateException(e);
+        }
+        return limitedEncryptionStrength;
+    }
+
+    public List<RecipientInfo> getRecipient() {
+        return recipient;
+    }
+
+    public void setRecipient(RecipientInfo recipient) {
+        this.recipient.add(recipient);
+    }
+
+    // for multi values
+    public void setRecipient(List<?> recipients) {
+        if (recipients == null) {
+            return;
+        }
+        for (Object recipientOb : recipients) {
+            if (recipientOb instanceof String) {
+                String recipientName = (String)recipientOb;
+                String valueNoHash = recipientName.replaceAll("#", "");
+                if (getContext() != null && recipientName != null) {
+                    RecipientInfo recipient = getContext().getRegistry().lookupByNameAndType(valueNoHash, RecipientInfo.class);
+                    if (recipient != null) {
+                        setRecipient(recipient);
+                    }
+                }
+            }
+        }
+
+    }
+
+    public String getContentEncryptionAlgorithm() {
+        return contentEncryptionAlgorithm;
+    }
+
+    /**
+     * Encryption algorithm, for example "DESede/CBC/PKCS5Padding". Further
+     * possible values: DESede/CBC/PKCS5Padding, AES/CBC/PKCS5Padding,
+     * Camellia/CBC/PKCS5Padding, CAST5/CBC/PKCS5Padding.
+     */
+    public void setContentEncryptionAlgorithm(String contentEncryptionAlgorithm) {
+        this.contentEncryptionAlgorithm = contentEncryptionAlgorithm;
+    }
+
+    public int getSecretKeyLength() {
+        return secretKeyLength;
+    }
+
+    /**
+     * Key length for the secret symmetric key used for the content encryption.
+     * Only used if the specified content-encryption algorithm allows keys of
+     * different sizes. If contentEncryptionAlgorithm=AES/CBC/PKCS5Padding or
+     * Camellia/CBC/PKCS5Padding then 128; if
+     * contentEncryptionAlgorithm=DESede/CBC/PKCS5Padding then 192, 128; if
+     * strong encryption is enabled then for AES/CBC/PKCS5Padding and
+     * Camellia/CBC/PKCS5Padding also the key lengths 192 and 256 are possible.
+     */
+    public void setSecretKeyLength(int secretKeyLength) {
+        this.secretKeyLength = secretKeyLength;
+    }
+
+    public AttributesGeneratorProvider getUnprotectedAttributesGeneratorProvider() {
+        return unprotectedAttributesGeneratorProvider;
+    }
+
+    /**
+     * Provider of the generator for the unprotected attributes. The default
+     * value is <code>null</code> which means no unprotected attribute is added
+     * to the Enveloped Data object. See
+     * https://tools.ietf.org/html/rfc5652#section-6.1.
+     */
+    public void setUnprotectedAttributesGeneratorProvider(AttributesGeneratorProvider unprotectedAttributeTableGeneratorProvider) {
+        this.unprotectedAttributesGeneratorProvider = unprotectedAttributeTableGeneratorProvider;
+    }
+
+    public OriginatorInformationProvider getOriginatorInformationProvider() {
+        return originatorInformationProvider;
+    }
+
+    /**
+     * Provider for the originator info. See
+     * https://tools.ietf.org/html/rfc5652#section-6.1. The default value is
+     * <code>null</code>.
+     */
+    public void setOriginatorInformationProvider(OriginatorInformationProvider originatorInformationProvider) {
+        this.originatorInformationProvider = originatorInformationProvider;
+    }
+
+    public void init() throws CryptoCmsException {
+        if (recipient.size() == 0) {
+            logErrorAndThrow(LOG, "No recipient configured.");
+        }
+        checkEncryptionAlgorithmAndSecretKeyLength();
+
+        calcualteAlgorithmIdWithKeyLength();
+    }
+
+    private void checkEncryptionAlgorithmAndSecretKeyLength() throws CryptoCmsException {
+        if (contentEncryptionAlgorithm == null) {
+            logErrorAndThrow(LOG, "Content encryption algorithm is null");
+        } else if (!SUPPORTED_ENCRYPTION_ALGORITHMS.keySet().contains(contentEncryptionAlgorithm)) {
+            logErrorAndThrow(LOG, "Content encryption algorithm " + contentEncryptionAlgorithm + " not supported");
+        } else if (!SUPPORTED_ENCRYPTION_ALGORITHMS.get(contentEncryptionAlgorithm).contains(secretKeyLength)) {
+            logErrorAndThrow(LOG, "Content encryption algorithm " + contentEncryptionAlgorithm + " does not supported secretKeyLength of " + secretKeyLength);
+        }
+    }
+
+    private void calcualteAlgorithmIdWithKeyLength() {
+
+        if (DESEDE_CBC_PKCS5_PADDING.equals(getContentEncryptionAlgorithm())) {
+
+            algorithmId = CMSAlgorithm.DES_EDE3_CBC;
+
+        } else if (DES_CBC_PKCS5_PADDING.equals(getContentEncryptionAlgorithm())) {
+
+            algorithmId = CMSAlgorithm.DES_CBC;
+
+        } else if (AES_CBC_PKCS5_PADDING.equals(getContentEncryptionAlgorithm())) {
+
+            switch (getSecretKeyLength()) {
+            case 256:
+                algorithmId = CMSAlgorithm.AES256_CBC;
+                break;
+            case 192:
+                algorithmId = CMSAlgorithm.AES192_CBC;
+                break;
+            case 128:
+                algorithmId = CMSAlgorithm.AES128_CBC;
+                break;
+
+            default:
+                // should not happen, has already been checked
+                throw new IllegalStateException("Unsupported secret key length " + getSecretKeyLength() + " for algorithm AES");
+            }
+
+        } else if (CAMELLIA_CBC_PKCS5_PADDING.equals(getContentEncryptionAlgorithm())) {
+
+            switch (getSecretKeyLength()) {
+            case 256:
+                algorithmId = CMSAlgorithm.CAMELLIA256_CBC;
+                break;
+            case 192:
+                algorithmId = CMSAlgorithm.CAMELLIA192_CBC;
+                break;
+            case 128:
+                algorithmId = CMSAlgorithm.CAMELLIA128_CBC;
+                break;
+            default:
+                // should not happen, has already been checked
+                throw new IllegalStateException("Unsupported secret key length " + getSecretKeyLength() + " for algorithm Camellia");
+            }
+
+        } else if (RC2_CBC_PKCS5_PADDING.equals(getContentEncryptionAlgorithm())) {
+
+            algorithmId = CMSAlgorithm.RC2_CBC;
+
+        } else if (CAST5_CBC_PKCS5_PADDING.equals(getContentEncryptionAlgorithm())) {
+
+            algorithmId = CMSAlgorithm.CAST5_CBC;
+
+        } else {
+            // should not occur, has already been checked
+            throw new IllegalStateException("Content encryption algorithm " + getContentEncryptionAlgorithm() + " not supported");
+        }
+
+    }
+
+    /**
+     * Content encryption algorithm.
+     * 
+     * @return algorithm Id
+     */
+    public ASN1ObjectIdentifier getAlgorithmID() {
+        return algorithmId;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/PrivateKeyWithCertificate.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/PrivateKeyWithCertificate.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/PrivateKeyWithCertificate.java
new file mode 100644
index 0000000..bc1e726
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/PrivateKeyWithCertificate.java
@@ -0,0 +1,44 @@
+/**
+ * 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.crypto.cms.crypt;
+
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import org.apache.camel.util.ObjectHelper;
+
+public class PrivateKeyWithCertificate {
+
+    private final PrivateKey privateKey;
+
+    private final X509Certificate certificate;
+
+    public PrivateKeyWithCertificate(PrivateKey privateKey, X509Certificate certificate) {
+
+        this.privateKey = ObjectHelper.notNull(privateKey, "privateKey");
+        this.certificate = ObjectHelper.notNull(certificate, "certificate");
+    }
+
+    public PrivateKey getPrivateKey() {
+        return privateKey;
+    }
+
+    public X509Certificate getCertificate() {
+        return certificate;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/RecipientInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/RecipientInfo.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/RecipientInfo.java
new file mode 100644
index 0000000..06110a4
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/RecipientInfo.java
@@ -0,0 +1,54 @@
+/**
+ * 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.crypto.cms.crypt;
+
+/**
+ * Information about the receiver of an encrypted message used in
+ * {@link EnvelopedDataEncryptor}. The RecipientInfo type depends on the key
+ * management algorithm used for the recipient of an <code>EnvelopedData</code>
+ * or <code>AuthenticatedData</code>. CMS provides three alternatives (see rfc5652):
+ * <ul>
+ * <li>key transport: the content-encryption key is encrypted with the public
+ * key of the recipient. This technique id compatible to PKCS#7 when creating a
+ * RecipientInfo for the public key of the recipient's certificate, identified
+ * by issuer and serial number. CMS recommends to use RSA for encrypting the
+ * content encryption key.
+ * <li>key agreement: the recipient's public key and the sender's private key
+ * are used to generate a symmetric key, then the content encryption key is
+ * encrypted with the symmetric key. Each RecipientInfo of type may transfer the
+ * encrypted content encryption key to one or more recipient using the same key
+ * agreement algorithm and domain parameters for that algorithm. CMS recommends
+ * to use ESDH with an ephemeral sender key.
+ * <li>symmetric key-encryption keys: the content-encryption key is encrypted
+ * with a previously distributed symmetric key-encryption key. The RecipientInfo
+ * is using a CMS key wrap algorithm like Triple-DES key wrap or RC2 key wrap.
+ * <li>password based encryption: the content-encryption key is encrypted with
+ * key-encryption key derived from a password. The RecipientInfo is using a key
+ * derivation algorithm like PBKDF2 as specified by <a href =
+ * http://www.ietf.org/rfc/rfc2898.txt" target="_blank">RFC 2898</a> (PKCS#5)
+ * and a key encryption algorithm like PWRI-KEK as specified by <a href =
+ * http://www.ietf.org/rfc/rfc3211.txt" target="_blank">RFC 3211</a>.
+ * <li>any other technique: based on private, user defined key management
+ * techniques
+ * </ul>
+ * Currently we only support the "key transport" alternative. However in
+ * preparation to support in future further types, we have introduced this
+ * class.
+ */
+public interface RecipientInfo {
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/TransRecipientInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/TransRecipientInfo.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/TransRecipientInfo.java
new file mode 100644
index 0000000..d4cfa42
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/crypt/TransRecipientInfo.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.crypto.cms.crypt;
+
+import java.security.cert.X509Certificate;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+
+/**
+ * Information about the receiver of an encrypted message used in
+ * CmsEnvelopedDataEncryptor.
+ * <p>
+ * Represents the "key transport" recipient info alternative: The
+ * content-encryption key is encrypted with the public key of the recipient.
+ * This technique is compatible to PKCS#7 when creating a RecipientInfo for the
+ * public key of the recipient's certificate, identified by issuer and serial
+ * number. CMS recommends to use RSA for encrypting the content encryption key.
+ */
+public interface TransRecipientInfo extends RecipientInfo {
+
+    /** Currently, the key encryption algorithm is fixed to "RSA". */
+    String getKeyEncryptionAlgorithm(Exchange exchange) throws CryptoCmsException;
+
+    /**
+     * Returns the certificate containign the public key which is used for the
+     * encryption and the issuer and serial number which is added to the
+     * recipient information.
+     */
+    X509Certificate getCertificate(Exchange exchange) throws CryptoCmsException;
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsException.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsException.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsException.java
new file mode 100644
index 0000000..073c166
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsException.java
@@ -0,0 +1,40 @@
+/**
+ * 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.crypto.cms.exception;
+
+public class CryptoCmsException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    public CryptoCmsException() {
+    }
+
+    public CryptoCmsException(String message) {
+        super(message);
+
+    }
+
+    public CryptoCmsException(Throwable cause) {
+        super(cause);
+
+    }
+
+    public CryptoCmsException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsFormatException.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsFormatException.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsFormatException.java
new file mode 100644
index 0000000..02aea9a
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsFormatException.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.crypto.cms.exception;
+
+/**
+ * Exception thrown when the decoding of an input stream to a cms object, like
+ * singed data or enveloped data, fails.
+ * 
+ * 
+ */
+public class CryptoCmsFormatException extends CryptoCmsException {
+
+    private static final long serialVersionUID = 1L;
+
+    public CryptoCmsFormatException(String message) {
+        super(message);
+    }
+
+    public CryptoCmsFormatException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsInvalidKeyException.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsInvalidKeyException.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsInvalidKeyException.java
new file mode 100644
index 0000000..5609f50
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsInvalidKeyException.java
@@ -0,0 +1,33 @@
+/**
+ * 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.crypto.cms.exception;
+
+/**
+ * Exception thrown during singing if the key type does not fit to the signature
+ * algorithm.
+ * 
+ * 
+ */
+public class CryptoCmsInvalidKeyException extends CryptoCmsException {
+
+    private static final long serialVersionUID = 1L;
+
+    public CryptoCmsInvalidKeyException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForRecipientsException.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForRecipientsException.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForRecipientsException.java
new file mode 100644
index 0000000..ebf78ac
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForRecipientsException.java
@@ -0,0 +1,31 @@
+/**
+ * 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.crypto.cms.exception;
+
+/**
+ * Exception thrown when no certificate in the keystore fits to the recipients
+ * in the CMS enveloped data during the decryption process.
+ */
+public class CryptoCmsNoCertificateForRecipientsException extends CryptoCmsException {
+
+    private static final long serialVersionUID = 1L;
+
+    public CryptoCmsNoCertificateForRecipientsException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForSignerInfoException.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForSignerInfoException.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForSignerInfoException.java
new file mode 100644
index 0000000..d1ed3a6
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForSignerInfoException.java
@@ -0,0 +1,34 @@
+/**
+ * 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.crypto.cms.exception;
+
+/**
+ * Is thrown when the signature validation fails because no certificate is found
+ * the keystore which corresponds to the a specific signer information.
+ * <p>
+ * Can only be thrown when the configuration "verifySignatureOfAllSigners" is
+ * true.
+ */
+public class CryptoCmsNoCertificateForSignerInfoException extends CryptoCmsSignatureException {
+
+    private static final long serialVersionUID = 1L;
+
+    public CryptoCmsNoCertificateForSignerInfoException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForSignerInfosException.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForSignerInfosException.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForSignerInfosException.java
new file mode 100644
index 0000000..ac05c77
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoCertificateForSignerInfosException.java
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.crypto.cms.exception;
+
+/**
+ * Is thrown when the signature validation fails because no certificate is found
+ * in the keystore which corresponds to the sent signer infos.
+ */
+public class CryptoCmsNoCertificateForSignerInfosException extends CryptoCmsSignatureException {
+
+    private static final long serialVersionUID = 1L;
+
+    public CryptoCmsNoCertificateForSignerInfosException(String message) {
+        super(message);
+    }
+
+    public CryptoCmsNoCertificateForSignerInfosException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoKeyOrCertificateForAliasException.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoKeyOrCertificateForAliasException.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoKeyOrCertificateForAliasException.java
new file mode 100644
index 0000000..00fa790
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsNoKeyOrCertificateForAliasException.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.crypto.cms.exception;
+
+/**
+ * Exception which is thrown when for a specified alias a key or certificate is
+ * not found in the keystore.
+ * 
+ * 
+ */
+public class CryptoCmsNoKeyOrCertificateForAliasException extends CryptoCmsException {
+
+    private static final long serialVersionUID = 1L;
+
+    public CryptoCmsNoKeyOrCertificateForAliasException() {
+
+    }
+
+    public CryptoCmsNoKeyOrCertificateForAliasException(String message) {
+        super(message);
+    }
+
+    public CryptoCmsNoKeyOrCertificateForAliasException(Throwable cause) {
+        super(cause);
+    }
+
+    public CryptoCmsNoKeyOrCertificateForAliasException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsSignatureException.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsSignatureException.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsSignatureException.java
new file mode 100644
index 0000000..66ba4b0
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsSignatureException.java
@@ -0,0 +1,33 @@
+/**
+ * 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.crypto.cms.exception;
+
+/**
+ * This exception is thrown if SignedData signature verification fails.
+ */
+public class CryptoCmsSignatureException extends CryptoCmsException {
+
+    private static final long serialVersionUID = 1L;
+
+    public CryptoCmsSignatureException(String message) {
+        super(message);
+    }
+
+    public CryptoCmsSignatureException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsSignatureInvalidContentHashException.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsSignatureInvalidContentHashException.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsSignatureInvalidContentHashException.java
new file mode 100644
index 0000000..cec8b9c
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsSignatureInvalidContentHashException.java
@@ -0,0 +1,33 @@
+/**
+ * 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.crypto.cms.exception;
+
+/**
+ * This exception is thrown if the verification of a SignedData signature fails
+ * because the hash calculated over the content does not match to the value of
+ * signed MessageDigest attribute value.
+ * 
+ */
+public class CryptoCmsSignatureInvalidContentHashException extends CryptoCmsSignatureException {
+
+    private static final long serialVersionUID = 1L;
+
+    public CryptoCmsSignatureInvalidContentHashException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsVerifierCertificateNotValidException.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsVerifierCertificateNotValidException.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsVerifierCertificateNotValidException.java
new file mode 100644
index 0000000..836e790
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/CryptoCmsVerifierCertificateNotValidException.java
@@ -0,0 +1,31 @@
+/**
+ * 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.crypto.cms.exception;
+
+/**
+ * If the verifier tries to verify a signature with a certificate which is not
+ * valid at the time given as the SignerInfo's signing time.
+ */
+public class CryptoCmsVerifierCertificateNotValidException extends CryptoCmsSignatureException {
+
+    private static final long serialVersionUID = 1L;
+
+    public CryptoCmsVerifierCertificateNotValidException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/packageinfo
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/packageinfo b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/packageinfo
new file mode 100644
index 0000000..e252556
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/exception/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/DefaultSignedDataVerifierConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/DefaultSignedDataVerifierConfiguration.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/DefaultSignedDataVerifierConfiguration.java
new file mode 100644
index 0000000..59c5c2e
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/DefaultSignedDataVerifierConfiguration.java
@@ -0,0 +1,105 @@
+/**
+ * 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.crypto.cms.sig;
+
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.crypto.cms.common.DefaultCryptoCmsUnMarshallerConfiguration;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+
+/**
+ * Fetches the X.509 certificates which can be used for the verification from a
+ * Java keystore.
+ */
+@UriParams
+public class DefaultSignedDataVerifierConfiguration extends DefaultCryptoCmsUnMarshallerConfiguration implements SignedDataVerifierConfiguration, Cloneable {
+
+    @UriParam(label = "verify", defaultValue = "false")
+    private Boolean signedDataHeaderBase64 = Boolean.FALSE;
+
+    @UriParam(label = "verify", defaultValue = "true")
+    private Boolean verifySignaturesOfAllSigners = Boolean.TRUE;
+
+    /**
+     * Indicates whether the value in the header CamelCryptoCmsSignedData is
+     * base64 encoded. Default value is <code>false</code>.
+     * <p>
+     * Only relevant for detached signatures. In the detached signature case,
+     * the header contains the Signed Data object.
+     */
+    public void setSignedDataHeaderBase64(Boolean signedDataHeaderBase64) {
+        this.signedDataHeaderBase64 = signedDataHeaderBase64;
+    }
+
+    @Override
+    public Boolean isSignedDataHeaderBase64(Exchange exchange) throws CryptoCmsException {
+        return signedDataHeaderBase64;
+    }
+
+    /**
+     * If <code>true</code> then the signatures of all signers contained in the
+     * Signed Data object are verified. If <code>false</code> then only one
+     * signature whose signer info matches with one of the specified
+     * certificates is verified. Default value is <code>true</code>.
+     */
+    public void setVerifySignaturesOfAllSigners(Boolean verifySignaturesOfAllSigners) {
+        this.verifySignaturesOfAllSigners = verifySignaturesOfAllSigners;
+    }
+
+    @Override
+    public Boolean isVerifySignaturesOfAllSigners(Exchange exchange) throws CryptoCmsException {
+        return verifySignaturesOfAllSigners;
+    }
+
+    @Override
+    public Collection<X509Certificate> getCertificates(Exchange exchange) throws CryptoCmsException {
+        KeyStore keystore = getKeyStore();
+        try {
+            List<X509Certificate> certs = new ArrayList<>(keystore.size());
+            for (Enumeration<String> aliases = keystore.aliases(); aliases.hasMoreElements();) {
+                String alias = aliases.nextElement();
+                Certificate cert = keystore.getCertificate(alias);
+                if (cert instanceof X509Certificate) {
+                    certs.add((X509Certificate)cert);
+                }
+            }
+            return certs;
+        } catch (KeyStoreException e) {
+            throw new CryptoCmsException("Problem during reading the certificates of the verifier keystore");
+        }
+    }
+
+    public DefaultSignedDataVerifierConfiguration copy() {
+        try {
+            return (DefaultSignedDataVerifierConfiguration)clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeCamelException(e); // should never happen
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/DefaultSignerInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/DefaultSignerInfo.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/DefaultSignerInfo.java
new file mode 100644
index 0000000..0a02a03
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/DefaultSignerInfo.java
@@ -0,0 +1,198 @@
+/**
+ * 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.crypto.cms.sig;
+
+import java.security.Key;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.common.DefaultCryptoCmsConfiguration;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsNoKeyOrCertificateForAliasException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.bouncycastle.cms.CMSAttributeTableGenerator;
+import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator;
+
+/**
+ * Reads the signer information from a Java keystore. You have to specify an
+ * alias for the private key entry, the signature algorithm, and the keystore.
+ */
+@UriParams
+public class DefaultSignerInfo extends DefaultCryptoCmsConfiguration implements SignerInfo {
+
+    @UriParam(label = "sign")
+    private String privateKeyAlias;
+
+    @UriParam(label = "sign")
+    private char[] password;
+    @UriParam(label = "sign", defaultValue = "SHA256withRSA")
+    private String signatureAlgorithm = "SHA256withRSA";
+    @UriParam(label = "sign", defaultValue = "true")
+    private boolean includeCertificates = true;
+
+    @UriParam(label = "sign,advanced")
+    private CMSAttributeTableGenerator signedAttributeGenerator = new DefaultSignedAttributeTableGenerator();
+
+    @UriParam(label = "sign,advanced", defaultValue = "null")
+    private CMSAttributeTableGenerator unsignedAttributeGenerator;
+
+    /**
+     * Password of the private key. If not set then the password set in the
+     * parameter 'keystoreParameters' is used.
+     */
+    public void setPassword(char[] password) {
+        this.password = password;
+    }
+
+    protected char[] getPassword(Exchange exchange) throws CryptoCmsException {
+        if (password != null) {
+            return password;
+        }
+
+        String pw = null;
+        if (getKeyStoreParameters() != null) {
+            pw = getKeyStoreParameters().getPassword();
+        }
+        if (pw == null) {
+            throw new CryptoCmsException("No password for accessing the private key from the keystore found for the singer infor " + this);
+        }
+        return pw.toCharArray();
+    }
+
+    protected String getPrivateKeyAlias(Exchange exchange) throws CryptoCmsException {
+        if (privateKeyAlias == null) {
+            throw new CryptoCmsException("No alias defined for signer info " + this);
+        }
+        return privateKeyAlias;
+    }
+
+    /**
+     * Alias of the private key entry in the keystore which is used for signing.
+     */
+    public void setPrivateKeyAlias(String privateKeyAlias) {
+        this.privateKeyAlias = privateKeyAlias;
+    }
+
+    /**
+     * Signature algorithm. The default algorithm is "SHA256withRSA".
+     * <p>
+     * Attention, the signature algorithm must fit to the signer private key.
+     */
+    public void setSignatureAlgorithm(String signatureAlgorithm) {
+        this.signatureAlgorithm = signatureAlgorithm;
+    }
+
+    /**
+     * If <tt>true</tt> then the certificate chain corresponding to the alias of
+     * the private key is added to the certificate list of the Signed Data
+     * instance.
+     */
+    public void setIncludeCertificates(boolean includeCertificates) {
+        this.includeCertificates = includeCertificates;
+    }
+
+    @Override
+    public String getSignatureAlgorithm(Exchange exchange) throws CryptoCmsException {
+        return signatureAlgorithm;
+    }
+
+    @Override
+    public PrivateKey getPrivateKey(Exchange exchange) throws CryptoCmsException {
+        String alias = getPrivateKeyAlias(exchange);
+        try {
+            Key key = getKeyStore().getKey(alias, getPassword(exchange));
+            if (key instanceof PrivateKey) {
+                return (PrivateKey)key;
+            }
+        } catch (UnrecoverableKeyException | KeyStoreException | NoSuchAlgorithmException e) {
+            throw new CryptoCmsException("Problem occured during accessing the private key for the alias '" + alias + "' in the keystore of signer " + this);
+        }
+        throw new CryptoCmsNoKeyOrCertificateForAliasException("No private key found  for the alias '" + alias + "' in the keystore of signer " + this);
+    }
+
+    @Override
+    public X509Certificate getCertificate(Exchange exchange) throws CryptoCmsException {
+
+        String alias = getPrivateKeyAlias(exchange);
+        Certificate cert;
+        try {
+            cert = getKeyStore().getCertificate(alias);
+        } catch (KeyStoreException e) {
+            throw new CryptoCmsException("Problem during accessing the certificate for the alias '" + alias + "' in the signer " + this, e);
+        }
+        if (cert instanceof X509Certificate) {
+            return (X509Certificate)cert;
+        }
+        throw new CryptoCmsNoKeyOrCertificateForAliasException("No X.509 certificate found for alias '" + alias + "' in the keystore of signer " + this);
+    }
+
+    @Override
+    public Certificate[] getCertificateChain(Exchange exchange) throws CryptoCmsException {
+        if (includeCertificates) {
+            String alias = getPrivateKeyAlias(exchange);
+            Certificate[] certs;
+            try {
+                certs = getKeyStore().getCertificateChain(alias);
+            } catch (KeyStoreException e) {
+                throw new CryptoCmsException("Problem during accessing the certificate chain for the alias '" + alias + "' in the keystore of signer " + this, e);
+            }
+            if (certs == null) {
+                return new Certificate[0];
+            } else {
+                return certs;
+            }
+        } else {
+            return new Certificate[0];
+        }
+    }
+
+    /**
+     * Signed attributes of the Signed Data instance. By default contentType,
+     * signingTime, messageDigest, and id-aa-CMSAlgorithmProtection are set.
+     */
+    public void setSignedAttributeGenerator(CMSAttributeTableGenerator signedAttributeGenerator) {
+        this.signedAttributeGenerator = signedAttributeGenerator;
+    }
+
+    /**
+     * Unsigned attributes of the Signed Data instance. By default no unsigned
+     * attribute is set.
+     */
+    public void setUnsignedAttributeGenerator(CMSAttributeTableGenerator unsignedAttributeGenerator) {
+        this.unsignedAttributeGenerator = unsignedAttributeGenerator;
+    }
+
+    @Override
+    public CMSAttributeTableGenerator getSignedAttributeGenerator(Exchange exchange) throws CryptoCmsException {
+        return signedAttributeGenerator;
+    }
+
+    @Override
+    public CMSAttributeTableGenerator getUnsignedAttributeGenerator(Exchange exchange) throws CryptoCmsException {
+        return unsignedAttributeGenerator;
+    }
+
+    public String toString() {
+        return "private key alias=" + privateKeyAlias + ", signature algorithm=" + signatureAlgorithm + ", isIncludeCertificates=" + includeCertificates;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataCreator.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataCreator.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataCreator.java
new file mode 100644
index 0000000..1369551
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataCreator.java
@@ -0,0 +1,129 @@
+/**
+ * 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.crypto.cms.sig;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsConstants;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsMarshallerAbstract;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsInvalidKeyException;
+import org.apache.camel.util.IOHelper;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cms.CMSSignedDataStreamGenerator;
+import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SignedDataCreator extends CryptoCmsMarshallerAbstract {
+    private static final Logger LOG = LoggerFactory.getLogger(SignedDataCreator.class);
+
+    private SignedDataCreatorConfiguration config;
+
+    public SignedDataCreator(SignedDataCreatorConfiguration conf) {
+        super(conf);
+        config = conf;
+    }
+
+    @Override
+    protected void setBodyAndHeader(Message out, Object encodedSignedData) {
+        if (config.getIncludeContent()) {
+            /*
+             * The encodedSignedData object contains the signer infos including
+             * the message content.
+             */
+            out.setBody(encodedSignedData);
+        } else {
+            /*
+             * The encodedSignedData object contains only the signer infos
+             * (without the message content). As the message body is not changed
+             * in this case and is passed through
+             */
+            out.setHeader(CryptoCmsConstants.CAMEL_CRYPTO_CMS_SIGNED_DATA, encodedSignedData);
+        }
+    }
+
+    @Override
+    protected void marshalInternal(InputStream is, OutputStream os, Exchange exchange) throws Exception {
+
+        CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
+
+        if (config.getSigner().isEmpty()) {
+            throw new CryptoCmsException("No signer information configured");
+        }
+        for (SignerInfo signer : config.getSigner()) {
+            // these certificates are sent within the signature
+            LOG.debug("Signer info: {}", signer);
+            X509Certificate signerCert = signer.getCertificate(exchange);
+            if (signerCert == null) {
+                throw new CryptoCmsException("Certificate missing in the singer information " + signer);
+            }
+
+            PrivateKey key = signer.getPrivateKey(exchange);
+            if (key == null) {
+                throw new CryptoCmsException("Private key missing in the singer information " + signer);
+            }
+
+            ContentSigner contentSigner;
+            try {
+                contentSigner = new JcaContentSignerBuilder(signer.getSignatureAlgorithm(exchange)).setProvider(BouncyCastleProvider.PROVIDER_NAME).build(key);
+            } catch (OperatorCreationException e) {
+                throw new CryptoCmsInvalidKeyException("The private key of the signer information  '" + signer + "' does not fit to the specified signature algorithm '"
+                                                       + signer.getSignatureAlgorithm(exchange) + "': " + e.getMessage(), e);
+            }
+
+            JcaSignerInfoGeneratorBuilder signerBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME)
+                .build());
+            signerBuilder.setSignedAttributeGenerator(signer.getSignedAttributeGenerator(exchange)).setUnsignedAttributeGenerator(signer.getUnsignedAttributeGenerator(exchange));
+
+            gen.addSignerInfoGenerator(signerBuilder.build(contentSigner, signerCert));
+
+            List<Certificate> certificateList = new ArrayList<Certificate>();
+            for (Certificate cert : signer.getCertificateChain(exchange)) {
+                if (!certificateList.contains(cert)) {
+                    certificateList.add(cert);
+                    gen.addCertificate(new X509CertificateHolder(cert.getEncoded()));
+                    LOG.debug("Certificate added to Signed Data certificate list: {}", cert);
+                }
+            }
+        }
+
+        OutputStream sigOut = gen.open(os, config.getIncludeContent());
+        try {
+            IOHelper.copyAndCloseInput(is, sigOut);
+        } finally {
+            IOHelper.close(sigOut);
+        }
+
+        LOG.debug("CMS Signed Data generation successful");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataCreatorConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataCreatorConfiguration.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataCreatorConfiguration.java
new file mode 100644
index 0000000..354aede
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataCreatorConfiguration.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.crypto.cms.sig;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsMarshallerConfiguration;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@UriParams
+public class SignedDataCreatorConfiguration extends CryptoCmsMarshallerConfiguration {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SignedDataCreatorConfiguration.class);
+
+    @UriParam(label = "sign", defaultValue = "true")
+    private Boolean includeContent = Boolean.TRUE;
+
+    @UriParam(label = "sign", multiValue = true, description = "Signer information: reference to a bean which implements org.apache.camel.component.crypto.cms.api.SignerInfo")
+    private final List<SignerInfo> signer = new ArrayList<SignerInfo>(3);
+
+    public SignedDataCreatorConfiguration(CamelContext context) {
+        super(context);
+    }
+
+    public Boolean getIncludeContent() {
+        return includeContent;
+    }
+
+    /**
+     * Indicates whether the signed content should be included into the Signed
+     * Data instance. If false then a detached Signed Data instance is created
+     * in the header CamelCryptoCmsSignedData.
+     */
+    public void setIncludeContent(Boolean includeContent) {
+        this.includeContent = includeContent;
+    }
+
+    public List<SignerInfo> getSigner() {
+        return signer;
+    }
+
+    public void setSigner(SignerInfo signer) {
+        this.signer.add(signer);
+    }
+
+    // for multi values
+    public void setSigner(List<?> signers) {
+        if (signers == null) {
+            return;
+        }
+        for (Object signerOb : signers) {
+            if (signerOb instanceof String) {
+                String signerName = (String)signerOb;
+                String valueNoHash = signerName.replaceAll("#", "");
+                if (getContext() != null && signerName != null) {
+                    SignerInfo signer = getContext().getRegistry().lookupByNameAndType(valueNoHash, SignerInfo.class);
+                    if (signer != null) {
+                        setSigner(signer);
+                    }
+                }
+            }
+        }
+
+    }
+
+    public void init() throws CryptoCmsException {
+
+        if (signer.isEmpty()) {
+            logErrorAndThrow(LOG, "No signer set.");
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b831203b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifier.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifier.java b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifier.java
new file mode 100644
index 0000000..f3c1e11
--- /dev/null
+++ b/components/camel-crypto-cms/src/main/java/org/apache/camel/component/crypto/cms/sig/SignedDataVerifier.java
@@ -0,0 +1,286 @@
+/**
+ * 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.crypto.cms.sig;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.crypto.cms.common.CryptoCmsUnmarshaller;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsFormatException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsNoCertificateForSignerInfoException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsNoCertificateForSignerInfosException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsSignatureException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsSignatureInvalidContentHashException;
+import org.apache.camel.component.crypto.cms.exception.CryptoCmsVerifierCertificateNotValidException;
+import org.apache.camel.converter.stream.OutputStreamBuilder;
+import org.apache.camel.util.IOHelper;
+import org.bouncycastle.asn1.cms.Attribute;
+import org.bouncycastle.asn1.cms.CMSAttributes;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.jcajce.JcaCertStore;
+import org.bouncycastle.cms.CMSAttributeTableGenerator;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.CMSSignedDataParser;
+import org.bouncycastle.cms.CMSSignerDigestMismatchException;
+import org.bouncycastle.cms.CMSVerifierCertificateNotValidException;
+import org.bouncycastle.cms.SignerInformation;
+import org.bouncycastle.cms.SignerInformationStore;
+import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SignedDataVerifier extends CryptoCmsUnmarshaller {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SignedDataVerifier.class);
+
+    private final SignedDataVerifierConfiguration conf;
+
+    public SignedDataVerifier(SignedDataVerifierConfiguration config) {
+        super(config);
+        this.conf = config;
+    }
+
+    @Override
+    protected Object unmarshalInternal(InputStream is, Exchange exchange) throws Exception {
+
+        CMSSignedDataParser sp;
+        try {
+            sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME).build(), is);
+        } catch (CMSException e) {
+            throw new CryptoCmsFormatException(getFormatErrorMessage(), e);
+        }
+        OutputStreamBuilder output = getOutputStream(sp, exchange);
+
+        debugLog(sp);
+
+        verify(sp, exchange);
+
+        return output.build();
+    }
+
+    protected String getFormatErrorMessage() {
+        return "Message has invalid format. It was not possible to parse the message into a PKCS7/CMS content info object containing PKCS7/CMS Signed Data.";
+    }
+
+    protected OutputStreamBuilder getOutputStream(CMSSignedDataParser sp, Exchange exchange) throws Exception {
+        // get the InputStream with the plain data
+        InputStream data;
+        try {
+            data = sp.getSignedContent().getContentStream();
+        } catch (NullPointerException e) { // nullpointer exception is
+                                           // thrown when the signed content
+                                           // is missing
+            throw getContentMissingException(e);
+        }
+
+        // the input stream must be completely read, otherwise the signer
+        // info is not available!
+        OutputStreamBuilder osb = OutputStreamBuilder.withExchange(exchange);
+
+        try {
+            // data can be null in the case of explicit Signed Data
+            if (data != null) {
+                try {
+                    IOHelper.copy(data, osb);
+                } finally {
+                    IOHelper.close(data);
+                }
+            }
+        } catch (IOException e) {
+            throw new CryptoCmsException("Error during reading the signed content of the signed data object", e);
+        }
+        return osb;
+    }
+
+    protected CryptoCmsException getContentMissingException(NullPointerException e) {
+        return new CryptoCmsException("PKCS7/CMS signature validation not possible: The content for which the hash-value must be calculated is missing in the PKCS7/CMS signed data instance. "
+                                      + "Please check the configuration of the sender of the PKCS7/CMS signature.", e);
+    }
+
+    protected void debugLog(CMSSignedDataParser sp) throws CMSException {
+        if (!LOG.isDebugEnabled()) {
+            return;
+        }
+        SignerInformationStore signers = sp.getSignerInfos();
+        Set<AlgorithmIdentifier> messageDigestAlgorithms = sp.getDigestAlgorithmIDs();
+        for (AlgorithmIdentifier algorithm : messageDigestAlgorithms) {
+            LOG.debug("Message digest algorithm: {}", algorithm.getAlgorithm().getId());
+        }
+
+        LOG.debug("Included Signer Infos:");
+        int i = 0;
+        for (SignerInformation signer : signers.getSigners()) {
+            i++;
+            LOG.debug("    Signer {}: {} ", new Object[] {i, signerInformationToString(signer)});
+            if (signer.getSignedAttributes() != null) {
+                @SuppressWarnings("unchecked")
+                Hashtable<String, Attribute> authAttTable = signer.getSignedAttributes().toHashtable();
+                if (authAttTable != null) {
+                    LOG.debug("    Signed attributes of signer {}: {}", i, attributesToString(authAttTable));
+                }
+            }
+            if (signer.getUnsignedAttributes() != null) {
+                @SuppressWarnings("unchecked")
+                Hashtable<String, Attribute> unAuthAtts = signer.getUnsignedAttributes().toHashtable();
+                if (unAuthAtts != null) {
+                    LOG.debug("    Unsigned attributes of signer {}: {}", i, attributesToString(unAuthAtts));
+                }
+            }
+        }
+    }
+
+    protected void verify(CMSSignedDataParser signed, Exchange exchange) throws Exception {
+
+        SignerInformationStore signers = getNonEmptySenderInfos(signed);
+
+        Collection<X509Certificate> allowedVerifyCerts = conf.getCertificates(exchange);
+        if (allowedVerifyCerts.isEmpty()) {
+            throw new CryptoCmsNoCertificateForSignerInfosException("Cannot verify the signatures of the the PKCS7/CMS Signed Data object: No verifier certificate is configured.");
+        }
+
+        JcaCertStore certStore = new JcaCertStore(allowedVerifyCerts);
+
+        boolean atLeastOneSignatureVerified = false;
+        for (SignerInformation signer : signers.getSigners()) {
+            @SuppressWarnings("unchecked")
+            Collection<X509CertificateHolder> certCollection = certStore.getMatches(signer.getSID());
+
+            if (certCollection.isEmpty()) {
+                if (conf.isVerifySignaturesOfAllSigners(exchange)) {
+                    throw new CryptoCmsNoCertificateForSignerInfoException("KCS7/CMS signature verification failed. The public key for the signer information with"
+                                                                           + signerInformationToString(signer) + " cannot be found in the configured certificates: "
+                                                                           + certsToString(allowedVerifyCerts));
+                } else {
+                    continue;
+                }
+            }
+            Iterator<X509CertificateHolder> certIt = certCollection.iterator();
+            X509CertificateHolder cert = certIt.next();
+
+            try {
+                if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME).build(cert))) {
+                    LOG.debug("Verification successful");
+                    atLeastOneSignatureVerified = true;
+                    if (!conf.isVerifySignaturesOfAllSigners(exchange)) {
+                        return;
+                    }
+                } else {
+                    throw new CryptoCmsSignatureException("PKCS7/CMS signature verification failed for signer information with " + issuerSerialNumberSubject(cert));
+                }
+            } catch (CMSSignerDigestMismatchException e) {
+                throw new CryptoCmsSignatureInvalidContentHashException("PKCS7/CMS signature verification failed for signer information with " + issuerSerialNumberSubject(cert)
+                                                                        + ". Calculated hash differs from the signed hash value. Either the message content does not correspond "
+                                                                        + "to the signature or the message might be tampered.", e);
+            } catch (CMSVerifierCertificateNotValidException e) {
+                throw new CryptoCmsVerifierCertificateNotValidException("PKCS7/CMS signature verification failed for signer information with " + issuerSerialNumberSubject(cert)
+                                                                        + ". Certificate was not valid at the signing time.", e);
+            }
+        }
+
+        if (!atLeastOneSignatureVerified) {
+            throw new CryptoCmsNoCertificateForSignerInfosException("Cannot verify the signature of the PKCS7/CMS signed data object with the certificates "
+                                                                    + certsToString(allowedVerifyCerts)
+                                                                    + " specified in the configuration. The signers in the signed data object are: " + signersToString(signers));
+
+        }
+    }
+
+    SignerInformationStore getNonEmptySenderInfos(CMSSignedDataParser signed) throws CryptoCmsException, CMSException {
+        SignerInformationStore senders = signed.getSignerInfos();
+        if (senders.size() == 0) {
+            throw new CryptoCmsException("Sent CMS/PKCS7 signed data message is incorrect. No signer info found in signed data. Correct the sent message.");
+        }
+        return senders;
+    }
+
+    protected String signerInformationToString(SignerInformation sigInfo) {
+        if (sigInfo == null) {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        sb.append("ContentTypeOID=");
+        sb.append(sigInfo.getContentType());
+        sb.append(", Issuer=");
+        sb.append(sigInfo.getSID().getIssuer());
+        sb.append(", SerialNumber=");
+        sb.append(sigInfo.getSID().getSerialNumber());
+        sb.append(", SignerInfoVersion=");
+        sb.append(sigInfo.getVersion());
+        sb.append(", SignatureAlgorithmOID=");
+        sb.append(sigInfo.getDigestAlgOID());
+        sb.append(", EncryptionAlgorithmOID=");
+        sb.append(sigInfo.getEncryptionAlgOID());
+        sb.append(", isCounterSignature=");
+        sb.append(sigInfo.isCounterSignature());
+
+        return sb.toString();
+
+    }
+
+    protected String signersToString(SignerInformationStore signers) {
+        if (signers == null) {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        Collection<SignerInformation> sigInfos = signers.getSigners();
+        int size = sigInfos.size();
+        int counter = 0;
+        for (SignerInformation sigInfo : sigInfos) {
+            counter++;
+            sb.append('[');
+            sb.append("Issuer=");
+            sb.append(sigInfo.getSID().getIssuer());
+            sb.append(", SerialNumber=");
+            sb.append(sigInfo.getSID().getSerialNumber());
+            sb.append(']');
+            if (counter < size) {
+                sb.append("; ");
+            }
+        }
+        return sb.toString();
+    }
+
+    protected String attributesToString(Hashtable<String, Attribute> attributes) {
+        if (attributes == null) {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Attribute attr : attributes.values()) {
+            sb.append(attr.getAttrType());
+            if (CMSAttributes.signingTime.equals(attr.getAttrType()) || CMSAttributes.messageDigest.equals(attr.getAttrType())
+                || CMSAttributes.cmsAlgorithmProtect.equals(attr.getAttrType()) || CMSAttributeTableGenerator.CONTENT_TYPE.equals(attr.getAttrType())) {
+                // for these attributes we can print the value because we know
+                // they do not contain confidential or personal data
+                sb.append("=");
+                sb.append(attr.getAttrValues());
+            }
+            sb.append(",");
+        }
+        return sb.toString();
+    }
+
+}