mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-09 18:29:39 +02:00
Add workaround for decryption with non-encryption subkey
This commit is contained in:
parent
ce65e406c1
commit
cb440776f2
3 changed files with 32 additions and 4 deletions
|
@ -43,6 +43,7 @@ class ConsumerOptions {
|
||||||
private val decryptionPassphrases = mutableSetOf<Passphrase>()
|
private val decryptionPassphrases = mutableSetOf<Passphrase>()
|
||||||
private var missingKeyPassphraseStrategy = MissingKeyPassphraseStrategy.INTERACTIVE
|
private var missingKeyPassphraseStrategy = MissingKeyPassphraseStrategy.INTERACTIVE
|
||||||
private var multiPassStrategy: MultiPassStrategy = InMemoryMultiPassStrategy()
|
private var multiPassStrategy: MultiPassStrategy = InMemoryMultiPassStrategy()
|
||||||
|
private var allowDecryptionWithNonEncryptionKey: Boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consider signatures on the message made before the given timestamp invalid. Null means no
|
* Consider signatures on the message made before the given timestamp invalid. Null means no
|
||||||
|
@ -328,6 +329,14 @@ class ConsumerOptions {
|
||||||
|
|
||||||
fun isIgnoreMDCErrors(): Boolean = ignoreMDCErrors
|
fun isIgnoreMDCErrors(): Boolean = ignoreMDCErrors
|
||||||
|
|
||||||
|
fun setAllowDecryptionWithNonEncryptionKey(allow: Boolean): ConsumerOptions = apply {
|
||||||
|
allowDecryptionWithNonEncryptionKey = allow
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAllowDecryptionWithNonEncryptionKey(): Boolean {
|
||||||
|
return allowDecryptionWithNonEncryptionKey
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Force PGPainless to handle the data provided by the [InputStream] as non-OpenPGP data. This
|
* Force PGPainless to handle the data provided by the [InputStream] as non-OpenPGP data. This
|
||||||
* workaround might come in handy if PGPainless accidentally mistakes the data for binary
|
* workaround might come in handy if PGPainless accidentally mistakes the data for binary
|
||||||
|
|
|
@ -409,6 +409,11 @@ class OpenPgpMessageInputStream(
|
||||||
val decryptionKeyCandidates = getDecryptionKeys(pkesk)
|
val decryptionKeyCandidates = getDecryptionKeys(pkesk)
|
||||||
for (decryptionKeys in decryptionKeyCandidates) {
|
for (decryptionKeys in decryptionKeyCandidates) {
|
||||||
val secretKey = decryptionKeys.getSecretKeyFor(pkesk)!!
|
val secretKey = decryptionKeys.getSecretKeyFor(pkesk)!!
|
||||||
|
if (!secretKey.isEncryptionKey && !options.getAllowDecryptionWithNonEncryptionKey()) {
|
||||||
|
LOGGER.debug(
|
||||||
|
"Message is encrypted for ${secretKey.keyIdentifier}, but the key is not encryption capable.")
|
||||||
|
continue
|
||||||
|
}
|
||||||
if (hasUnsupportedS2KSpecifier(secretKey)) {
|
if (hasUnsupportedS2KSpecifier(secretKey)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import java.nio.charset.StandardCharsets;
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.util.io.Streams;
|
import org.bouncycastle.util.io.Streams;
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.exception.MissingDecryptionMethodException;
|
import org.pgpainless.exception.MissingDecryptionMethodException;
|
||||||
|
@ -206,7 +205,6 @@ public class PreventDecryptionUsingNonEncryptionKeyTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
|
||||||
public void nonEncryptionKeyCannotDecrypt() throws IOException {
|
public void nonEncryptionKeyCannotDecrypt() throws IOException {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(ENCRYPTION_INCAPABLE_KEY);
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(ENCRYPTION_INCAPABLE_KEY);
|
||||||
|
|
||||||
|
@ -217,4 +215,20 @@ public class PreventDecryptionUsingNonEncryptionKeyTest {
|
||||||
.onInputStream(msgIn)
|
.onInputStream(msgIn)
|
||||||
.withOptions(ConsumerOptions.get().addDecryptionKey(secretKeys)));
|
.withOptions(ConsumerOptions.get().addDecryptionKey(secretKeys)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nonEncryptionKeyCanDecryptIfAllowed() throws IOException, PGPException {
|
||||||
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(ENCRYPTION_INCAPABLE_KEY);
|
||||||
|
|
||||||
|
ByteArrayInputStream msgIn = new ByteArrayInputStream(MSG.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify()
|
||||||
|
.onInputStream(msgIn)
|
||||||
|
.withOptions(ConsumerOptions.get()
|
||||||
|
.setAllowDecryptionWithNonEncryptionKey(true)
|
||||||
|
.addDecryptionKey(secretKeys));
|
||||||
|
|
||||||
|
byte[] decrypted = Streams.readAll(decryptionStream);
|
||||||
|
decryptionStream.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue