mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-30 00:02:06 +01:00
Properly handle failed decryption caused by removed private keys
This commit is contained in:
parent
58aa9f5712
commit
58195c19b1
3 changed files with 38 additions and 14 deletions
|
@ -18,6 +18,7 @@ import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.bouncycastle.bcpg.ArmoredInputStream;
|
import org.bouncycastle.bcpg.ArmoredInputStream;
|
||||||
import org.bouncycastle.bcpg.BCPGInputStream;
|
import org.bouncycastle.bcpg.BCPGInputStream;
|
||||||
|
import org.bouncycastle.bcpg.S2K;
|
||||||
import org.bouncycastle.bcpg.UnsupportedPacketVersionException;
|
import org.bouncycastle.bcpg.UnsupportedPacketVersionException;
|
||||||
import org.bouncycastle.openpgp.PGPCompressedData;
|
import org.bouncycastle.openpgp.PGPCompressedData;
|
||||||
import org.bouncycastle.openpgp.PGPEncryptedData;
|
import org.bouncycastle.openpgp.PGPEncryptedData;
|
||||||
|
@ -507,6 +508,14 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
}
|
}
|
||||||
PGPSecretKey secretKey = decryptionKeys.getSecretKey(keyId);
|
PGPSecretKey secretKey = decryptionKeys.getSecretKey(keyId);
|
||||||
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKeys, secretKey.getKeyID());
|
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKeys, secretKey.getKeyID());
|
||||||
|
S2K s2K = secretKey.getS2K();
|
||||||
|
if (s2K != null) {
|
||||||
|
int s2kType = s2K.getType();
|
||||||
|
if (s2kType >= 100 && s2kType <= 110) {
|
||||||
|
LOGGER.debug("Skipping PKESK because key " + decryptionKeyId + " has unsupported private S2K specifier " + s2kType);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
LOGGER.debug("Attempt decryption using secret key " + decryptionKeyId);
|
LOGGER.debug("Attempt decryption using secret key " + decryptionKeyId);
|
||||||
|
|
||||||
SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKeys);
|
SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKeys);
|
||||||
|
@ -532,6 +541,14 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
PGPSecretKeyRing decryptionKeys = decryptionKeyCandidate.getA();
|
PGPSecretKeyRing decryptionKeys = decryptionKeyCandidate.getA();
|
||||||
PGPSecretKey secretKey = decryptionKeyCandidate.getB();
|
PGPSecretKey secretKey = decryptionKeyCandidate.getB();
|
||||||
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKeys, secretKey.getKeyID());
|
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKeys, secretKey.getKeyID());
|
||||||
|
S2K s2K = secretKey.getS2K();
|
||||||
|
if (s2K != null) {
|
||||||
|
int s2kType = s2K.getType();
|
||||||
|
if (s2kType >= 100 && s2kType <= 110) {
|
||||||
|
LOGGER.debug("Skipping PKESK because key " + decryptionKeyId + " has unsupported private S2K specifier " + s2kType);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
LOGGER.debug("Attempt decryption of anonymous PKESK with key " + decryptionKeyId);
|
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())) {
|
||||||
|
@ -567,6 +584,14 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
|
||||||
long keyId = secretKey.getKeyID();
|
long keyId = secretKey.getKeyID();
|
||||||
PGPSecretKeyRing decryptionKey = getDecryptionKey(keyId);
|
PGPSecretKeyRing decryptionKey = getDecryptionKey(keyId);
|
||||||
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKey, keyId);
|
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKey, keyId);
|
||||||
|
S2K s2K = secretKey.getS2K();
|
||||||
|
if (s2K != null) {
|
||||||
|
int s2kType = s2K.getType();
|
||||||
|
if (s2kType >= 100 && s2kType <= 110) {
|
||||||
|
LOGGER.debug("Skipping PKESK because key " + decryptionKeyId + " has unsupported private S2K specifier " + s2kType);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
LOGGER.debug("Attempt decryption with key " + decryptionKeyId + " while interactively requesting its passphrase");
|
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));
|
||||||
|
|
|
@ -4,25 +4,23 @@
|
||||||
|
|
||||||
package org.gnupg;
|
package org.gnupg;
|
||||||
|
|
||||||
import org.bouncycastle.bcpg.S2K;
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
import org.bouncycastle.bcpg.SecretKeyPacket;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
|
||||||
import org.gnupg.GnuPGDummyExtension;
|
|
||||||
import org.gnupg.GnuPGDummyKeyUtil;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.pgpainless.PGPainless;
|
|
||||||
import org.pgpainless.key.SubkeyIdentifier;
|
|
||||||
import org.pgpainless.key.util.KeyIdUtil;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
import org.bouncycastle.bcpg.S2K;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import org.bouncycastle.bcpg.SecretKeyPacket;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.key.SubkeyIdentifier;
|
||||||
|
import org.pgpainless.key.util.KeyIdUtil;
|
||||||
|
|
||||||
public class GnuPGDummyKeyUtilTest {
|
public class GnuPGDummyKeyUtilTest {
|
||||||
// normal, non-hw-backed key
|
// normal, non-hw-backed key
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.pgpainless.encryption_signing.EncryptionOptions;
|
||||||
import org.pgpainless.encryption_signing.EncryptionStream;
|
import org.pgpainless.encryption_signing.EncryptionStream;
|
||||||
import org.pgpainless.encryption_signing.ProducerOptions;
|
import org.pgpainless.encryption_signing.ProducerOptions;
|
||||||
import org.gnupg.GnuPGDummyKeyUtil;
|
import org.gnupg.GnuPGDummyKeyUtil;
|
||||||
|
import org.pgpainless.exception.MissingDecryptionMethodException;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
@ -45,7 +46,7 @@ public class TryDecryptWithUnavailableGnuDummyKeyTest {
|
||||||
.removePrivateKeys(GnuPGDummyKeyUtil.KeyFilter.any());
|
.removePrivateKeys(GnuPGDummyKeyUtil.KeyFilter.any());
|
||||||
|
|
||||||
ByteArrayInputStream ciphertextIn = new ByteArrayInputStream(ciphertextOut.toByteArray());
|
ByteArrayInputStream ciphertextIn = new ByteArrayInputStream(ciphertextOut.toByteArray());
|
||||||
assertThrows(PGPException.class, () -> PGPainless.decryptAndOrVerify()
|
assertThrows(MissingDecryptionMethodException.class, () -> PGPainless.decryptAndOrVerify()
|
||||||
.onInputStream(ciphertextIn)
|
.onInputStream(ciphertextIn)
|
||||||
.withOptions(ConsumerOptions.get().addDecryptionKey(removedKeys)));
|
.withOptions(ConsumerOptions.get().addDecryptionKey(removedKeys)));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue