From a46f1706369c3bceb3abaaabd12a4b37427d3cfa Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Thu, 15 May 2025 14:50:21 +0200 Subject: [PATCH] Test edge-cases in inline-detach operation --- .../org/pgpainless/sop/InlineDetachTest.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/pgpainless-sop/src/test/java/org/pgpainless/sop/InlineDetachTest.java b/pgpainless-sop/src/test/java/org/pgpainless/sop/InlineDetachTest.java index acbba821..ebb39694 100644 --- a/pgpainless-sop/src/test/java/org/pgpainless/sop/InlineDetachTest.java +++ b/pgpainless-sop/src/test/java/org/pgpainless/sop/InlineDetachTest.java @@ -5,6 +5,8 @@ package org.pgpainless.sop; import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -23,10 +25,16 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.api.OpenPGPImplementation; +import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.util.io.Streams; import org.junit.jupiter.api.Test; import org.pgpainless.PGPainless; +import org.pgpainless.algorithm.CompressionAlgorithm; +import org.pgpainless.encryption_signing.EncryptionStream; +import org.pgpainless.encryption_signing.ProducerOptions; +import org.pgpainless.encryption_signing.SigningOptions; import org.pgpainless.key.OpenPgpV4Fingerprint; +import org.pgpainless.key.protection.SecretKeyRingProtector; import sop.ByteArrayAndResult; import sop.SOP; import sop.Signatures; @@ -201,4 +209,62 @@ public class InlineDetachTest { assertArrayEquals(data, message); } + + @Test + public void detachSignaturesFromCompressedMessage() throws PGPException, IOException { + PGPainless api = PGPainless.getInstance(); + OpenPGPKey key = api.generateKey() + .modernKeyRing("Alice "); + byte[] cert = key.toCertificate().getEncoded(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + EncryptionStream eOut = api.generateMessage() + .onOutputStream(bOut) + .withOptions(ProducerOptions.sign( + SigningOptions.get().addInlineSignature(SecretKeyRingProtector.unprotectedKeys(), key) + ).overrideCompressionAlgorithm(CompressionAlgorithm.ZIP)); + eOut.write("Hello, World!\n".getBytes(StandardCharsets.UTF_8)); + eOut.close(); + + ByteArrayAndResult result = sop.inlineDetach() + .message(bOut.toByteArray()) + .toByteArrayAndResult(); + + byte[] message = result.getBytes(); + byte[] signatures = result.getResult().getBytes(); + + List verifications = sop.detachedVerify() + .cert(cert) + .signatures(signatures) + .data(message); + + assertFalse(verifications.isEmpty()); + } + + @Test + public void detachMissingSignaturesFails() throws PGPException, IOException { + PGPainless api = PGPainless.getInstance(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + EncryptionStream eOut = api.generateMessage() + .onOutputStream(bOut) + .withOptions(ProducerOptions.noEncryptionNoSigning() + .overrideCompressionAlgorithm(CompressionAlgorithm.ZIP)); + + eOut.write("Hello, World!\n".getBytes(StandardCharsets.UTF_8)); + eOut.close(); + + assertThrows(SOPGPException.BadData.class, () -> + sop.inlineDetach() + .message(bOut.toByteArray()) + .toByteArrayAndResult()); + } + + @Test + public void detachBadDataFails() { + byte[] bytes = "Hello, World\n".getBytes(StandardCharsets.UTF_8); + assertThrows(SOPGPException.BadData.class, () -> + sop.inlineDetach().message(bytes) + .toByteArrayAndResult()); + } }