camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ningji...@apache.org
Subject git commit: CAMEL-7244 Fix the issue that verification with subkey restricted by User ID does not work with thanks to Franz
Date Thu, 27 Feb 2014 07:25:25 GMT
Repository: camel
Updated Branches:
  refs/heads/master 4c20035bd -> cf7ae6936


CAMEL-7244 Fix the issue that verification with subkey restricted by User ID does not work
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/cf7ae693
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/cf7ae693
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/cf7ae693

Branch: refs/heads/master
Commit: cf7ae69364a57028c55161dcdff494f7f963c208
Parents: 4c20035
Author: Willem Jiang <willem.jiang@gmail.com>
Authored: Thu Feb 27 15:17:21 2014 +0800
Committer: Willem Jiang <willem.jiang@gmail.com>
Committed: Thu Feb 27 15:17:21 2014 +0800

----------------------------------------------------------------------
 .../crypto/DefaultPGPPublicKeyAccessor.java     |  7 ++-
 .../camel/converter/crypto/PGPDataFormat.java   | 14 +++--
 .../converter/crypto/PGPDataFormatUtil.java     | 61 ++++++++++++++++++++
 .../crypto/PGPKeyAccessDataFormat.java          | 36 ++----------
 .../converter/crypto/PGPPublicKeyAccessor.java  | 11 +++-
 .../converter/crypto/PGPDataFormatTest.java     | 31 ++++++++++
 6 files changed, 119 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/cf7ae693/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/DefaultPGPPublicKeyAccessor.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/DefaultPGPPublicKeyAccessor.java
b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/DefaultPGPPublicKeyAccessor.java
index 55b8b72..a1911fb 100644
--- a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/DefaultPGPPublicKeyAccessor.java
+++ b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/DefaultPGPPublicKeyAccessor.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.converter.crypto;
 
+
+
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.List;
@@ -32,6 +34,7 @@ import org.bouncycastle.openpgp.PGPUtil;
  * 
  */
 public class DefaultPGPPublicKeyAccessor implements PGPPublicKeyAccessor {
+    
 
     private final PGPPublicKeyRingCollection pgpPublicKeyRing;
 
@@ -46,8 +49,8 @@ public class DefaultPGPPublicKeyAccessor implements PGPPublicKeyAccessor
{
     }
 
     @Override
-    public PGPPublicKey getPublicKey(Exchange exchange, long keyId) throws Exception {
-        return pgpPublicKeyRing.getPublicKey(keyId);
+    public PGPPublicKey getPublicKey(Exchange exchange, long keyId, List<String> userIdParts)
throws Exception {       
+        return PGPDataFormatUtil.getPublicKeyWithKeyIdAndUserID(keyId, userIdParts, pgpPublicKeyRing);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/cf7ae693/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 07f855f..a147a10 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
@@ -27,6 +27,7 @@ import org.apache.camel.Exchange;
 import org.bouncycastle.openpgp.PGPException;
 import org.bouncycastle.openpgp.PGPPrivateKey;
 import org.bouncycastle.openpgp.PGPPublicKey;
+import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
 
 /**
  * <code>PGPDataFormat</code> uses the <a
@@ -37,7 +38,7 @@ import org.bouncycastle.openpgp.PGPPublicKey;
  * 
  */
 public class PGPDataFormat extends PGPKeyAccessDataFormat implements PGPPublicKeyAccessor,
PGPSecretKeyAccessor {
-
+    
     public static final String KEY_FILE_NAME = "CamelPGPDataFormatKeyFileName";
     public static final String ENCRYPTION_KEY_RING = "CamelPGPDataFormatEncryptionKeyRing";
     public static final String KEY_PASSWORD = "CamelPGPDataFormatKeyPassword";
@@ -256,10 +257,13 @@ public class PGPDataFormat extends PGPKeyAccessDataFormat implements
PGPPublicKe
                 keyId, findKeyPassword(exchange), getPassphraseAccessor(), getProvider());
     }
 
+
+   
     @Override
-    public PGPPublicKey getPublicKey(Exchange exchange, long keyId) throws Exception {
-        return PGPDataFormatUtil.findPublicKeyWithKeyId(exchange.getContext(), findSignatureKeyFileName(exchange),
-                findSignatureKeyRing(exchange), keyId, false);
+    public PGPPublicKey getPublicKey(Exchange exchange, long keyId, List<String> userIdParts)
throws Exception {
+        PGPPublicKeyRingCollection publicKeyringCollection = PGPDataFormatUtil.getPublicKeyRingCollection(exchange.getContext(),

+                findSignatureKeyFileName(exchange), findSignatureKeyRing(exchange), false);
+        return PGPDataFormatUtil.getPublicKeyWithKeyIdAndUserID(keyId, userIdParts, publicKeyringCollection);
     
     }
 
     @Override
@@ -271,5 +275,5 @@ public class PGPDataFormat extends PGPKeyAccessDataFormat implements PGPPublicKe
     public void setSecretKeyAccessor(PGPSecretKeyAccessor secretKeyAccessor) {
         throw new UnsupportedOperationException("Use PGPKeyAccessDataFormat if you want to
set the secret key access");
     }
-
+    
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/cf7ae693/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 083729c..b8849db 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
@@ -100,6 +100,7 @@ public final class PGPDataFormatUtil {
         }
     }
 
+    @Deprecated
     public static PGPPublicKey findPublicKeyWithKeyId(CamelContext context, String filename,
byte[] keyRing, long keyid,
             boolean forEncryption) throws IOException, PGPException, NoSuchProviderException
{
         InputStream is = determineKeyRingInputStream(context, filename, keyRing, forEncryption);
@@ -111,6 +112,15 @@ public final class PGPDataFormatUtil {
         }
         return pubKey;
     }
+    
+    public static PGPPublicKeyRingCollection getPublicKeyRingCollection(CamelContext context,
String filename, byte[] keyRing, boolean forEncryption) throws IOException, PGPException {
+        InputStream is = determineKeyRingInputStream(context, filename, keyRing, forEncryption);
+        try {
+            return new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(is));
+        } finally {
+            IOHelper.close(is);
+        }
+    }
 
     public static PGPPrivateKey findPrivateKeyWithKeyId(CamelContext context, String filename,
byte[] secretKeyRing, long keyid,
             String passphrase, PGPPassphraseAccessor passpraseAccessor, String provider)
throws IOException, PGPException,
@@ -483,4 +493,55 @@ public final class PGPDataFormatUtil {
         }
         return null; // no key flag
     }
+    
+    
+    /**
+     * Determines a public key from the keyring collection which has a certain key ID and
which has a User ID which contains at least one of the User ID parts.
+     * 
+     * @param keyId key ID
+     * @param userIdParts user ID parts, can be empty, than no filter on the User ID is executed
+     * @param publicKeyringCollection keyring collection
+     * @return public key or <code>null</code> if no fitting key is found
+     * @throws PGPException
+     */
+    @SuppressWarnings("unchecked")
+    public static PGPPublicKey getPublicKeyWithKeyIdAndUserID(long keyId, List<String>
userIdParts, PGPPublicKeyRingCollection publicKeyringCollection)
+        throws PGPException {
+        PGPPublicKeyRing publicKeyring = publicKeyringCollection.getPublicKeyRing(keyId);
+        if (publicKeyring == null) {
+            LOG.debug("No public key found for key ID {}.", Long.toString(keyId));
+            return null;
+        }
+        // publicKey can be a subkey the user IDs must therefore be provided by the primary/master
key
+        if (isAllowedKey(userIdParts, publicKeyring.getPublicKey().getUserIDs())) {
+            return publicKeyring.getPublicKey(keyId);
+        } else {
+            return null;
+        }
+    }
+    
+    private static boolean isAllowedKey(List<String> allowedUserIds, Iterator<String>
verifyingPublicKeyUserIds) {
+
+        if (allowedUserIds == null || allowedUserIds.isEmpty()) {
+            // no restrictions specified
+            return true;
+        }
+        String keyUserId = null;
+        for (; verifyingPublicKeyUserIds.hasNext();) {
+            keyUserId = verifyingPublicKeyUserIds.next();
+            for (String userid : allowedUserIds) {
+                if (keyUserId != null && keyUserId.contains(userid)) {
+                    LOG.debug(
+                            "Public key with  user ID {} fulfills the User ID restriction.",
+                            keyUserId, allowedUserIds);
+                    return true;
+                }
+            }
+        }
+        LOG.warn(
+                "Public key with User ID {} does not fulfill the User ID restriction.",
+                keyUserId, allowedUserIds);
+        return false;
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/cf7ae693/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPKeyAccessDataFormat.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPKeyAccessDataFormat.java
b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPKeyAccessDataFormat.java
index f0e0281..a0762c8 100644
--- a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPKeyAccessDataFormat.java
+++ b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPKeyAccessDataFormat.java
@@ -26,7 +26,6 @@ import java.security.SignatureException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.camel.Exchange;
@@ -409,15 +408,13 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements
DataFormat
         for (int i = 0; i < signatureList.size(); i++) {
             PGPOnePassSignature signature = signatureList.get(i);
             // Determine public key from signature keyId
-            PGPPublicKey sigPublicKey = publicKeyAccessor.getPublicKey(exchange, signature.getKeyID());
+            PGPPublicKey sigPublicKey = publicKeyAccessor.getPublicKey(exchange, signature.getKeyID(),
allowedUserIds);
             if (sigPublicKey == null) {
                 continue;
             }
-            if (isAllowedVerifyingKey(allowedUserIds, sigPublicKey)) {
-                // choose that signature for which a public key exists!
-                signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(getProvider()),
sigPublicKey);
-                return signature;
-            }
+            // choose that signature for which a public key exists!
+            signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(getProvider()),
sigPublicKey);
+            return signature;
         }
         if (signatureList.isEmpty()) {
             return null;
@@ -427,31 +424,6 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements
DataFormat
 
     }
 
