You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ha...@apache.org on 2014/02/07 21:10:16 UTC
git commit: CAMEL-7002. Support for serveral signatures.
Updated Branches:
refs/heads/master f832af138 -> a346c1c1c
CAMEL-7002. Support for serveral signatures.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/a346c1c1
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/a346c1c1
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/a346c1c1
Branch: refs/heads/master
Commit: a346c1c1c66d0f2132b8ff9b244c8050cdcd1292
Parents: f832af1
Author: Hadrian Zbarcea <hz...@gmail.com>
Authored: Fri Feb 7 15:09:09 2014 -0500
Committer: Hadrian Zbarcea <hz...@gmail.com>
Committed: Fri Feb 7 15:09:29 2014 -0500
----------------------------------------------------------------------
.../camel/converter/crypto/PGPDataFormat.java | 243 +++++++++++++++----
.../converter/crypto/PGPDataFormatUtil.java | 131 ++++++----
.../crypto/PGPDataFormatDynamicTest.java | 10 +
.../converter/crypto/PGPDataFormatTest.java | 149 +++++++++++-
4 files changed, 438 insertions(+), 95 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/a346c1c1/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 985e80d..0157088 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
@@ -29,9 +29,13 @@ import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import org.apache.camel.Exchange;
+import org.apache.camel.converter.crypto.PGPDataFormatUtil.PGPSecretKeyAndPrivateKeyAndUserId;
import org.apache.camel.converter.stream.CachedOutputStream;
import org.apache.camel.spi.DataFormat;
import org.apache.camel.support.ServiceSupport;
@@ -56,7 +60,6 @@ import org.bouncycastle.openpgp.PGPOnePassSignatureList;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
-import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPSignatureList;
@@ -64,7 +67,6 @@ import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
-import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
@@ -86,6 +88,7 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
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_USERIDS = "CamelPGPDataFormatSignatureKeyUserids";
public static final String SIGNATURE_KEY_PASSWORD = "CamelPGPDataFormatSignatureKeyPassword";
public static final String ENCRYPTION_ALGORITHM = "CamelPGPDataFormatEncryptionAlgorithm";
public static final String SIGNATURE_HASH_ALGORITHM = "CamelPGPDataFormatSignatureHashAlgorithm";
@@ -109,8 +112,10 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
private byte[] encryptionKeyRing;
// signature / verification key info (optional)
- private String signatureKeyUserid; // for encryption
- private String signaturePassword; // for encryption
+ private String signatureKeyUserid; // for signing and verification (optional for verification)
+ //For verification you can specify further User IDs in addition
+ private List<String> signatureKeyUserids; //only for signing with several keys and verifying;
+ private String signaturePassword; //only for signing, optional if you have several signature keys, then you should use passphaseAccessor
private String signatureKeyFileName;
// alternatively to the signature key file name you can specify the signature key ring as byte array
private byte[] signatureKeyRing;
@@ -124,7 +129,7 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
private int compressionAlgorithm = CompressionAlgorithmTags.ZIP; // for encryption
- private PGPPassphraseAccessor passphraseAccessor;
+ private PGPPassphraseAccessor passphraseAccessor; // for signing and decryption with multiple keys
public PGPDataFormat() {
}
@@ -168,6 +173,11 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
return exchange.getIn().getHeader(SIGNATURE_KEY_USERID, getSignatureKeyUserid(), String.class);
}
+ @SuppressWarnings("unchecked")
+ protected List<String> findSignatureKeyUserids(Exchange exchange) {
+ return exchange.getIn().getHeader(SIGNATURE_KEY_USERIDS, getSignatureKeyUserids(), List.class);
+ }
+
protected String findSignatureKeyPassword(Exchange exchange) {
String sigPassword = exchange.getIn().getHeader(SIGNATURE_KEY_PASSWORD, getSignaturePassword(), String.class);
if (sigPassword != null) {
@@ -218,7 +228,7 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(findCompressionAlgorithm(exchange));
OutputStream comOut = new BufferedOutputStream(comData.open(encOut));
- PGPSignatureGenerator sigGen = createSignatureGenerator(exchange, comOut);
+ List<PGPSignatureGenerator> sigGens = createSignatureGenerator(exchange, comOut);
PGPLiteralDataGenerator litData = new PGPLiteralDataGenerator();
String fileName = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class);
@@ -234,21 +244,29 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
litOut.write(buffer, 0, bytesRead);
- if (sigGen != null) {
- sigGen.update(buffer, 0, bytesRead);
+ if (sigGens != null && !sigGens.isEmpty()) {
+ for (PGPSignatureGenerator sigGen : sigGens) {
+ // not nested therefore it is the same for all
+ // can this be improved that we only do it for one sigGen and set the result on the others?
+ sigGen.update(buffer, 0, bytesRead);
+ }
}
litOut.flush();
}
} finally {
IOHelper.close(litOut);
- if (sigGen != null) {
- sigGen.generate().encode(comOut);
+ if (sigGens != null && !sigGens.isEmpty()) {
+ // reverse order
+ for (int i = sigGens.size() - 1; i > -1; i--) {
+ PGPSignatureGenerator sigGen = sigGens.get(i);
+ sigGen.generate().encode(comOut);
+ }
}
IOHelper.close(comOut, encOut, outputStream, input);
}
}
- public List<String> determineEncryptionUserIds(Exchange exchange) {
+ protected List<String> determineEncryptionUserIds(Exchange exchange) {
String userid = findKeyUserid(exchange);
List<String> userids = findKeyUserids(exchange);
// merge them together
@@ -270,44 +288,94 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
return result;
}
- protected PGPSignatureGenerator createSignatureGenerator(Exchange exchange, OutputStream out) throws IOException, PGPException,
+ protected List<String> determineSignaturenUserIds(Exchange exchange) {
+ String userid = findSignatureKeyUserid(exchange);
+ List<String> userids = findSignatureKeyUserids(exchange);
+ // merge them together
+ List<String> result;
+ if (userid != null) {
+ if (userids == null || userids.isEmpty()) {
+ result = Collections.singletonList(userid);
+ } else {
+ result = new ArrayList<String>(userids.size() + 1);
+ result.add(userid);
+ result.addAll(userids);
+ }
+ } else {
+ // userids can be empty or null!
+ result = userids;
+ }
+ return result;
+ }
+
+ protected List<PGPSignatureGenerator> createSignatureGenerator(Exchange exchange, OutputStream out) throws IOException, PGPException,
NoSuchProviderException, NoSuchAlgorithmException {
String sigKeyFileName = findSignatureKeyFileName(exchange);
- String sigKeyUserid = findSignatureKeyUserid(exchange);
+ List<String> sigKeyUserids = determineSignaturenUserIds(exchange);
String sigKeyPassword = findSignatureKeyPassword(exchange);
byte[] sigKeyRing = findSignatureKeyRing(exchange);
- if ((sigKeyFileName == null && sigKeyRing == null) || sigKeyUserid == null || sigKeyPassword == null) {
+ if ((sigKeyFileName == null && sigKeyRing == null) || sigKeyUserids == null || sigKeyUserids.isEmpty()
+ || (sigKeyPassword == null && passphraseAccessor == null)) {
return null;
}
- PGPSecretKey sigSecretKey = PGPDataFormatUtil.findSecretKey(exchange.getContext(), sigKeyFileName, sigKeyRing, sigKeyPassword,
- sigKeyUserid, getProvider());
- if (sigSecretKey == null) {
+ List<PGPSecretKeyAndPrivateKeyAndUserId> sigSecretKeysWithPrivateKeyAndUserId = determineSecretKeysWithPrivateKeyAndUserId(
+ exchange, sigKeyFileName, sigKeyUserids, sigKeyPassword, sigKeyRing);
+
+ List<PGPSignatureGenerator> sigGens = new ArrayList<PGPSignatureGenerator>();
+ for (PGPSecretKeyAndPrivateKeyAndUserId sigSecretKeyWithPrivateKeyAndUserId : sigSecretKeysWithPrivateKeyAndUserId) {
+ PGPPrivateKey sigPrivateKey = sigSecretKeyWithPrivateKeyAndUserId.getPrivateKey();
+
+ PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
+ spGen.setSignerUserID(false, sigSecretKeyWithPrivateKeyAndUserId.getUserId());
+
+ int algorithm = sigSecretKeyWithPrivateKeyAndUserId.getSecretKey().getPublicKey().getAlgorithm();
+ PGPSignatureGenerator sigGen = new PGPSignatureGenerator(
+ new JcaPGPContentSignerBuilder(algorithm, findHashAlgorithm(exchange)).setProvider(getProvider()));
+ sigGen.init(PGPSignature.BINARY_DOCUMENT, sigPrivateKey);
+ sigGen.setHashedSubpackets(spGen.generate());
+ sigGen.generateOnePassVersion(false).encode(out);
+ sigGens.add(sigGen);
+ }
+ return sigGens;
+ }
+
+ public List<PGPSecretKeyAndPrivateKeyAndUserId> determineSecretKeysWithPrivateKeyAndUserId(Exchange exchange, String sigKeyFileName,
+ List<String> sigKeyUserids, String sigKeyPassword, byte[] sigKeyRing) throws IOException, PGPException, NoSuchProviderException {
+
+ Map<String, String> sigKeyUserId2Password = determineSignatureKeyUserId2Password(sigKeyUserids, sigKeyPassword);
+
+ List<PGPSecretKeyAndPrivateKeyAndUserId> sigSecretKeysWithPrivateKeyAndUserId = PGPDataFormatUtil
+ .findSecretKeysWithPrivateKeyAndUserId(exchange.getContext(), sigKeyFileName, sigKeyRing, sigKeyUserId2Password,
+ getProvider());
+
+ if (sigSecretKeysWithPrivateKeyAndUserId.isEmpty()) {
throw new IllegalArgumentException(
String.format(
- "Cannot PGP encrypt message. No secret key found for User ID %s. Either add a key with this User ID to the secret keyring or change the configured User ID.",
- sigKeyUserid));
+ "Cannot PGP sign message. No secret key found for User IDs %s. Either add keys with this User IDs to the secret keyring or change the configured User IDs.",
+ sigKeyUserids));
}
+ return sigSecretKeysWithPrivateKeyAndUserId;
+ }
- PGPPrivateKey sigPrivateKey = sigSecretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(getProvider())
- .build(sigKeyPassword.toCharArray()));
- if (sigPrivateKey == null) {
- // this exception will never happen
- throw new IllegalArgumentException("Signature private key is null, cannot proceed");
+ public Map<String, String> determineSignatureKeyUserId2Password(List<String> sigKeyUserids, String sigKeyPassword) {
+ // we want to keep the order of the entries, therefore we use LinkedHashMap
+ Map<String, String> sigKeyUserId2Password = new LinkedHashMap<String, String>(sigKeyUserids.size());
+ for (String sigKeyUserid : sigKeyUserids) {
+ if (sigKeyPassword == null) {
+ sigKeyPassword = passphraseAccessor.getPassphrase(sigKeyUserid);
+ }
+ if (sigKeyPassword == null) {
+ throw new IllegalArgumentException(
+ String.format(
+ "No passphrase specified for signature key user ID %s. Either specify a passphrase or remove this user ID from the configuration.",
+ sigKeyUserid));
+ }
+ sigKeyUserId2Password.put(sigKeyUserid, sigKeyPassword);
}
-
- PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
- spGen.setSignerUserID(false, sigKeyUserid);
-
- int algorithm = sigSecretKey.getPublicKey().getAlgorithm();
- PGPSignatureGenerator sigGen = new PGPSignatureGenerator(
- new JcaPGPContentSignerBuilder(algorithm, findHashAlgorithm(exchange)).setProvider(getProvider()));
- sigGen.init(PGPSignature.BINARY_DOCUMENT, sigPrivateKey);
- sigGen.setHashedSubpackets(spGen.generate());
- sigGen.generateOnePassVersion(false).encode(out);
- return sigGen;
+ return sigKeyUserId2Password;
}
@SuppressWarnings("resource")
@@ -333,6 +401,10 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
pbe = (PGPPublicKeyEncryptedData) enc.get(i);
key = PGPDataFormatUtil.findPrivateKeyWithKeyId(exchange.getContext(), findKeyFileName(exchange),
findEncryptionKeyRing(exchange), pbe.getKeyID(), findKeyPassword(exchange), getPassphraseAccessor(), getProvider());
+ if (key != null) {
+ // take the first key
+ break;
+ }
}
if (key == null) {
throw new PGPException("Provided input is encrypted with unknown pair of keys.");
@@ -368,7 +440,7 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
bos = new ByteArrayOutputStream();
os = bos;
}
-
+
try {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
@@ -389,7 +461,7 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
throw new SignatureException("Cannot verify PGP signature");
}
}
-
+
if (cos != null) {
return cos.newStreamCache();
} else {
@@ -410,6 +482,7 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
protected PGPOnePassSignature getSignature(Exchange exchange, PGPOnePassSignatureList signatureList) throws IOException, PGPException,
NoSuchProviderException {
+ List<String> allowedUserIds = determineSignaturenUserIds(exchange);
for (int i = 0; i < signatureList.size(); i++) {
PGPOnePassSignature signature = signatureList.get(i);
// Determine public key from signature keyId
@@ -418,9 +491,11 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
if (sigPublicKey == null) {
continue;
}
- // choose that signature for which a public key exists!
- signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(getProvider()), sigPublicKey);
- return signature;
+ if (isAllowedVerifyingKey(allowedUserIds, sigPublicKey)) {
+ // choose that signature for which a public key exists!
+ signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(getProvider()), sigPublicKey);
+ return signature;
+ }
}
if (signatureList.isEmpty()) {
return null;
@@ -430,6 +505,31 @@ public class PGPDataFormat 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).
@@ -455,11 +555,8 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
}
/**
- * Userid of the key used to encrypt. If you want to encrypt with several
- * keys then use the method {@link #setKeyUserids(List<String>)}. The User
- * ID of this method and the User IDs of the method {@link
- * #setKeyUserids(List<String>)} will be merged together and the
- * corresponding public keys will be used for the encryption.
+ * User ID, or more precisely user ID part, of the key used for encryption.
+ * See also {@link #setKeyUserids(List<String>)}.
*/
public void setKeyUserid(String keyUserid) {
this.keyUserid = keyUserid;
@@ -474,11 +571,15 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
}
/**
- * KeyUserIds used to determine the public keys for encryption. If you just
- * have one User ID, then you can also use the method
- * {@link #setKeyUserid(String)} or this method. The User ID specified in
- * {@link #setKeyUserid(String)} and in this method will be merged together
- * and the corresponding public keys will be used for the encryption.
+ * Keys User IDs, or more precisely user ID parts, used for determining the
+ * public keys for encryption. If you just have one User ID, then you can
+ * also use the method {@link #setKeyUserid(String)}. The User ID specified
+ * in {@link #setKeyUserid(String)} and in this method will be merged
+ * together and the public keys which have a User ID which contain a value
+ * of the specified User IDs the will be used for the encryption. Be aware
+ * that you may get several public keys even if you specify only one User
+ * Id, because there can be several public keys which have a User ID which
+ * contains the specified User ID.
*/
public void setKeyUserids(List<String> keyUserids) {
this.keyUserids = keyUserids;
@@ -511,7 +612,9 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
}
/**
- * Userid of the signature key used to sign (marshal).
+ * Userid, or more precisely user ID part, of the signature key used for
+ * signing (marshal) and verifying (unmarshal). See also
+ * {@link #setSignatureKeyUserids(List)}.
*/
public void setSignatureKeyUserid(String signatureKeyUserid) {
this.signatureKeyUserid = signatureKeyUserid;
@@ -521,6 +624,44 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
return signatureKeyUserid;
}
+ public List<String> getSignatureKeyUserids() {
+ return signatureKeyUserids;
+ }
+
+ /**
+ * User IDs, or more precisely user ID parts, used for signing and
+ * verification.
+ * <p>
+ * In the signing case, the User IDs specify the private keys which are used
+ * for signing. If the result are several private keys then several
+ * signatures will be created. If you just have one signature User ID, then
+ * you can also use the method {@link #setSignatureKeyUserid(String)} or
+ * this method. The User ID specified in
+ * {@link #setSignatureKeyUserid(String)} and in this method will be merged
+ * together and the private keys which have a User Id which contain one
+ * value out of the specified UserIds will be used for the signature
+ * creation. Be aware that you may get several private keys even if you
+ * specify only one User Id, because there can be several private keys which
+ * have a User ID which contains the specified User ID.
+ * <p>
+ * In the verification case the User IDs restrict the set of public keys
+ * which can be used for verification. The public keys used for verification
+ * must contain a User ID which contain one value of the User ID list. If
+ * you neither specify in this method and nor specify in the method
+ * {@link #setSignatureKeyUserid(String)} any value then any public key in
+ * the public key ring will be taken into consideration for the
+ * verification.
+ * <p>
+ * If you just have one User ID, then you can also use the method
+ * {@link #setSignatureKeyUserid(String)}. The User ID specified in
+ * {@link #setSignatureKeyUserid(String)} and in this method will be merged
+ * together and the corresponding public keys represent the potential keys
+ * for the verification of the message.
+ */
+ public void setSignatureKeyUserids(List<String> signatureKeyUserids) {
+ this.signatureKeyUserids = signatureKeyUserids;
+ }
+
/**
* Filename of the signature keyring that will be used, classpathResource.
*/
http://git-wip-us.apache.org/repos/asf/camel/blob/a346c1c1/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 0753957..3408a4a 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
@@ -25,6 +25,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.camel.CamelContext;
@@ -43,6 +44,8 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import static org.bouncycastle.bcpg.PublicKeyAlgorithmTags.DSA;
import static org.bouncycastle.bcpg.PublicKeyAlgorithmTags.ECDSA;
@@ -51,6 +54,8 @@ import static org.bouncycastle.bcpg.PublicKeyAlgorithmTags.RSA_GENERAL;
import static org.bouncycastle.bcpg.PublicKeyAlgorithmTags.RSA_SIGN;
public final class PGPDataFormatUtil {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PGPDataFormatUtil.class);
private PGPDataFormatUtil() {
}
@@ -81,7 +86,7 @@ public final class PGPDataFormatUtil {
}
public static List<PGPPublicKey> findPublicKeys(CamelContext context, String filename, byte[] keyRing, List<String> userids,
- boolean forEncryption) throws IOException, PGPException, NoSuchProviderException {
+ boolean forEncryption) throws IOException, PGPException, NoSuchProviderException {
InputStream is = determineKeyRingInputStream(context, filename, keyRing, forEncryption);
try {
return findPublicKeys(is, userids, forEncryption);
@@ -91,7 +96,7 @@ public final class PGPDataFormatUtil {
}
public static PGPPublicKey findPublicKeyWithKeyId(CamelContext context, String filename, byte[] keyRing, long keyid,
- boolean forEncryption) throws IOException, PGPException, NoSuchProviderException {
+ boolean forEncryption) throws IOException, PGPException, NoSuchProviderException {
InputStream is = determineKeyRingInputStream(context, filename, keyRing, forEncryption);
PGPPublicKey pubKey;
try {
@@ -103,8 +108,8 @@ public final class PGPDataFormatUtil {
}
public static PGPPrivateKey findPrivateKeyWithKeyId(CamelContext context, String filename, byte[] secretKeyRing, long keyid,
- String passphrase, PGPPassphraseAccessor passpraseAccessor, String provider) throws IOException, PGPException,
- NoSuchProviderException {
+ String passphrase, PGPPassphraseAccessor passpraseAccessor, String provider) throws IOException, PGPException,
+ NoSuchProviderException {
InputStream is = determineKeyRingInputStream(context, filename, secretKeyRing, true);
try {
return findPrivateKeyWithKeyId(is, keyid, passphrase, passpraseAccessor, provider);
@@ -115,7 +120,7 @@ public final class PGPDataFormatUtil {
@SuppressWarnings("unchecked")
private static PGPPrivateKey findPrivateKeyWithKeyId(InputStream keyringInput, long keyid, String passphrase,
- PGPPassphraseAccessor passphraseAccessor, String provider) throws IOException, PGPException {
+ PGPPassphraseAccessor passphraseAccessor, String provider) throws IOException, PGPException {
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyringInput));
for (Iterator<?> i = pgpSec.getKeyRings(); i.hasNext();) {
Object data = i.next();
@@ -168,25 +173,24 @@ public final class PGPDataFormatUtil {
@SuppressWarnings("unchecked")
private static PGPPublicKey findPublicKeyWithKeyId(InputStream input, long keyid) throws IOException, PGPException,
- NoSuchProviderException {
+ NoSuchProviderException {
PGPPublicKeyRingCollection pgpSec = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input));
for (Iterator<PGPPublicKeyRing> keyRingIter = pgpSec.getKeyRings(); keyRingIter.hasNext();) {
- PGPPublicKeyRing keyRing = keyRingIter.next();
- for (Iterator<PGPPublicKey> keyIter = keyRing.getPublicKeys(); keyIter.hasNext();) {
- PGPPublicKey key = keyIter.next();
- if (keyid == key.getKeyID()) {
- return key;
- }
+ PGPPublicKeyRing keyRing = keyRingIter.next();
+ PGPPublicKey key = keyRing.getPublicKey(keyid);
+ if (key != null) {
+ return key;
}
- }
+ }
+
return null;
}
@SuppressWarnings("unchecked")
private static List<PGPPublicKey> findPublicKeys(InputStream input, List<String> userids, boolean forEncryption) throws IOException,
- PGPException, NoSuchProviderException {
+ PGPException, NoSuchProviderException {
List<PGPPublicKey> result = new ArrayList<PGPPublicKey>(3);
PGPPublicKeyRingCollection pgpSec = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input));
@@ -196,13 +200,17 @@ public final class PGPDataFormatUtil {
Set<String> keyUserIds = getUserIds(keyRing);
for (Iterator<PGPPublicKey> keyIter = keyRing.getPublicKeys(); keyIter.hasNext();) {
PGPPublicKey key = keyIter.next();
- for (String userid : userids) {
+ for (String useridPart : userids) {
for (String keyUserId : keyUserIds) {
- if (keyUserId != null && keyUserId.contains(userid)) {
+ if (keyUserId != null && keyUserId.contains(useridPart)) {
if (forEncryption && key.isEncryptionKey()) {
result.add(key);
+ LOG.debug("Public key with key user ID {} and key ID {} found for specified user ID part {}", new Object[] {
+ keyUserId, Long.toString(key.getKeyID()), useridPart });
} else if (!forEncryption && isSignatureKey(key)) {
result.add(key);
+ LOG.debug("Public key with key user ID {} and key ID {} found for specified user ID part {}", new Object[] {
+ keyUserId, Long.toString(key.getKeyID()), useridPart });
}
}
}
@@ -243,14 +251,14 @@ public final class PGPDataFormatUtil {
@Deprecated
public static PGPPrivateKey findPrivateKey(CamelContext context, String keychainFilename, byte[] secKeyRing,
- InputStream encryptedInput, String passphrase, String provider) throws IOException, PGPException, NoSuchProviderException {
+ InputStream encryptedInput, String passphrase, String provider) throws IOException, PGPException, NoSuchProviderException {
return findPrivateKey(context, keychainFilename, secKeyRing, encryptedInput, passphrase, null, provider);
}
@Deprecated
public static PGPPrivateKey findPrivateKey(CamelContext context, String keychainFilename, byte[] secKeyRing,
- InputStream encryptedInput, String passphrase, PGPPassphraseAccessor passphraseAccessor, String provider) throws IOException,
- PGPException, NoSuchProviderException {
+ InputStream encryptedInput, String passphrase, PGPPassphraseAccessor passphraseAccessor, String provider) throws IOException,
+ PGPException, NoSuchProviderException {
InputStream keyChainInputStream = determineKeyRingInputStream(context, keychainFilename, secKeyRing, true);
PGPPrivateKey privKey = null;
@@ -264,7 +272,7 @@ public final class PGPDataFormatUtil {
@Deprecated
private static PGPPrivateKey findPrivateKey(InputStream keyringInput, InputStream encryptedInput, String passphrase,
- PGPPassphraseAccessor passphraseAccessor, String provider) throws IOException, PGPException, NoSuchProviderException {
+ PGPPassphraseAccessor passphraseAccessor, String provider) throws IOException, PGPException, NoSuchProviderException {
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyringInput));
PGPObjectFactory factory = new PGPObjectFactory(PGPUtil.getDecoderStream(encryptedInput));
PGPEncryptedDataList enc;
@@ -305,60 +313,101 @@ public final class PGPDataFormatUtil {
@Deprecated
public static PGPSecretKey findSecretKey(CamelContext context, String keychainFilename, String passphrase) throws IOException,
- PGPException, NoSuchProviderException {
+ PGPException, NoSuchProviderException {
return findSecretKey(context, keychainFilename, null, passphrase, "BC");
}
+ @Deprecated
public static PGPSecretKey findSecretKey(CamelContext context, String keychainFilename, byte[] secKeyRing, String passphrase,
- String userId, String provider) throws IOException, PGPException, NoSuchProviderException {
+ String userId, String provider) throws IOException, PGPException, NoSuchProviderException {
InputStream keyChainInputStream = determineKeyRingInputStream(context, keychainFilename, secKeyRing, false);
- PGPSecretKey secKey = null;
try {
- secKey = findSecretKey(keyChainInputStream, passphrase, userId, provider);
+ List<PGPSecretKeyAndPrivateKeyAndUserId> secKeys = findSecretKeysWithPrivateKeyAndUserId(keyChainInputStream,
+ Collections.singletonMap(userId, passphrase), provider);
+ if (!secKeys.isEmpty()) {
+ return secKeys.get(0).getSecretKey();
+ }
+ return null;
+ } finally {
+ IOHelper.close(keyChainInputStream);
+ }
+ }
+
+ public static List<PGPSecretKeyAndPrivateKeyAndUserId> findSecretKeysWithPrivateKeyAndUserId(CamelContext context,
+ String keychainFilename, byte[] secKeyRing, Map<String, String> sigKeyUserId2Password, String provider) throws IOException,
+ PGPException, NoSuchProviderException {
+ InputStream keyChainInputStream = determineKeyRingInputStream(context, keychainFilename, secKeyRing, false);
+ try {
+ return findSecretKeysWithPrivateKeyAndUserId(keyChainInputStream, sigKeyUserId2Password, provider);
} finally {
IOHelper.close(keyChainInputStream);
}
- return secKey;
}
@Deprecated
public static PGPSecretKey findSecretKey(CamelContext context, String keychainFilename, byte[] secKeyRing, String passphrase,
- String provider) throws IOException, PGPException, NoSuchProviderException {
+ String provider) throws IOException, PGPException, NoSuchProviderException {
return findSecretKey(context, keychainFilename, secKeyRing, passphrase, null, provider);
}
@SuppressWarnings("unchecked")
- private static PGPSecretKey findSecretKey(InputStream keyringInput, String passphrase, String userId, String provider)
- throws IOException, PGPException, NoSuchProviderException {
- PGPSecretKey pgpSecKey = null;
+ private static List<PGPSecretKeyAndPrivateKeyAndUserId> findSecretKeysWithPrivateKeyAndUserId(InputStream keyringInput,
+ Map<String, String> sigKeyUserId2Password, String provider) throws IOException, PGPException, NoSuchProviderException {
+ List<PGPSecretKeyAndPrivateKeyAndUserId> result = new ArrayList<PGPDataFormatUtil.PGPSecretKeyAndPrivateKeyAndUserId>(
+ sigKeyUserId2Password.size());
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyringInput));
- for (Iterator<?> i = pgpSec.getKeyRings(); i.hasNext() && pgpSecKey == null;) {
+ for (Iterator<?> i = pgpSec.getKeyRings(); i.hasNext();) {
Object data = i.next();
if (data instanceof PGPSecretKeyRing) {
PGPSecretKeyRing keyring = (PGPSecretKeyRing) data;
PGPSecretKey secKey = keyring.getSecretKey();
- if (userId != null) {
+ for (String userIdPart : sigKeyUserId2Password.keySet()) {
for (Iterator<String> iterator = secKey.getUserIDs(); iterator.hasNext();) {
String keyUserId = iterator.next();
// there can be serveral user IDs!
- if (keyUserId != null && keyUserId.contains(userId)) {
+ if (keyUserId != null && keyUserId.contains(userIdPart)) {
PGPPrivateKey privateKey = secKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(provider)
- .build(passphrase.toCharArray()));
+ .build(sigKeyUserId2Password.get(userIdPart).toCharArray()));
if (privateKey != null) {
- return secKey;
+ result.add(new PGPSecretKeyAndPrivateKeyAndUserId(secKey, privateKey, keyUserId));
+ LOG.debug("Private key with key user ID {} and key ID {} found for specified user ID part {}",
+ new Object[] {keyUserId, Long.toString(privateKey.getKeyID()), userIdPart});
+
}
}
}
- } else {
- PGPPrivateKey privateKey = secKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(provider).build(
- passphrase.toCharArray()));
- if (privateKey != null) {
- pgpSecKey = secKey;
- }
}
}
}
- return pgpSecKey;
+ return result;
+ }
+
+ public static class PGPSecretKeyAndPrivateKeyAndUserId {
+
+ private final PGPSecretKey secretKey;
+
+ private final PGPPrivateKey privateKey;
+
+ private final String userId;
+
+ public PGPSecretKeyAndPrivateKeyAndUserId(PGPSecretKey secretKey, PGPPrivateKey privateKey, String userId) {
+ this.secretKey = secretKey;
+ this.privateKey = privateKey;
+ this.userId = userId;
+ }
+
+ public PGPSecretKey getSecretKey() {
+ return secretKey;
+ }
+
+ public PGPPrivateKey getPrivateKey() {
+ return privateKey;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/a346c1c1/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatDynamicTest.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatDynamicTest.java b/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatDynamicTest.java
index 144b655..6250695 100644
--- a/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatDynamicTest.java
+++ b/components/camel-crypto/src/test/java/org/apache/camel/converter/crypto/PGPDataFormatDynamicTest.java
@@ -41,6 +41,15 @@ public class PGPDataFormatDynamicTest extends PGPDataFormatTest {
userids.add(getKeyUserId());
return userids;
}
+
+ // setup a wrong signature userids
+ @Override
+ protected List<String> getSignatureKeyUserIds() {
+ List<String> userids = new ArrayList<String>(2);
+ userids.add("wrong1");
+ userids.add(getKeyUserId());
+ return userids;
+ }
// setup a wrong password
@Override
@@ -77,6 +86,7 @@ public class PGPDataFormatDynamicTest extends PGPDataFormatTest {
headers.put(PGPDataFormat.ENCRYPTION_ALGORITHM, SymmetricKeyAlgorithmTags.AES_128);
headers.put(PGPDataFormat.SIGNATURE_HASH_ALGORITHM, HashAlgorithmTags.SHA512);
headers.put(PGPDataFormat.COMPRESSION_ALGORITHM, CompressionAlgorithmTags.ZLIB);
+ headers.put(PGPDataFormat.SIGNATURE_KEY_USERIDS, Collections.singletonList("second"));
return headers;
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/a346c1c1/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 50af476..b815882 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
@@ -20,11 +20,15 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.util.IOHelper;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.bcpg.HashAlgorithmTags;
@@ -55,6 +59,13 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
return userids;
}
+ protected List<String> getSignatureKeyUserIds() {
+ List<String> userids = new ArrayList<String>(2);
+ userids.add("second");
+ userids.add(getKeyUserId());
+ return userids;
+ }
+
protected String getKeyPassword() {
return "sdude";
}
@@ -105,9 +116,62 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
doRoundTripEncryptionTests("direct:sign-key-ring-byte-array");
}
+ @Test
+ public void testSeveralSignerKeys() throws Exception {
+ doRoundTripEncryptionTests("direct:several-signer-keys");
+ }
+
+ @Test
+ public void testOneUserIdWithServeralKeys() throws Exception {
+ doRoundTripEncryptionTests("direct:one-userid-several-keys");
+ }
+
+ @Test
+ public void testVerifyExceptionNoPublicKeyFoundCorrespondingToSignatureUserIds() throws Exception {
+ setupExpectations(context, 1, "mock:encrypted");
+ MockEndpoint exception = setupExpectations(context, 1, "mock:exception");
+
+ String payload = "Hi Alice, Be careful Eve is listening, signed Bob";
+ Map<String, Object> headers = getHeaders();
+ template.sendBodyAndHeaders("direct:verify_exception_sig_userids", payload, headers);
+ assertMockEndpointsSatisfied();
+
+ //check exception text
+ Exception e = (Exception) exception.getExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT);
+ assertNotNull("Expected excpetion missing", e);
+ assertTrue(e.getMessage().contains("No public key found fitting to the signature key Id"));
+
+ }
+
+
+ @Test
+ public void testVerifyExceptionNoPassphraseSpecifiedForSignatureKeyUserId() throws Exception {
+ MockEndpoint exception = setupExpectations(context, 1, "mock:exception");
+
+ String payload = "Hi Alice, Be careful Eve is listening, signed Bob";
+ Map<String, Object> headers = new HashMap<String, Object>();
+ // add signature user id which does not have a passphrase
+ headers.put(PGPDataFormat.SIGNATURE_KEY_USERID, "userIDWithNoPassphrase");
+ // the following entry is necessary for the dynamic test
+ headers.put(PGPDataFormat.KEY_USERID, "second");
+ template.sendBodyAndHeaders("direct:several-signer-keys", payload, headers);
+ assertMockEndpointsSatisfied();
+
+ //check exception text
+ Exception e = (Exception) exception.getExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT);
+ assertNotNull("Expected excpetion missing", e);
+ assertTrue(e.getMessage().contains("No passphrase specified for signature key user ID"));
+
+ }
+
+
+
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
public void configure() throws Exception {
+
+ onException(IllegalArgumentException.class).handled(true).to("mock:exception");
+
// START SNIPPET: pgp-format
// Public Key FileName
String keyFileName = getKeyFileName();
@@ -147,7 +211,7 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
pgpSignAndEncrypt.setKeyUserid(keyUserid);
pgpSignAndEncrypt.setSignatureKeyFileName(keyFileNameSec);
PGPPassphraseAccessor passphraseAccessor = getPassphraseAccessor();
- pgpSignAndEncrypt.setSignatureKeyUserid(keyUserid);
+ pgpSignAndEncrypt.setSignatureKeyUserid("Super <sd...@nowhere.net>"); // must be the exact user Id because passphrase is searched in accessor
pgpSignAndEncrypt.setPassphraseAccessor(passphraseAccessor);
pgpSignAndEncrypt.setProvider(getProvider());
pgpSignAndEncrypt.setAlgorithm(getAlgorithm());
@@ -159,10 +223,18 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
pgpVerifyAndDecrypt.setPassword(keyPassword);
pgpVerifyAndDecrypt.setSignatureKeyFileName(keyFileName);
pgpVerifyAndDecrypt.setProvider(getProvider());
+ pgpVerifyAndDecrypt.setSignatureKeyUserid(keyUserid); // restrict verification to public keys with certain User ID
from("direct:inline-sign").marshal(pgpSignAndEncrypt).to("mock:encrypted").unmarshal(pgpVerifyAndDecrypt)
.to("mock:unencrypted");
// END SNIPPET: pgp-format-signature
+
+ // test verifying exception, no public key found corresponding to signature key userIds
+ from("direct:verify_exception_sig_userids").marshal(pgpSignAndEncrypt).to("mock:encrypted")
+ .setHeader(PGPDataFormat.SIGNATURE_KEY_USERIDS).constant(Arrays.asList(new String[] {"wrong1", "wrong2"}))
+ .setHeader(PGPDataFormat.SIGNATURE_KEY_USERID).constant("wrongUserID").unmarshal(pgpVerifyAndDecrypt)
+ .to("mock:unencrypted");
+
/* ---- key ring as byte array -- */
// START SNIPPET: pgp-format-key-ring-byte-array
PGPDataFormat pgpEncryptByteArray = new PGPDataFormat();
@@ -177,8 +249,8 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
pgpDecryptByteArray.setPassphraseAccessor(passphraseAccessor);
pgpDecryptByteArray.setProvider(getProvider());
- from("direct:key-ring-byte-array").streamCaching().marshal(pgpEncryptByteArray).to("mock:encrypted").unmarshal(pgpDecryptByteArray)
- .to("mock:unencrypted");
+ from("direct:key-ring-byte-array").streamCaching().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
@@ -196,6 +268,8 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
pgpVerifyAndDecryptByteArray.setPassphraseAccessor(passphraseAccessor);
pgpVerifyAndDecryptByteArray.setEncryptionKeyRing(getSecKeyRing());
pgpVerifyAndDecryptByteArray.setProvider(getProvider());
+ // restrict verification to public keys with certain User ID
+ pgpVerifyAndDecryptByteArray.setSignatureKeyUserids(getSignatureKeyUserIds());
from("direct:sign-key-ring-byte-array").streamCaching()
// encryption key ring can also be set as header
@@ -207,7 +281,76 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
// 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
+
+ // START SNIPPET: pgp-format-several-signer-keys
+ PGPDataFormat pgpSignAndEncryptSeveralSignerKeys = new PGPDataFormat();
+ pgpSignAndEncryptSeveralSignerKeys.setKeyUserid(keyUserid);
+ pgpSignAndEncryptSeveralSignerKeys.setEncryptionKeyRing(getPublicKeyRing());
+ pgpSignAndEncryptSeveralSignerKeys.setSignatureKeyRing(getSecKeyRing());
+
+ List<String> signerUserIds = new ArrayList<String>();
+ signerUserIds.add("Third (comment third) <em...@third.com>");
+ signerUserIds.add("Second <em...@second.com>");
+ pgpSignAndEncryptSeveralSignerKeys.setSignatureKeyUserids(signerUserIds);
+
+ Map<String, String> userId2Passphrase = new HashMap<String, String>();
+ userId2Passphrase.put("Third (comment third) <em...@third.com>", "sdude");
+ userId2Passphrase.put("Second <em...@second.com>", "sdude");
+ PGPPassphraseAccessor passphraseAccessorSeveralKeys = new PGPPassphraseAccessorDefault(userId2Passphrase);
+ pgpSignAndEncryptSeveralSignerKeys.setPassphraseAccessor(passphraseAccessorSeveralKeys);
+
+ PGPDataFormat pgpVerifyAndDecryptSeveralSignerKeys = new PGPDataFormat();
+ pgpVerifyAndDecryptSeveralSignerKeys.setPassphraseAccessor(passphraseAccessor);
+ pgpVerifyAndDecryptSeveralSignerKeys.setEncryptionKeyRing(getSecKeyRing());
+ pgpVerifyAndDecryptSeveralSignerKeys.setSignatureKeyRing(getPublicKeyRing());
+ pgpVerifyAndDecryptSeveralSignerKeys.setProvider(getProvider());
+ // only specify one expected signature
+ List<String> expectedSigUserIds = new ArrayList<String>();
+ expectedSigUserIds.add("Second <em...@second.com>");
+ pgpVerifyAndDecryptSeveralSignerKeys.setSignatureKeyUserids(expectedSigUserIds);
+ from("direct:several-signer-keys").streamCaching().marshal(pgpSignAndEncryptSeveralSignerKeys).to("mock:encrypted")
+ .unmarshal(pgpVerifyAndDecryptSeveralSignerKeys).to("mock:unencrypted");
+ // END SNIPPET: pgp-format-several-signer-keys
+
+ // test encryption by several key and signing by serveral keys where the keys are specified by one User ID part
+ PGPDataFormat pgpSignAndEncryptOneUserIdWithServeralKeys = new PGPDataFormat();
+ pgpSignAndEncryptOneUserIdWithServeralKeys.setEncryptionKeyRing(getPublicKeyRing());
+ pgpSignAndEncryptOneUserIdWithServeralKeys.setSignatureKeyRing(getSecKeyRing());
+ // the two private keys have the same password therefore we do not need a passphrase accessor
+ pgpSignAndEncryptOneUserIdWithServeralKeys.setPassword(getKeyPassword());
+
+ PGPDataFormat pgpVerifyAndDecryptOneUserIdWithServeralKeys = new PGPDataFormat();
+ pgpVerifyAndDecryptOneUserIdWithServeralKeys.setPassword(getKeyPassword());
+ pgpVerifyAndDecryptOneUserIdWithServeralKeys.setEncryptionKeyRing(getSecKeyRing());
+ pgpVerifyAndDecryptOneUserIdWithServeralKeys.setSignatureKeyRing(getPublicKeyRing());
+ pgpVerifyAndDecryptOneUserIdWithServeralKeys.setProvider(getProvider());
+ pgpVerifyAndDecryptOneUserIdWithServeralKeys.setSignatureKeyUserids(expectedSigUserIds);
+ from("direct:one-userid-several-keys")
+ // there are two keys which have a User ID which contains the string "econd"
+ .setHeader(PGPDataFormat.KEY_USERID)
+ .constant("econd")
+ .setHeader(PGPDataFormat.SIGNATURE_KEY_USERID)
+ .constant("econd")
+ .marshal(pgpSignAndEncryptOneUserIdWithServeralKeys)
+ // it is recommended to remove the header immediately when it is no longer needed
+ .removeHeader(PGPDataFormat.KEY_USERID)
+ .removeHeader(PGPDataFormat.SIGNATURE_KEY_USERID)
+ .to("mock:encrypted")
+ // only specify one expected signature key, to check the first signature
+ .setHeader(PGPDataFormat.SIGNATURE_KEY_USERID)
+ .constant("Second <em...@second.com>")
+ .unmarshal(pgpVerifyAndDecryptOneUserIdWithServeralKeys)
+ // do it again but now check the second signature key
+ // there are two keys which have a User ID which contains the string "econd"
+ .setHeader(PGPDataFormat.KEY_USERID).constant("econd").setHeader(PGPDataFormat.SIGNATURE_KEY_USERID)
+ .constant("econd").marshal(pgpSignAndEncryptOneUserIdWithServeralKeys)
+ // it is recommended to remove the header immediately when it is no longer needed
+ .removeHeader(PGPDataFormat.KEY_USERID).removeHeader(PGPDataFormat.SIGNATURE_KEY_USERID)
+ // only specify one expected signature key, to check the second signature
+ .setHeader(PGPDataFormat.SIGNATURE_KEY_USERID).constant("Third (comment third) <em...@third.com>")
+ .unmarshal(pgpVerifyAndDecryptOneUserIdWithServeralKeys).to("mock:unencrypted");
}
+
};
}