You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2011/11/04 14:41:01 UTC

svn commit: r1197560 - in /camel/trunk: components/camel-crypto/ components/camel-crypto/src/main/java/org/apache/camel/component/crypto/ components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/ components/camel-crypto/src/test/java/org...

Author: davsclaus
Date: Fri Nov  4 13:41:01 2011
New Revision: 1197560

URL: http://svn.apache.org/viewvc?rev=1197560&view=rev
Log:
CAMEL-4549: Added PGP data format. Thanks to Adam for the patch.

Added:
    camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java   (with props)
    camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java   (with props)
    camel/trunk/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java   (with props)
    camel/trunk/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/pubring.gpg   (with props)
    camel/trunk/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/secring.gpg   (with props)
Modified:
    camel/trunk/components/camel-crypto/pom.xml
    camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/component/crypto/DigitalSignatureComponent.java
    camel/trunk/parent/pom.xml
    camel/trunk/platforms/karaf/features/pom.xml
    camel/trunk/platforms/karaf/features/src/main/resources/features.xml

Modified: camel/trunk/components/camel-crypto/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-crypto/pom.xml?rev=1197560&r1=1197559&r2=1197560&view=diff
==============================================================================
--- camel/trunk/components/camel-crypto/pom.xml (original)
+++ camel/trunk/components/camel-crypto/pom.xml Fri Nov  4 13:41:01 2011
@@ -17,73 +17,77 @@
 -->
 <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>
+	<modelVersion>4.0.0</modelVersion>
 
