From 061e1c929251c75da63e20a0b35eb7cbc310ffac Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Fri, 8 Jun 2018 15:29:09 +0200 Subject: [PATCH] Fix signature verification --- .../InputStreamFactory.java | 11 +++++----- .../SignatureVerifyingInputStream.java | 12 ++++++----- .../crypto/pgpainless/EncryptDecryptTest.java | 21 +++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/InputStreamFactory.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/InputStreamFactory.java index 72e6f541..98d5c13e 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/InputStreamFactory.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/InputStreamFactory.java @@ -37,8 +37,6 @@ import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; public class InputStreamFactory { - private InputStream inputStream; - private final PGPSecretKeyRingCollection decryptionKeys; private final SecretKeyRingProtector decryptionKeyDecryptor; private final Set verificationKeys = new HashSet<>(); @@ -47,6 +45,7 @@ public class InputStreamFactory { private final PainlessResult.Builder resultBuilder = PainlessResult.getBuilder(); private final PGPContentVerifierBuilderProvider verifierBuilderProvider = new BcPGPContentVerifierBuilderProvider(); + private final KeyFingerPrintCalculator fingerCalc = new BcKeyFingerprintCalculator(); private final Map verifiableOnePassSignatures = new HashMap<>(); private InputStreamFactory(PGPSecretKeyRingCollection decryptionKeys, @@ -85,9 +84,8 @@ public class InputStreamFactory { } private InputStream wrap(PGPObjectFactory objectFactory) throws IOException, PGPException { - KeyFingerPrintCalculator fingerCalc = new BcKeyFingerprintCalculator(); - Object pgpObj = null; + Object pgpObj; while ((pgpObj = objectFactory.nextObject()) != null) { if (pgpObj instanceof PGPEncryptedDataList) { @@ -107,7 +105,8 @@ public class InputStreamFactory { if (pgpObj instanceof PGPOnePassSignatureList) { PGPOnePassSignatureList onePassSignatures = (PGPOnePassSignatureList) pgpObj; - verify(onePassSignatures); + initOnePassSignatures(onePassSignatures); + return wrap(objectFactory); } if (pgpObj instanceof PGPLiteralData) { @@ -166,7 +165,7 @@ public class InputStreamFactory { return decryptionStream; } - private void verify(PGPOnePassSignatureList onePassSignatureList) throws PGPException { + private void initOnePassSignatures(PGPOnePassSignatureList onePassSignatureList) throws PGPException { Iterator iterator = onePassSignatureList.iterator(); if (!iterator.hasNext()) { throw new PGPException("Verification failed - No OnePassSignatures found!"); diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/SignatureVerifyingInputStream.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/SignatureVerifyingInputStream.java index e5469779..2a89b91c 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/SignatureVerifyingInputStream.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/SignatureVerifyingInputStream.java @@ -49,11 +49,12 @@ public class SignatureVerifyingInputStream extends FilterInputStream { try { PGPSignatureList signatureList = null; - Iterator objectIterator = objectFactory.iterator(); - while (objectIterator.hasNext() && signatureList == null) { - Object object = objectIterator.next(); - if (object instanceof PGPSignatureList) { - signatureList = (PGPSignatureList) object; + Object obj = objectFactory.nextObject(); + while (obj != null && signatureList == null) { + if (obj instanceof PGPSignatureList) { + signatureList = (PGPSignatureList) obj; + } else { + obj = objectFactory.nextObject(); } } @@ -70,6 +71,7 @@ public class SignatureVerifyingInputStream extends FilterInputStream { throw new SignatureException("Bad Signature of key " + signature.getKeyID()); } else { resultBuilder.addVerifiedSignatureKeyId(signature.getKeyID()); + onePassSignatures.remove(signature.getKeyID()); } } } catch (PGPException | SignatureException e) { diff --git a/src/test/java/de/vanitasvitae/crypto/pgpainless/EncryptDecryptTest.java b/src/test/java/de/vanitasvitae/crypto/pgpainless/EncryptDecryptTest.java index d8bab55c..d5fd8ddd 100644 --- a/src/test/java/de/vanitasvitae/crypto/pgpainless/EncryptDecryptTest.java +++ b/src/test/java/de/vanitasvitae/crypto/pgpainless/EncryptDecryptTest.java @@ -8,6 +8,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.Charset; import java.security.Security; import java.util.Arrays; import java.util.Collections; @@ -15,7 +16,6 @@ import java.util.Collections; import de.vanitasvitae.crypto.pgpainless.key.UnprotectedKeysProtector; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; @@ -38,7 +38,8 @@ public class EncryptDecryptTest { } @Test - public void test() throws IOException, PGPException { + public void test() throws Exception { + Security.addProvider(new BouncyCastleProvider()); PGPPublicKeyRing jPub = new PGPPublicKeyRing(PGPUtil.getDecoderStream(new ByteArrayInputStream(TestKeys.JULIET_PUB.getBytes())), new BcKeyFingerprintCalculator()); ByteArrayOutputStream toEncrypted = new ByteArrayOutputStream(); @@ -66,7 +67,8 @@ public class EncryptDecryptTest { .onInputStream(fromEncrypted) .decryptWith(new PGPSecretKeyRingCollection(Collections.singleton(juliet)), new UnprotectedKeysProtector()) - .doNotVerify() + .verifyWith(Collections.singleton(jPub.getPublicKey().getKeyID()), Collections.singleton(jPub)) + .ignoreMissingPublicKeys() .build(); InputStream decryptor = resultAndInputStream.getInputStream(); @@ -79,14 +81,8 @@ public class EncryptDecryptTest { assertTrue(Arrays.equals(message.getBytes(), toPlain.toByteArray())); } - public static void main(String[] args) throws IOException, PGPException { - Security.addProvider(new BouncyCastleProvider()); - EncryptDecryptTest test = new EncryptDecryptTest(); - test.decryptVerifyTest(); - } - @Test - public void decryptVerifyTest() throws IOException, PGPException { + public void decryptVerifyTest() throws Exception { String encryptedMessage = "-----BEGIN PGP MESSAGE-----\n" + "\n" + "hQGMAwAAAAAAAAAAAQwAoJtfpcBPCwhUzzHuVIcBzBLyfIWT/EJ527neb46lN56S\n" + @@ -137,6 +133,9 @@ public class EncryptDecryptTest { decryptor.close(); toPlain.close(); - assertTrue(Arrays.equals("This message is encrypted".getBytes(), toPlain.toByteArray())); + byte[] expected = "This message is encrypted\n".getBytes(Charset.forName("UTF-8")); + byte[] actual = toPlain.toByteArray(); + + assertTrue(Arrays.equals(expected, actual)); } }