From 5c3fa28946ec2ffe094e710b900f3fa8acbd4c5e Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Wed, 27 Oct 2021 13:09:39 +0200 Subject: [PATCH] Fix Kleopatra Interoperability The cause of this issue was that we skipped the first (proper) PKESK and instead tried to decrypt the wildcard PKESKs. Furthermore, we had an issue in MessageInspector which read past the PKESK packets --- .../DecryptionStreamFactory.java | 1 + .../decryption_verification/MessageInspector.java | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStreamFactory.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStreamFactory.java index 55ae284d..e2b2da54 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStreamFactory.java +++ b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStreamFactory.java @@ -343,6 +343,7 @@ public final class DecryptionStreamFactory { } decryptionKey = privateKey; encryptedSessionKey = publicKeyEncryptedData; + break; } // Try postponed keys with missing passphrases (will cause missing passphrase callbacks to fire) diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/MessageInspector.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/MessageInspector.java index 1b94f877..e8b04afb 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/MessageInspector.java +++ b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/MessageInspector.java @@ -19,6 +19,8 @@ import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; +import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.util.ArmorUtils; @@ -85,11 +87,12 @@ public final class MessageInspector { return info; } - private static void processMessage(InputStream dataIn, EncryptionInfo info) throws PGPException { - PGPObjectFactory objectFactory = new PGPObjectFactory(dataIn, - ImplementationFactory.getInstance().getKeyFingerprintCalculator()); + private static void processMessage(InputStream dataIn, EncryptionInfo info) throws PGPException, IOException { + KeyFingerPrintCalculator calculator = ImplementationFactory.getInstance().getKeyFingerprintCalculator(); + PGPObjectFactory objectFactory = new PGPObjectFactory(dataIn, calculator); - for (Object next : objectFactory) { + Object next; + while ((next = objectFactory.nextObject()) != null) { if (next instanceof PGPOnePassSignatureList) { PGPOnePassSignatureList signatures = (PGPOnePassSignatureList) next; if (!signatures.isEmpty()) { @@ -108,12 +111,14 @@ public final class MessageInspector { info.isPassphraseEncrypted = true; } } + // Data is encrypted, we cannot go deeper + return; } if (next instanceof PGPCompressedData) { PGPCompressedData compressed = (PGPCompressedData) next; InputStream decompressed = compressed.getDataStream(); - processMessage(decompressed, info); + objectFactory = new PGPObjectFactory(PGPUtil.getDecoderStream(decompressed), calculator); } if (next instanceof PGPLiteralData) {