-    <parent>
-        <groupId>org.apache.camel</groupId>
-        <artifactId>camel-parent</artifactId>
-        <version>2.9-SNAPSHOT</version>
-        <relativePath>../../parent</relativePath>
-    </parent>
-
-    <artifactId>camel-crypto</artifactId>
-    <packaging>bundle</packaging>
-    <name>Camel :: Crypto</name>
-    <description>Camel Cryptographic Support</description>
-
-    <properties>
-        <camel.osgi.export.pkg>
-            org.apache.camel.component.crypto.*;${camel.osgi.version},
-            org.apache.camel.converter.crypto.*
-        </camel.osgi.export.pkg>
-        <camel.osgi.import.pkg>
-            !org.apache.camel.component.crypto.*,
-            !org.apache.camel.converter.crypto.*,
-            ${camel.osgi.import.defaults},
-            *
-        </camel.osgi.import.pkg>    
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>commons-codec</groupId>
-            <artifactId>commons-codec</artifactId>
-            <version>${commons-codec}</version>
-        </dependency>
-
-        <!-- for testing -->
-        <dependency>
-            <groupId>bouncycastle</groupId>
-            <artifactId>bcprov-jdk15</artifactId>
-            <version>${bouncycastle-version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-spring</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-          <groupId>org.slf4j</groupId>
-          <artifactId>slf4j-log4j12</artifactId>
-          <scope>test</scope>
-        </dependency>
+	<parent>
+		<groupId>org.apache.camel</groupId>
+		<artifactId>camel-parent</artifactId>
+		<version>2.9-SNAPSHOT</version>
+		<relativePath>../../parent</relativePath>
+	</parent>
+
+	<artifactId>camel-crypto</artifactId>
+	<packaging>bundle</packaging>
+	<name>Camel :: Crypto</name>
+	<description>Camel Cryptographic Support</description>
+
+	<properties>
+		<camel.osgi.export.pkg>
+			org.apache.camel.component.crypto.*;${camel.osgi.version},
+			org.apache.camel.converter.crypto.*
+		</camel.osgi.export.pkg>
+		<camel.osgi.import.pkg>
+			!org.apache.camel.component.crypto.*,
+			!org.apache.camel.converter.crypto.*,
+			${camel.osgi.import.defaults},
+			*
+		</camel.osgi.import.pkg>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.camel</groupId>
+			<artifactId>camel-core</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>commons-codec</groupId>
+			<artifactId>commons-codec</artifactId>
+			<version>${commons-codec}</version>
+		</dependency>
+ 		<dependency>
+			<groupId>org.bouncycastle</groupId>
+			<artifactId>bcpg-jdk16</artifactId>
+			<version>${bouncycastle-version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.bouncycastle</groupId>
+			<artifactId>bcprov-jdk16</artifactId>
+			<version>${bouncycastle-version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>${commons-io-version}</version>
+		</dependency> 
+
+		<!-- for testing -->
+		<dependency>
+			<groupId>org.apache.camel</groupId>
+			<artifactId>camel-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-log4j12</artifactId>
+			<scope>test</scope>
+		</dependency>
 
-    </dependencies>
+	</dependencies>
 
 </project>
 

Modified: camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/component/crypto/DigitalSignatureComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/component/crypto/DigitalSignatureComponent.java?rev=1197560&r1=1197559&r2=1197560&view=diff
==============================================================================
--- camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/component/crypto/DigitalSignatureComponent.java (original)
+++ camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/component/crypto/DigitalSignatureComponent.java Fri Nov  4 13:41:01 2011
@@ -28,7 +28,6 @@ import org.apache.camel.util.ObjectHelpe
 /**
  * <code>DigitalSignatureComponent</code>
  */
-@SuppressWarnings("unchecked")
 public class DigitalSignatureComponent extends DefaultComponent {
 
     private DigitalSignatureConfiguration configuration;
@@ -40,10 +39,11 @@ public class DigitalSignatureComponent e
         super(context);
     }
 
-    protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception {
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
         ObjectHelper.notNull(getCamelContext(), "CamelContext");
 
         DigitalSignatureConfiguration config = getConfiguration().copy();
+
         setProperties(config, parameters);
         config.setCamelContext(getCamelContext());
         try {

Added: camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java?rev=1197560&view=auto
==============================================================================
--- camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java (added)
+++ camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java Fri Nov  4 13:41:01 2011
@@ -0,0 +1,196 @@
+/**
+ * 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.converter.crypto;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.util.Date;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.util.ExchangeHelper;
+import org.apache.camel.util.IOHelper;
+import org.apache.commons.io.IOUtils;
+import org.bouncycastle.bcpg.ArmoredOutputStream;
+import org.bouncycastle.bcpg.CompressionAlgorithmTags;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openpgp.PGPCompressedData;
+import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
+import org.bouncycastle.openpgp.PGPEncryptedData;
+import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
+import org.bouncycastle.openpgp.PGPEncryptedDataList;
+import org.bouncycastle.openpgp.PGPLiteralData;
+import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
+import org.bouncycastle.openpgp.PGPObjectFactory;
+import org.bouncycastle.openpgp.PGPPrivateKey;
+import org.bouncycastle.openpgp.PGPPublicKey;
+import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
+import org.bouncycastle.openpgp.PGPUtil;
+import org.bouncycastle.util.io.Streams;
+
+/**
+ * <code>PGPDataFormat</code> uses the bouncy castle libraries to enable
+ * encryption and decryption in the PGP format I have also tested decrypting the
+ * files produced using GnuPG Linux command line program gpg (GnuPG) 1.4.11
+ * <ul>
+ *   <li>http://www.bouncycastle.org/java.html</li>
+ * <ul>
+ * <p/>
+ */
+public class PGPDataFormat implements DataFormat {
+
+    public static final String KEY_PUB = "CamelCryptoKeyPub";
+    public static final String KEY_PRI = "CamelCryptoKeyPri";
+
+    private PGPPublicKey configuredKey;
+    private PGPPrivateKey configuredPrivateKey;
+    private boolean armor;
+    private boolean integrity = true;
+
+    public PGPDataFormat() {
+        if (Security.getProvider("BC") == null) {
+            Security.addProvider(new BouncyCastleProvider());
+        }
+    }
+
+    public void setArmored(boolean armor) {
+        this.armor = armor;
+    }
+
+    public void setIntegrity(boolean integrity) {
+        this.integrity = integrity;
+    }
+
+    /**
+     * Set the key that should be used to encrypt or decrypt incoming encrypted exchanges.
+     */
+    public void setPublicKey(PGPPublicKey key) {
+        this.configuredKey = key;
+    }
+
+    public void setPrivateKey(PGPPrivateKey key) {
+        this.configuredPrivateKey = key;
+    }
+
+    public void marshal(Exchange exchange, Object graph, OutputStream outputStream) throws Exception {
+        PGPPublicKey key = getPublicKey(exchange);
+        if (key == null) {
+            throw new IllegalArgumentException("Public key is null, cannot proceed");
+        }
+
+        InputStream plaintextStream = ExchangeHelper.convertToMandatoryType(exchange, InputStream.class, graph);
+
+        byte[] compressedData = compress(IOUtils.toByteArray(plaintextStream),
+                PGPLiteralData.CONSOLE, CompressionAlgorithmTags.ZIP);
+
+        if (armor) {
+            outputStream = new ArmoredOutputStream(outputStream);
+        }
+
+        PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
+                PGPEncryptedData.CAST5, integrity, new SecureRandom(), "BC");
+        encGen.addMethod(key);
+
+        OutputStream encOut = encGen.open(outputStream, compressedData.length);
+        try {
+            encOut.write(compressedData);
+        } finally {
+            IOHelper.close(encOut);
+            if (armor) {
+                IOHelper.close(outputStream);
+            }
+        }
+    }
+
+    public Object unmarshal(Exchange exchange, InputStream encryptedStream) throws Exception {
+        if (encryptedStream == null) {
+            return null;
+        }
+
+        PGPPrivateKey key = getPrivateKey(exchange);
+        if (key == null) {
+            throw new IllegalArgumentException("Private key is null, cannot proceed");
+        }
+
+        InputStream in = new ByteArrayInputStream(IOUtils.toByteArray(encryptedStream));
+        in = PGPUtil.getDecoderStream(in);
+
+        PGPObjectFactory pgpF = new PGPObjectFactory(in);
+        PGPEncryptedDataList enc;
+        Object o = pgpF.nextObject();
+
+        // the first object might be a PGP marker packet.
+        if (o instanceof PGPEncryptedDataList) {
+            enc = (PGPEncryptedDataList) o;
+        } else {
+            enc = (PGPEncryptedDataList) pgpF.nextObject();
+        }
+
+        PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) enc.get(0);
+        InputStream clear = pbe.getDataStream(key, "BC");
+
+        PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
+        PGPCompressedData cData = (PGPCompressedData) pgpFact.nextObject();
+        pgpFact = new PGPObjectFactory(cData.getDataStream());
+        PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject();
+        return Streams.readAll(ld.getInputStream());
+    }
+
+    private static byte[] compress(byte[] clearData, String fileName, int algorithm) throws IOException {
+        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+        PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(algorithm);
+        OutputStream cos = comData.open(bOut); // open it with the final destination
+
+        PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
+
+        OutputStream pOut = lData.open(cos, // the compressed output stream
+                PGPLiteralData.BINARY, fileName, // "filename" to store
+                clearData.length, // length of clear data
+                new Date() // current time
+        );
+
+        try {
+            pOut.write(clearData);
+        } finally {
+            IOHelper.close(pOut);
+            comData.close();
+        }
+        return bOut.toByteArray();
+    }
+
+    private PGPPublicKey getPublicKey(Exchange exchange) {
+        PGPPublicKey key = exchange.getIn().getHeader(KEY_PUB, PGPPublicKey.class);
+        if (key == null) {
+            key = configuredKey;
+        }
+        return key;
+    }
+
+    private PGPPrivateKey getPrivateKey(Exchange exchange) {
+        PGPPrivateKey key = exchange.getIn().getHeader(KEY_PRI, PGPPrivateKey.class);
+        if (key == null) {
+            key = configuredPrivateKey;
+        }
+        return key;
+    }
+
+}

Propchange: camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java?rev=1197560&view=auto
==============================================================================
--- camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java (added)
+++ camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java Fri Nov  4 13:41:01 2011
@@ -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.converter.crypto;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.NoSuchProviderException;
+import java.util.Iterator;
+
+import org.bouncycastle.openpgp.PGPException;
+import org.bouncycastle.openpgp.PGPPrivateKey;
+import org.bouncycastle.openpgp.PGPPublicKey;
+import org.bouncycastle.openpgp.PGPPublicKeyRing;
+import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
+import org.bouncycastle.openpgp.PGPSecretKey;
+import org.bouncycastle.openpgp.PGPSecretKeyRing;
+import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
+import org.bouncycastle.openpgp.PGPUtil;
+
+public final class PGPDataFormatUtil {
+    
+    private PGPDataFormatUtil() {
+        
+    }
+    
+    public static PGPPublicKey findPublicKey(String filename, String userid) throws IOException, PGPException,
+        NoSuchProviderException {
+        FileInputStream fis = new FileInputStream(filename);
+        PGPPublicKey privKey;
+        try {
+            privKey = findPublicKey(fis, userid);
+        } finally {
+            fis.close();
+        }
+        return privKey;
+    }
+
+    public static PGPPublicKey findPublicKey(InputStream input, String userid) throws IOException, PGPException,
+        NoSuchProviderException {
+        PGPPublicKeyRingCollection pgpSec = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input));
+
+        @SuppressWarnings("unchecked")
+        Iterator<PGPPublicKeyRing> keyRingIter = (Iterator<PGPPublicKeyRing>)pgpSec.getKeyRings();
+        while (keyRingIter.hasNext()) {
+            PGPPublicKeyRing keyRing = keyRingIter.next();
+
+            @SuppressWarnings("unchecked")
+            Iterator<PGPPublicKey> keyIter = (Iterator<PGPPublicKey>)keyRing.getPublicKeys();
+            while (keyIter.hasNext()) {
+                PGPPublicKey key = (PGPPublicKey)keyIter.next();
+                for (@SuppressWarnings("unchecked")
+                Iterator<String> iterator = (Iterator<String>)key.getUserIDs(); iterator.hasNext();) {
+                    String userId = iterator.next();
+                    if (key.isEncryptionKey() && userId.contains(userid)) {
+                        return key;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public static PGPPrivateKey findPrivateKey(String filename, String userid, String passphrase)
+        throws IOException, PGPException, NoSuchProviderException {
+        FileInputStream fis = new FileInputStream(filename);
+        PGPPrivateKey privKey;
+        try {
+            privKey = findPrivateKey(fis, userid, passphrase);
+        } finally {
+            fis.close();
+        }
+        return privKey;
+    }
+
+    public static PGPPrivateKey findPrivateKey(InputStream input, String userid, String passphrase)
+        throws IOException, PGPException, NoSuchProviderException {
+        PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(input));
+
+        @SuppressWarnings("unchecked")
+        Iterator<PGPSecretKeyRing> keyRingIter = (Iterator<PGPSecretKeyRing>)pgpSec.getKeyRings();
+        while (keyRingIter.hasNext()) {
+            PGPSecretKeyRing keyRing = keyRingIter.next();
+
+            @SuppressWarnings("unchecked")
+            Iterator<PGPSecretKey> keyIter = (Iterator<PGPSecretKey>)keyRing.getSecretKeys();
+            while (keyIter.hasNext()) {
+                PGPSecretKey key = (PGPSecretKey)keyIter.next();
+                for (@SuppressWarnings("unchecked")
+                Iterator<String> iterator = (Iterator<String>)key.getUserIDs(); iterator.hasNext();) {
+                    String userId = iterator.next();
+                    if (key.isSigningKey() && userId.contains(userid)) {
+                        return key.extractPrivateKey(passphrase.toCharArray(), "BC");
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+}

Propchange: camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java?rev=1197560&view=auto
==============================================================================
--- camel/trunk/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java (added)
+++ camel/trunk/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java Fri Nov  4 13:41:01 2011
@@ -0,0 +1,110 @@
+/**
+ * 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.converter.crypto;
+
+import java.io.ByteArrayInputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.InvalidPayloadException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.camel.util.ExchangeHelper;
+import org.bouncycastle.openpgp.PGPPrivateKey;
+import org.bouncycastle.openpgp.PGPPublicKey;  
+import org.junit.Test;
+
+public class PGPDataFormatTest extends CamelTestSupport {
+
+    static String keyFileName = "src/test/resources/org/apache/camel/component/crypto/pubring.gpg";
+    static String keyFileNameSec = "src/test/resources/org/apache/camel/component/crypto/secring.gpg";
+    static String keyUserid = "sdude@nowhere.net";
+    static String keyPassword = "sdude";
+
+    @Test
+    public void testEncryption() throws Exception {
+        doRoundTripEncryptionTests("direct:inline", new HashMap<String, Object>());
+    }
+
+    @Test
+    public void testEncryptionHeaders() throws Exception {
+        doRoundTripEncryptionTests("direct:inlineHeaders", new HashMap<String, Object>());
+    }
+
+    private void doRoundTripEncryptionTests(String endpoint, Map<String, Object> headers) throws Exception {
+        MockEndpoint encrypted = setupExpectations(context, 3, "mock:encrypted");
+        MockEndpoint unencrypted = setupExpectations(context, 3, "mock:unencrypted");
+
+        String payload = "Hi Alice, Be careful Eve is listening, signed Bob";
+        template.sendBodyAndHeaders(endpoint, payload, headers);
+        template.sendBodyAndHeaders(endpoint, payload.getBytes(), headers);
+        template.sendBodyAndHeaders(endpoint, new ByteArrayInputStream(payload.getBytes()), headers);
+
+        assertMocksSatisfied(encrypted, unencrypted, payload);
+    }
+
+    private void assertMocksSatisfied(MockEndpoint encrypted, MockEndpoint unencrypted, String payload)
+        throws InterruptedException, InvalidPayloadException {
+        awaitAndAssert(unencrypted);
+        awaitAndAssert(encrypted);
+        for (Exchange e : unencrypted.getReceivedExchanges()) {
+            assertEquals(payload, ExchangeHelper.getMandatoryInBody(e, String.class));
+        }
+        for (Exchange e : encrypted.getReceivedExchanges()) {
+            byte[] ciphertext = ExchangeHelper.getMandatoryInBody(e, byte[].class);
+            assertNotSame(payload, new String(ciphertext));
+        }
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                PGPDataFormat cryptoFormat = new PGPDataFormat();
+                PGPPublicKey pKey = PGPDataFormatUtil.findPublicKey(keyFileName, keyUserid);
+                PGPPrivateKey sKey = PGPDataFormatUtil.findPrivateKey(keyFileNameSec, keyUserid, keyPassword);
+                cryptoFormat.setPublicKey(pKey);
+                cryptoFormat.setPrivateKey(sKey);
+
+                from("direct:inline").marshal(cryptoFormat).to("mock:encrypted").unmarshal(cryptoFormat)
+                    .to("mock:unencrypted");
+
+                PGPDataFormat cryptoFormatNoKey = new PGPDataFormat();
+                cryptoFormat.setPublicKey(pKey);
+                cryptoFormat.setPrivateKey(sKey);
+
+                from("direct:inlineHeaders").setHeader(PGPDataFormat.KEY_PUB).constant(pKey)
+                    .setHeader(PGPDataFormat.KEY_PRI).constant(sKey).marshal(cryptoFormatNoKey)
+                    .to("mock:encrypted").unmarshal(cryptoFormatNoKey).to("mock:unencrypted");
+            }
+        };
+    }
+
+    private void awaitAndAssert(MockEndpoint mock) throws InterruptedException {
+        mock.assertIsSatisfied();
+    }
+
+    public MockEndpoint setupExpectations(CamelContext context, int expected, String mock) {
+        MockEndpoint mockEp = context.getEndpoint(mock, MockEndpoint.class);
+        mockEp.expectedMessageCount(expected);
+        return mockEp;
+    }
+
+}

Propchange: camel/trunk/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/pubring.gpg
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/pubring.gpg?rev=1197560&view=auto
==============================================================================
Binary file - no diff available.

Propchange: camel/trunk/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/pubring.gpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: camel/trunk/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/secring.gpg
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/secring.gpg?rev=1197560&view=auto
==============================================================================
Binary file - no diff available.

Propchange: camel/trunk/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/secring.gpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: camel/trunk/parent/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/parent/pom.xml?rev=1197560&r1=1197559&r2=1197560&view=diff
==============================================================================
--- camel/trunk/parent/pom.xml (original)
+++ camel/trunk/parent/pom.xml Fri Nov  4 13:41:01 2011
@@ -42,7 +42,7 @@
     <aries-blueprint-version>0.3</aries-blueprint-version>
     <atomikos-trascations-version>3.7.0</atomikos-trascations-version>
     <axiom-version>1.2.12</axiom-version>
-    <bouncycastle-version>140</bouncycastle-version>
+    <bouncycastle-version>1.46</bouncycastle-version>
     <castor-bundle-version>1.3.1_1</castor-bundle-version>
     <cometd-bayeux-version>6.1.11</cometd-bayeux-version>
     <cometd-java-server>2.3.1</cometd-java-server>

Modified: camel/trunk/platforms/karaf/features/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/platforms/karaf/features/pom.xml?rev=1197560&r1=1197559&r2=1197560&view=diff
==============================================================================
--- camel/trunk/platforms/karaf/features/pom.xml (original)
+++ camel/trunk/platforms/karaf/features/pom.xml Fri Nov  4 13:41:01 2011
@@ -40,6 +40,7 @@
       <asm-bundle-version>3.3_2</asm-bundle-version>
       <aws-java-sdk-bundle-version>1.1.1_1</aws-java-sdk-bundle-version>
       <bcel-bundle-version>5.2_3</bcel-bundle-version>
+      <bcpg-jdk16-bundle-version>1.46_1</bcpg-jdk16-bundle-version>
       <cglib-version>2.1_3_6</cglib-version>
       <cometd-java-server-bundle-version>2.3.1_1</cometd-java-server-bundle-version>
       <commons-beanutils-bundle-version>1.7.0_3</commons-beanutils-bundle-version>

Modified: camel/trunk/platforms/karaf/features/src/main/resources/features.xml
URL: http://svn.apache.org/viewvc/camel/trunk/platforms/karaf/features/src/main/resources/features.xml?rev=1197560&r1=1197559&r2=1197560&view=diff
==============================================================================
--- camel/trunk/platforms/karaf/features/src/main/resources/features.xml (original)
+++ camel/trunk/platforms/karaf/features/src/main/resources/features.xml Fri Nov  4 13:41:01 2011
@@ -75,6 +75,7 @@
   <feature name='camel-crypto' version='${pom.version}' resolver='(obr)' start-level='50'>
     <feature version='${pom.version}'>camel-core</feature>
     <bundle dependency="true">mvn:commons-codec/commons-codec/${commons-codec}</bundle>
+    <bundle dependency="true">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.bcpg-jdk16/${bcpg-jdk16-bundle-version}</bundle>
     <bundle>mvn:org.apache.camel/camel-crypto/${pom.version}</bundle>
   </feature>
   <feature name='camel-http' version='${pom.version}' resolver='(obr)' start-level='50'>