mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-26 12:58:02 +01:00
Allow setting custom version header when encrypting/signing message
This commit is contained in:
parent
add1b89019
commit
41e663e25b
4 changed files with 109 additions and 7 deletions
|
@ -99,6 +99,12 @@ public final class EncryptionStream extends OutputStream {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (options.hasVersion()) {
|
||||
String version = options.getVersion().trim();
|
||||
if (!version.isEmpty()) {
|
||||
ArmorUtils.setVersionHeader(armorOutputStream, version);
|
||||
}
|
||||
}
|
||||
outermostStream = armorOutputStream;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ public final class ProducerOptions {
|
|||
.defaultCompressionAlgorithm();
|
||||
private boolean asciiArmor = true;
|
||||
private String comment = null;
|
||||
private String version = null;
|
||||
|
||||
private ProducerOptions(EncryptionOptions encryptionOptions, SigningOptions signingOptions) {
|
||||
this.encryptionOptions = encryptionOptions;
|
||||
|
@ -120,7 +121,7 @@ public final class ProducerOptions {
|
|||
* Set the comment header in ASCII armored output.
|
||||
* The default value is null, which means no comment header is added.
|
||||
* Multiline comments are possible using '\\n'.
|
||||
*
|
||||
* <br>
|
||||
* Note: If a default header comment is set using {@link org.pgpainless.util.ArmoredOutputStreamFactory#setComment(String)},
|
||||
* then both comments will be written to the produced ASCII armor.
|
||||
*
|
||||
|
@ -128,13 +129,25 @@ public final class ProducerOptions {
|
|||
* @return builder
|
||||
*/
|
||||
public ProducerOptions setComment(String comment) {
|
||||
if (!asciiArmor) {
|
||||
throw new IllegalArgumentException("Comment can only be set when ASCII armoring is enabled.");
|
||||
}
|
||||
this.comment = comment;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the version header in ASCII armored output.
|
||||
* The default value is null, which means no version header is added.
|
||||
* <br>
|
||||
* Note: If the value is non-null, then this method overrides the default version header set using
|
||||
* {@link org.pgpainless.util.ArmoredOutputStreamFactory#setVersionInfo(String)}.
|
||||
*
|
||||
* @param version version header, or null for no version info.
|
||||
* @return builder
|
||||
*/
|
||||
public ProducerOptions setVersion(String version) {
|
||||
this.version = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return comment set for header in ascii armored output.
|
||||
*
|
||||
|
@ -144,15 +157,33 @@ public final class ProducerOptions {
|
|||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the version info header in ascii armored output.
|
||||
*
|
||||
* @return version info
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a comment was set (!= null).
|
||||
*
|
||||
* @return comment
|
||||
* @return true if commend is set
|
||||
*/
|
||||
public boolean hasComment() {
|
||||
return comment != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a version header was set (!= null).
|
||||
*
|
||||
* @return true if version header is set
|
||||
*/
|
||||
public boolean hasVersion() {
|
||||
return version != null;
|
||||
}
|
||||
|
||||
public ProducerOptions setCleartextSigned() {
|
||||
if (signingOptions == null) {
|
||||
throw new IllegalArgumentException("Signing Options cannot be null if cleartext signing is enabled.");
|
||||
|
@ -233,7 +264,7 @@ public final class ProducerOptions {
|
|||
/**
|
||||
* Set format metadata field of the literal data packet.
|
||||
* Defaults to {@link StreamEncoding#BINARY}.
|
||||
*
|
||||
* <br>
|
||||
* This does not change the encoding of the wrapped data itself.
|
||||
* To apply CR/LF encoding to your input data before processing, use {@link #applyCRLFEncoding()} instead.
|
||||
*
|
||||
|
@ -257,7 +288,7 @@ public final class ProducerOptions {
|
|||
/**
|
||||
* Apply special encoding of line endings to the input data.
|
||||
* By default, this is disabled, which means that the data is not altered.
|
||||
*
|
||||
* <br>
|
||||
* Enabling it will change the line endings to CR/LF.
|
||||
* Note: The encoding will not be reversed when decrypting, so applying CR/LF encoding will result in
|
||||
* the identity "decrypt(encrypt(data)) == data == verify(sign(data))".
|
||||
|
|
|
@ -417,6 +417,22 @@ public final class ArmorUtils {
|
|||
return new Tuple<>(printed, countIdentities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the version header entry in the ASCII armor.
|
||||
* If the version info is null or only contains whitespace characters, then the version header will be removed.
|
||||
*
|
||||
* @param armor armored output stream
|
||||
* @param version version header.
|
||||
*/
|
||||
public static void setVersionHeader(@Nonnull ArmoredOutputStream armor,
|
||||
@Nullable String version) {
|
||||
if (version == null || version.trim().isEmpty()) {
|
||||
armor.setHeader(HEADER_VERSION, null);
|
||||
} else {
|
||||
armor.setHeader(HEADER_VERSION, version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an ASCII armor header entry about the used hash algorithm into the {@link ArmoredOutputStream}.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.encryption_signing;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pgpainless.PGPainless;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class AsciiArmorTest {
|
||||
|
||||
@Test
|
||||
public void testCustomAsciiArmorComments() throws PGPException, IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign()
|
||||
.onOutputStream(out)
|
||||
.withOptions(ProducerOptions.noEncryptionNoSigning()
|
||||
.setAsciiArmor(true)
|
||||
.setComment("This is a comment.\nThis is another comment."));
|
||||
encryptionStream.write("Hello, World!".getBytes(StandardCharsets.UTF_8));
|
||||
encryptionStream.close();
|
||||
|
||||
String asciiArmored = out.toString();
|
||||
assertTrue(asciiArmored.contains("Comment: This is a comment."));
|
||||
assertTrue(asciiArmored.contains("Comment: This is another comment."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomAsciiArmorVersion() throws IOException, PGPException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign()
|
||||
.onOutputStream(out)
|
||||
.withOptions(ProducerOptions.noEncryptionNoSigning()
|
||||
.setAsciiArmor(true)
|
||||
.setVersion("Custom-PGP 1.2.3"));
|
||||
encryptionStream.write("Hello, World!".getBytes(StandardCharsets.UTF_8));
|
||||
encryptionStream.close();
|
||||
|
||||
String asciiArmored = out.toString();
|
||||
assertTrue(asciiArmored.contains("Version: Custom-PGP 1.2.3"));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue