You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by fo...@apache.org on 2015/09/24 16:43:59 UTC
camel git commit: CAMEL-9163: PGP Data Format: Support PGP Messages
without Compressed Data packet
Repository: camel
Updated Branches:
refs/for/master [created] ecbbeb74f
CAMEL-9163: PGP Data Format: Support PGP Messages without Compressed
Data packet
Change-Id: I6818cb2ee4777a7069a0760cae22c72074c63042
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/ecbbeb74
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/ecbbeb74
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/ecbbeb74
Branch: refs/for/master
Commit: ecbbeb74f753ce81995171fb5d25f58930c22d26
Parents: 92c4a81
Author: Franz Forsthofer <fr...@sap.com>
Authored: Thu Sep 24 16:28:27 2015 +0200
Committer: Franz Forsthofer <fr...@sap.com>
Committed: Thu Sep 24 16:30:32 2015 +0200
----------------------------------------------------------------------
.../converter/crypto/PGPDataFormatUtil.java | 4 +-
.../crypto/PGPKeyAccessDataFormat.java | 63 +++++++++++++-------
.../converter/crypto/PGPDataFormatTest.java | 60 +++++++++++++++----
3 files changed, 89 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/ecbbeb74/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 864337c..6f8f815 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
@@ -207,7 +207,6 @@ public final class PGPDataFormatUtil {
return findPublicKeys(userids, forEncryption, pgpSec);
}
- @SuppressWarnings("unchecked")
public static List<PGPPublicKey> findPublicKeys(List<String> useridParts, boolean forEncryption, PGPPublicKeyRingCollection pgpPublicKeyringCollection) {
List<PGPPublicKey> result = new ArrayList<PGPPublicKey>(useridParts.size());
for (Iterator<PGPPublicKeyRing> keyRingIter = pgpPublicKeyringCollection.getKeyRings(); keyRingIter.hasNext();) {
@@ -422,8 +421,7 @@ public final class PGPDataFormatUtil {
LOG.debug("User ID {} found in primary key with key ID {} containing one of the parts {}", new Object[] {
foundKeyUserIdForUserIdPart[0], primaryKey.getKeyID(), useridParts });
// add all signing keys
- for (@SuppressWarnings("unchecked")
- Iterator<PGPSecretKey> iterKey = keyring.getSecretKeys(); iterKey.hasNext();) {
+ for (Iterator<PGPSecretKey> iterKey = keyring.getSecretKeys(); iterKey.hasNext();) {
PGPSecretKey secKey = iterKey.next();
if (isSigningKey(secKey)) {
PGPPrivateKey privateKey = secKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(provider)
http://git-wip-us.apache.org/repos/asf/camel/blob/ecbbeb74/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 88c0261..0d521a8 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
@@ -80,6 +80,8 @@ import org.slf4j.LoggerFactory;
*/
public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat {
+ private static final Logger log = LoggerFactory.getLogger(PGPKeyAccessDataFormat.class);
+
public static final String KEY_USERID = "CamelPGPDataFormatKeyUserid";
public static final String KEY_USERIDS = "CamelPGPDataFormatKeyUserids";
public static final String SIGNATURE_KEY_USERID = "CamelPGPDataFormatSignatureKeyUserid";
@@ -163,6 +165,8 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
private int algorithm = SymmetricKeyAlgorithmTags.CAST5; // for encryption
private int compressionAlgorithm = CompressionAlgorithmTags.ZIP; // for encryption
+
+ private boolean withCompressedDataPacket = true; // for encryption
private String signatureVerificationOption = "optional";
@@ -210,7 +214,7 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
return exchange.getIn().getHeader(Exchange.FILE_NAME, getFileName(), String.class);
}
- public void marshal(Exchange exchange, Object graph, OutputStream outputStream) throws Exception {
+ public void marshal(Exchange exchange, Object graph, OutputStream outputStream) throws Exception { //NOPMD
List<String> userids = determineEncryptionUserIds(exchange);
List<PGPPublicKey> keys = publicKeyAccessor.getEncryptionKeys(exchange, userids);
if (keys.isEmpty()) {
@@ -233,9 +237,15 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
}
OutputStream encOut = encGen.open(outputStream, new byte[BUFFER_SIZE]);
- PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(findCompressionAlgorithm(exchange));
- OutputStream comOut = new BufferedOutputStream(comData.open(encOut));
-
+ OutputStream comOut;
+ if (withCompressedDataPacket) {
+ PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(findCompressionAlgorithm(exchange));
+ comOut = new BufferedOutputStream(comData.open(encOut));
+ } else {
+ comOut = encOut;
+ LOG.debug("No Compressed Data packet is added");
+ }
+
List<PGPSignatureGenerator> sigGens = createSignatureGenerator(exchange, comOut);
PGPLiteralDataGenerator litData = new PGPLiteralDataGenerator();
@@ -311,7 +321,7 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
return result;
}
- protected List<PGPSignatureGenerator> createSignatureGenerator(Exchange exchange, OutputStream out) throws Exception {
+ protected List<PGPSignatureGenerator> createSignatureGenerator(Exchange exchange, OutputStream out) throws Exception { //NOPMD
if (secretKeyAccessor == null) {
return null;
@@ -345,7 +355,7 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
}
@SuppressWarnings("resource")
- public Object unmarshal(Exchange exchange, InputStream encryptedStream) throws Exception {
+ public Object unmarshal(Exchange exchange, InputStream encryptedStream) throws Exception { //NOPMD
if (encryptedStream == null) {
return null;
}
@@ -361,10 +371,16 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
try {
in = PGPUtil.getDecoderStream(encryptedStream);
encData = getDecryptedData(exchange, in);
- uncompressedData = getUncompressedData(encData);
- PGPObjectFactory pgpFactory = new PGPObjectFactory(uncompressedData, new BcKeyFingerprintCalculator());
+ PGPObjectFactory pgpFactory = new PGPObjectFactory(encData, new BcKeyFingerprintCalculator());
Object object = pgpFactory.nextObject();
-
+ if (object instanceof PGPCompressedData) {
+ PGPCompressedData comData = (PGPCompressedData) object;
+ uncompressedData = comData.getDataStream();
+ pgpFactory = new PGPObjectFactory(uncompressedData, new BcKeyFingerprintCalculator());
+ object = pgpFactory.nextObject();
+ } else {
+ log.debug("PGP Message does not contain a Compressed Data Packet");
+ }
PGPOnePassSignature signature;
if (object instanceof PGPOnePassSignatureList) {
signature = getSignature(exchange, (PGPOnePassSignatureList) object);
@@ -418,17 +434,6 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
}
}
- private InputStream getUncompressedData(InputStream encData) throws IOException, PGPException {
- PGPObjectFactory pgpFactory = new PGPObjectFactory(encData, new BcKeyFingerprintCalculator());
- Object compObj = pgpFactory.nextObject();
- if (!(compObj instanceof PGPCompressedData)) {
- throw getFormatException();
- }
- PGPCompressedData comData = (PGPCompressedData) compObj;
- InputStream uncompressedData = comData.getDataStream();
- return uncompressedData;
- }
-
private InputStream getDecryptedData(Exchange exchange, InputStream encryptedStream) throws Exception, PGPException {
PGPObjectFactory pgpFactory = new PGPObjectFactory(encryptedStream, new BcKeyFingerprintCalculator());
Object firstObject = pgpFactory.nextObject();
@@ -489,7 +494,7 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
return new IllegalArgumentException(
"The input message body has an invalid format. The PGP decryption/verification processor expects a sequence of PGP packets of the form "
+ "(entries in brackets are optional and ellipses indicate repetition, comma represents sequential composition, and vertical bar separates alternatives): "
- + "Public Key Encrypted Session Key ..., Symmetrically Encrypted Data | Sym. Encrypted and Integrity Protected Data, Compressed Data, (One Pass Signature ...,) "
+ + "Public Key Encrypted Session Key ..., Symmetrically Encrypted Data | Sym. Encrypted and Integrity Protected Data, (Compressed Data,) (One Pass Signature ...,) "
+ "Literal Data, (Signature ...,)");
}
@@ -709,6 +714,18 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
return signatureVerificationOption;
}
+ public boolean isWithCompressedDataPacket() {
+ return withCompressedDataPacket;
+ }
+
+ /** Indicator that Compressed Data packet shall be added during encryption.
+ * The default value is true.
+ * If <tt>false</tt> then the compression algorithm (see {@link #setCompressionAlgorithm(int)} is ignored.
+ */
+ public void setWithCompressedDataPacket(boolean withCompressedDataPacket) {
+ this.withCompressedDataPacket = withCompressedDataPacket;
+ }
+
/**
* Signature verification option. Controls the behavior for the signature
* verification during unmarshaling. Possible values are
@@ -762,7 +779,7 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
}
@Override
- protected void doStart() throws Exception {
+ protected void doStart() throws Exception { //NOPMD
if (Security.getProvider(BC) == null && BC.equals(getProvider())) {
LOG.debug("Adding BouncyCastleProvider as security provider");
Security.addProvider(new BouncyCastleProvider());
@@ -772,7 +789,7 @@ public class PGPKeyAccessDataFormat extends ServiceSupport implements DataFormat
}
@Override
- protected void doStop() throws Exception {
+ protected void doStop() throws Exception { //NOPMD
// noop
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/ecbbeb74/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 f24d40e..565496b 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
@@ -298,17 +298,19 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
}
@Test
- public void testExceptionDecryptorIncorrectInputNoCompression() throws Exception {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
- createEncryptedNonCompressedData(bos, PUB_KEY_RING_SUBKEYS_FILE_NAME);
-
- MockEndpoint mock = getMockEndpoint("mock:exception");
- mock.expectedMessageCount(1);
- template.sendBody("direct:subkeyUnmarshal", bos.toByteArray());
- assertMockEndpointsSatisfied();
-
- checkThrownException(mock, IllegalArgumentException.class, null, "The input message body has an invalid format.");
+ public void testEncryptSignWithoutCompressedDataPacket() throws Exception {
+
+ doRoundTripEncryptionTests("direct:encrypt-sign-without-compressed-data-packet");
+// ByteArrayOutputStream bos = new ByteArrayOutputStream();
+//
+//// createEncryptedNonCompressedData(bos, PUB_KEY_RING_SUBKEYS_FILE_NAME);
+//
+// MockEndpoint mock = getMockEndpoint("mock:exception");
+// mock.expectedMessageCount(1);
+// template.sendBody("direct:encrypt-sign-without-compressed-data-packet", bos.toByteArray());
+// assertMockEndpointsSatisfied();
+//
+// //checkThrownException(mock, IllegalArgumentException.class, null, "The input message body has an invalid format.");
}
@Test
@@ -710,7 +712,41 @@ public class PGPDataFormatTest extends AbstractPGPDataFormatTest {
.to("mock:unencrypted");
}
- } };
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+
+ // START SNIPPET: pgp-encrypt-sign-without-compressed-data-packet
+ PGPDataFormat pgpEncryptSign = new PGPDataFormat();
+ pgpEncryptSign.setKeyUserid(getKeyUserId());
+ pgpEncryptSign.setSignatureKeyRing(getSecKeyRing());
+ pgpEncryptSign.setSignatureKeyUserid(getKeyUserId());
+ pgpEncryptSign.setSignaturePassword(getKeyPassword());
+ pgpEncryptSign.setProvider(getProvider());
+ pgpEncryptSign.setAlgorithm(SymmetricKeyAlgorithmTags.BLOWFISH);
+ pgpEncryptSign.setHashAlgorithm(HashAlgorithmTags.RIPEMD160);
+ // without compressed data packet
+ pgpEncryptSign.setWithCompressedDataPacket(false);
+
+ PGPDataFormat pgpVerifyAndDecryptByteArray = new PGPDataFormat();
+ pgpVerifyAndDecryptByteArray.setPassphraseAccessor(getPassphraseAccessor());
+ pgpVerifyAndDecryptByteArray.setEncryptionKeyRing(getSecKeyRing());
+ pgpVerifyAndDecryptByteArray.setProvider(getProvider());
+ // restrict verification to public keys with certain User ID
+ pgpVerifyAndDecryptByteArray.setSignatureKeyUserids(getSignatureKeyUserIds());
+ pgpVerifyAndDecryptByteArray.setSignatureVerificationOption(PGPKeyAccessDataFormat.SIGNATURE_VERIFICATION_OPTION_REQUIRED);
+
+ from("direct:encrypt-sign-without-compressed-data-packet").streamCaching()
+ // encryption key ring can also be set as header
+ .setHeader(PGPDataFormat.ENCRYPTION_KEY_RING).constant(getPublicKeyRing()).marshal(pgpEncryptSign)
+ // it is recommended to remove the header immediately when it is no longer needed
+ .removeHeader(PGPDataFormat.ENCRYPTION_KEY_RING).to("mock:encrypted")
+ // signature key ring can also be set as header
+ .setHeader(PGPDataFormat.SIGNATURE_KEY_RING).constant(getPublicKeyRing()).unmarshal(pgpVerifyAndDecryptByteArray)
+ // it is recommended to remove the header immediately when it is no longer needed
+ .removeHeader(PGPDataFormat.SIGNATURE_KEY_RING).to("mock:unencrypted");
+ // END SNIPPET: pgp-encrypt-sign-without-compressed-data-packet
+ }
+ }};
}
public static byte[] getPublicKeyRing() throws Exception {