diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/ArmorImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/ArmorImpl.java index 71bc3e6b..d65c2925 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/ArmorImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/ArmorImpl.java @@ -11,6 +11,7 @@ import java.io.OutputStream; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.util.io.Streams; +import org.pgpainless.decryption_verification.OpenPgpInputStream; import org.pgpainless.util.ArmoredOutputStreamFactory; import sop.Ready; import sop.enums.ArmorLabel; @@ -31,8 +32,21 @@ public class ArmorImpl implements Armor { public void writeTo(OutputStream outputStream) throws IOException { // By buffering the output stream, we can improve performance drastically BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream); + + // Determine nature of the given data + OpenPgpInputStream openPgpIn = new OpenPgpInputStream(data); + openPgpIn.reset(); + + if (openPgpIn.isAsciiArmored()) { + // armoring already-armored data is an idempotent operation + Streams.pipeAll(openPgpIn, bufferedOutputStream); + bufferedOutputStream.flush(); + openPgpIn.close(); + return; + } + ArmoredOutputStream armor = ArmoredOutputStreamFactory.get(bufferedOutputStream); - Streams.pipeAll(data, armor); + Streams.pipeAll(openPgpIn, armor); bufferedOutputStream.flush(); armor.close(); } diff --git a/pgpainless-sop/src/test/java/org/pgpainless/sop/ArmorTest.java b/pgpainless-sop/src/test/java/org/pgpainless/sop/ArmorTest.java index 95129dfa..3830912a 100644 --- a/pgpainless-sop/src/test/java/org/pgpainless/sop/ArmorTest.java +++ b/pgpainless-sop/src/test/java/org/pgpainless/sop/ArmorTest.java @@ -29,7 +29,9 @@ public class ArmorTest { @Test public void armor() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { byte[] data = PGPainless.generateKeyRing().modernKeyRing("Alice").getEncoded(); - byte[] knownGoodArmor = ArmorUtils.toAsciiArmoredString(data).getBytes(StandardCharsets.UTF_8); + byte[] knownGoodArmor = ArmorUtils.toAsciiArmoredString(data) + .replace("Version: PGPainless\n", "") // armor command does not add version anymore + .getBytes(StandardCharsets.UTF_8); byte[] armored = new SOPImpl() .armor() .data(data)