1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-16 17:32:06 +01:00

Add detailled logging to OpenPgpMessageInputStream

This commit is contained in:
Paul Schaub 2022-10-20 19:35:50 +02:00
parent bc75b3bb9a
commit 380dcf3f65
3 changed files with 82 additions and 19 deletions

View file

@ -59,6 +59,7 @@ import org.pgpainless.key.SubkeyIdentifier;
import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.info.KeyRingInfo;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
import org.pgpainless.key.util.KeyIdUtil;
import org.pgpainless.policy.Policy; import org.pgpainless.policy.Policy;
import org.pgpainless.signature.SignatureUtils; import org.pgpainless.signature.SignatureUtils;
import org.pgpainless.signature.consumer.OnePassSignatureCheck; import org.pgpainless.signature.consumer.OnePassSignatureCheck;
@ -234,6 +235,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
// Marker Packets need to be skipped and ignored // Marker Packets need to be skipped and ignored
case MARKER: case MARKER:
LOGGER.debug("Skipping Marker Packet");
packetInputStream.readMarker(); packetInputStream.readMarker();
break; break;
@ -263,6 +265,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
} }
private void processLiteralData() throws IOException { private void processLiteralData() throws IOException {
LOGGER.debug("Literal Data Packet at depth " + metadata.depth + " encountered");
automaton.next(InputAlphabet.LiteralData); automaton.next(InputAlphabet.LiteralData);
PGPLiteralData literalData = packetInputStream.readLiteralData(); PGPLiteralData literalData = packetInputStream.readLiteralData();
this.metadata.setChild(new MessageMetadata.LiteralData( this.metadata.setChild(new MessageMetadata.LiteralData(
@ -279,6 +282,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
MessageMetadata.CompressedData compressionLayer = new MessageMetadata.CompressedData( MessageMetadata.CompressedData compressionLayer = new MessageMetadata.CompressedData(
CompressionAlgorithm.fromId(compressedData.getAlgorithm()), CompressionAlgorithm.fromId(compressedData.getAlgorithm()),
metadata.depth + 1); metadata.depth + 1);
LOGGER.debug("Compressed Data Packet (" + compressionLayer.algorithm + ") at depth " + metadata.depth + " encountered");
InputStream decompressed = compressedData.getDataStream(); InputStream decompressed = compressedData.getDataStream();
nestedInputStream = new OpenPgpMessageInputStream(buffer(decompressed), options, compressionLayer, policy); nestedInputStream = new OpenPgpMessageInputStream(buffer(decompressed), options, compressionLayer, policy);
} }
@ -286,6 +290,8 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
private void processOnePassSignature() throws PGPException, IOException { private void processOnePassSignature() throws PGPException, IOException {
automaton.next(InputAlphabet.OnePassSignature); automaton.next(InputAlphabet.OnePassSignature);
PGPOnePassSignature onePassSignature = packetInputStream.readOnePassSignature(); PGPOnePassSignature onePassSignature = packetInputStream.readOnePassSignature();
LOGGER.debug("One-Pass-Signature Packet by key " + KeyIdUtil.formatKeyId(onePassSignature.getKeyID()) +
"at depth " + metadata.depth + " encountered");
signatures.addOnePassSignature(onePassSignature); signatures.addOnePassSignature(onePassSignature);
} }
@ -294,42 +300,59 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
boolean isSigForOPS = automaton.peekStack() == StackAlphabet.ops; boolean isSigForOPS = automaton.peekStack() == StackAlphabet.ops;
automaton.next(InputAlphabet.Signature); automaton.next(InputAlphabet.Signature);
PGPSignature signature = packetInputStream.readSignature(); PGPSignature signature = packetInputStream.readSignature();
long keyId = SignatureUtils.determineIssuerKeyId(signature);
if (isSigForOPS) { if (isSigForOPS) {
LOGGER.debug("Signature Packet corresponding to One-Pass-Signature by key " +
KeyIdUtil.formatKeyId(keyId) +
" at depth " + metadata.depth + " encountered");
signatures.leaveNesting(); // TODO: Only leave nesting if all OPSs of the nesting layer are dealt with signatures.leaveNesting(); // TODO: Only leave nesting if all OPSs of the nesting layer are dealt with
signatures.addCorrespondingOnePassSignature(signature, metadata, policy); signatures.addCorrespondingOnePassSignature(signature, metadata, policy);
} else { } else {
LOGGER.debug("Prepended Signature Packet by key " +
KeyIdUtil.formatKeyId(keyId) +
" at depth " + metadata.depth + " encountered");
signatures.addPrependedSignature(signature); signatures.addPrependedSignature(signature);
} }
} }
private boolean processEncryptedData() throws IOException, PGPException { private boolean processEncryptedData() throws IOException, PGPException {
LOGGER.debug("Symmetrically Encrypted Data Packet at depth " + metadata.depth + " encountered");
automaton.next(InputAlphabet.EncryptedData); automaton.next(InputAlphabet.EncryptedData);
PGPEncryptedDataList encDataList = packetInputStream.readEncryptedDataList(); PGPEncryptedDataList encDataList = packetInputStream.readEncryptedDataList();
// TODO: Replace with !encDataList.isIntegrityProtected() // TODO: Replace with !encDataList.isIntegrityProtected()
// once BC ships it // once BC ships it
if (!encDataList.get(0).isIntegrityProtected()) { if (!encDataList.get(0).isIntegrityProtected()) {
LOGGER.debug("Symmetrically Encrypted Data Packet is not integrity-protected and is therefore rejected.");
throw new MessageNotIntegrityProtectedException(); throw new MessageNotIntegrityProtectedException();
} }
SortedESKs esks = new SortedESKs(encDataList); SortedESKs esks = new SortedESKs(encDataList);
LOGGER.debug("Symmetrically Encrypted Integrity-Protected Data has " +
esks.skesks.size() + " SKESK(s) and " +
(esks.pkesks.size() + esks.anonPkesks.size()) + " PKESK(s) from which " +
esks.anonPkesks.size() + " PKESK(s) have an anonymous recipient");
// Try custom decryptor factory // Try custom decryptor factories
for (SubkeyIdentifier subkeyIdentifier : options.getCustomDecryptorFactories().keySet()) { for (SubkeyIdentifier subkeyIdentifier : options.getCustomDecryptorFactories().keySet()) {
LOGGER.debug("Attempt decryption with custom decryptor factory with key " + subkeyIdentifier);
PublicKeyDataDecryptorFactory decryptorFactory = options.getCustomDecryptorFactories().get(subkeyIdentifier); PublicKeyDataDecryptorFactory decryptorFactory = options.getCustomDecryptorFactories().get(subkeyIdentifier);
for (PGPPublicKeyEncryptedData pkesk : esks.pkesks) { for (PGPPublicKeyEncryptedData pkesk : esks.pkesks) {
// find matching PKESK
if (pkesk.getKeyID() != subkeyIdentifier.getSubkeyId()) { if (pkesk.getKeyID() != subkeyIdentifier.getSubkeyId()) {
continue; continue;
} }
// attempt decryption
if (decryptPKESKAndStream(subkeyIdentifier, decryptorFactory, pkesk)) { if (decryptPKESKAndStream(subkeyIdentifier, decryptorFactory, pkesk)) {
return true; return true;
} }
} }
} }
// Try session key // Try provided session key
if (options.getSessionKey() != null) { if (options.getSessionKey() != null) {
LOGGER.debug("Attempt decryption with provided session key");
SessionKey sessionKey = options.getSessionKey(); SessionKey sessionKey = options.getSessionKey();
throwIfUnacceptable(sessionKey.getAlgorithm()); throwIfUnacceptable(sessionKey.getAlgorithm());
@ -340,6 +363,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
try { try {
// TODO: Use BCs new API once shipped // TODO: Use BCs new API once shipped
// see https://github.com/bcgit/bc-java/pull/1228 (discussion)
PGPEncryptedData esk = esks.all().get(0); PGPEncryptedData esk = esks.all().get(0);
if (esk instanceof PGPPBEEncryptedData) { if (esk instanceof PGPPBEEncryptedData) {
PGPPBEEncryptedData skesk = (PGPPBEEncryptedData) esk; PGPPBEEncryptedData skesk = (PGPPBEEncryptedData) esk;
@ -347,6 +371,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
encryptedData.sessionKey = sessionKey; encryptedData.sessionKey = sessionKey;
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, skesk, options); IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, skesk, options);
nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy); nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy);
LOGGER.debug("Successfully decrypted data with provided session key");
return true; return true;
} else if (esk instanceof PGPPublicKeyEncryptedData) { } else if (esk instanceof PGPPublicKeyEncryptedData) {
PGPPublicKeyEncryptedData pkesk = (PGPPublicKeyEncryptedData) esk; PGPPublicKeyEncryptedData pkesk = (PGPPublicKeyEncryptedData) esk;
@ -354,20 +379,29 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
encryptedData.sessionKey = sessionKey; encryptedData.sessionKey = sessionKey;
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, pkesk, options); IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, pkesk, options);
nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy); nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy);
LOGGER.debug("Successfully decrypted data with provided session key");
return true; return true;
} else { } else {
throw new RuntimeException("Unknown ESK class type: " + esk.getClass().getName()); throw new RuntimeException("Unknown ESK class type: " + esk.getClass().getName());
} }
} catch (PGPException e) { } catch (PGPException e) {
// Session key mismatch? // Session key mismatch?
LOGGER.debug("Decryption using provided session key failed. Mismatched session key and message?", e);
} }
} }
// Try passwords // Try passwords
for (PGPPBEEncryptedData skesk : esks.skesks) { for (Passphrase passphrase : options.getDecryptionPassphrases()) {
SymmetricKeyAlgorithm kekAlgorithm = SymmetricKeyAlgorithm.requireFromId(skesk.getAlgorithm()); for (PGPPBEEncryptedData skesk : esks.skesks) {
throwIfUnacceptable(kekAlgorithm); LOGGER.debug("Attempt decryption with provided passphrase");
for (Passphrase passphrase : options.getDecryptionPassphrases()) { SymmetricKeyAlgorithm kekAlgorithm = SymmetricKeyAlgorithm.requireFromId(skesk.getAlgorithm());
try {
throwIfUnacceptable(kekAlgorithm);
} catch (UnacceptableAlgorithmException e) {
LOGGER.debug("Skipping SKESK with unacceptable encapsulation algorithm", e);
continue;
}
PBEDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance() PBEDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPBEDataDecryptorFactory(passphrase); .getPBEDataDecryptorFactory(passphrase);
@ -381,22 +415,25 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
// Try (known) secret keys // Try (known) secret keys
for (PGPPublicKeyEncryptedData pkesk : esks.pkesks) { for (PGPPublicKeyEncryptedData pkesk : esks.pkesks) {
long keyId = pkesk.getKeyID(); long keyId = pkesk.getKeyID();
LOGGER.debug("Encountered PKESK with recipient " + KeyIdUtil.formatKeyId(keyId));
PGPSecretKeyRing decryptionKeys = getDecryptionKey(keyId); PGPSecretKeyRing decryptionKeys = getDecryptionKey(keyId);
if (decryptionKeys == null) { if (decryptionKeys == null) {
LOGGER.debug("Skipping PKESK because no matching key " + KeyIdUtil.formatKeyId(keyId) + " was provided");
continue; continue;
} }
PGPSecretKey secretKey = decryptionKeys.getSecretKey(keyId); PGPSecretKey secretKey = decryptionKeys.getSecretKey(keyId);
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKeys, secretKey.getKeyID());
LOGGER.debug("Attempt decryption using secret key " + decryptionKeyId);
SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKeys); SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKeys);
// Postpone keys with missing passphrase // Postpone keys with missing passphrase
if (!protector.hasPassphraseFor(keyId)) { if (!protector.hasPassphraseFor(keyId)) {
LOGGER.debug("Missing passphrase for key " + decryptionKeyId + ". Postponing decryption until all other keys were tried");
postponedDueToMissingPassphrase.add(new Tuple<>(secretKey, pkesk)); postponedDueToMissingPassphrase.add(new Tuple<>(secretKey, pkesk));
continue; continue;
} }
PGPSecretKey decryptionKey = decryptionKeys.getSecretKey(keyId); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector);
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKeys, decryptionKey.getKeyID());
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(decryptionKey, protector);
PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance() PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPublicKeyDataDecryptorFactory(privateKey); .getPublicKeyDataDecryptorFactory(privateKey);
@ -408,16 +445,19 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
// try anonymous secret keys // try anonymous secret keys
for (PGPPublicKeyEncryptedData pkesk : esks.anonPkesks) { for (PGPPublicKeyEncryptedData pkesk : esks.anonPkesks) {
for (Tuple<PGPSecretKeyRing, PGPSecretKey> decryptionKeyCandidate : findPotentialDecryptionKeys(pkesk)) { for (Tuple<PGPSecretKeyRing, PGPSecretKey> decryptionKeyCandidate : findPotentialDecryptionKeys(pkesk)) {
PGPSecretKeyRing decryptionKeys = decryptionKeyCandidate.getA();
PGPSecretKey secretKey = decryptionKeyCandidate.getB(); PGPSecretKey secretKey = decryptionKeyCandidate.getB();
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKeys, secretKey.getKeyID());
LOGGER.debug("Attempt decryption of anonymous PKESK with key " + decryptionKeyId);
SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKeyCandidate.getA()); SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKeyCandidate.getA());
if (!protector.hasPassphraseFor(secretKey.getKeyID())) { if (!protector.hasPassphraseFor(secretKey.getKeyID())) {
LOGGER.debug("Missing passphrase for key " + decryptionKeyId + ". Postponing decryption until all other keys were tried.");
postponedDueToMissingPassphrase.add(new Tuple<>(secretKey, pkesk)); postponedDueToMissingPassphrase.add(new Tuple<>(secretKey, pkesk));
continue; continue;
} }
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(decryptionKeyCandidate.getB(), protector); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(decryptionKeyCandidate.getB(), protector);
PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance() PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPublicKeyDataDecryptorFactory(privateKey); .getPublicKeyDataDecryptorFactory(privateKey);
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKeyCandidate.getA(), privateKey.getKeyID());
if (decryptPKESKAndStream(decryptionKeyId, decryptorFactory, pkesk)) { if (decryptPKESKAndStream(decryptionKeyId, decryptorFactory, pkesk)) {
return true; return true;
@ -442,9 +482,10 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
PGPSecretKey secretKey = missingPassphrases.getA(); PGPSecretKey secretKey = missingPassphrases.getA();
long keyId = secretKey.getKeyID(); long keyId = secretKey.getKeyID();
PGPSecretKeyRing decryptionKey = getDecryptionKey(keyId); PGPSecretKeyRing decryptionKey = getDecryptionKey(keyId);
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKey, keyId);
LOGGER.debug("Attempt decryption with key " + decryptionKeyId + " while interactively requesting its passphrase");
SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKey); SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKey);
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector.getDecryptor(keyId)); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector.getDecryptor(keyId));
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKey, keyId);
PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance() PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPublicKeyDataDecryptorFactory(privateKey); .getPublicKeyDataDecryptorFactory(privateKey);
@ -458,10 +499,13 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
} }
// we did not yet succeed in decrypting any session key :/ // we did not yet succeed in decrypting any session key :/
LOGGER.debug("Failed to decrypt encrypted data packet");
return false; return false;
} }
private boolean decryptSKESKAndStream(PGPPBEEncryptedData skesk, PBEDataDecryptorFactory decryptorFactory) throws IOException, UnacceptableAlgorithmException { private boolean decryptSKESKAndStream(PGPPBEEncryptedData skesk, PBEDataDecryptorFactory decryptorFactory)
throws IOException, UnacceptableAlgorithmException {
try { try {
InputStream decrypted = skesk.getDataStream(decryptorFactory); InputStream decrypted = skesk.getDataStream(decryptorFactory);
SessionKey sessionKey = new SessionKey(skesk.getSessionKey(decryptorFactory)); SessionKey sessionKey = new SessionKey(skesk.getSessionKey(decryptorFactory));
@ -469,18 +513,19 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
MessageMetadata.EncryptedData encryptedData = new MessageMetadata.EncryptedData( MessageMetadata.EncryptedData encryptedData = new MessageMetadata.EncryptedData(
sessionKey.getAlgorithm(), metadata.depth + 1); sessionKey.getAlgorithm(), metadata.depth + 1);
encryptedData.sessionKey = sessionKey; encryptedData.sessionKey = sessionKey;
LOGGER.debug("Successfully decrypted data with passphrase");
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, skesk, options); IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, skesk, options);
nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy); nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy);
return true; return true;
} catch (UnacceptableAlgorithmException e) { } catch (UnacceptableAlgorithmException e) {
throw e; throw e;
} catch (PGPException e) { } catch (PGPException e) {
// Password mismatch? LOGGER.debug("Decryption of encrypted data packet using password failed. Password mismatch?", e);
} }
return false; return false;
} }
private boolean decryptPKESKAndStream(SubkeyIdentifier subkeyIdentifier, private boolean decryptPKESKAndStream(SubkeyIdentifier decryptionKeyId,
PublicKeyDataDecryptorFactory decryptorFactory, PublicKeyDataDecryptorFactory decryptorFactory,
PGPPublicKeyEncryptedData pkesk) PGPPublicKeyEncryptedData pkesk)
throws IOException, UnacceptableAlgorithmException { throws IOException, UnacceptableAlgorithmException {
@ -492,16 +537,17 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
MessageMetadata.EncryptedData encryptedData = new MessageMetadata.EncryptedData( MessageMetadata.EncryptedData encryptedData = new MessageMetadata.EncryptedData(
SymmetricKeyAlgorithm.requireFromId(pkesk.getSymmetricAlgorithm(decryptorFactory)), SymmetricKeyAlgorithm.requireFromId(pkesk.getSymmetricAlgorithm(decryptorFactory)),
metadata.depth + 1); metadata.depth + 1);
encryptedData.decryptionKey = subkeyIdentifier; encryptedData.decryptionKey = decryptionKeyId;
encryptedData.sessionKey = sessionKey; encryptedData.sessionKey = sessionKey;
LOGGER.debug("Successfully decrypted data with key " + decryptionKeyId);
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, pkesk, options); IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, pkesk, options);
nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy); nestedInputStream = new OpenPgpMessageInputStream(buffer(integrityProtected), options, encryptedData, policy);
return true; return true;
} catch (UnacceptableAlgorithmException e) { } catch (UnacceptableAlgorithmException e) {
throw e; throw e;
} catch (PGPException e) { } catch (PGPException e) {
LOGGER.debug("Decryption of encrypted data packet using secret key failed.", e);
} }
return false; return false;
} }
@ -823,8 +869,10 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
SignatureValidator.signatureWasCreatedInBounds(options.getVerifyNotBefore(), options.getVerifyNotAfter()) SignatureValidator.signatureWasCreatedInBounds(options.getVerifyNotBefore(), options.getVerifyNotAfter())
.verify(signature); .verify(signature);
SignatureVerifier.verifyOnePassSignature(signature, onePassSignature.getVerificationKeys().getPublicKey(signature.getKeyID()), onePassSignature, policy); SignatureVerifier.verifyOnePassSignature(signature, onePassSignature.getVerificationKeys().getPublicKey(signature.getKeyID()), onePassSignature, policy);
LOGGER.debug("Acceptable signature by key " + verification.getSigningKey());
layer.addVerifiedOnePassSignature(verification); layer.addVerifiedOnePassSignature(verification);
} catch (SignatureValidationException e) { } catch (SignatureValidationException e) {
LOGGER.debug("Rejected signature by key " + verification.getSigningKey(), e);
layer.addRejectedOnePassSignature(new SignatureVerification.Failure(verification, e)); layer.addRejectedOnePassSignature(new SignatureVerification.Failure(verification, e));
} }
break; break;
@ -929,8 +977,10 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
detached.getSignature(), detached.getSignature(),
detached.getSigningKeyRing().getPublicKey(detached.getSigningKeyIdentifier().getKeyId()), detached.getSigningKeyRing().getPublicKey(detached.getSigningKeyIdentifier().getKeyId()),
policy, detached.getSignature().getCreationTime()); policy, detached.getSignature().getCreationTime());
LOGGER.debug("Acceptable signature by key " + verification.getSigningKey());
layer.addVerifiedDetachedSignature(verification); layer.addVerifiedDetachedSignature(verification);
} catch (SignatureValidationException e) { } catch (SignatureValidationException e) {
LOGGER.debug("Rejected signature by key " + verification.getSigningKey(), e);
layer.addRejectedDetachedSignature(new SignatureVerification.Failure(verification, e)); layer.addRejectedDetachedSignature(new SignatureVerification.Failure(verification, e));
} }
} }
@ -944,8 +994,10 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
prepended.getSignature(), prepended.getSignature(),
prepended.getSigningKeyRing().getPublicKey(prepended.getSigningKeyIdentifier().getKeyId()), prepended.getSigningKeyRing().getPublicKey(prepended.getSigningKeyIdentifier().getKeyId()),
policy, prepended.getSignature().getCreationTime()); policy, prepended.getSignature().getCreationTime());
LOGGER.debug("Acceptable signature by key " + verification.getSigningKey());
layer.addVerifiedPrependedSignature(verification); layer.addVerifiedPrependedSignature(verification);
} catch (SignatureValidationException e) { } catch (SignatureValidationException e) {
LOGGER.debug("Rejected signature by key " + verification.getSigningKey(), e);
layer.addRejectedPrependedSignature(new SignatureVerification.Failure(verification, e)); layer.addRejectedPrependedSignature(new SignatureVerification.Failure(verification, e));
} }
} }