-    public boolean isAllowedVerifyingKey(List<String> allowedUserIds, PGPPublicKey
verifyingPublicKey) {
-
-        if (allowedUserIds == null || allowedUserIds.isEmpty()) {
-            // no restrictions specified
-            return true;
-        }
-        String keyUserId = null;
-        for (@SuppressWarnings("unchecked")
-        Iterator<String> iterator = verifyingPublicKey.getUserIDs(); iterator.hasNext();)
{
-            keyUserId = iterator.next();
-            for (String userid : allowedUserIds) {
-                if (keyUserId != null && keyUserId.contains(userid)) {
-                    LOG.debug(
-                            "Public key with  user ID {} fulfills the User ID restriction
{}. Therefore this key will be used for the signature verification. ",
-                            keyUserId, allowedUserIds);
-                    return true;
-                }
-            }
-        }
-        LOG.warn(
-                "Public key with User ID {} does not fulfill the User ID restriction {}.
Therefore this key will not be used for the signature verification.",
-                keyUserId, allowedUserIds);
-        return false;
-    }
-
     /**
      * Sets if the encrypted file should be written in ascii visible text (for
      * marshaling).

http://git-wip-us.apache.org/repos/asf/camel/blob/cf7ae693/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPublicKeyAccessor.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPublicKeyAccessor.java
b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPublicKeyAccessor.java
index 0d55931..a114b3a 100644
--- a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPublicKeyAccessor.java
+++ b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPublicKeyAccessor.java
@@ -37,14 +37,21 @@ public interface PGPPublicKeyAccessor {
 
     /**
      * Returns the public key with a certain key ID. This method is used for
-     * verifying the signature.
+     * verifying the signature. The given User IDs are provided to filter the
+     * public key, further. If the User ID parts list is empty, then any public
+     * key can be returned which has the specified key ID. If the User ID parts
+     * list is not empty then the returned key must have a User ID which
+     * contains at least one User ID part.
      * 
      * @param exchange
      *            exchange
      * @param keyId
      *            key ID
+     * @param useridParts
+     *            parts of User IDs, must not be <code>null</code>, but can be
+     *            empty
      * @return public key or <code>null</code> if the key cannot be found
      */
-    PGPPublicKey getPublicKey(Exchange exchange, long keyId) throws Exception;
+    PGPPublicKey getPublicKey(Exchange exchange, long keyId, List<String> useridParts)
throws Exception;
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/cf7ae693/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 7cd9f74..f99746b 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
@@ -195,6 +195,26 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
         assertEquals(1, inMess.getHeader(PGPDataFormat.NUMBER_OF_ENCRYPTION_KEYS));
         assertEquals(1, inMess.getHeader(PGPDataFormat.NUMBER_OF_SIGNING_KEYS));
     }
+    
+    /**
+     * You get three keys with the UserId "keyflag", a primary key and its two
+     * sub-keys. The sub-key with KeyFlag {@link KeyFlags#SIGN_DATA} should be
+     * used for signing and the sub-key with KeyFlag
+     * {@link KeyFlags#ENCRYPT_COMMS} or {@link KeyFlags#ENCRYPT_COMMS} or
+     * {@link KeyFlags#ENCRYPT_STORAGE} should be used for decryption.
+     * <p>
+     * Tests also the decryption and verifying part with the subkeys.
+     * @throws Exception
+     */
+    @Test
+    public void testDecryptVerifyWithSubkey() throws Exception {       
+        // do not use doRoundTripEncryptionTests("direct:subkey"); because otherwise you
get an error in the dynamic test
+        String payload = "Test Message";
+        MockEndpoint mockSubkey = getMockEndpoint("mock:unencrypted");
+        mockSubkey.expectedBodiesReceived(payload);
+        template.sendBody("direct:subkey", payload);
+        assertMockEndpointsSatisfied();
+    }
 
     protected RouteBuilder[] createRouteBuilders() {
         return new RouteBuilder[] {new RouteBuilder() {
@@ -394,6 +414,17 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
                 pgpKeyFlag.setSignatureKeyUserid("keyflag");
 
                 from("direct:keyflag").marshal(pgpKeyFlag).to("mock:encrypted_keyflag");
+                
+                PGPDataFormat pgpDecryptVerifySubkey = new PGPDataFormat();
+                // the following keyring contains a primary key with KeyFlag "Certify" and
a subkey for signing and a subkey for encryption
+                pgpDecryptVerifySubkey.setKeyFileName("org/apache/camel/component/crypto/secringSubKeys.gpg");
+                pgpDecryptVerifySubkey.setSignatureKeyFileName("org/apache/camel/component/crypto/pubringSubKeys.gpg");
+                pgpDecryptVerifySubkey.setPassword("Abcd1234");
+                pgpDecryptVerifySubkey.setSignatureKeyUserid("keyflag");
+                
+                // test that the correct subkey is selected during decrypt and verify
+                from("direct:subkey").marshal(pgpKeyFlag).to("mock:encrypted").unmarshal(pgpDecryptVerifySubkey)
+                .to("mock:unencrypted");
             }
         }, new RouteBuilder() {
             public void configure() throws Exception {


Mime
View raw message