mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-25 12:27:58 +01:00
WIP: Play around with TeeInputStreams
This commit is contained in:
parent
9b647742da
commit
371bebe8b9
3 changed files with 121 additions and 5 deletions
|
@ -343,7 +343,8 @@ public class OpenPgpMessageInputStream extends InputStream {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PGPOnePassSignatureList readOnePassSignatures() throws IOException {
|
private PGPOnePassSignatureListWrapper readOnePassSignatures() throws IOException {
|
||||||
|
List<Boolean> encapsulating = new ArrayList<>();
|
||||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||||
BCPGOutputStream bcpgOut = new BCPGOutputStream(buf);
|
BCPGOutputStream bcpgOut = new BCPGOutputStream(buf);
|
||||||
int tag;
|
int tag;
|
||||||
|
@ -351,14 +352,16 @@ public class OpenPgpMessageInputStream extends InputStream {
|
||||||
Packet packet = bcpgIn.readPacket();
|
Packet packet = bcpgIn.readPacket();
|
||||||
if (tag == PacketTags.ONE_PASS_SIGNATURE) {
|
if (tag == PacketTags.ONE_PASS_SIGNATURE) {
|
||||||
OnePassSignaturePacket sigPacket = (OnePassSignaturePacket) packet;
|
OnePassSignaturePacket sigPacket = (OnePassSignaturePacket) packet;
|
||||||
sigPacket.encode(bcpgOut);
|
byte[] bytes = sigPacket.getEncoded();
|
||||||
|
encapsulating.add(bytes[bytes.length - 1] == 1);
|
||||||
|
bcpgOut.write(bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bcpgOut.close();
|
bcpgOut.close();
|
||||||
|
|
||||||
PGPObjectFactory objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(buf.toByteArray());
|
PGPObjectFactory objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(buf.toByteArray());
|
||||||
PGPOnePassSignatureList signatureList = (PGPOnePassSignatureList) objectFactory.nextObject();
|
PGPOnePassSignatureList signatureList = (PGPOnePassSignatureList) objectFactory.nextObject();
|
||||||
return signatureList;
|
return new PGPOnePassSignatureListWrapper(signatureList, encapsulating);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PGPSignatureList readSignatures() throws IOException {
|
private PGPSignatureList readSignatures() throws IOException {
|
||||||
|
@ -490,6 +493,26 @@ public class OpenPgpMessageInputStream extends InputStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Workaround for BC not exposing, whether an OPS is encapsulating or not.
|
||||||
|
* TODO: Remove once our PR is merged
|
||||||
|
*
|
||||||
|
* @see <a href="https://github.com/bcgit/bc-java/pull/1232">PR against BC</a>
|
||||||
|
*/
|
||||||
|
private static class PGPOnePassSignatureListWrapper {
|
||||||
|
private final PGPOnePassSignatureList list;
|
||||||
|
private final List<Boolean> encapsulating;
|
||||||
|
|
||||||
|
public PGPOnePassSignatureListWrapper(PGPOnePassSignatureList signatures, List<Boolean> encapsulating) {
|
||||||
|
this.list = signatures;
|
||||||
|
this.encapsulating = encapsulating;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class Signatures {
|
private static class Signatures {
|
||||||
final ConsumerOptions options;
|
final ConsumerOptions options;
|
||||||
List<PGPSignature> detachedSignatures = new ArrayList<>();
|
List<PGPSignature> detachedSignatures = new ArrayList<>();
|
||||||
|
@ -521,9 +544,9 @@ public class OpenPgpMessageInputStream extends InputStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addOnePassSignatures(PGPOnePassSignatureList signatures) {
|
void addOnePassSignatures(PGPOnePassSignatureListWrapper signatures) {
|
||||||
System.out.println("Adding " + signatures.size() + " OPSs");
|
System.out.println("Adding " + signatures.size() + " OPSs");
|
||||||
for (PGPOnePassSignature ops : signatures) {
|
for (PGPOnePassSignature ops : signatures.list) {
|
||||||
PGPPublicKeyRing certificate = findCertificate(ops.getKeyID());
|
PGPPublicKeyRing certificate = findCertificate(ops.getKeyID());
|
||||||
initialize(ops, certificate);
|
initialize(ops, certificate);
|
||||||
this.onePassSignatures.add(ops);
|
this.onePassSignatures.add(ops);
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package org.pgpainless.decryption_verification;
|
||||||
|
|
||||||
|
import org.bouncycastle.bcpg.BCPGInputStream;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class TeeBCPGInputStream extends BCPGInputStream {
|
||||||
|
|
||||||
|
private final OutputStream out;
|
||||||
|
|
||||||
|
public TeeBCPGInputStream(InputStream in, OutputStream outputStream) {
|
||||||
|
super(in);
|
||||||
|
this.out = outputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
int r = super.read();
|
||||||
|
if (r != -1) {
|
||||||
|
out.write(r);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] buf, int off, int len) throws IOException {
|
||||||
|
int r = super.read(buf, off, len);
|
||||||
|
if (r > 0) {
|
||||||
|
out.write(buf, off, r);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package org.pgpainless.decryption_verification;
|
||||||
|
|
||||||
|
import org.bouncycastle.bcpg.ArmoredInputStream;
|
||||||
|
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
||||||
|
import org.bouncycastle.bcpg.BCPGInputStream;
|
||||||
|
import org.bouncycastle.bcpg.Packet;
|
||||||
|
import org.bouncycastle.openpgp.PGPCompressedData;
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.pgpainless.algorithm.OpenPgpPacket;
|
||||||
|
import org.pgpainless.util.ArmoredInputStreamFactory;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class TeeBCPGInputStreamTest {
|
||||||
|
|
||||||
|
private static final String INBAND_SIGNED = "-----BEGIN PGP MESSAGE-----\n" +
|
||||||
|
"Version: PGPainless\n" +
|
||||||
|
"\n" +
|
||||||
|
"owGbwMvMyCUWdXSHvVTUtXbG0yJJDCDgkZqTk6+jEJ5flJOiyNVRysIoxsXAxsqU\n" +
|
||||||
|
"GDiVjUGRUwCmQUyRRWnOn9Z/PIseF3Yz6cCEL05nZDj1OClo75WVTjNmJPemW6qV\n" +
|
||||||
|
"6ki//1K1++2s0qTP+0N11O4z/BVLDDdxnmQryS+5VXjBX7/0Hxnm/eqeX6Zum35r\n" +
|
||||||
|
"M8e7ufwA\n" +
|
||||||
|
"=RDiy\n" +
|
||||||
|
"-----END PGP MESSAGE-----";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws IOException, PGPException {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
ArmoredOutputStream armorOut = new ArmoredOutputStream(out);
|
||||||
|
|
||||||
|
ByteArrayInputStream bytesIn = new ByteArrayInputStream(INBAND_SIGNED.getBytes(StandardCharsets.UTF_8));
|
||||||
|
ArmoredInputStream armorIn = ArmoredInputStreamFactory.get(bytesIn);
|
||||||
|
BCPGInputStream bcpgIn = new BCPGInputStream(armorIn);
|
||||||
|
TeeBCPGInputStream teeIn = new TeeBCPGInputStream(bcpgIn, armorOut);
|
||||||
|
|
||||||
|
ByteArrayOutputStream nestedOut = new ByteArrayOutputStream();
|
||||||
|
ArmoredOutputStream nestedArmorOut = new ArmoredOutputStream(nestedOut);
|
||||||
|
|
||||||
|
PGPCompressedData compressedData = new PGPCompressedData(teeIn);
|
||||||
|
InputStream nestedStream = compressedData.getDataStream();
|
||||||
|
BCPGInputStream nestedBcpgIn = new BCPGInputStream(nestedStream);
|
||||||
|
TeeBCPGInputStream nestedTeeIn = new TeeBCPGInputStream(nestedBcpgIn, nestedArmorOut);
|
||||||
|
|
||||||
|
int tag;
|
||||||
|
while ((tag = nestedTeeIn.nextPacketTag()) != -1) {
|
||||||
|
System.out.println(OpenPgpPacket.requireFromTag(tag));
|
||||||
|
Packet packet = nestedTeeIn.readPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
nestedArmorOut.close();
|
||||||
|
System.out.println(nestedOut);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue