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:06 UTC

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

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();
+
+}