You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2013/09/13 10:41:30 UTC

[2/3] git commit: CAMEL-6742 PGP Data Format: enable configuration of public and secure key ring via byte array parameter with thanks to Franz

CAMEL-6742 PGP Data Format: enable configuration of public and secure key ring via byte array parameter with thanks to Franz


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

Branch: refs/heads/camel-2.12.x
Commit: e4a81eac727b6ca51149fb0a1d604a3816d2179a
Parents: c57359a
Author: Willem Jiang <ni...@apache.org>
Authored: Fri Sep 13 16:27:32 2013 +0800
Committer: Willem Jiang <ni...@apache.org>
Committed: Fri Sep 13 16:28:40 2013 +0800

----------------------------------------------------------------------
 .../camel/converter/crypto/PGPDataFormat.java   | 54 +++++++++++---
 .../converter/crypto/PGPDataFormatUtil.java     | 43 ++++++++++-
 .../converter/crypto/PGPDataFormatTest.java     | 77 +++++++++++++++++++-
 .../crypto/SpringPGPDataFormatTest.java         |  5 ++
 .../crypto/SpringPGPDataFormatTest.xml          | 31 +++++++-
 5 files changed, 193 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/e4a81eac/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java
index df13927..d0d3730 100644
--- a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java
+++ b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormat.java
@@ -73,9 +73,11 @@ import org.bouncycastle.util.io.Streams;
 public class PGPDataFormat implements DataFormat {
 
     public static final String KEY_FILE_NAME = "CamelPGPDataFormatKeyFileName";
+    public static final String ENCRYPTION_KEY_RING = "CamelPGPDataFormatEncryptionKeyRing";
     public static final String KEY_USERID = "CamelPGPDataFormatKeyUserid";
     public static final String KEY_PASSWORD = "CamelPGPDataFormatKeyPassword";
     public static final String SIGNATURE_KEY_FILE_NAME = "CamelPGPDataFormatSignatureKeyFileName";
+    public static final String SIGNATURE_KEY_RING = "CamelPGPDataFormatSignatureKeyRing";
     public static final String SIGNATURE_KEY_USERID = "CamelPGPDataFormatSignatureKeyUserid";
     public static final String SIGNATURE_KEY_PASSWORD = "CamelPGPDataFormatSignatureKeyPassword";
 
@@ -85,11 +87,15 @@ public class PGPDataFormat implements DataFormat {
     private String keyUserid;
     private String password;
     private String keyFileName;
+    // alternatively to the file name you can specify the key ring as byte array
+    private byte[] encryptionKeyRing;
 
     // signature / verification key info (optional)
     private String signatureKeyUserid;
     private String signaturePassword;
     private String signatureKeyFileName;
+    // alternatively to the sigknature key file name you can specify the signature key ring as byte array
+    private byte[] signatureKeyRing;
 
     private boolean armored;
     private boolean integrity = true;
@@ -101,31 +107,39 @@ public class PGPDataFormat implements DataFormat {
     }
     
     protected String findKeyFileName(Exchange exchange) {
-        return exchange.getIn().getHeader(KEY_FILE_NAME, keyFileName, String.class);
+        return exchange.getIn().getHeader(KEY_FILE_NAME, getKeyFileName(), String.class);
+    }
+    
+    protected byte[] findEncryptionKeyRing(Exchange exchange) {
+        return exchange.getIn().getHeader(ENCRYPTION_KEY_RING, getEncryptionKeyRing(), byte[].class);
     }
     
     protected String findKeyUserid(Exchange exchange) {
-        return exchange.getIn().getHeader(KEY_USERID, keyUserid, String.class);
+        return exchange.getIn().getHeader(KEY_USERID, getKeyUserid(), String.class);
     }
     
     protected String findKeyPassword(Exchange exchange) {
-        return exchange.getIn().getHeader(KEY_PASSWORD, password, String.class);
+        return exchange.getIn().getHeader(KEY_PASSWORD, getPassword(), String.class);
     }
 
     protected String findSignatureKeyFileName(Exchange exchange) {
-        return exchange.getIn().getHeader(SIGNATURE_KEY_FILE_NAME, signatureKeyFileName, String.class);
+        return exchange.getIn().getHeader(SIGNATURE_KEY_FILE_NAME, getSignatureKeyFileName(), String.class);
+    }
+    
+    protected byte[] findSignatureKeyRing(Exchange exchange) {
+        return exchange.getIn().getHeader(SIGNATURE_KEY_RING, getSignatureKeyRing(), byte[].class);
     }
 
     protected String findSignatureKeyUserid(Exchange exchange) {
-        return exchange.getIn().getHeader(SIGNATURE_KEY_USERID, signatureKeyUserid, String.class);
+        return exchange.getIn().getHeader(SIGNATURE_KEY_USERID, getSignatureKeyUserid(), String.class);
     }
 
     protected String findSignatureKeyPassword(Exchange exchange) {
-        return exchange.getIn().getHeader(SIGNATURE_KEY_PASSWORD, signaturePassword, String.class);
+        return exchange.getIn().getHeader(SIGNATURE_KEY_PASSWORD, getSignaturePassword(), String.class);
     }
 
     public void marshal(Exchange exchange, Object graph, OutputStream outputStream) throws Exception {
-        PGPPublicKey key = PGPDataFormatUtil.findPublicKey(exchange.getContext(), findKeyFileName(exchange), findKeyUserid(exchange), true);
+        PGPPublicKey key = PGPDataFormatUtil.findPublicKey(exchange.getContext(), findKeyFileName(exchange), findEncryptionKeyRing(exchange), findKeyUserid(exchange), true);
         if (key == null) {
             throw new IllegalArgumentException("Public key is null, cannot proceed");
         }
@@ -182,12 +196,13 @@ public class PGPDataFormat implements DataFormat {
         String sigKeyFileName = findSignatureKeyFileName(exchange);
         String sigKeyUserid = findSignatureKeyUserid(exchange);
         String sigKeyPassword = findSignatureKeyPassword(exchange);
+        byte[] sigKeyRing = findSignatureKeyRing(exchange);
 
-        if (sigKeyFileName == null || sigKeyUserid == null || sigKeyPassword == null) {
+        if ((sigKeyFileName == null && sigKeyRing == null) || sigKeyUserid == null || sigKeyPassword == null) {
             return null;
         }
 
-        PGPSecretKey sigSecretKey = PGPDataFormatUtil.findSecretKey(exchange.getContext(), sigKeyFileName, sigKeyPassword);
+        PGPSecretKey sigSecretKey = PGPDataFormatUtil.findSecretKey(exchange.getContext(), sigKeyFileName, sigKeyRing, sigKeyPassword);
         if (sigSecretKey == null) {
             throw new IllegalArgumentException("Signature secret key is null, cannot proceed");
         }
@@ -213,7 +228,7 @@ public class PGPDataFormat implements DataFormat {
             return null;
         }
 
-        PGPPrivateKey key = PGPDataFormatUtil.findPrivateKey(exchange.getContext(), findKeyFileName(exchange), encryptedStream, findKeyPassword(exchange));
+        PGPPrivateKey key = PGPDataFormatUtil.findPrivateKey(exchange.getContext(), findKeyFileName(exchange), findEncryptionKeyRing(exchange), encryptedStream, findKeyPassword(exchange));
         if (key == null) {
             throw new IllegalArgumentException("Private key is null, cannot proceed");
         }
@@ -279,7 +294,7 @@ public class PGPDataFormat implements DataFormat {
     protected PGPOnePassSignature getSignature(Exchange exchange, PGPOnePassSignatureList signatureList)
         throws IOException, PGPException, NoSuchProviderException {
 
-        PGPPublicKey sigPublicKey = PGPDataFormatUtil.findPublicKey(exchange.getContext(), findSignatureKeyFileName(exchange), findSignatureKeyUserid(exchange), false);
+        PGPPublicKey sigPublicKey = PGPDataFormatUtil.findPublicKey(exchange.getContext(), findSignatureKeyFileName(exchange), findSignatureKeyRing(exchange), findSignatureKeyUserid(exchange), false);
         if (sigPublicKey == null) {
             throw new IllegalArgumentException("Signature public key is null, cannot proceed");
         }
@@ -376,4 +391,21 @@ public class PGPDataFormat implements DataFormat {
     public String getSignaturePassword() {
         return signaturePassword;
     }
+
+    public byte[] getEncryptionKeyRing() {
+        return encryptionKeyRing;
+    }
+
+    public void setEncryptionKeyRing(byte[] encryptionKeyRing) {
+        this.encryptionKeyRing = encryptionKeyRing;
+    }
+
+    public byte[] getSignatureKeyRing() {
+        return signatureKeyRing;
+    }
+
+    public void setSignatureKeyRing(byte[] signatureKeyRing) {
+        this.signatureKeyRing = signatureKeyRing;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/e4a81eac/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java
index f01724d..0916075 100644
--- a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java
+++ b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPDataFormatUtil.java
@@ -16,6 +16,9 @@
  */
 package org.apache.camel.converter.crypto;
 
+
+
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.NoSuchProviderException;
@@ -51,8 +54,13 @@ public final class PGPDataFormatUtil {
 
     public static PGPPublicKey findPublicKey(CamelContext context, String filename, String userid, boolean forEncryption) throws IOException, PGPException,
             NoSuchProviderException {
+        return findPublicKey(context, filename, null, userid, forEncryption);
+    }
 
-        InputStream is = ResourceHelper.resolveMandatoryResourceAsInputStream(context.getClassResolver(), filename);
+    public static PGPPublicKey findPublicKey(CamelContext context, String filename, byte[] keyRing, String userid, boolean forEncryption)
+        throws IOException, PGPException, NoSuchProviderException {
+
+        InputStream is = determineKeyRingInputStream(context, filename, keyRing, forEncryption);
         PGPPublicKey pubKey;
         try {
             pubKey = findPublicKey(is, userid, forEncryption);
@@ -62,6 +70,27 @@ public final class PGPDataFormatUtil {
         return pubKey;
     }
 
+    private static InputStream determineKeyRingInputStream(CamelContext context, String filename, byte[] keyRing, boolean forEncryption)
+        throws IOException {
+        if (filename != null && keyRing != null) {
+            String encryptionOrSignature;
+            if (forEncryption) {
+                encryptionOrSignature = "encryption";
+            } else {
+                encryptionOrSignature = "signature";
+            }
+            throw new IllegalStateException(String.format("Either specify %s file name or key ring byte array. You can not specify both.",
+                    encryptionOrSignature));
+        }
+        InputStream is;
+        if (keyRing != null) {
+            is = new ByteArrayInputStream(keyRing);
+        } else {
+            is = ResourceHelper.resolveMandatoryResourceAsInputStream(context.getClassResolver(), filename);
+        }
+        return is;
+    }
+
     @SuppressWarnings("unchecked")
     private static PGPPublicKey findPublicKey(InputStream input, String userid, boolean forEncryption) throws IOException, PGPException,
             NoSuchProviderException {
@@ -98,9 +127,13 @@ public final class PGPDataFormatUtil {
 
     public static PGPPrivateKey findPrivateKey(CamelContext context, String keychainFilename, InputStream encryptedInput, String passphrase)
         throws IOException, PGPException, NoSuchProviderException {
+        return findPrivateKey(context, keychainFilename, null, encryptedInput, passphrase);
+    }
 
-        InputStream keyChainInputStream = ResourceHelper.resolveMandatoryResourceAsInputStream(context.getClassResolver(), keychainFilename);
+    public static PGPPrivateKey findPrivateKey(CamelContext context, String keychainFilename, byte[] secKeyRing,
+        InputStream encryptedInput, String passphrase) throws IOException, PGPException, NoSuchProviderException {
 
+        InputStream keyChainInputStream = determineKeyRingInputStream(context, keychainFilename, secKeyRing, true);
         PGPPrivateKey privKey = null;
         try {
             privKey = findPrivateKey(keyChainInputStream, encryptedInput, passphrase);
@@ -135,9 +168,13 @@ public final class PGPDataFormatUtil {
 
     public static PGPSecretKey findSecretKey(CamelContext context, String keychainFilename, String passphrase)
         throws IOException, PGPException, NoSuchProviderException {
+        return findSecretKey(context, keychainFilename, null, passphrase);
+    }
 
-        InputStream keyChainInputStream = ResourceHelper.resolveMandatoryResourceAsInputStream(context.getClassResolver(), keychainFilename);
+    public static PGPSecretKey findSecretKey(CamelContext context, String keychainFilename, byte[] secKeyRing, String passphrase)
+        throws IOException, PGPException, NoSuchProviderException {
 
+        InputStream keyChainInputStream = determineKeyRingInputStream(context, keychainFilename, secKeyRing, false);
         PGPSecretKey secKey = null;
         try {
             secKey = findSecretKey(keyChainInputStream, passphrase);

http://git-wip-us.apache.org/repos/asf/camel/blob/e4a81eac/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java b/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java
index b923c2d..8597d12 100644
--- a/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java
+++ b/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatTest.java
@@ -16,17 +16,26 @@
  */
 package org.apache.camel.converter.crypto;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.util.IOHelper;
 import org.junit.Test;
 
 public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
     
+    private static final String SEC_KEY_RING_FILE_NAME = "org/apache/camel/component/crypto/secring.gpg";
+    private static final String PUB_KEY_RING_FILE_NAME = "org/apache/camel/component/crypto/pubring.gpg";
+
+    
     protected String getKeyFileName() {
-        return "org/apache/camel/component/crypto/pubring.gpg";
+        return PUB_KEY_RING_FILE_NAME;
     }
     
     protected String getKeyFileNameSec() {
-        return "org/apache/camel/component/crypto/secring.gpg";
+        return SEC_KEY_RING_FILE_NAME;
     }
     
     protected String getKeyUserId() {
@@ -56,6 +65,16 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
     public void testEncryptionSigned() throws Exception {
         doRoundTripEncryptionTests("direct:inline-sign");
     }
+    
+    @Test
+    public void testEncryptionKeyRingByteArray() throws Exception {
+        doRoundTripEncryptionTests("direct:key-ring-byte-array");
+    }
+
+    @Test
+    public void testEncryptionSignedKeyRingByteArray() throws Exception {
+        doRoundTripEncryptionTests("direct:sign-key-ring-byte-array");
+    }
 
     protected RouteBuilder createRouteBuilder() {
         return new RouteBuilder() {
@@ -121,8 +140,62 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
                         .unmarshal(pgpVerifyAndDecrypt)
                         .to("mock:unencrypted");
                 // END SNIPPET: pgp-format-signature
+                /* ---- key ring as byte array -- */
+                // START SNIPPET: pgp-format-key-ring-byte-array
+                PGPDataFormat pgpEncryptByteArray = new PGPDataFormat();
+                pgpEncryptByteArray.setEncryptionKeyRing(getPublicKeyRing());
+                pgpEncryptByteArray.setKeyUserid(keyUserid);
+
+                PGPDataFormat pgpDecryptByteArray = new PGPDataFormat();
+                pgpDecryptByteArray.setEncryptionKeyRing(getSecKeyRing());
+                pgpDecryptByteArray.setKeyUserid(keyUserid);
+                pgpDecryptByteArray.setPassword(keyPassword);
+
+                from("direct:key-ring-byte-array").marshal(pgpEncryptByteArray).to("mock:encrypted").unmarshal(pgpDecryptByteArray)
+                        .to("mock:unencrypted");
+                // END SNIPPET: pgp-format-key-ring-byte-array
+
+                // START SNIPPET: pgp-format-signature-key-ring-byte-array
+                PGPDataFormat pgpSignAndEncryptByteArray = new PGPDataFormat();
+                pgpSignAndEncryptByteArray.setKeyUserid(keyUserid);
+                pgpSignAndEncryptByteArray.setSignatureKeyRing(getSecKeyRing());
+                pgpSignAndEncryptByteArray.setSignatureKeyUserid(keyUserid);
+                pgpSignAndEncryptByteArray.setSignaturePassword(keyPassword);
+
+                PGPDataFormat pgpVerifyAndDecryptByteArray = new PGPDataFormat();
+                pgpVerifyAndDecryptByteArray.setKeyUserid(keyUserid);
+                pgpVerifyAndDecryptByteArray.setPassword(keyPassword);
+                pgpVerifyAndDecryptByteArray.setEncryptionKeyRing(getSecKeyRing());
+                pgpVerifyAndDecryptByteArray.setSignatureKeyUserid(keyUserid);
+
+                from("direct:sign-key-ring-byte-array")
+                // encryption key ring can also be set as header
+                        .setHeader(PGPDataFormat.ENCRYPTION_KEY_RING).constant(getPublicKeyRing()).marshal(pgpSignAndEncryptByteArray)
+                        // it is recommended to remove the header immediately when it is no longer needed
+                        .removeHeader(PGPDataFormat.ENCRYPTION_KEY_RING).to("mock:encrypted")
+                        // signature key ring can also be set as header
+                        .setHeader(PGPDataFormat.SIGNATURE_KEY_RING).constant(getPublicKeyRing()).unmarshal(pgpVerifyAndDecryptByteArray)
+                        // it is recommended to remove the header immediately when it is no longer needed
+                        .removeHeader(PGPDataFormat.SIGNATURE_KEY_RING).to("mock:unencrypted");
+                // END SNIPPET: pgp-format-signature-key-ring-byte-array
             }
         };
     }
 
+    public static byte[] getPublicKeyRing() throws Exception {
+        return getKeyRing(PUB_KEY_RING_FILE_NAME);
+    }
+
+    public static byte[] getSecKeyRing() throws Exception {
+        return getKeyRing(SEC_KEY_RING_FILE_NAME);
+    }
+
+    private static byte[] getKeyRing(String fileName) throws IOException {
+        InputStream is = PGPDataFormatTest.class.getClassLoader().getResourceAsStream(fileName);
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        IOHelper.copyAndCloseInput(is, output);
+        output.close();
+        return output.toByteArray();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/e4a81eac/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/SpringPGPDataFormatTest.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/SpringPGPDataFormatTest.java b/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/SpringPGPDataFormatTest.java
index a31e919..1c8d6fa 100644
--- a/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/SpringPGPDataFormatTest.java
+++ b/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/SpringPGPDataFormatTest.java
@@ -30,5 +30,10 @@ public class SpringPGPDataFormatTest extends AbstractPGPDataFormatTest {
     public void testEncryption() throws Exception {
         doRoundTripEncryptionTests("direct:inline");
     }
+    
+    @Test
+    public void testEncryptionWithKeyRingByteArray() throws Exception {
+        doRoundTripEncryptionTests("direct:pgp-key-ring-byte-array");
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/e4a81eac/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/SpringPGPDataFormatTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/SpringPGPDataFormatTest.xml b/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/SpringPGPDataFormatTest.xml
index 4811310..e511126 100644
--- a/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/SpringPGPDataFormatTest.xml
+++ b/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/SpringPGPDataFormatTest.xml
@@ -39,7 +39,36 @@
       <to uri="mock:unencrypted"/>
     </route>
     <!-- END SNIPPET: pgp-xml-basic -->
+    
+    <!-- START SNIPPET: pgp-xml-data-format-bean-with-keyring-bytearray -->
+    <route>
+      <from uri="direct:pgp-key-ring-byte-array"/>
+      <marshal ref="encryptBean"/>
+      <to uri="mock:encrypted"/>
+      <unmarshal ref="decryptBean"/>
+      <to uri="mock:unencrypted"/>
+    </route>
   </camelContext>
 
-
+   <bean id="encryptBean" class="org.apache.camel.converter.crypto.PGPDataFormat">
+      <property name="keyUserid" value="sdude@nowhere.net"/>  
+      <property name="encryptionKeyRing" ref="pubKeyRing"/>
+   </bean>
+   
+   <bean id="decryptBean" class="org.apache.camel.converter.crypto.PGPDataFormat">
+      <property name="keyUserid" value="sdude@nowhere.net"/>  
+      <property name="encryptionKeyRing" ref="secKeyRing"/>
+      <property name="password" value="sdude"/>
+   </bean>
+   
+   <!-- bean represents the publik key ring as byte array -->
+   <bean id="pubKeyRing"
+		class="org.apache.camel.converter.crypto.PGPDataFormatTest"
+		factory-method="getPublicKeyRing" />
+		
+	<!-- bean represents the secure key ring as byte array -->	
+   <bean id="secKeyRing"
+		class="org.apache.camel.converter.crypto.PGPDataFormatTest"
+		factory-method="getSecKeyRing" />
+    <!-- END SNIPPET:  pgp-xml-data-format-bean-with-keyring-bytearray -->
 </beans>
\ No newline at end of file