Add logic for MissingPublicKeyCallback

This commit is contained in:
Paul Schaub 2018-07-02 20:46:27 +02:00
parent 07c689b556
commit 975b336699
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
4 changed files with 40 additions and 16 deletions

View File

@ -33,7 +33,7 @@ public class DecryptionBuilder implements DecryptionBuilderInterface {
private PGPSecretKeyRingCollection decryptionKeys;
private SecretKeyRingProtector decryptionKeyDecryptor;
private Set<PGPPublicKeyRing> 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<Long> trustedKeyIds,
PGPPublicKeyRingCollection publicKeyRingCollection) {
public HandleMissingPublicKeys verifyWith(Set<Long> trustedKeyIds,
PGPPublicKeyRingCollection publicKeyRingCollection) {
Set<PGPPublicKeyRing> publicKeyRings = new HashSet<>();
for (Iterator<PGPPublicKeyRing> i = publicKeyRingCollection.getKeyRings(); i.hasNext(); ) {
PGPPublicKeyRing p = i.next();
@ -74,9 +74,9 @@ public class DecryptionBuilder implements DecryptionBuilderInterface {
}
@Override
public MissingPublicKeyFeedback verifyWith(Set<PGPPublicKeyRing> publicKeyRings) {
public HandleMissingPublicKeys verifyWith(Set<PGPPublicKeyRing> 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();
}
}

View File

@ -39,17 +39,17 @@ public interface DecryptionBuilderInterface {
interface VerifyWith {
MissingPublicKeyFeedback verifyWith(Set<Long> trustedFingerprints, PGPPublicKeyRingCollection publicKeyRings);
HandleMissingPublicKeys verifyWith(Set<Long> trustedFingerprints, PGPPublicKeyRingCollection publicKeyRings);
MissingPublicKeyFeedback verifyWith(Set<PGPPublicKeyRing> publicKeyRings);
HandleMissingPublicKeys verifyWith(Set<PGPPublicKeyRing> publicKeyRings);
Build doNotVerify();
}
interface MissingPublicKeyFeedback {
interface HandleMissingPublicKeys {
Build handleMissingPublicKeysWith(MissingPublicKeyCallback callback);
Build handleMissingPublicKeysWith(org.pgpainless.pgpainless.decryption_verification.MissingPublicKeyCallback callback);
Build ignoreMissingPublicKeys();
}

View File

@ -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);
}
}
}

View File

@ -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);
}