From e420678076fb33bad2fd94e6928d760098786115 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Thu, 6 Oct 2022 21:52:23 +0200 Subject: [PATCH] 2/3 the way to working sig verification --- .../DelayedTeeInputStreamInputStream.java | 38 +++ .../OpenPgpMessageInputStream.java | 263 ++++++++++++------ .../TeeBCPGInputStream.java | 36 --- .../OpenPgpMessageInputStreamTest.java | 234 ++++++++++------ .../TeeBCPGInputStreamTest.java | 61 ---- 5 files changed, 353 insertions(+), 279 deletions(-) create mode 100644 pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DelayedTeeInputStreamInputStream.java delete mode 100644 pgpainless-core/src/main/java/org/pgpainless/decryption_verification/TeeBCPGInputStream.java delete mode 100644 pgpainless-core/src/test/java/org/pgpainless/decryption_verification/TeeBCPGInputStreamTest.java diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DelayedTeeInputStreamInputStream.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DelayedTeeInputStreamInputStream.java new file mode 100644 index 00000000..5cbabf89 --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DelayedTeeInputStreamInputStream.java @@ -0,0 +1,38 @@ +package org.pgpainless.decryption_verification; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class DelayedTeeInputStreamInputStream extends InputStream { + + private int last = -1; + private final InputStream inputStream; + private final OutputStream outputStream; + + public DelayedTeeInputStreamInputStream(InputStream inputStream, OutputStream outputStream) { + this.inputStream = inputStream; + this.outputStream = outputStream; + } + + @Override + public int read() throws IOException { + if (last != -1) { + outputStream.write(last); + } + last = inputStream.read(); + return last; + } + + /** + * Squeeze the last byte out and update the output stream. + * + * @throws IOException in case of an IO error + */ + public void squeeze() throws IOException { + if (last != -1) { + outputStream.write(last); + } + last = -1; + } +} diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/OpenPgpMessageInputStream.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/OpenPgpMessageInputStream.java index 2d031edc..8d370965 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/OpenPgpMessageInputStream.java +++ b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/OpenPgpMessageInputStream.java @@ -20,7 +20,6 @@ import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; -import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPPBEEncryptedData; import org.bouncycastle.openpgp.PGPPrivateKey; @@ -53,7 +52,6 @@ import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.signature.SignatureUtils; -import org.pgpainless.util.ArmorUtils; import org.pgpainless.util.Passphrase; import org.pgpainless.util.Tuple; import org.slf4j.Logger; @@ -68,6 +66,7 @@ public class OpenPgpMessageInputStream extends InputStream { protected final OpenPgpMetadata.Builder resultBuilder; // Pushdown Automaton to verify validity of OpenPGP packet sequence in an OpenPGP message protected final PDA automaton = new PDA(); + protected final DelayedTeeInputStreamInputStream delayedTee; // InputStream of OpenPGP packets of the current layer protected final BCPGInputStream packetInputStream; // InputStream of a nested data packet @@ -96,8 +95,9 @@ public class OpenPgpMessageInputStream extends InputStream { this.signatures.addDetachedSignatures(options.getDetachedSignatures()); } - BCPGInputStream bcpg = BCPGInputStream.wrap(inputStream); - this.packetInputStream = new TeeBCPGInputStream(bcpg, signatures); + delayedTee = new DelayedTeeInputStreamInputStream(inputStream, signatures); + BCPGInputStream bcpg = BCPGInputStream.wrap(delayedTee); + this.packetInputStream = bcpg; // *omnomnom* consumePackets(); @@ -121,22 +121,15 @@ public class OpenPgpMessageInputStream extends InputStream { */ private void consumePackets() throws IOException, PGPException { - int tag; - loop: while ((tag = nextTag()) != -1) { - OpenPgpPacket nextPacket; - try { - nextPacket = OpenPgpPacket.requireFromTag(tag); - } catch (NoSuchElementException e) { - log("Invalid tag: " + tag); - throw e; - } - log(nextPacket.toString()); + OpenPgpPacket nextPacket; + loop: while ((nextPacket = nextPacketTag()) != null) { signatures.nextPacket(nextPacket); switch (nextPacket) { // Literal Data - the literal data content is the new input stream case LIT: automaton.next(InputAlphabet.LiteralData); + delayedTee.squeeze(); processLiteralData(); break loop; @@ -145,12 +138,14 @@ public class OpenPgpMessageInputStream extends InputStream { automaton.next(InputAlphabet.CompressedData); signatures.commitNested(); processCompressedData(); + delayedTee.squeeze(); break loop; // One Pass Signature case OPS: automaton.next(InputAlphabet.OnePassSignatures); PGPOnePassSignature onePassSignature = readOnePassSignature(); + delayedTee.squeeze(); signatures.addOnePassSignature(onePassSignature); break; @@ -160,6 +155,7 @@ public class OpenPgpMessageInputStream extends InputStream { automaton.next(InputAlphabet.Signatures); PGPSignature signature = readSignature(); + delayedTee.squeeze(); processSignature(signature, isSigForOPS); break; @@ -170,6 +166,7 @@ public class OpenPgpMessageInputStream extends InputStream { case SED: case SEIPD: automaton.next(InputAlphabet.EncryptedData); + delayedTee.squeeze(); if (processEncryptedData()) { break loop; } @@ -179,6 +176,7 @@ public class OpenPgpMessageInputStream extends InputStream { // Marker Packets need to be skipped and ignored case MARKER: packetInputStream.readPacket(); // skip + delayedTee.squeeze(); break; // Key Packets are illegal in this context @@ -206,6 +204,23 @@ public class OpenPgpMessageInputStream extends InputStream { } } + private OpenPgpPacket nextPacketTag() throws IOException { + int tag = nextTag(); + if (tag == -1) { + log("EOF"); + return null; + } + OpenPgpPacket packet; + try { + packet = OpenPgpPacket.requireFromTag(tag); + } catch (NoSuchElementException e) { + log("Invalid tag: " + tag); + throw e; + } + log(packet.toString()); + return packet; + } + private void processSignature(PGPSignature signature, boolean isSigForOPS) { if (isSigForOPS) { signatures.popNested(); @@ -229,41 +244,6 @@ public class OpenPgpMessageInputStream extends InputStream { nestedInputStream = literalData.getDataStream(); } - private void debugEncryptedData() throws PGPException, IOException { - PGPEncryptedDataList encDataList = new PGPEncryptedDataList(packetInputStream); - - // TODO: Replace with !encDataList.isIntegrityProtected() - if (!encDataList.get(0).isIntegrityProtected()) { - throw new MessageNotIntegrityProtectedException(); - } - - SortedESKs esks = new SortedESKs(encDataList); - for (PGPPublicKeyEncryptedData pkesk : esks.pkesks) { - long keyId = pkesk.getKeyID(); - PGPSecretKeyRing decryptionKeys = getDecryptionKey(keyId); - if (decryptionKeys == null) { - continue; - } - SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKeys); - PGPSecretKey decryptionKey = decryptionKeys.getSecretKey(keyId); - PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(decryptionKey, protector); - - PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance() - .getPublicKeyDataDecryptorFactory(privateKey); - try { - InputStream decrypted = pkesk.getDataStream(decryptorFactory); - InputStream decoder = PGPUtil.getDecoderStream(decrypted); - PGPObjectFactory objectFactory = ImplementationFactory.getInstance() - .getPGPObjectFactory(decoder); - objectFactory.nextObject(); - objectFactory.nextObject(); - objectFactory.nextObject(); - } catch (PGPException e) { - // hm :/ - } - } - } - private boolean processEncryptedData() throws IOException, PGPException { PGPEncryptedDataList encDataList = new PGPEncryptedDataList(packetInputStream); @@ -553,12 +533,13 @@ public class OpenPgpMessageInputStream extends InputStream { // for literal data. UUUUUGLY!!!! private static final class Signatures extends OutputStream { final ConsumerOptions options; - final List detachedSignatures; - final List prependedSignatures; + final List detachedSignatures; + final List prependedSignatures; final List onePassSignatures; final Stack> opsUpdateStack; List literalOPS = new ArrayList<>(); final List correspondingSignatures; + boolean isLiteral = true; private Signatures(ConsumerOptions options) { this.options = options; @@ -579,14 +560,14 @@ public class OpenPgpMessageInputStream extends InputStream { long keyId = SignatureUtils.determineIssuerKeyId(signature); PGPPublicKeyRing certificate = findCertificate(keyId); initialize(signature, certificate, keyId); - this.detachedSignatures.add(signature); + this.detachedSignatures.add(new SIG(signature)); } void addPrependedSignature(PGPSignature signature) { long keyId = SignatureUtils.determineIssuerKeyId(signature); PGPPublicKeyRing certificate = findCertificate(keyId); initialize(signature, certificate, keyId); - this.prependedSignatures.add(signature); + this.prependedSignatures.add(new SIG(signature)); } void addOnePassSignature(PGPOnePassSignature signature) { @@ -630,7 +611,7 @@ public class OpenPgpMessageInputStream extends InputStream { opsUpdateStack.pop(); } - private void initialize(PGPSignature signature, PGPPublicKeyRing certificate, long keyId) { + private static void initialize(PGPSignature signature, PGPPublicKeyRing certificate, long keyId) { if (certificate == null) { // SHIT return; @@ -672,7 +653,7 @@ public class OpenPgpMessageInputStream extends InputStream { ops.update(b); } - for (PGPSignature detached : detachedSignatures) { + for (SIG detached : detachedSignatures) { detached.update(b); } } @@ -682,13 +663,22 @@ public class OpenPgpMessageInputStream extends InputStream { ops.update(b, off, len); } - for (PGPSignature detached : detachedSignatures) { + for (SIG detached : detachedSignatures) { detached.update(b, off, len); } } public void updatePacket(byte b) { - for (List nestedOPSs : opsUpdateStack) { + for (SIG detached : detachedSignatures) { + detached.update(b); + } + + for (SIG prepended : prependedSignatures) { + prepended.update(b); + } + + for (int i = opsUpdateStack.size() - 1; i >= 0; i--) { + List nestedOPSs = opsUpdateStack.get(i); for (OPS ops : nestedOPSs) { ops.update(b); } @@ -696,6 +686,14 @@ public class OpenPgpMessageInputStream extends InputStream { } public void updatePacket(byte[] buf, int off, int len) { + for (SIG detached : detachedSignatures) { + detached.update(buf, off, len); + } + + for (SIG prepended : prependedSignatures) { + prepended.update(buf, off, len); + } + for (int i = opsUpdateStack.size() - 1; i >= 0; i--) { List nestedOPSs = opsUpdateStack.get(i); for (OPS ops : nestedOPSs) { @@ -705,24 +703,16 @@ public class OpenPgpMessageInputStream extends InputStream { } public void finish() { - for (PGPSignature detached : detachedSignatures) { - boolean verified = false; - try { - verified = detached.verify(); - } catch (PGPException e) { - log("Cannot verify detached signature.", e); - } - log("Detached Signature by " + Long.toHexString(detached.getKeyID()) + " is " + (verified ? "verified" : "unverified")); + for (SIG detached : detachedSignatures) { + boolean verified = detached.verify(); + log("Detached Signature by " + Long.toHexString(detached.signature.getKeyID()) + " is " + (verified ? "verified" : "unverified")); + System.out.println(detached); } - for (PGPSignature prepended : prependedSignatures) { - boolean verified = false; - try { - verified = prepended.verify(); - } catch (PGPException e) { - log("Cannot verify prepended signature.", e); - } - log("Prepended Signature by " + Long.toHexString(prepended.getKeyID()) + " is " + (verified ? "verified" : "unverified")); + for (SIG prepended : prependedSignatures) { + boolean verified = prepended.verify(); + log("Prepended Signature by " + Long.toHexString(prepended.signature.getKeyID()) + " is " + (verified ? "verified" : "unverified")); + System.out.println(prepended); } } @@ -738,9 +728,92 @@ public class OpenPgpMessageInputStream extends InputStream { public void nextPacket(OpenPgpPacket nextPacket) { if (nextPacket == OpenPgpPacket.LIT) { + isLiteral = true; if (literalOPS.isEmpty() && !opsUpdateStack.isEmpty()) { literalOPS = opsUpdateStack.pop(); } + } else { + isLiteral = false; + } + } + + static class SIG { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + PGPSignature signature; + boolean finished; + boolean valid; + + public SIG(PGPSignature signature) { + this.signature = signature; + } + + public void init(PGPPublicKeyRing certificate) { + initialize(signature, certificate, signature.getKeyID()); + } + + public boolean verify() { + finished = true; + try { + valid = this.signature.verify(); + } catch (PGPException e) { + log("Cannot verify SIG " + signature.getKeyID()); + } + return valid; + } + + public void update(byte b) { + if (finished) { + log("Updating finished sig!"); + return; + } + signature.update(b); + bytes.write(b); + } + + public void update(byte[] bytes, int off, int len) { + if (finished) { + log("Updating finished sig!"); + return; + } + signature.update(bytes, off, len); + this.bytes.write(bytes, off, len); + } + + @Override + public String toString() { + String OPS = "c40d03000a01fbfcc82a015e733001"; + String LIT_H = "cb28620000000000"; + String LIT = "656e637279707420e28898207369676e20e28898207369676e20e28898207369676e"; + String SIG1 = "c2c10400010a006f058262c806350910fbfcc82a015e7330471400000000001e002073616c74406e6f746174696f6e732e736571756f69612d7067702e6f7267b0409ed8ea96dac66447bdff5b7b60c9f80a0ab91d257029153dc3b6d8c27b98162104d1a66e1a23b182c9980f788cfbfcc82a015e7330000029640c00846b5096d92474fd446cc7edaf9f14572cab93a80e12384c1e829f95debc6e8373c2ce5402be53dc1a18cf92a0ed909e0fb38855713ef8ffb13502ffac7c830fa254cc1aa6c666a97b0cc3bc176538f6913d3b8e8981a65cc42df10e0f39e4d0a06dfe961437b59a71892f4fca1116aed15123ea0d86a7b2ce47dd9d3ef22d920631bc011e82babe03ad5d72b3ba7f95bf646f20ccf6f7a4d95de37397c76c7d53741458e51ab6074007f61181c7b88b7c98f5b7510c8dfa3be01f4841501679478b15c5249d928e2a10d15ec63efa1500b994d5bfb32ffb174a976116930eb97a111e6dfd4c5e43e04a5d76ba74806a62fda63a8c3f53f6eebaf852892340e81dd08bbf348454a2cf525aeb512cf33aeeee78465ee4c442e41cc45ac4e3bb0c3333677aa60332ee7f464d9020f8554b82d619872477cca18d8431888f4ae8abe5894e9720f759c410cd7991db12703dc147040dd0d3758223e0b75de6ceae49c1a0c2c45efedeb7114ae785cc886afdc45c82172e4476e1ab5b86dc4314dd76"; + String SIG1f = "c2c13b0400010a006f058262c806350910fbfcc82a015e7330471400000000001e002073616c74406e6f746174696f6e732e736571756f69612d7067702e6f7267b0409ed8ea96dac66447bdff5b7b60c9f80a0ab91d257029153dc3b6d8c27b98162104d1a66e1a23b182c9980f788cfbfcc82a015e7330000029640c00846b5096d92474fd446cc7edaf9f14572cab93a80e12384c1e829f95debc6e8373c2ce5402be53dc1a18cf92a0ed909e0fb38855713ef8ffb13502ffac7c830fa254cc1aa6c666a97b0cc3bc176538f6913d3b8e8981a65cc42df10e0f39e4d0a06dfe961437b59a71892f4fca1116aed15123ea0d86a7b2ce47dd9d3ef22d920631bc011e82babe03ad5d72b3ba7f95bf646f20ccf6f7a4d95de37397c76c7d53741458e51ab6074007f61181c7b88b7c98f5b7510c8dfa3be01f4841501679478b15c5249d928e2a10d15ec63efa1500b994d5bfb32ffb174a976116930eb97a111e6dfd4c5e43e04a5d76ba74806a62fda63a8c3f53f6eebaf852892340e81dd08bbf348454a2cf525aeb512cf33aeeee78465ee4c442e41cc45ac4e3bb0c3333677aa60332ee7f464d9020f8554b82d619872477cca18d8431888f4ae8abe5894e9720f759c410cd7991db12703dc147040dd0d3758223e0b75de6ceae49c1a0c2c45efedeb7114ae785cc886afdc45c82172e4476e1ab5b86dc4314dd76"; + String SIG2 = "c2c10400010a006f058262c806350910fbfcc82a015e7330471400000000001e002073616c74406e6f746174696f6e732e736571756f69612d7067702e6f7267a4d9c117dc7ba3a7e9270856f128d2ab271743eac3cb5750b22a89bd5fd60753162104d1a66e1a23b182c9980f788cfbfcc82a015e73300000b8400bff796c20fa8b25ff7a42686338e06417a2966e85a0fc2723c928bef6cd19d34cf5e7d55ada33080613012dadb79e0278e59d9e7ed7d2d6102912a5f768c2e75b60099225c3d8bfe0c123240188b80dbee89b9b3bd5b13ccc662abc37e2129b6968adac9aba43aa778c0fe4fe337591ee87a96a29a013debc83555293c877144fc676aa1b03782c501949521a320adf6ad96c4f2e036b52a18369c637fdc49033696a84d03a69580b953187fce5aca6fb26fc8815da9f3b513bfe8e304f33ecb4b521aeb7d09c4a284ea66123bd0d6a358b2526d762ca110e1f7f20b3038d774b64d5cfd34e2213765828359d7afc5bf24d5270e99d80c3c1568fa01624b6ea1e9ce4e6890ce9bacf6611a45d41e2671f68f5b096446bf08d27ce75608425b2e3ab92146229ad1fcd8224aca5b5f73960506e7df07bfbf3664348e8ecbfb2eb467b9cfe412cb377a6ee2eb5fd11be9cf9208fe9a74c296f52cfa02a1eb0519ad9a8349bf6ccd6495feb7e391451bf96e08a0798883dee5974e47cbf3b51f111b6d3"; + String SIG2f = "c2c13b0400010a006f058262c806350910fbfcc82a015e7330471400000000001e002073616c74406e6f746174696f6e732e736571756f69612d7067702e6f7267a4d9c117dc7ba3a7e9270856f128d2ab271743eac3cb5750b22a89bd5fd60753162104d1a66e1a23b182c9980f788cfbfcc82a015e73300000b8400bff796c20fa8b25ff7a42686338e06417a2966e85a0fc2723c928bef6cd19d34cf5e7d55ada33080613012dadb79e0278e59d9e7ed7d2d6102912a5f768c2e75b60099225c3d8bfe0c123240188b80dbee89b9b3bd5b13ccc662abc37e2129b6968adac9aba43aa778c0fe4fe337591ee87a96a29a013debc83555293c877144fc676aa1b03782c501949521a320adf6ad96c4f2e036b52a18369c637fdc49033696a84d03a69580b953187fce5aca6fb26fc8815da9f3b513bfe8e304f33ecb4b521aeb7d09c4a284ea66123bd0d6a358b2526d762ca110e1f7f20b3038d774b64d5cfd34e2213765828359d7afc5bf24d5270e99d80c3c1568fa01624b6ea1e9ce4e6890ce9bacf6611a45d41e2671f68f5b096446bf08d27ce75608425b2e3ab92146229ad1fcd8224aca5b5f73960506e7df07bfbf3664348e8ecbfb2eb467b9cfe412cb377a6ee2eb5fd11be9cf9208fe9a74c296f52cfa02a1eb0519ad9a8349bf6ccd6495feb7e391451bf96e08a0798883dee5974e47cbf3b51f111b6d3"; + String out = ""; + + String hex = Hex.toHexString(bytes.toByteArray()); + while (hex.contains(OPS)) { + hex = hex.replace(OPS, "[OPS]"); + } + while (hex.contains(LIT_H)) { + hex = hex.replace(LIT_H, "[LIT]"); + } + while (hex.contains(LIT)) { + hex = hex.replace(LIT, ""); + } + while (hex.contains(SIG1)) { + hex = hex.replace(SIG1, "[SIG1]"); + } + while (hex.contains(SIG1f)) { + hex = hex.replace(SIG1f, "[SIG1f]"); + } + while (hex.contains(SIG2)) { + hex = hex.replace(SIG2, "[SIG2]"); + } + while (hex.contains(SIG2f)) { + hex = hex.replace(SIG2f, "[SIG2f]"); + } + + return out + hex; } } @@ -796,27 +869,35 @@ public class OpenPgpMessageInputStream extends InputStream { String LIT_H = "cb28620000000000"; String LIT = "656e637279707420e28898207369676e20e28898207369676e20e28898207369676e"; String SIG1 = "c2c10400010a006f058262c806350910fbfcc82a015e7330471400000000001e002073616c74406e6f746174696f6e732e736571756f69612d7067702e6f7267b0409ed8ea96dac66447bdff5b7b60c9f80a0ab91d257029153dc3b6d8c27b98162104d1a66e1a23b182c9980f788cfbfcc82a015e7330000029640c00846b5096d92474fd446cc7edaf9f14572cab93a80e12384c1e829f95debc6e8373c2ce5402be53dc1a18cf92a0ed909e0fb38855713ef8ffb13502ffac7c830fa254cc1aa6c666a97b0cc3bc176538f6913d3b8e8981a65cc42df10e0f39e4d0a06dfe961437b59a71892f4fca1116aed15123ea0d86a7b2ce47dd9d3ef22d920631bc011e82babe03ad5d72b3ba7f95bf646f20ccf6f7a4d95de37397c76c7d53741458e51ab6074007f61181c7b88b7c98f5b7510c8dfa3be01f4841501679478b15c5249d928e2a10d15ec63efa1500b994d5bfb32ffb174a976116930eb97a111e6dfd4c5e43e04a5d76ba74806a62fda63a8c3f53f6eebaf852892340e81dd08bbf348454a2cf525aeb512cf33aeeee78465ee4c442e41cc45ac4e3bb0c3333677aa60332ee7f464d9020f8554b82d619872477cca18d8431888f4ae8abe5894e9720f759c410cd7991db12703dc147040dd0d3758223e0b75de6ceae49c1a0c2c45efedeb7114ae785cc886afdc45c82172e4476e1ab5b86dc4314dd76"; + String SIG1f = "c2c13b0400010a006f058262c806350910fbfcc82a015e7330471400000000001e002073616c74406e6f746174696f6e732e736571756f69612d7067702e6f7267b0409ed8ea96dac66447bdff5b7b60c9f80a0ab91d257029153dc3b6d8c27b98162104d1a66e1a23b182c9980f788cfbfcc82a015e7330000029640c00846b5096d92474fd446cc7edaf9f14572cab93a80e12384c1e829f95debc6e8373c2ce5402be53dc1a18cf92a0ed909e0fb38855713ef8ffb13502ffac7c830fa254cc1aa6c666a97b0cc3bc176538f6913d3b8e8981a65cc42df10e0f39e4d0a06dfe961437b59a71892f4fca1116aed15123ea0d86a7b2ce47dd9d3ef22d920631bc011e82babe03ad5d72b3ba7f95bf646f20ccf6f7a4d95de37397c76c7d53741458e51ab6074007f61181c7b88b7c98f5b7510c8dfa3be01f4841501679478b15c5249d928e2a10d15ec63efa1500b994d5bfb32ffb174a976116930eb97a111e6dfd4c5e43e04a5d76ba74806a62fda63a8c3f53f6eebaf852892340e81dd08bbf348454a2cf525aeb512cf33aeeee78465ee4c442e41cc45ac4e3bb0c3333677aa60332ee7f464d9020f8554b82d619872477cca18d8431888f4ae8abe5894e9720f759c410cd7991db12703dc147040dd0d3758223e0b75de6ceae49c1a0c2c45efedeb7114ae785cc886afdc45c82172e4476e1ab5b86dc4314dd76"; String SIG2 = "c2c10400010a006f058262c806350910fbfcc82a015e7330471400000000001e002073616c74406e6f746174696f6e732e736571756f69612d7067702e6f7267a4d9c117dc7ba3a7e9270856f128d2ab271743eac3cb5750b22a89bd5fd60753162104d1a66e1a23b182c9980f788cfbfcc82a015e73300000b8400bff796c20fa8b25ff7a42686338e06417a2966e85a0fc2723c928bef6cd19d34cf5e7d55ada33080613012dadb79e0278e59d9e7ed7d2d6102912a5f768c2e75b60099225c3d8bfe0c123240188b80dbee89b9b3bd5b13ccc662abc37e2129b6968adac9aba43aa778c0fe4fe337591ee87a96a29a013debc83555293c877144fc676aa1b03782c501949521a320adf6ad96c4f2e036b52a18369c637fdc49033696a84d03a69580b953187fce5aca6fb26fc8815da9f3b513bfe8e304f33ecb4b521aeb7d09c4a284ea66123bd0d6a358b2526d762ca110e1f7f20b3038d774b64d5cfd34e2213765828359d7afc5bf24d5270e99d80c3c1568fa01624b6ea1e9ce4e6890ce9bacf6611a45d41e2671f68f5b096446bf08d27ce75608425b2e3ab92146229ad1fcd8224aca5b5f73960506e7df07bfbf3664348e8ecbfb2eb467b9cfe412cb377a6ee2eb5fd11be9cf9208fe9a74c296f52cfa02a1eb0519ad9a8349bf6ccd6495feb7e391451bf96e08a0798883dee5974e47cbf3b51f111b6d3"; - String out = signature.getKeyID() + " last=" + signature.isContaining() + "\n"; + String SIG2f = "c2c13b0400010a006f058262c806350910fbfcc82a015e7330471400000000001e002073616c74406e6f746174696f6e732e736571756f69612d7067702e6f7267a4d9c117dc7ba3a7e9270856f128d2ab271743eac3cb5750b22a89bd5fd60753162104d1a66e1a23b182c9980f788cfbfcc82a015e73300000b8400bff796c20fa8b25ff7a42686338e06417a2966e85a0fc2723c928bef6cd19d34cf5e7d55ada33080613012dadb79e0278e59d9e7ed7d2d6102912a5f768c2e75b60099225c3d8bfe0c123240188b80dbee89b9b3bd5b13ccc662abc37e2129b6968adac9aba43aa778c0fe4fe337591ee87a96a29a013debc83555293c877144fc676aa1b03782c501949521a320adf6ad96c4f2e036b52a18369c637fdc49033696a84d03a69580b953187fce5aca6fb26fc8815da9f3b513bfe8e304f33ecb4b521aeb7d09c4a284ea66123bd0d6a358b2526d762ca110e1f7f20b3038d774b64d5cfd34e2213765828359d7afc5bf24d5270e99d80c3c1568fa01624b6ea1e9ce4e6890ce9bacf6611a45d41e2671f68f5b096446bf08d27ce75608425b2e3ab92146229ad1fcd8224aca5b5f73960506e7df07bfbf3664348e8ecbfb2eb467b9cfe412cb377a6ee2eb5fd11be9cf9208fe9a74c296f52cfa02a1eb0519ad9a8349bf6ccd6495feb7e391451bf96e08a0798883dee5974e47cbf3b51f111b6d3"; + String out = "last=" + signature.isContaining() + "\n"; - String hex = Hex.toHexString(bytes.toByteArray()); - while (hex.contains(OPS)) { - hex = hex.replace(OPS, "[OPS]"); - } - while (hex.contains(LIT_H)) { - hex = hex.replace(LIT_H, "[LIT]"); - } - while (hex.contains(LIT)) { - hex = hex.replace(LIT, ""); - } - while (hex.contains(SIG1)) { - hex = hex.replace(SIG1, "[SIG1]"); - } - while (hex.contains(SIG2)) { - hex = hex.replace(SIG2, "[SIG2]"); - } + String hex = Hex.toHexString(bytes.toByteArray()); + while (hex.contains(OPS)) { + hex = hex.replace(OPS, "[OPS]"); + } + while (hex.contains(LIT_H)) { + hex = hex.replace(LIT_H, "[LIT]"); + } + while (hex.contains(LIT)) { + hex = hex.replace(LIT, ""); + } + while (hex.contains(SIG1)) { + hex = hex.replace(SIG1, "[SIG1]"); + } + while (hex.contains(SIG1f)) { + hex = hex.replace(SIG1f, "[SIG1f]"); + } + while (hex.contains(SIG2)) { + hex = hex.replace(SIG2, "[SIG2]"); + } + while (hex.contains(SIG2f)) { + hex = hex.replace(SIG2f, "[SIG2f]"); + } - return out + hex; + return out + hex; } } } diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/TeeBCPGInputStream.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/TeeBCPGInputStream.java deleted file mode 100644 index cce21051..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/TeeBCPGInputStream.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.pgpainless.decryption_verification; - -import org.bouncycastle.bcpg.BCPGInputStream; -import org.pgpainless.util.ArmorUtils; - -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; - } -} diff --git a/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/OpenPgpMessageInputStreamTest.java b/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/OpenPgpMessageInputStreamTest.java index f780b2eb..46c521ef 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/OpenPgpMessageInputStreamTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/OpenPgpMessageInputStreamTest.java @@ -4,7 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -143,11 +142,11 @@ public class OpenPgpMessageInputStreamTest { "-----BEGIN PGP MESSAGE-----\n" + "Version: PGPainless\n" + "\n" + - "hF4Dyqa/GWUy6WsSAQdAQ62BwmUt8Iby0+jvrLhMgST79KR/as+dyl0nf1uki2sw\n" + - "Thg1Ojtf0hOyJgcpQ4nP2Q0wYFR0F1sCydaIlTGreYZHlGtybP7/Ml6KNZILTRWP\n" + - "0kYBkGBgK7oQWRIVyoF2POvEP6EX1X8nvQk7O3NysVdRVbnia7gE3AzRYuha4kxs\n" + - "pI6xJkntLMS3K6him1Y9FHINIASFSB+C\n" + - "=5p00\n" + + "hF4Dyqa/GWUy6WsSAQdAuGt49sQwdAHH3jPx11V3wSh7Amur3TbnONiQYJmMo3Qw\n" + + "87yBnZCsaB7evxLBgi6PpF3tiytHM60xlrPeKKPpJhu60vNafRM2OOwqk7AdcZw4\n" + + "0kYBEhiioO2btSuafNrQEjYzAgC7K6l7aPCcQObNp4ofryXu1P5vN+vUZp357hyS\n" + + "6zZqP+0wJQ9yJZMvFTtFeSaSi0oMP2sb\n" + + "=LvRL\n" + "-----END PGP MESSAGE-----"; public static final String OPS_LIT_SIG = "" + @@ -170,8 +169,8 @@ public class OpenPgpMessageInputStreamTest { // genKey(); // genSIG_LIT(); // genSENC_LIT(); - // genPENC_COMP_LIT(); - genOPS_LIT_SIG(); + genPENC_COMP_LIT(); + // genOPS_LIT_SIG(); } public static void genLIT() throws IOException { @@ -433,91 +432,144 @@ public class OpenPgpMessageInputStreamTest { assertNull(metadata.getCompressionAlgorithm()); } + String BOB_KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Comment: Bob's OpenPGP Transferable Secret Key\n" + + "\n" + + "lQVYBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv\n" + + "/seOXpgecTdOcVttfzC8ycIKrt3aQTiwOG/ctaR4Bk/t6ayNFfdUNxHWk4WCKzdz\n" + + "/56fW2O0F23qIRd8UUJp5IIlN4RDdRCtdhVQIAuzvp2oVy/LaS2kxQoKvph/5pQ/\n" + + "5whqsyroEWDJoSV0yOb25B/iwk/pLUFoyhDG9bj0kIzDxrEqW+7Ba8nocQlecMF3\n" + + "X5KMN5kp2zraLv9dlBBpWW43XktjcCZgMy20SouraVma8Je/ECwUWYUiAZxLIlMv\n" + + "9CurEOtxUw6N3RdOtLmYZS9uEnn5y1UkF88o8Nku890uk6BrewFzJyLAx5wRZ4F0\n" + + "qV/yq36UWQ0JB/AUGhHVPdFf6pl6eaxBwT5GXvbBUibtf8YI2og5RsgTWtXfU7eb\n" + + "SGXrl5ZMpbA6mbfhd0R8aPxWfmDWiIOhBufhMCvUHh1sApMKVZnvIff9/0Dca3wb\n" + + "vLIwa3T4CyshfT0AEQEAAQAL/RZqbJW2IqQDCnJi4Ozm++gPqBPiX1RhTWSjwxfM\n" + + "cJKUZfzLj414rMKm6Jh1cwwGY9jekROhB9WmwaaKT8HtcIgrZNAlYzANGRCM4TLK\n" + + "3VskxfSwKKna8l+s+mZglqbAjUg3wmFuf9Tj2xcUZYmyRm1DEmcN2ZzpvRtHgX7z\n" + + "Wn1mAKUlSDJZSQks0zjuMNbupcpyJokdlkUg2+wBznBOTKzgMxVNC9b2g5/tMPUs\n" + + "hGGWmF1UH+7AHMTaS6dlmr2ZBIyogdnfUqdNg5sZwsxSNrbglKP4sqe7X61uEAIQ\n" + + "bD7rT3LonLbhkrj3I8wilUD8usIwt5IecoHhd9HziqZjRCc1BUBkboUEoyedbDV4\n" + + "i4qfsFZ6CEWoLuD5pW7dEp0M+WeuHXO164Rc+LnH6i1VQrpb1Okl4qO6ejIpIjBI\n" + + "1t3GshtUu/mwGBBxs60KBX5g77mFQ9lLCRj8lSYqOsHRKBhUp4qM869VA+fD0BRP\n" + + "fqPT0I9IH4Oa/A3jYJcg622GwQYA1LhnP208Waf6PkQSJ6kyr8ymY1yVh9VBE/g6\n" + + "fRDYA+pkqKnw9wfH2Qho3ysAA+OmVOX8Hldg+Pc0Zs0e5pCavb0En8iFLvTA0Q2E\n" + + "LR5rLue9uD7aFuKFU/VdcddY9Ww/vo4k5p/tVGp7F8RYCFn9rSjIWbfvvZi1q5Tx\n" + + "+akoZbga+4qQ4WYzB/obdX6SCmi6BndcQ1QdjCCQU6gpYx0MddVERbIp9+2SXDyL\n" + + "hpxjSyz+RGsZi/9UAshT4txP4+MZBgDfK3ZqtW+h2/eMRxkANqOJpxSjMyLO/FXN\n" + + "WxzTDYeWtHNYiAlOwlQZEPOydZFty9IVzzNFQCIUCGjQ/nNyhw7adSgUk3+BXEx/\n" + + "MyJPYY0BYuhLxLYcrfQ9nrhaVKxRJj25SVHj2ASsiwGJRZW4CC3uw40OYxfKEvNC\n" + + "mer/VxM3kg8qqGf9KUzJ1dVdAvjyx2Hz6jY2qWCyRQ6IMjWHyd43C4r3jxooYKUC\n" + + "YnstRQyb/gCSKahveSEjo07CiXMr88UGALwzEr3npFAsPW3osGaFLj49y1oRe11E\n" + + "he9gCHFm+fuzbXrWmdPjYU5/ZdqdojzDqfu4ThfnipknpVUM1o6MQqkjM896FHm8\n" + + "zbKVFSMhEP6DPHSCexMFrrSgN03PdwHTO6iBaIBBFqmGY01tmJ03SxvSpiBPON9P\n" + + "NVvy/6UZFedTq8A07OUAxO62YUSNtT5pmK2vzs3SAZJmbFbMh+NN204TRI72GlqT\n" + + "t5hcfkuv8hrmwPS/ZR6q312mKQ6w/1pqO9qitCFCb2IgQmFiYmFnZSA8Ym9iQG9w\n" + + "ZW5wZ3AuZXhhbXBsZT6JAc4EEwEKADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgEC\n" + + "F4AWIQTRpm4aI7GCyZgPeIz7/MgqAV5zMAUCXaWe+gAKCRD7/MgqAV5zMG9sC/9U\n" + + "2T3RrqEbw533FPNfEflhEVRIZ8gDXKM8hU6cqqEzCmzZT6xYTe6sv4y+PJBGXJFX\n" + + "yhj0g6FDkSyboM5litOcTupURObVqMgA/Y4UKERznm4fzzH9qek85c4ljtLyNufe\n" + + "doL2pp3vkGtn7eD0QFRaLLmnxPKQ/TlZKdLE1G3u8Uot8QHicaR6GnAdc5UXQJE3\n" + + "BiV7jZuDyWmZ1cUNwJkKL6oRtp+ZNDOQCrLNLecKHcgCqrpjSQG5oouba1I1Q6Vl\n" + + "sP44dhA1nkmLHtxlTOzpeHj4jnk1FaXmyasurrrI5CgU/L2Oi39DGKTH/A/cywDN\n" + + "4ZplIQ9zR8enkbXquUZvFDe+Xz+6xRXtb5MwQyWODB3nHw85HocLwRoIN9WdQEI+\n" + + "L8a/56AuOwhs8llkSuiITjR7r9SgKJC2WlAHl7E8lhJ3VDW3ELC56KH308d6mwOG\n" + + "ZRAqIAKzM1T5FGjMBhq7ZV0eqdEntBh3EcOIfj2M8rg1MzJv+0mHZOIjByawikad\n" + + "BVgEXaWc8gEMANYwv1xsYyunXYK0X1vY/rP1NNPvhLyLIE7NpK90YNBj+xS1ldGD\n" + + "bUdZqZeef2xJe8gMQg05DoD1DF3GipZ0Ies65beh+d5hegb7N4pzh0LzrBrVNHar\n" + + "29b5ExdI7i4iYD5TO6Vr/qTUOiAN/byqELEzAb+L+b2DVz/RoCm4PIp1DU9ewcc2\n" + + "WB38Ofqut3nLYA5tqJ9XvAiEQme+qAVcM3ZFcaMt4I4dXhDZZNg+D9LiTWcxdUPB\n" + + "leu8iwDRjAgyAhPzpFp+nWoqWA81uIiULWD1Fj+IVoY3ZvgivoYOiEFBJ9lbb4te\n" + + "g9m5UT/AaVDTWuHzbspVlbiVe+qyB77C2daWzNyx6UYBPLOo4r0t0c91kbNE5lgj\n" + + "Z7xz6los0N1U8vq91EFSeQJoSQ62XWavYmlCLmdNT6BNfgh4icLsT7Vr1QMX9jzn\n" + + "JtTPxdXytSdHvpSpULsqJ016l0dtmONcK3z9mj5N5z0k1tg1AH970TGYOe2aUcSx\n" + + "IRDMXDOPyzEfjwARAQABAAv9F2CwsjS+Sjh1M1vegJbZjei4gF1HHpEM0K0PSXsp\n" + + "SfVvpR4AoSJ4He6CXSMWg0ot8XKtDuZoV9jnJaES5UL9pMAD7JwIOqZm/DYVJM5h\n" + + "OASCh1c356/wSbFbzRHPtUdZO9Q30WFNJM5pHbCJPjtNoRmRGkf71RxtvHBzy7np\n" + + "Ga+W6U/NVKHw0i0CYwMI0YlKDakYW3Pm+QL+gHZFvngGweTod0f9l2VLLAmeQR/c\n" + + "+EZs7lNumhuZ8mXcwhUc9JQIhOkpO+wreDysEFkAcsKbkQP3UDUsA1gFx9pbMzT0\n" + + "tr1oZq2a4QBtxShHzP/ph7KLpN+6qtjks3xB/yjTgaGmtrwM8tSe0wD1RwXS+/1o\n" + + "BHpXTnQ7TfeOGUAu4KCoOQLv6ELpKWbRBLWuiPwMdbGpvVFALO8+kvKAg9/r+/ny\n" + + "zM2GQHY+J3Jh5JxPiJnHfXNZjIKLbFbIPdSKNyJBuazXW8xIa//mEHMI5OcvsZBK\n" + + "clAIp7LXzjEjKXIwHwDcTn9pBgDpdOKTHOtJ3JUKx0rWVsDH6wq6iKV/FTVSY5jl\n" + + "zN+puOEsskF1Lfxn9JsJihAVO3yNsp6RvkKtyNlFazaCVKtDAmkjoh60XNxcNRqr\n" + + "gCnwdpbgdHP6v/hvZY54ZaJjz6L2e8unNEkYLxDt8cmAyGPgH2XgL7giHIp9jrsQ\n" + + "aS381gnYwNX6wE1aEikgtY91nqJjwPlibF9avSyYQoMtEqM/1UjTjB2KdD/MitK5\n" + + "fP0VpvuXpNYZedmyq4UOMwdkiNMGAOrfmOeT0olgLrTMT5H97Cn3Yxbk13uXHNu/\n" + + "ZUZZNe8s+QtuLfUlKAJtLEUutN33TlWQY522FV0m17S+b80xJib3yZVJteVurrh5\n" + + "HSWHAM+zghQAvCesg5CLXa2dNMkTCmZKgCBvfDLZuZbjFwnwCI6u/NhOY9egKuUf\n" + + "SA/je/RXaT8m5VxLYMxwqQXKApzD87fv0tLPlVIEvjEsaf992tFEFSNPcG1l/jpd\n" + + "5AVXw6kKuf85UkJtYR1x2MkQDrqY1QX/XMw00kt8y9kMZUre19aCArcmor+hDhRJ\n" + + "E3Gt4QJrD9z/bICESw4b4z2DbgD/Xz9IXsA/r9cKiM1h5QMtXvuhyfVeM01enhxM\n" + + "GbOH3gjqqGNKysx0UODGEwr6AV9hAd8RWXMchJLaExK9J5SRawSg671ObAU24SdY\n" + + "vMQ9Z4kAQ2+1ReUZzf3ogSMRZtMT+d18gT6L90/y+APZIaoArLPhebIAGq39HLmJ\n" + + "26x3z0WAgrpA1kNsjXEXkoiZGPLKIGoe3hqJAbYEGAEKACAWIQTRpm4aI7GCyZgP\n" + + "eIz7/MgqAV5zMAUCXaWc8gIbDAAKCRD7/MgqAV5zMOn/C/9ugt+HZIwX308zI+QX\n" + + "c5vDLReuzmJ3ieE0DMO/uNSC+K1XEioSIZP91HeZJ2kbT9nn9fuReuoff0T0Dief\n" + + "rbwcIQQHFFkrqSp1K3VWmUGp2JrUsXFVdjy/fkBIjTd7c5boWljv/6wAsSfiv2V0\n" + + "JSM8EFU6TYXxswGjFVfc6X97tJNeIrXL+mpSmPPqy2bztcCCHkWS5lNLWQw+R7Vg\n" + + "71Fe6yBSNVrqC2/imYG2J9zlowjx1XU63Wdgqp2Wxt0l8OmsB/W80S1fRF5G4SDH\n" + + "s9HXglXXqPsBRZJYfP+VStm9L5P/sKjCcX6WtZR7yS6G8zj/X767MLK/djANvpPd\n" + + "NVniEke6hM3CNBXYPAMhQBMWhCulcoz+0lxi8L34rMN+Dsbma96psdUrn7uLaB91\n" + + "6we0CTfF8qqm7BsVAgalon/UUiuMY80U3ueoj3okiSTiHIjD/YtpXSPioC8nMng7\n" + + "xqAY9Bwizt4FWgXuLm1a4+So4V9j1TRCXd12Uc2l2RNmgDE=\n" + + "=miES\n" + + "-----END PGP PRIVATE KEY BLOCK-----"; + + @ParameterizedTest(name = "Process PENC(OPS OPS LIT SIG SIG) using {0}") + @MethodSource("provideMessageProcessors") + public void testProcessPENC_OPS_OPS_LIT_SIG_SIG(Processor processor) throws IOException, PGPException { + String MSG = "-----BEGIN PGP MESSAGE-----\n" + + "\n" + + "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\n" + + "=mdYs\n" + + "-----END PGP MESSAGE-----\n"; + PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(BOB_KEY); + PGPPublicKeyRing certificate = PGPainless.extractCertificate(secretKeys); + + Tuple result = processor.process(MSG, ConsumerOptions.get() + .addVerificationCert(certificate) + .addDecryptionKey(secretKeys)); + String plain = result.getA(); + assertEquals("encrypt ∘ sign ∘ sign", plain); + MessageMetadata metadata = result.getB(); + assertEquals(SymmetricKeyAlgorithm.AES_256, metadata.getEncryptionAlgorithm()); + assertNull(metadata.getCompressionAlgorithm()); + } + @ParameterizedTest(name = "Process PENC(OPS OPS OPS LIT SIG SIG SIG) using {0}") @MethodSource("provideMessageProcessors") public void testProcessOPS_OPS_OPS_LIT_SIG_SIG_SIG(Processor processor) throws IOException, PGPException { - String KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + - "Comment: Bob's OpenPGP Transferable Secret Key\n" + - "\n" + - "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\n" + - "=miES\n" + - "-----END PGP PRIVATE KEY BLOCK-----"; String MSG = "-----BEGIN PGP MESSAGE-----\n" + "\n" + "wcDMA3wvqk35PDeyAQwA0yaEgydkAMEfl7rDTYVGanLKiFiWIs34mkF+LB8qR5eY\n" + @@ -565,7 +617,7 @@ public class OpenPgpMessageInputStreamTest { "x12WVuyITVU3fCfHp6/0A6wPtJezCvoodqPlw/3fd5eSVYzb5C3v564uhz4=\n" + "=JP9T\n" + "-----END PGP MESSAGE-----"; - PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY); + PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(BOB_KEY); PGPPublicKeyRing certificate = PGPainless.extractCertificate(secretKeys); Tuple result = processor.process(MSG, ConsumerOptions.get() diff --git a/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/TeeBCPGInputStreamTest.java b/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/TeeBCPGInputStreamTest.java deleted file mode 100644 index d31c6009..00000000 --- a/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/TeeBCPGInputStreamTest.java +++ /dev/null @@ -1,61 +0,0 @@ -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 org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -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 Logger LOGGER = LoggerFactory.getLogger(TeeBCPGInputStreamTest.class); - 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) { - LOGGER.debug(OpenPgpPacket.requireFromTag(tag).toString()); - Packet packet = nestedTeeIn.readPacket(); - } - - nestedArmorOut.close(); - LOGGER.debug(nestedOut.toString()); - } -}