mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-23 11:27:57 +01:00
Fix tests
This commit is contained in:
parent
e86062c427
commit
d81c0d4400
4 changed files with 98 additions and 10 deletions
|
@ -1,6 +1,5 @@
|
||||||
package org.pgpainless.decryption_verification;
|
package org.pgpainless.decryption_verification;
|
||||||
|
|
||||||
import com.sun.tools.javac.code.Attribute;
|
|
||||||
import org.bouncycastle.bcpg.BCPGInputStream;
|
import org.bouncycastle.bcpg.BCPGInputStream;
|
||||||
import org.bouncycastle.bcpg.BCPGOutputStream;
|
import org.bouncycastle.bcpg.BCPGOutputStream;
|
||||||
import org.bouncycastle.bcpg.OnePassSignaturePacket;
|
import org.bouncycastle.bcpg.OnePassSignaturePacket;
|
||||||
|
@ -25,13 +24,14 @@ import org.bouncycastle.openpgp.PGPSignature;
|
||||||
import org.bouncycastle.openpgp.PGPSignatureList;
|
import org.bouncycastle.openpgp.PGPSignatureList;
|
||||||
import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory;
|
import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory;
|
||||||
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
||||||
|
import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.algorithm.EncryptionPurpose;
|
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||||
import org.pgpainless.algorithm.OpenPgpPacket;
|
import org.pgpainless.algorithm.OpenPgpPacket;
|
||||||
import org.pgpainless.decryption_verification.automaton.InputAlphabet;
|
import org.pgpainless.decryption_verification.automaton.InputAlphabet;
|
||||||
import org.pgpainless.decryption_verification.automaton.PDA;
|
import org.pgpainless.decryption_verification.automaton.PDA;
|
||||||
import org.pgpainless.exception.MalformedOpenPgpMessageException;
|
|
||||||
import org.pgpainless.exception.MessageNotIntegrityProtectedException;
|
import org.pgpainless.exception.MessageNotIntegrityProtectedException;
|
||||||
|
import org.pgpainless.exception.MissingDecryptionMethodException;
|
||||||
import org.pgpainless.implementation.ImplementationFactory;
|
import org.pgpainless.implementation.ImplementationFactory;
|
||||||
import org.pgpainless.key.info.KeyRingInfo;
|
import org.pgpainless.key.info.KeyRingInfo;
|
||||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
@ -114,7 +114,27 @@ public class OpenPgpMessageInputStream extends InputStream {
|
||||||
|
|
||||||
SortedESKs esks = new SortedESKs(encDataList);
|
SortedESKs esks = new SortedESKs(encDataList);
|
||||||
|
|
||||||
// TODO: try session keys
|
if (options.getSessionKey() != null) {
|
||||||
|
SessionKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
|
||||||
|
.getSessionKeyDataDecryptorFactory(options.getSessionKey());
|
||||||
|
// TODO: Replace with encDataList.addSessionKeyDecryptionMethod(sessionKey)
|
||||||
|
PGPEncryptedData esk = esks.all().get(0);
|
||||||
|
try {
|
||||||
|
if (esk instanceof PGPPBEEncryptedData) {
|
||||||
|
PGPPBEEncryptedData skesk = (PGPPBEEncryptedData) esk;
|
||||||
|
in = skesk.getDataStream(decryptorFactory);
|
||||||
|
break loop;
|
||||||
|
} else if (esk instanceof PGPPublicKeyEncryptedData) {
|
||||||
|
PGPPublicKeyEncryptedData pkesk = (PGPPublicKeyEncryptedData) esk;
|
||||||
|
in = pkesk.getDataStream(decryptorFactory);
|
||||||
|
break loop;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unknown ESK class type: " + esk.getClass().getName());
|
||||||
|
}
|
||||||
|
} catch (PGPException e) {
|
||||||
|
// Session key mismatch?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try passwords
|
// Try passwords
|
||||||
for (PGPPBEEncryptedData skesk : esks.skesks) {
|
for (PGPPBEEncryptedData skesk : esks.skesks) {
|
||||||
|
@ -174,7 +194,7 @@ public class OpenPgpMessageInputStream extends InputStream {
|
||||||
|
|
||||||
// TODO: try interactive password callbacks
|
// TODO: try interactive password callbacks
|
||||||
|
|
||||||
break loop;
|
throw new MissingDecryptionMethodException("No working decryption method found.");
|
||||||
|
|
||||||
case MARKER:
|
case MARKER:
|
||||||
bcpgIn.readPacket(); // skip marker packet
|
bcpgIn.readPacket(); // skip marker packet
|
||||||
|
@ -256,6 +276,7 @@ public class OpenPgpMessageInputStream extends InputStream {
|
||||||
if (tag == PacketTags.SIGNATURE) {
|
if (tag == PacketTags.SIGNATURE) {
|
||||||
SignaturePacket sigPacket = (SignaturePacket) packet;
|
SignaturePacket sigPacket = (SignaturePacket) packet;
|
||||||
sigPacket.encode(bcpgOut);
|
sigPacket.encode(bcpgOut);
|
||||||
|
tag = bcpgIn.nextPacketTag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bcpgOut.close();
|
bcpgOut.close();
|
||||||
|
@ -270,16 +291,21 @@ public class OpenPgpMessageInputStream extends InputStream {
|
||||||
@Override
|
@Override
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
int r = -1;
|
int r = -1;
|
||||||
try {
|
if (in != null) {
|
||||||
r = in.read();
|
try {
|
||||||
} catch (IOException e) {
|
r = in.read();
|
||||||
//
|
} catch (IOException e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
if (in instanceof OpenPgpMessageInputStream) {
|
if (in instanceof OpenPgpMessageInputStream) {
|
||||||
|
System.out.println("Read -1: close " + automaton);
|
||||||
in.close();
|
in.close();
|
||||||
|
in = null;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
System.out.println("Walk " + automaton);
|
||||||
walk();
|
walk();
|
||||||
} catch (PGPException e) {
|
} catch (PGPException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
@ -291,8 +317,15 @@ public class OpenPgpMessageInputStream extends InputStream {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
|
if (in == null) {
|
||||||
|
System.out.println("Close " + automaton);
|
||||||
|
automaton.next(InputAlphabet.EndOfSequence);
|
||||||
|
automaton.assertValid();
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
in.close();
|
in.close();
|
||||||
|
in = null;
|
||||||
// Nested streams (except LiteralData) need to be closed.
|
// Nested streams (except LiteralData) need to be closed.
|
||||||
if (automaton.getState() != PDA.State.LiteralMessage) {
|
if (automaton.getState() != PDA.State.LiteralMessage) {
|
||||||
automaton.next(InputAlphabet.EndOfSequence);
|
automaton.next(InputAlphabet.EndOfSequence);
|
||||||
|
@ -327,5 +360,13 @@ public class OpenPgpMessageInputStream extends InputStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<PGPEncryptedData> all() {
|
||||||
|
List<PGPEncryptedData> esks = new ArrayList<>();
|
||||||
|
esks.addAll(skesks);
|
||||||
|
esks.addAll(pkesks);
|
||||||
|
esks.addAll(anonPkesks);
|
||||||
|
return esks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,9 @@ import static org.pgpainless.decryption_verification.automaton.StackAlphabet.ops
|
||||||
import static org.pgpainless.decryption_verification.automaton.StackAlphabet.terminus;
|
import static org.pgpainless.decryption_verification.automaton.StackAlphabet.terminus;
|
||||||
|
|
||||||
public class PDA {
|
public class PDA {
|
||||||
|
|
||||||
|
private static int ID = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 NestingPDA.State#transition(InputAlphabet, NestingPDA)}
|
||||||
|
@ -174,18 +177,20 @@ public class PDA {
|
||||||
|
|
||||||
private final Stack<StackAlphabet> stack = new Stack<>();
|
private final Stack<StackAlphabet> stack = new Stack<>();
|
||||||
private State state;
|
private State state;
|
||||||
|
private int id;
|
||||||
|
|
||||||
public PDA() {
|
public PDA() {
|
||||||
state = State.OpenPgpMessage;
|
state = State.OpenPgpMessage;
|
||||||
stack.push(terminus);
|
stack.push(terminus);
|
||||||
stack.push(msg);
|
stack.push(msg);
|
||||||
|
this.id = ID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void next(InputAlphabet input) throws MalformedOpenPgpMessageException {
|
public void next(InputAlphabet input) throws MalformedOpenPgpMessageException {
|
||||||
State old = state;
|
State old = state;
|
||||||
StackAlphabet stackItem = stack.isEmpty() ? null : stack.peek();
|
StackAlphabet stackItem = stack.isEmpty() ? null : stack.peek();
|
||||||
state = state.transition(input, this);
|
state = state.transition(input, this);
|
||||||
System.out.println("Transition from " + old + " to " + state + " via " + input + " with stack " + stackItem);
|
System.out.println(id + ": Transition from " + old + " to " + state + " via " + input + " with stack " + stackItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -232,6 +237,6 @@ public class PDA {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "State: " + state + " Stack: " + stack;
|
return "PDA " + id + ": State: " + state + " Stack: " + stack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,10 @@ package org.pgpainless.decryption_verification;
|
||||||
|
|
||||||
import org.bouncycastle.bcpg.ArmoredInputStream;
|
import org.bouncycastle.bcpg.ArmoredInputStream;
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.util.io.Streams;
|
import org.bouncycastle.util.io.Streams;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.exception.MalformedOpenPgpMessageException;
|
import org.pgpainless.exception.MalformedOpenPgpMessageException;
|
||||||
import org.pgpainless.util.ArmoredInputStreamFactory;
|
import org.pgpainless.util.ArmoredInputStreamFactory;
|
||||||
import org.pgpainless.util.Passphrase;
|
import org.pgpainless.util.Passphrase;
|
||||||
|
@ -18,9 +20,11 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.COMP;
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.COMP;
|
||||||
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.COMP_COMP_LIT;
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.COMP_COMP_LIT;
|
||||||
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.COMP_LIT;
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.COMP_LIT;
|
||||||
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.KEY;
|
||||||
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.LIT;
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.LIT;
|
||||||
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.LIT_LIT;
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.LIT_LIT;
|
||||||
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.PASSPHRASE;
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.PASSPHRASE;
|
||||||
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.PENC_COMP_LIT;
|
||||||
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.PLAINTEXT;
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.PLAINTEXT;
|
||||||
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.SENC_LIT;
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.SENC_LIT;
|
||||||
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.SIG_LIT;
|
import static org.pgpainless.decryption_verification.PGPDecryptionStreamTest.SIG_LIT;
|
||||||
|
@ -69,6 +73,14 @@ public class OpenPgpMessageInputStreamTest {
|
||||||
assertEquals(PLAINTEXT, plain);
|
assertEquals(PLAINTEXT, plain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProcessPENC_COMP_LIT() throws IOException, PGPException {
|
||||||
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY);
|
||||||
|
String plain = process(PENC_COMP_LIT, ConsumerOptions.get()
|
||||||
|
.addDecryptionKey(secretKeys));
|
||||||
|
assertEquals(PLAINTEXT, plain);
|
||||||
|
}
|
||||||
|
|
||||||
private String process(String armoredMessage, ConsumerOptions options) throws PGPException, IOException {
|
private String process(String armoredMessage, ConsumerOptions options) throws PGPException, IOException {
|
||||||
OpenPgpMessageInputStream in = get(armoredMessage, options);
|
OpenPgpMessageInputStream in = get(armoredMessage, options);
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
|
@ -7,6 +7,7 @@ import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPLiteralData;
|
import org.bouncycastle.openpgp.PGPLiteralData;
|
||||||
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
|
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSignature;
|
import org.bouncycastle.openpgp.PGPSignature;
|
||||||
import org.bouncycastle.util.io.Streams;
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
@ -124,6 +125,17 @@ public class PGPDecryptionStreamTest {
|
||||||
"=i4Y0\n" +
|
"=i4Y0\n" +
|
||||||
"-----END PGP MESSAGE-----";
|
"-----END PGP MESSAGE-----";
|
||||||
|
|
||||||
|
public static final String PENC_COMP_LIT = "" +
|
||||||
|
"-----BEGIN PGP MESSAGE-----\n" +
|
||||||
|
"Version: PGPainless\n" +
|
||||||
|
"\n" +
|
||||||
|
"hF4Dyqa/GWUy6WsSAQdAQ62BwmUt8Iby0+jvrLhMgST79KR/as+dyl0nf1uki2sw\n" +
|
||||||
|
"Thg1Ojtf0hOyJgcpQ4nP2Q0wYFR0F1sCydaIlTGreYZHlGtybP7/Ml6KNZILTRWP\n" +
|
||||||
|
"0kYBkGBgK7oQWRIVyoF2POvEP6EX1X8nvQk7O3NysVdRVbnia7gE3AzRYuha4kxs\n" +
|
||||||
|
"pI6xJkntLMS3K6him1Y9FHINIASFSB+C\n" +
|
||||||
|
"=5p00\n" +
|
||||||
|
"-----END PGP MESSAGE-----";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void genLIT() throws IOException {
|
public void genLIT() throws IOException {
|
||||||
ArmoredOutputStream armorOut = new ArmoredOutputStream(System.out);
|
ArmoredOutputStream armorOut = new ArmoredOutputStream(System.out);
|
||||||
|
@ -328,4 +340,22 @@ public class PGPDecryptionStreamTest {
|
||||||
|
|
||||||
System.out.println(out);
|
System.out.println(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void genPENC_COMP_LIT() throws IOException, PGPException {
|
||||||
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY);
|
||||||
|
PGPPublicKeyRing cert = PGPainless.extractCertificate(secretKeys);
|
||||||
|
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
EncryptionStream enc = PGPainless.encryptAndOrSign()
|
||||||
|
.onOutputStream(out)
|
||||||
|
.withOptions(ProducerOptions.encrypt(EncryptionOptions.get()
|
||||||
|
.addRecipient(cert))
|
||||||
|
.overrideCompressionAlgorithm(CompressionAlgorithm.ZLIB));
|
||||||
|
|
||||||
|
Streams.pipeAll(new ByteArrayInputStream(PLAINTEXT.getBytes(StandardCharsets.UTF_8)), enc);
|
||||||
|
enc.close();
|
||||||
|
|
||||||
|
System.out.println(out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue