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/10/22 12:15:43 UTC
[1/2] git commit: CAMEL-6875 Added PGPPassphraseAccessor to support
more sophsiticate keyring with thanks to Franz
Updated Branches:
refs/heads/camel-2.12.x 3b2da77ea -> d1d4b81a2
CAMEL-6875 Added PGPPassphraseAccessor to support more sophsiticate keyring 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/d8784008
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/d8784008
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/d8784008
Branch: refs/heads/camel-2.12.x
Commit: d878400812f3b38620c1a645448a93fb0b75cc28
Parents: 3b2da77
Author: Willem Jiang <ni...@apache.org>
Authored: Mon Oct 21 18:05:02 2013 +0800
Committer: Willem Jiang <wi...@gmail.com>
Committed: Tue Oct 22 18:10:54 2013 +0800
----------------------------------------------------------------------
.../camel/converter/crypto/PGPDataFormat.java | 122 ++++++++++----
.../converter/crypto/PGPDataFormatUtil.java | 163 ++++++++++++++++---
.../converter/crypto/PGPPassphraseAccessor.java | 34 ++++
.../crypto/PGPPassphraseAccessorDefault.java | 54 ++++++
.../converter/crypto/PGPDataFormatTest.java | 28 ++--
.../crypto/SpringPGPDataFormatTest.xml | 16 +-
.../apache/camel/component/crypto/pubring.gpg | Bin 1184 -> 2814 bytes
.../apache/camel/component/crypto/secring.gpg | Bin 2562 -> 5570 bytes
8 files changed, 343 insertions(+), 74 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/d8784008/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 e6d8921..c14c5c8 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
@@ -111,20 +111,30 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
private boolean armored;
private boolean integrity = true;
-
- /** Digest algorithm for signing (marshal).
- * Possible values are defined in {@link HashAlgorithmTags}.
- * Default value is SHA1.
+
+ /**
+ * Digest algorithm for signing (marshal). Possible values are defined in
+ * {@link HashAlgorithmTags}. Default value is SHA1.
*/
private int hashAlgorithm = HashAlgorithmTags.SHA1;
-
+
/**
- * Symmetric key algorithm for encryption (marschal).
- * Possible values are defined in {@link SymmetricKeyAlgorithmTags}.
- * Default value is CAST5.
+ * Symmetric key algorithm for encryption (marschal). Possible values are
+ * defined in {@link SymmetricKeyAlgorithmTags}. Default value is CAST5.
*/
private int algorithm = SymmetricKeyAlgorithmTags.CAST5;
+ /**
+ * If no passpharase can be found from the parameter <tt>password</tt> or
+ * <tt>signaturePassword</tt> or from the header
+ * {@link #SIGNATURE_KEY_PASSWORD} or {@link #KEY_PASSWORD} then we try to
+ * get the password from the passphrase accessor. This is especially useful
+ * in the decrypt case, where we chose the private key according to the key
+ * Id stored in the encrypted data. So in this case we do not know the user
+ * Id in advance.
+ */
+ private PGPPassphraseAccessor passphraseAccessor;
+
public PGPDataFormat() {
}
@@ -141,7 +151,15 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
}
protected String findKeyPassword(Exchange exchange) {
- return exchange.getIn().getHeader(KEY_PASSWORD, getPassword(), String.class);
+ String keyPassword = exchange.getIn().getHeader(KEY_PASSWORD, getPassword(), String.class);
+ if (keyPassword != null) {
+ return keyPassword;
+ }
+ if (passphraseAccessor != null) {
+ return passphraseAccessor.getPassphrase(findKeyUserid(exchange));
+ } else {
+ return null;
+ }
}
protected String findSignatureKeyFileName(Exchange exchange) {
@@ -157,9 +175,17 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
}
protected String findSignatureKeyPassword(Exchange exchange) {
- return exchange.getIn().getHeader(SIGNATURE_KEY_PASSWORD, getSignaturePassword(), String.class);
+ String sigPassword = exchange.getIn().getHeader(SIGNATURE_KEY_PASSWORD, getSignaturePassword(), String.class);
+ if (sigPassword != null) {
+ return sigPassword;
+ }
+ if (passphraseAccessor != null) {
+ return passphraseAccessor.getPassphrase(findSignatureKeyUserid(exchange));
+ } else {
+ return null;
+ }
}
-
+
protected int findAlgorithm(Exchange exchange) {
return exchange.getIn().getHeader(ENCRYPTION_ALGORITHM, getAlgorithm(), Integer.class);
}
@@ -231,13 +257,14 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
return null;
}
- PGPSecretKey sigSecretKey = PGPDataFormatUtil.findSecretKey(exchange.getContext(), sigKeyFileName, sigKeyRing, sigKeyPassword, getProvider());
+ PGPSecretKey sigSecretKey = PGPDataFormatUtil.findSecretKey(exchange.getContext(), sigKeyFileName, sigKeyRing, sigKeyPassword,
+ sigKeyUserid, getProvider());
if (sigSecretKey == null) {
throw new IllegalArgumentException("Signature secret key is null, cannot proceed");
}
- PGPPrivateKey sigPrivateKey = sigSecretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(getProvider()).build(
- sigKeyPassword.toCharArray()));
+ PGPPrivateKey sigPrivateKey = sigSecretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(getProvider())
+ .build(sigKeyPassword.toCharArray()));
if (sigPrivateKey == null) {
throw new IllegalArgumentException("Signature private key is null, cannot proceed");
}
@@ -259,15 +286,10 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
return null;
}
- PGPPrivateKey key = PGPDataFormatUtil.findPrivateKey(exchange.getContext(), findKeyFileName(exchange),
- findEncryptionKeyRing(exchange), encryptedStream, findKeyPassword(exchange), getProvider());
- if (key == null) {
- throw new IllegalArgumentException("Private key is null, cannot proceed");
- }
-
InputStream in;
try {
byte[] encryptedData = IOUtils.toByteArray(encryptedStream);
+ //TODO why do we need a byte array input stream? --> streaming not possible?
InputStream byteStream = new ByteArrayInputStream(encryptedData);
in = PGPUtil.getDecoderStream(byteStream);
} finally {
@@ -286,11 +308,21 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
}
IOHelper.close(in);
- PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) enc.get(0);
+ PGPPublicKeyEncryptedData pbe = null;
+ PGPPrivateKey key = null;
+ // find encrypted data for which a private key exists in the secret key ring
+ for (int i = 0; i < enc.size() && key == null; i++) {
+ pbe = (PGPPublicKeyEncryptedData) enc.get(i);
+ key = PGPDataFormatUtil.findPrivateKeyWithKeyId(exchange.getContext(), findKeyFileName(exchange),
+ findEncryptionKeyRing(exchange), pbe.getKeyID(), findKeyPassword(exchange), getPassphraseAccessor(), getProvider());
+ }
+ if (key == null) {
+ throw new PGPException("Provided input is encrypted with unknown pair of keys.");
+ }
+
InputStream encData = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(getProvider()).build(key));
pgpFactory = new PGPObjectFactory(encData);
PGPCompressedData comData = (PGPCompressedData) pgpFactory.nextObject();
-
pgpFactory = new PGPObjectFactory(comData.getDataStream());
Object object = pgpFactory.nextObject();
@@ -305,6 +337,7 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
PGPLiteralData ld = (PGPLiteralData) object;
InputStream litData = ld.getInputStream();
+ //TODO we should enable streaming here with CashedOutputStream!!
byte[] answer;
try {
answer = Streams.readAll(litData);
@@ -315,7 +348,7 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
if (signature != null) {
signature.update(answer);
PGPSignatureList sigList = (PGPSignatureList) pgpFactory.nextObject();
- if (!signature.verify(sigList.get(0))) {
+ if (!signature.verify(getSignatureWithKeyId(signature.getKeyID(), sigList))) {
throw new SignatureException("Cannot verify PGP signature");
}
}
@@ -323,18 +356,37 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
return answer;
}
+ protected PGPSignature getSignatureWithKeyId(long keyID, PGPSignatureList sigList) {
+ for (int i = 0; i < sigList.size(); i++) {
+ PGPSignature signature = sigList.get(i);
+ if (keyID == signature.getKeyID()) {
+ return signature;
+ }
+ }
+ throw new IllegalStateException("PGP signature is inconsistent");
+ }
+
protected PGPOnePassSignature getSignature(Exchange exchange, PGPOnePassSignatureList signatureList) throws IOException, PGPException,
NoSuchProviderException {
- 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");
+ for (int i = 0; i < signatureList.size(); i++) {
+ PGPOnePassSignature signature = signatureList.get(i);
+ // Determine public key from signature keyId
+ PGPPublicKey sigPublicKey = PGPDataFormatUtil.findPublicKeyWithKeyId(exchange.getContext(), findSignatureKeyFileName(exchange),
+ findSignatureKeyRing(exchange), signature.getKeyID(), false);
+ if (sigPublicKey == null) {
+ continue;
+ }
+ // choose that signature for which a public key exists!
+ signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(getProvider()), sigPublicKey);
+ return signature;
+ }
+ if (signatureList.isEmpty()) {
+ return null;
+ } else {
+ throw new IllegalArgumentException("No public key found fitting to the signature key Id; cannot verify the signature");
}
- PGPOnePassSignature signature = signatureList.get(0);
- signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(getProvider()), sigPublicKey);
- return signature;
}
/**
@@ -448,8 +500,6 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
public void setProvider(String provider) {
this.provider = provider;
}
-
-
public int getHashAlgorithm() {
return hashAlgorithm;
@@ -467,6 +517,14 @@ public class PGPDataFormat extends ServiceSupport implements DataFormat {
this.algorithm = algorithm;
}
+ public PGPPassphraseAccessor getPassphraseAccessor() {
+ return passphraseAccessor;
+ }
+
+ public void setPassphraseAccessor(PGPPassphraseAccessor passphraseAccessor) {
+ this.passphraseAccessor = passphraseAccessor;
+ }
+
@Override
protected void doStart() throws Exception {
if (Security.getProvider(BC) == null && BC.equals(getProvider())) {
http://git-wip-us.apache.org/repos/asf/camel/blob/d8784008/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 1dfa33a..bff00ad 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
@@ -50,8 +50,9 @@ public final class PGPDataFormatUtil {
private PGPDataFormatUtil() {
}
- public static PGPPublicKey findPublicKey(CamelContext context, String filename, String userid, boolean forEncryption) throws IOException, PGPException,
- NoSuchProviderException {
+ @Deprecated
+ public static PGPPublicKey findPublicKey(CamelContext context, String filename, String userid, boolean forEncryption)
+ throws IOException, PGPException, NoSuchProviderException {
return findPublicKey(context, filename, null, userid, forEncryption);
}
@@ -68,6 +69,57 @@ public final class PGPDataFormatUtil {
return pubKey;
}
+ 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);
+ PGPPublicKey pubKey;
+ try {
+ pubKey = findPublicKeyWithKeyId(is, keyid);
+ } finally {
+ IOHelper.close(is);
+ }
+ return pubKey;
+ }
+
+ public static PGPPrivateKey findPrivateKeyWithKeyId(CamelContext context, String filename, byte[] secreteKeyRing, long keyid,
+ String passphrase, PGPPassphraseAccessor passpraseAccessor, String provider) throws IOException, PGPException,
+ NoSuchProviderException {
+ InputStream is = determineKeyRingInputStream(context, filename, secreteKeyRing, true);
+ try {
+ return findPrivateKeyWithKeyId(is, keyid, passphrase, passpraseAccessor, provider);
+ } finally {
+ IOHelper.close(is);
+ }
+ }
+
+ private static PGPPrivateKey findPrivateKeyWithKeyId(InputStream keyringInput, long keyid, String passphrase,
+ 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();
+ if (data instanceof PGPSecretKeyRing) {
+ PGPSecretKeyRing keyring = (PGPSecretKeyRing) data;
+ PGPSecretKey secKey = keyring.getSecretKey();
+ if (secKey != null && keyid == secKey.getKeyID()) {
+ if (passphrase == null && passphraseAccessor != null) {
+ // get passphrase from accessor
+ @SuppressWarnings("unchecked")
+ Iterator<String> userIDs = secKey.getUserIDs();
+ while (passphrase == null && userIDs.hasNext()) {
+ passphrase = passphraseAccessor.getPassphrase(userIDs.next());
+ }
+ }
+ PGPPrivateKey privateKey = secKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(provider).build(
+ passphrase.toCharArray()));
+ if (privateKey != null) {
+ return privateKey;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
private static InputStream determineKeyRingInputStream(CamelContext context, String filename, byte[] keyRing, boolean forEncryption)
throws IOException {
if (filename != null && keyRing != null) {
@@ -90,6 +142,24 @@ public final class PGPDataFormatUtil {
}
@SuppressWarnings("unchecked")
+ private static PGPPublicKey findPublicKeyWithKeyId(InputStream input, long keyid) throws IOException, PGPException,
+ 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;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
private static PGPPublicKey findPublicKey(InputStream input, String userid, boolean forEncryption) throws IOException, PGPException,
NoSuchProviderException {
PGPPublicKeyRingCollection pgpSec = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input));
@@ -99,17 +169,17 @@ public final class PGPDataFormatUtil {
PGPPublicKeyRing keyRing = keyRingIter.next();
Iterator<PGPPublicKey> keyIter = keyRing.getPublicKeys();
- String keyUserId = null;
while (keyIter.hasNext()) {
PGPPublicKey key = keyIter.next();
for (Iterator<String> iterator = key.getUserIDs(); iterator.hasNext();) {
- keyUserId = iterator.next();
- }
- if (keyUserId != null && keyUserId.contains(userid)) {
- if (forEncryption && key.isEncryptionKey()) {
- return key;
- } else if (!forEncryption && isSignatureKey(key)) {
- return key;
+ String keyUserId = iterator.next();
+ // there can be serveral user IDs!
+ if (keyUserId != null && keyUserId.contains(userid)) {
+ if (forEncryption && key.isEncryptionKey()) {
+ return key;
+ } else if (!forEncryption && isSignatureKey(key)) {
+ return key;
+ }
}
}
}
@@ -123,26 +193,36 @@ public final class PGPDataFormatUtil {
return algorithm == RSA_GENERAL || algorithm == RSA_SIGN || algorithm == DSA || algorithm == ECDSA || algorithm == ELGAMAL_GENERAL;
}
+ @Deprecated
public static PGPPrivateKey findPrivateKey(CamelContext context, String keychainFilename, InputStream encryptedInput, String passphrase)
throws IOException, PGPException, NoSuchProviderException {
return findPrivateKey(context, keychainFilename, null, encryptedInput, passphrase, "BC");
}
+ @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 keyChainInputStream = determineKeyRingInputStream(context, keychainFilename, secKeyRing, true);
PGPPrivateKey privKey = null;
try {
- privKey = findPrivateKey(keyChainInputStream, encryptedInput, passphrase, provider);
+ privKey = findPrivateKey(keyChainInputStream, encryptedInput, passphrase, passphraseAccessor, provider);
} finally {
IOHelper.close(keyChainInputStream);
}
return privKey;
}
- private static PGPPrivateKey findPrivateKey(InputStream keyringInput, InputStream encryptedInput, String passphrase, String provider) throws IOException,
- PGPException, NoSuchProviderException {
+ @Deprecated
+ private static PGPPrivateKey findPrivateKey(InputStream keyringInput, InputStream encryptedInput, String passphrase,
+ PGPPassphraseAccessor passphraseAccessor, String provider) throws IOException, PGPException, NoSuchProviderException {
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyringInput));
PGPObjectFactory factory = new PGPObjectFactory(PGPUtil.getDecoderStream(encryptedInput));
PGPEncryptedDataList enc;
@@ -163,7 +243,16 @@ public final class PGPDataFormatUtil {
encryptedData = (PGPPublicKeyEncryptedData) encryptedDataObjects.next();
PGPSecretKey pgpSecKey = pgpSec.getSecretKey(encryptedData.getKeyID());
if (pgpSecKey != null) {
- privateKey = pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(provider).build(passphrase.toCharArray()));
+ if (passphrase == null && passphraseAccessor != null) {
+ // get passphrase from accessor
+ @SuppressWarnings("unchecked")
+ Iterator<String> userIDs = pgpSecKey.getUserIDs();
+ while (passphrase == null && userIDs.hasNext()) {
+ passphrase = passphraseAccessor.getPassphrase(userIDs.next());
+ }
+ }
+ privateKey = pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(provider).build(
+ passphrase.toCharArray()));
}
}
if (privateKey == null && pgpSec.size() > 0 && encryptedData != null) {
@@ -172,25 +261,34 @@ public final class PGPDataFormatUtil {
return privateKey;
}
- public static PGPSecretKey findSecretKey(CamelContext context, String keychainFilename, String passphrase)
- throws IOException, PGPException, NoSuchProviderException {
+ @Deprecated
+ public static PGPSecretKey findSecretKey(CamelContext context, String keychainFilename, String passphrase) throws IOException,
+ PGPException, NoSuchProviderException {
return findSecretKey(context, keychainFilename, null, passphrase, "BC");
}
- public static PGPSecretKey findSecretKey(CamelContext context, String keychainFilename, byte[] secKeyRing, String passphrase, String provider)
- throws IOException, PGPException, NoSuchProviderException {
-
+ public static PGPSecretKey findSecretKey(CamelContext context, String keychainFilename, byte[] secKeyRing, String passphrase,
+ String userId, String provider) throws IOException, PGPException, NoSuchProviderException {
InputStream keyChainInputStream = determineKeyRingInputStream(context, keychainFilename, secKeyRing, false);
PGPSecretKey secKey = null;
try {
- secKey = findSecretKey(keyChainInputStream, passphrase, provider);
+ secKey = findSecretKey(keyChainInputStream, passphrase, userId, provider);
} finally {
IOHelper.close(keyChainInputStream);
}
return secKey;
}
- private static PGPSecretKey findSecretKey(InputStream keyringInput, String passphrase, String provider) throws IOException, PGPException, NoSuchProviderException {
+ @Deprecated
+ public static PGPSecretKey findSecretKey(CamelContext context, String keychainFilename, byte[] secKeyRing, String passphrase,
+ 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;
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyringInput));
for (Iterator<?> i = pgpSec.getKeyRings(); i.hasNext() && pgpSecKey == null;) {
@@ -198,9 +296,24 @@ public final class PGPDataFormatUtil {
if (data instanceof PGPSecretKeyRing) {
PGPSecretKeyRing keyring = (PGPSecretKeyRing) data;
PGPSecretKey secKey = keyring.getSecretKey();
- PGPPrivateKey privateKey = secKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(provider).build(passphrase.toCharArray()));
- if (privateKey != null) {
- pgpSecKey = secKey;
+ if (userId != null) {
+ for (Iterator<String> iterator = secKey.getUserIDs(); iterator.hasNext();) {
+ String keyUserId = iterator.next();
+ // there can be serveral user IDs!
+ if (keyUserId != null && keyUserId.contains(userId)) {
+ PGPPrivateKey privateKey = secKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(provider)
+ .build(passphrase.toCharArray()));
+ if (privateKey != null) {
+ return secKey;
+ }
+ }
+ }
+ } else {
+ PGPPrivateKey privateKey = secKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(provider).build(
+ passphrase.toCharArray()));
+ if (privateKey != null) {
+ pgpSecKey = secKey;
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/d8784008/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPassphraseAccessor.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPassphraseAccessor.java b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPassphraseAccessor.java
new file mode 100644
index 0000000..4bd6b8f
--- /dev/null
+++ b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPassphraseAccessor.java
@@ -0,0 +1,34 @@
+/**
+ * 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;
+
+/**
+ * Access to the password for a user Id.
+ *
+ */
+public interface PGPPassphraseAccessor {
+
+ /**
+ * Returns the passphrase for a user Id
+ *
+ * @param userId
+ * user Id, can be <code>null</code>
+ * @return the passphrase for the user Id, or <code>null</code> if the
+ * passphrase cannot be found
+ */
+ String getPassphrase(String userId);
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d8784008/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPassphraseAccessorDefault.java
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPassphraseAccessorDefault.java b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPassphraseAccessorDefault.java
new file mode 100644
index 0000000..6796ccd
--- /dev/null
+++ b/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPPassphraseAccessorDefault.java
@@ -0,0 +1,54 @@
+/**
+ * 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.util.Map;
+
+/**
+ * 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.
+ */
+import org.apache.camel.util.ObjectHelper;
+
+public class PGPPassphraseAccessorDefault implements PGPPassphraseAccessor {
+
+ private final Map<String, String> userId2Passphrase;
+
+ public PGPPassphraseAccessorDefault(Map<String, String> userId2Passphrase) {
+ ObjectHelper.notNull(userId2Passphrase, "userIdPassphrase");
+
+ this.userId2Passphrase = userId2Passphrase;
+ }
+
+ @Override
+ public String getPassphrase(String userId) {
+ return userId2Passphrase.get(userId);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d8784008/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 e890d53..a739a42 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
@@ -19,6 +19,8 @@ package org.apache.camel.converter.crypto;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Collections;
+import java.util.Map;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.util.IOHelper;
@@ -106,7 +108,7 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
from("direct:inline")
.marshal().pgp(keyFileName, keyUserid)
.to("mock:encrypted")
- .unmarshal().pgp(keyFileNameSec, keyUserid, keyPassword)
+ .unmarshal().pgp(keyFileNameSec, null, keyPassword)
.to("mock:unencrypted");
// END SNIPPET: pgp-format
@@ -119,7 +121,7 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
PGPDataFormat pgpDecrypt = new PGPDataFormat();
pgpDecrypt.setKeyFileName(keyFileNameSec);
- pgpDecrypt.setKeyUserid(keyUserid);
+ // pgpDecrypt.setKeyUserid(keyUserid);
pgpDecrypt.setPassword(keyPassword);
pgpDecrypt.setProvider(getProvider());
@@ -132,7 +134,7 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
from("direct:inline-armor")
.marshal().pgp(keyFileName, keyUserid, null, true, true)
.to("mock:encrypted")
- .unmarshal().pgp(keyFileNameSec, keyUserid, keyPassword, true, true)
+ .unmarshal().pgp(keyFileNameSec, null, keyPassword, true, true)
.to("mock:unencrypted");
// END SNIPPET: pgp-format-header
@@ -141,8 +143,9 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
pgpSignAndEncrypt.setKeyFileName(keyFileName);
pgpSignAndEncrypt.setKeyUserid(keyUserid);
pgpSignAndEncrypt.setSignatureKeyFileName(keyFileNameSec);
+ PGPPassphraseAccessor passphraseAccessor = getPassphraseAccessor();
pgpSignAndEncrypt.setSignatureKeyUserid(keyUserid);
- pgpSignAndEncrypt.setSignaturePassword(keyPassword);
+ pgpSignAndEncrypt.setPassphraseAccessor(passphraseAccessor);
pgpSignAndEncrypt.setProvider(getProvider());
pgpSignAndEncrypt.setAlgorithm(getAlgorithm());
pgpSignAndEncrypt.setHashAlgorithm(getHashAlgorithm());
@@ -150,10 +153,8 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
PGPDataFormat pgpVerifyAndDecrypt = new PGPDataFormat();
pgpVerifyAndDecrypt.setKeyFileName(keyFileNameSec);
- pgpVerifyAndDecrypt.setKeyUserid(keyUserid);
pgpVerifyAndDecrypt.setPassword(keyPassword);
pgpVerifyAndDecrypt.setSignatureKeyFileName(keyFileName);
- pgpVerifyAndDecrypt.setSignatureKeyUserid(keyUserid);
pgpVerifyAndDecrypt.setProvider(getProvider());
from("direct:inline-sign")
@@ -172,8 +173,7 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
PGPDataFormat pgpDecryptByteArray = new PGPDataFormat();
pgpDecryptByteArray.setEncryptionKeyRing(getSecKeyRing());
- pgpDecryptByteArray.setKeyUserid(keyUserid);
- pgpDecryptByteArray.setPassword(keyPassword);
+ pgpDecryptByteArray.setPassphraseAccessor(passphraseAccessor);
pgpDecryptByteArray.setProvider(getProvider());
from("direct:key-ring-byte-array").marshal(pgpEncryptByteArray).to("mock:encrypted").unmarshal(pgpDecryptByteArray)
@@ -191,10 +191,8 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
pgpSignAndEncryptByteArray.setHashAlgorithm(HashAlgorithmTags.RIPEMD160);
PGPDataFormat pgpVerifyAndDecryptByteArray = new PGPDataFormat();
- pgpVerifyAndDecryptByteArray.setKeyUserid(keyUserid);
- pgpVerifyAndDecryptByteArray.setPassword(keyPassword);
+ pgpVerifyAndDecryptByteArray.setPassphraseAccessor(passphraseAccessor);
pgpVerifyAndDecryptByteArray.setEncryptionKeyRing(getSecKeyRing());
- pgpVerifyAndDecryptByteArray.setSignatureKeyUserid(keyUserid);
pgpVerifyAndDecryptByteArray.setProvider(getProvider());
from("direct:sign-key-ring-byte-array")
@@ -208,6 +206,8 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
.removeHeader(PGPDataFormat.SIGNATURE_KEY_RING).to("mock:unencrypted");
// END SNIPPET: pgp-format-signature-key-ring-byte-array
}
+
+
};
}
@@ -226,5 +226,11 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
output.close();
return output.toByteArray();
}
+
+ public static PGPPassphraseAccessor getPassphraseAccessor() {
+ Map<String, String> userId2Passphrase = Collections.singletonMap("Super <sd...@nowhere.net>", "sdude");
+ PGPPassphraseAccessor passphraseAccessor = new PGPPassphraseAccessorDefault(userId2Passphrase);
+ return passphraseAccessor;
+ }
}
http://git-wip-us.apache.org/repos/asf/camel/blob/d8784008/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 38d8c39..fcc15ac 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
@@ -28,7 +28,7 @@
<pgp id="encrypt" keyFileName="org/apache/camel/component/crypto/pubring.gpg"
keyUserid="sdude@nowhere.net"/>
<pgp id="decrypt" keyFileName="org/apache/camel/component/crypto/secring.gpg"
- keyUserid="sdude@nowhere.net" password="sdude"/>
+ password="sdude"/>
</dataFormats>
<route>
@@ -56,20 +56,24 @@
<property name="algorithm" value="7"/> <!-- AES128 algorithm -->
</bean>
- <bean id="decryptBean" class="org.apache.camel.converter.crypto.PGPDataFormat">
- <property name="keyUserid" value="sdude@nowhere.net"/>
+ <bean id="decryptBean" class="org.apache.camel.converter.crypto.PGPDataFormat">
<property name="encryptionKeyRing" ref="secKeyRing"/>
- <property name="password" value="sdude"/>
+ <property name="passphraseAccessor" ref="passphraseAccessorBean"/>
</bean>
- <!-- bean represents the publik key ring as byte array -->
+ <!-- bean represents the public 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 represents the secret key ring as byte array -->
<bean id="secKeyRing"
class="org.apache.camel.converter.crypto.PGPDataFormatTest"
factory-method="getSecKeyRing" />
+
+ <!-- bean passphrase accessor -->
+ <bean id="passphraseAccessorBean"
+ class="org.apache.camel.converter.crypto.PGPDataFormatTest"
+ factory-method="getPassphraseAccessor" />
<!-- END SNIPPET: pgp-xml-data-format-bean-with-keyring-bytearray -->
</beans>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/d8784008/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/pubring.gpg
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/pubring.gpg b/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/pubring.gpg
index 4b3e405..21029c6 100644
Binary files a/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/pubring.gpg and b/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/pubring.gpg differ
http://git-wip-us.apache.org/repos/asf/camel/blob/d8784008/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/secring.gpg
----------------------------------------------------------------------
diff --git a/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/secring.gpg b/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/secring.gpg
index d631be3..36af553 100644
Binary files a/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/secring.gpg and b/components/camel-crypto/src/test/resources/org/apache/camel/component/crypto/secring.gpg differ
[2/2] git commit: CAMEL-6881 The XmlSignatureProcessor should support
other SecurityProvider
Posted by ni...@apache.org.
CAMEL-6881 The XmlSignatureProcessor should support other SecurityProvider
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/d1d4b81a
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/d1d4b81a
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/d1d4b81a
Branch: refs/heads/camel-2.12.x
Commit: d1d4b81a21c50f9227455c67c7fef5fe21476c4d
Parents: d878400
Author: Willem Jiang <ni...@apache.org>
Authored: Tue Oct 22 17:53:09 2013 +0800
Committer: Willem Jiang <wi...@gmail.com>
Committed: Tue Oct 22 18:11:01 2013 +0800
----------------------------------------------------------------------
.../xmlsecurity/processor/XmlSignatureProcessor.java | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/d1d4b81a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureProcessor.java b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureProcessor.java
index 9a6fd5c..c0e03d1 100644
--- a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureProcessor.java
+++ b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignatureProcessor.java
@@ -34,8 +34,13 @@ public abstract class XmlSignatureProcessor implements Processor {
private static final Logger LOG = LoggerFactory.getLogger(XmlSignatureProcessor.class);
static {
- SantuarioUtil.initializeSantuario();
- SantuarioUtil.addSantuarioJSR105Provider();
+ try {
+ SantuarioUtil.initializeSantuario();
+ SantuarioUtil.addSantuarioJSR105Provider();
+ } catch (Throwable t) {
+ // provider not in classpath, ignore and fall back to jre default
+ LOG.info("Cannot add the SantuarioJSR105Provider due to {0}, fall back to JRE default.", t);
+ }
}
public abstract XmlSignatureConfiguration getConfiguration();