View file

@ -5,6 +5,8 @@
package org.pgpainless.decryption_verification.automaton; package org.pgpainless.decryption_verification.automaton;
import org.pgpainless.exception.MalformedOpenPgpMessageException; import org.pgpainless.exception.MalformedOpenPgpMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Stack; import java.util.Stack;
@ -15,11 +17,11 @@ import static org.pgpainless.decryption_verification.automaton.StackAlphabet.ter
public class PDA { public class PDA {
private static int ID = 0; private static int ID = 0;
private static final Logger LOGGER = LoggerFactory.getLogger(PDA.class);
/** /**
* Set of states of the automaton. * Set of states of the automaton.
* Each state defines its valid transitions in their {@link NestingPDA.State#transition(InputAlphabet, NestingPDA)} * Each state defines its valid transitions in their {@link State#transition(InputAlphabet, PDA)} method.
* method.
*/ */
public enum State { public enum State {
@ -199,7 +201,12 @@ public class PDA {
} }
public void next(InputAlphabet input) throws MalformedOpenPgpMessageException { public void next(InputAlphabet input) throws MalformedOpenPgpMessageException {
state = state.transition(input, this); try {
state = state.transition(input, this);
} catch (MalformedOpenPgpMessageException e) {
LOGGER.debug("Unexpected Packet or Token '" + input + "' encountered. Message is malformed.", e);
throw e;
}
} }
/** /**

View file

@ -30,4 +30,8 @@ public final class KeyIdUtil {
return new BigInteger(longKeyId, 16).longValue(); return new BigInteger(longKeyId, 16).longValue();
} }
public static String formatKeyId(long keyId) {
return Long.toHexString(keyId).toUpperCase();
}
} }