From 3023d532e3a36e793538380915b7e0b81716fa5d Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Wed, 16 Nov 2022 15:32:15 +0100 Subject: [PATCH] Make DecryptionStream.getMetadata() first-class, deprecate getResult() --- .../CloseForResultInputStream.java | 39 ------------------- .../DecryptionStream.java | 12 ++++-- .../MessageMetadata.java | 35 +++++++++++++++++ .../OpenPgpMessageInputStream.java | 33 ++-------------- 4 files changed, 46 insertions(+), 73 deletions(-) delete mode 100644 pgpainless-core/src/main/java/org/pgpainless/decryption_verification/CloseForResultInputStream.java diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/CloseForResultInputStream.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/CloseForResultInputStream.java deleted file mode 100644 index ba895a08..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/CloseForResultInputStream.java +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.decryption_verification; - -import java.io.IOException; -import java.io.InputStream; -import javax.annotation.Nonnull; - -public abstract class CloseForResultInputStream extends InputStream { - - protected final OpenPgpMetadata.Builder resultBuilder; - private boolean isClosed = false; - - public CloseForResultInputStream(@Nonnull OpenPgpMetadata.Builder resultBuilder) { - this.resultBuilder = resultBuilder; - } - - @Override - public void close() throws IOException { - this.isClosed = true; - } - - /** - * Return the result of the decryption. - * The result contains metadata about the decryption, such as signatures, used keys and algorithms, as well as information - * about the decrypted file/stream. - * - * Can only be obtained once the stream got successfully closed ({@link #close()}). - * @return metadata - */ - public OpenPgpMetadata getResult() { - if (!isClosed) { - throw new IllegalStateException("Stream MUST be closed before the result can be accessed."); - } - return resultBuilder.build(); - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStream.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStream.java index 0f221ad7..e3a51bb9 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStream.java +++ b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStream.java @@ -4,10 +4,14 @@ package org.pgpainless.decryption_verification; -import javax.annotation.Nonnull; +import java.io.InputStream; -public abstract class DecryptionStream extends CloseForResultInputStream { - public DecryptionStream(@Nonnull OpenPgpMetadata.Builder resultBuilder) { - super(resultBuilder); +public abstract class DecryptionStream extends InputStream { + + public abstract MessageMetadata getMetadata(); + + @Deprecated + public OpenPgpMetadata getResult() { + return getMetadata().toLegacyMetadata(); } } diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/MessageMetadata.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/MessageMetadata.java index 7811578e..26439b40 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/MessageMetadata.java +++ b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/MessageMetadata.java @@ -300,9 +300,16 @@ public class MessageMetadata { public static class Message extends Layer { + protected boolean cleartextSigned; + public Message() { super(0); } + + public boolean isCleartextSigned() { + return cleartextSigned; + } + } public static class LiteralData implements Nested { @@ -453,4 +460,32 @@ public class MessageMetadata { abstract O getProperty(Layer last); } + public OpenPgpMetadata toLegacyMetadata() { + OpenPgpMetadata.Builder resultBuilder = OpenPgpMetadata.getBuilder(); + resultBuilder.setCompressionAlgorithm(getCompressionAlgorithm()); + resultBuilder.setModificationDate(getModificationDate()); + resultBuilder.setFileName(getFilename()); + resultBuilder.setFileEncoding(getFormat()); + resultBuilder.setSessionKey(getSessionKey()); + resultBuilder.setDecryptionKey(getDecryptionKey()); + + for (SignatureVerification accepted : getVerifiedDetachedSignatures()) { + resultBuilder.addVerifiedDetachedSignature(accepted); + } + for (SignatureVerification.Failure rejected : getRejectedDetachedSignatures()) { + resultBuilder.addInvalidDetachedSignature(rejected.getSignatureVerification(), rejected.getValidationException()); + } + + for (SignatureVerification accepted : getVerifiedInlineSignatures()) { + resultBuilder.addVerifiedInbandSignature(accepted); + } + for (SignatureVerification.Failure rejected : getRejectedInlineSignatures()) { + resultBuilder.addInvalidInbandSignature(rejected.getSignatureVerification(), rejected.getValidationException()); + } + if (message.isCleartextSigned()) { + resultBuilder.setCleartextSigned(); + } + + return resultBuilder.build(); + } } 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 a73b5154..a820dca5 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 @@ -156,6 +156,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream { if (openPgpIn.isAsciiArmored()) { ArmoredInputStream armorIn = ArmoredInputStreamFactory.get(openPgpIn); if (armorIn.isClearText()) { + ((MessageMetadata.Message) metadata).cleartextSigned = true; return new OpenPgpMessageInputStream(Type.cleartext_signed, armorIn, options, metadata, policy); } else { @@ -173,7 +174,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream { @Nonnull MessageMetadata.Layer metadata, @Nonnull Policy policy) throws PGPException, IOException { - super(OpenPgpMetadata.getBuilder()); + super(); this.policy = policy; this.options = options; @@ -203,7 +204,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream { @Nonnull ConsumerOptions options, @Nonnull MessageMetadata.Layer metadata, @Nonnull Policy policy) throws PGPException, IOException { - super(OpenPgpMetadata.getBuilder()); + super(); this.policy = policy; this.options = options; this.metadata = metadata; @@ -226,7 +227,6 @@ public class OpenPgpMessageInputStream extends DecryptionStream { // Cleartext Signature Framework (probably signed message) case cleartext_signed: - resultBuilder.setCleartextSigned(); MultiPassStrategy multiPassStrategy = options.getMultiPassStrategy(); PGPSignatureList detachedSignatures = ClearsignedMessageUtil .detachSignaturesFromInbandClearsignedMessage( @@ -799,33 +799,6 @@ public class OpenPgpMessageInputStream extends DecryptionStream { return new MessageMetadata((MessageMetadata.Message) metadata); } - @Override - public OpenPgpMetadata getResult() { - MessageMetadata m = getMetadata(); - resultBuilder.setCompressionAlgorithm(m.getCompressionAlgorithm()); - resultBuilder.setModificationDate(m.getModificationDate()); - resultBuilder.setFileName(m.getFilename()); - resultBuilder.setFileEncoding(m.getFormat()); - resultBuilder.setSessionKey(m.getSessionKey()); - resultBuilder.setDecryptionKey(m.getDecryptionKey()); - - for (SignatureVerification accepted : m.getVerifiedDetachedSignatures()) { - resultBuilder.addVerifiedDetachedSignature(accepted); - } - for (SignatureVerification.Failure rejected : m.getRejectedDetachedSignatures()) { - resultBuilder.addInvalidDetachedSignature(rejected.getSignatureVerification(), rejected.getValidationException()); - } - - for (SignatureVerification accepted : m.getVerifiedInlineSignatures()) { - resultBuilder.addVerifiedInbandSignature(accepted); - } - for (SignatureVerification.Failure rejected : m.getRejectedInlineSignatures()) { - resultBuilder.addInvalidInbandSignature(rejected.getSignatureVerification(), rejected.getValidationException()); - } - - return resultBuilder.build(); - } - private static class SortedESKs { private final List skesks = new ArrayList<>();