mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-12-10 22:31:09 +01:00
Fix detection of signed messages when verification keys are missing
Fixes #187, supersedes #189
This commit is contained in:
parent
0c122c1643
commit
33f516efe8
2 changed files with 67 additions and 3 deletions
|
|
@ -9,8 +9,10 @@ import java.io.EOFException;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
|
@ -45,6 +47,7 @@ import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
|||
import org.pgpainless.exception.MessageNotIntegrityProtectedException;
|
||||
import org.pgpainless.exception.MissingDecryptionMethodException;
|
||||
import org.pgpainless.exception.MissingLiteralDataException;
|
||||
import org.pgpainless.exception.SignatureValidationException;
|
||||
import org.pgpainless.exception.UnacceptableAlgorithmException;
|
||||
import org.pgpainless.exception.WrongConsumingMethodException;
|
||||
import org.pgpainless.implementation.ImplementationFactory;
|
||||
|
|
@ -71,6 +74,7 @@ public final class DecryptionStreamFactory {
|
|||
private final OpenPgpMetadata.Builder resultBuilder = OpenPgpMetadata.getBuilder();
|
||||
private final List<OnePassSignatureCheck> onePassSignatureChecks = new ArrayList<>();
|
||||
private final List<DetachedSignatureCheck> detachedSignatureChecks = new ArrayList<>();
|
||||
private final Map<Long, OnePassSignatureCheck> onePassSignaturesWithMissingCert = new HashMap<>();
|
||||
|
||||
private static final PGPContentVerifierBuilderProvider verifierBuilderProvider =
|
||||
ImplementationFactory.getInstance().getPGPContentVerifierBuilderProvider();
|
||||
|
|
@ -96,6 +100,8 @@ public final class DecryptionStreamFactory {
|
|||
long issuerKeyId = SignatureUtils.determineIssuerKeyId(signature);
|
||||
PGPPublicKeyRing signingKeyRing = findSignatureVerificationKeyRing(issuerKeyId);
|
||||
if (signingKeyRing == null) {
|
||||
SignatureValidationException ex = new SignatureValidationException("Missing verification certificate " + Long.toHexString(issuerKeyId));
|
||||
resultBuilder.addInvalidDetachedSignature(new SignatureVerification(signature, null), ex);
|
||||
continue;
|
||||
}
|
||||
PGPPublicKey signingKey = signingKeyRing.getPublicKey(issuerKeyId);
|
||||
|
|
@ -105,7 +111,8 @@ public final class DecryptionStreamFactory {
|
|||
DetachedSignatureCheck detachedSignature = new DetachedSignatureCheck(signature, signingKeyRing, signingKeyIdentifier);
|
||||
detachedSignatureChecks.add(detachedSignature);
|
||||
} catch (PGPException e) {
|
||||
LOGGER.warn("Cannot verify detached signature made by {}. Reason: {}", signingKeyIdentifier, e.getMessage(), e);
|
||||
SignatureValidationException ex = new SignatureValidationException("Cannot verify detached signature made by " + signingKeyIdentifier + ".", e);
|
||||
resultBuilder.addInvalidDetachedSignature(new SignatureVerification(signature, signingKeyIdentifier), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -223,7 +230,7 @@ public final class DecryptionStreamFactory {
|
|||
.setModificationDate(pgpLiteralData.getModificationTime())
|
||||
.setFileEncoding(StreamEncoding.fromCode(pgpLiteralData.getFormat()));
|
||||
|
||||
if (onePassSignatureChecks.isEmpty()) {
|
||||
if (onePassSignatureChecks.isEmpty() && onePassSignaturesWithMissingCert.isEmpty()) {
|
||||
LOGGER.debug("No OnePassSignatures found -> We are done");
|
||||
return literalDataInputStream;
|
||||
}
|
||||
|
|
@ -237,6 +244,16 @@ public final class DecryptionStreamFactory {
|
|||
onePassSignatureChecks.get(i).setSignature(signatureList.get(reversedIndex));
|
||||
}
|
||||
|
||||
for (PGPSignature signature : signatureList) {
|
||||
if (onePassSignaturesWithMissingCert.containsKey(signature.getKeyID())) {
|
||||
OnePassSignatureCheck check = onePassSignaturesWithMissingCert.remove(signature.getKeyID());
|
||||
check.setSignature(signature);
|
||||
|
||||
resultBuilder.addInvalidInbandSignature(new SignatureVerification(signature, null),
|
||||
new SignatureValidationException("Missing verification certificate " + Long.toHexString(signature.getKeyID())));
|
||||
}
|
||||
}
|
||||
|
||||
return new SignatureInputStream.VerifySignatures(literalDataInputStream,
|
||||
onePassSignatureChecks, detachedSignatureChecks, options, resultBuilder) {
|
||||
};
|
||||
|
|
@ -488,7 +505,7 @@ public final class DecryptionStreamFactory {
|
|||
// Find public key
|
||||
PGPPublicKeyRing verificationKeyRing = findSignatureVerificationKeyRing(keyId);
|
||||
if (verificationKeyRing == null) {
|
||||
LOGGER.debug("Missing verification key from {}", Long.toHexString(keyId));
|
||||
onePassSignaturesWithMissingCert.put(keyId, new OnePassSignatureCheck(signature, null));
|
||||
return;
|
||||
}
|
||||
PGPPublicKey verificationKey = verificationKeyRing.getPublicKey(keyId);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue