From 975b336699ac73b14cd845a74c773803c7b277f6 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Mon, 2 Jul 2018 20:46:27 +0200 Subject: [PATCH] Add logic for MissingPublicKeyCallback --- .../DecryptionBuilder.java | 15 +++++----- .../DecryptionBuilderInterface.java | 8 ++--- .../DecryptionStreamFactory.java | 29 ++++++++++++++++--- .../MissingPublicKeyCallback.java | 4 ++- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionBuilder.java b/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionBuilder.java index 4e62f74b..5ada109f 100644 --- a/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionBuilder.java +++ b/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionBuilder.java @@ -33,7 +33,7 @@ public class DecryptionBuilder implements DecryptionBuilderInterface { private PGPSecretKeyRingCollection decryptionKeys; private SecretKeyRingProtector decryptionKeyDecryptor; private Set verificationKeys = new HashSet<>(); - private MissingPublicKeyCallback missingPublicKeyCallback = null; + private org.pgpainless.pgpainless.decryption_verification.MissingPublicKeyCallback missingPublicKeyCallback = null; @Override public DecryptWith onInputStream(InputStream inputStream) { @@ -61,8 +61,8 @@ public class DecryptionBuilder implements DecryptionBuilderInterface { class VerifyWithImpl implements VerifyWith { @Override - public MissingPublicKeyFeedback verifyWith(Set trustedKeyIds, - PGPPublicKeyRingCollection publicKeyRingCollection) { + public HandleMissingPublicKeys verifyWith(Set trustedKeyIds, + PGPPublicKeyRingCollection publicKeyRingCollection) { Set publicKeyRings = new HashSet<>(); for (Iterator i = publicKeyRingCollection.getKeyRings(); i.hasNext(); ) { PGPPublicKeyRing p = i.next(); @@ -74,9 +74,9 @@ public class DecryptionBuilder implements DecryptionBuilderInterface { } @Override - public MissingPublicKeyFeedback verifyWith(Set publicKeyRings) { + public HandleMissingPublicKeys verifyWith(Set publicKeyRings) { DecryptionBuilder.this.verificationKeys = publicKeyRings; - return new MissingPublicKeyFeedbackImpl(); + return new HandleMissingPublicKeysImpl(); } @Override @@ -86,16 +86,17 @@ public class DecryptionBuilder implements DecryptionBuilderInterface { } } - class MissingPublicKeyFeedbackImpl implements MissingPublicKeyFeedback { + class HandleMissingPublicKeysImpl implements HandleMissingPublicKeys { @Override - public Build handleMissingPublicKeysWith(MissingPublicKeyCallback callback) { + public Build handleMissingPublicKeysWith(org.pgpainless.pgpainless.decryption_verification.MissingPublicKeyCallback callback) { DecryptionBuilder.this.missingPublicKeyCallback = callback; return new BuildImpl(); } @Override public Build ignoreMissingPublicKeys() { + DecryptionBuilder.this.missingPublicKeyCallback = null; return new BuildImpl(); } } diff --git a/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionBuilderInterface.java b/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionBuilderInterface.java index af1bb9bf..2339c53c 100644 --- a/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionBuilderInterface.java +++ b/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionBuilderInterface.java @@ -39,17 +39,17 @@ public interface DecryptionBuilderInterface { interface VerifyWith { - MissingPublicKeyFeedback verifyWith(Set trustedFingerprints, PGPPublicKeyRingCollection publicKeyRings); + HandleMissingPublicKeys verifyWith(Set trustedFingerprints, PGPPublicKeyRingCollection publicKeyRings); - MissingPublicKeyFeedback verifyWith(Set publicKeyRings); + HandleMissingPublicKeys verifyWith(Set publicKeyRings); Build doNotVerify(); } - interface MissingPublicKeyFeedback { + interface HandleMissingPublicKeys { - Build handleMissingPublicKeysWith(MissingPublicKeyCallback callback); + Build handleMissingPublicKeysWith(org.pgpainless.pgpainless.decryption_verification.MissingPublicKeyCallback callback); Build ignoreMissingPublicKeys(); } diff --git a/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionStreamFactory.java b/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionStreamFactory.java index 96004fd4..f9d07d2b 100644 --- a/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionStreamFactory.java +++ b/src/main/java/org/pgpainless/pgpainless/decryption_verification/DecryptionStreamFactory.java @@ -197,7 +197,7 @@ public class DecryptionStreamFactory { while (iterator.hasNext()) { PGPOnePassSignature signature = iterator.next(); - long keyId = signature.getKeyID(); + final long keyId = signature.getKeyID(); resultBuilder.addSignatureKeyId(keyId); LOGGER.log(LEVEL, "Message contains OnePassSignature from " + Long.toHexString(keyId)); @@ -212,10 +212,31 @@ public class DecryptionStreamFactory { } } - if (verificationKey != null) { - signature.init(verifierBuilderProvider, verificationKey); - verifiableOnePassSignatures.put(signature.getKeyID(), signature); + if (verificationKey == null) { + LOGGER.log(Level.INFO, "No public key for signature of " + Long.toHexString(keyId) + " found."); + + if (missingPublicKeyCallback == null) { + LOGGER.log(Level.INFO, "Skip signature of " + Long.toHexString(keyId)); + continue; + } + + PGPPublicKey missingPublicKey = missingPublicKeyCallback.onMissingPublicKeyEncountered(keyId); + if (missingPublicKey == null) { + LOGGER.log(Level.INFO, "Skip signature of " + Long.toHexString(keyId)); + continue; + } + + if (missingPublicKey.getKeyID() != keyId) { + throw new IllegalArgumentException("KeyID of the provided public key differs from the signatures keyId. " + + "The signature was created from " + Long.toHexString(keyId) + " while the provided key has ID " + + Long.toHexString(missingPublicKey.getKeyID())); + } + + verificationKey = missingPublicKey; } + + signature.init(verifierBuilderProvider, verificationKey); + verifiableOnePassSignatures.put(keyId, signature); } } } diff --git a/src/main/java/org/pgpainless/pgpainless/decryption_verification/MissingPublicKeyCallback.java b/src/main/java/org/pgpainless/pgpainless/decryption_verification/MissingPublicKeyCallback.java index 10ccf907..881ac9c9 100644 --- a/src/main/java/org/pgpainless/pgpainless/decryption_verification/MissingPublicKeyCallback.java +++ b/src/main/java/org/pgpainless/pgpainless/decryption_verification/MissingPublicKeyCallback.java @@ -15,8 +15,10 @@ */ package org.pgpainless.pgpainless.decryption_verification; +import org.bouncycastle.openpgp.PGPPublicKey; + public interface MissingPublicKeyCallback { - void onMissingPublicKeyEncountered(Long keyId); + PGPPublicKey onMissingPublicKeyEncountered(Long keyId); }