1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-01-09 19:57:57 +01:00

Move file-related encryption-info into ProducerOptions

This commit is contained in:
Paul Schaub 2021-07-10 12:22:47 +02:00
parent 447c08b446
commit 2ba782c451
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
7 changed files with 111 additions and 77 deletions

View file

@ -156,12 +156,12 @@ public class OpenPgpMetadata {
public static final String FOR_YOUR_EYES_ONLY = PGPLiteralData.CONSOLE; public static final String FOR_YOUR_EYES_ONLY = PGPLiteralData.CONSOLE;
protected final String fileName; protected final String fileName;
protected final Date modicationDate; protected final Date modificationDate;
protected final StreamEncoding streamEncoding; protected final StreamEncoding streamEncoding;
public FileInfo(String fileName, Date modicationDate, StreamEncoding streamEncoding) { public FileInfo(String fileName, Date modificationDate, StreamEncoding streamEncoding) {
this.fileName = fileName == null ? "" : fileName; this.fileName = fileName == null ? "" : fileName;
this.modicationDate = modicationDate == null ? PGPLiteralData.NOW : modicationDate; this.modificationDate = modificationDate == null ? PGPLiteralData.NOW : modificationDate;
this.streamEncoding = streamEncoding; this.streamEncoding = streamEncoding;
} }
@ -182,7 +182,7 @@ public class OpenPgpMetadata {
} }
public Date getModificationDate() { public Date getModificationDate() {
return modicationDate; return modificationDate;
} }
public StreamEncoding getStreamFormat() { public StreamEncoding getStreamFormat() {

View file

@ -27,18 +27,15 @@ import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.CompressionAlgorithm; import org.pgpainless.algorithm.CompressionAlgorithm;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm; import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
import org.pgpainless.algorithm.negotiation.SymmetricKeyAlgorithmNegotiator; import org.pgpainless.algorithm.negotiation.SymmetricKeyAlgorithmNegotiator;
import org.pgpainless.decryption_verification.OpenPgpMetadata;
import org.pgpainless.key.SubkeyIdentifier; import org.pgpainless.key.SubkeyIdentifier;
public class EncryptionBuilder implements EncryptionBuilderInterface { public class EncryptionBuilder implements EncryptionBuilderInterface {
private OutputStream outputStream; private OutputStream outputStream;
private OpenPgpMetadata.FileInfo fileInfo;
@Override @Override
public WithOptions onOutputStream(@Nonnull OutputStream outputStream, OpenPgpMetadata.FileInfo fileInfo) { public WithOptions onOutputStream(@Nonnull OutputStream outputStream) {
this.outputStream = outputStream; this.outputStream = outputStream;
this.fileInfo = fileInfo;
return new WithOptionsImpl(); return new WithOptionsImpl();
} }
@ -48,7 +45,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
if (options == null) { if (options == null) {
throw new NullPointerException("ProducerOptions cannot be null."); throw new NullPointerException("ProducerOptions cannot be null.");
} }
return new EncryptionStream(outputStream, options, fileInfo); return new EncryptionStream(outputStream, options);
} }
} }

View file

@ -17,12 +17,9 @@ package org.pgpainless.encryption_signing;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Date;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.pgpainless.algorithm.StreamEncoding;
import org.pgpainless.decryption_verification.OpenPgpMetadata;
public interface EncryptionBuilderInterface { public interface EncryptionBuilderInterface {
@ -33,47 +30,7 @@ public interface EncryptionBuilderInterface {
* @param outputStream output stream of the plain data. * @param outputStream output stream of the plain data.
* @return api handle * @return api handle
*/ */
default WithOptions onOutputStream(@Nonnull OutputStream outputStream) { WithOptions onOutputStream(@Nonnull OutputStream outputStream);
return onOutputStream(outputStream, OpenPgpMetadata.FileInfo.binaryStream());
}
/**
* Create a {@link EncryptionStream} on an {@link OutputStream} that contains the plain data which shall
* be encrypted and/or signed.
*
* @param outputStream outputStream
* @param forYourEyesOnly flag indicating that the data is intended for the recipients eyes only
* @return api handle
*
* @deprecated use {@link #onOutputStream(OutputStream, OpenPgpMetadata.FileInfo)} instead.
*/
default WithOptions onOutputStream(@Nonnull OutputStream outputStream, boolean forYourEyesOnly) {
return onOutputStream(outputStream, forYourEyesOnly ? OpenPgpMetadata.FileInfo.forYourEyesOnly() : OpenPgpMetadata.FileInfo.binaryStream());
}
/**
* Creates a {@link EncryptionStream} on an {@link OutputStream} that contains the plain data which shall
* be encrypted and/or signed.
*
* @param outputStream outputStream
* @param fileName name of the file (or "" if the encrypted data is not a file)
* @param forYourEyesOnly flag indicating that the data is intended for the recipients eyes only
* @return api handle
*
* @deprecated use {@link #onOutputStream(OutputStream, OpenPgpMetadata.FileInfo)} instead.
*/
default WithOptions onOutputStream(@Nonnull OutputStream outputStream, String fileName, boolean forYourEyesOnly) {
return onOutputStream(outputStream, new OpenPgpMetadata.FileInfo(forYourEyesOnly ? "_CONSOLE" : fileName, new Date(), StreamEncoding.BINARY));
}
/**
* Create an {@link EncryptionStream} on an {@link OutputStream} that contains the plain data which shall
* be encrypted and/or signed.
*
* @param outputStream outputStream
* @param fileInfo file information
* @return api handle
*/
WithOptions onOutputStream(@Nonnull OutputStream outputStream, OpenPgpMetadata.FileInfo fileInfo);
interface WithOptions { interface WithOptions {

View file

@ -33,8 +33,8 @@ import org.pgpainless.algorithm.EncryptionPurpose;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm; import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.SubkeyIdentifier; import org.pgpainless.key.SubkeyIdentifier;
import org.pgpainless.key.info.KeyRingInfo;
import org.pgpainless.key.info.KeyAccessor; import org.pgpainless.key.info.KeyAccessor;
import org.pgpainless.key.info.KeyRingInfo;
import org.pgpainless.util.Passphrase; import org.pgpainless.util.Passphrase;
/** /**

View file

@ -62,8 +62,7 @@ public final class EncryptionStream extends OutputStream {
private OutputStream literalDataStream; private OutputStream literalDataStream;
EncryptionStream(@Nonnull OutputStream targetOutputStream, EncryptionStream(@Nonnull OutputStream targetOutputStream,
@Nonnull ProducerOptions options, @Nonnull ProducerOptions options)
@Nonnull OpenPgpMetadata.FileInfo fileInfo)
throws IOException, PGPException { throws IOException, PGPException {
this.options = options; this.options = options;
outermostStream = targetOutputStream; outermostStream = targetOutputStream;
@ -72,7 +71,7 @@ public final class EncryptionStream extends OutputStream {
prepareEncryption(); prepareEncryption();
prepareCompression(); prepareCompression();
prepareOnePassSignatures(); prepareOnePassSignatures();
prepareLiteralDataProcessing(fileInfo); prepareLiteralDataProcessing();
} }
private void prepareArmor() { private void prepareArmor() {
@ -146,15 +145,17 @@ public final class EncryptionStream extends OutputStream {
} }
} }
private void prepareLiteralDataProcessing(@Nonnull OpenPgpMetadata.FileInfo fileInfo) throws IOException { private void prepareLiteralDataProcessing() throws IOException {
literalDataGenerator = new PGPLiteralDataGenerator(); literalDataGenerator = new PGPLiteralDataGenerator();
literalDataStream = literalDataGenerator.open(outermostStream, literalDataStream = literalDataGenerator.open(outermostStream,
fileInfo.getStreamFormat().getCode(), options.getEncoding().getCode(),
fileInfo.getFileName(), options.getFileName(),
fileInfo.getModificationDate(), options.getModificationDate(),
new byte[BUFFER_SIZE]); new byte[BUFFER_SIZE]);
outermostStream = literalDataStream; outermostStream = literalDataStream;
resultBuilder.setFileInfo(fileInfo);
resultBuilder.setFileInfo(new OpenPgpMetadata.FileInfo(
options.getFileName(), options.getModificationDate(), options.getEncoding()));
} }
@Override @Override

View file

@ -15,15 +15,22 @@
*/ */
package org.pgpainless.encryption_signing; package org.pgpainless.encryption_signing;
import java.util.Date;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.CompressionAlgorithm; import org.pgpainless.algorithm.CompressionAlgorithm;
import org.pgpainless.algorithm.StreamEncoding;
public final class ProducerOptions { public final class ProducerOptions {
private final EncryptionOptions encryptionOptions; private final EncryptionOptions encryptionOptions;
private final SigningOptions signingOptions; private final SigningOptions signingOptions;
private String fileName = "";
private Date modificationDate = PGPLiteralData.NOW;
private StreamEncoding streamEncoding = StreamEncoding.BINARY;
private CompressionAlgorithm compressionAlgorithmOverride = PGPainless.getPolicy().getCompressionAlgorithmPolicy() private CompressionAlgorithm compressionAlgorithmOverride = PGPainless.getPolicy().getCompressionAlgorithmPolicy()
.defaultCompressionAlgorithm(); .defaultCompressionAlgorithm();
@ -86,20 +93,6 @@ public final class ProducerOptions {
} }
} }
/**
* Override which compression algorithm shall be used.
*
* @param compressionAlgorithm compression algorithm override
* @return builder
*/
public ProducerOptions overrideCompressionAlgorithm(CompressionAlgorithm compressionAlgorithm) {
if (compressionAlgorithm == null) {
throw new NullPointerException("Compression algorithm cannot be null.");
}
this.compressionAlgorithmOverride = compressionAlgorithm;
return this;
}
/** /**
* Specify, whether or not the result of the encryption/signing operation shall be ascii armored. * Specify, whether or not the result of the encryption/signing operation shall be ascii armored.
* The default value is true. * The default value is true.
@ -121,6 +114,89 @@ public final class ProducerOptions {
return asciiArmor; return asciiArmor;
} }
/**
* Set the name of the encrypted file.
* Note: This option cannot be used simultaneously with {@link #setForYourEyesOnly()}.
*
* @param fileName name of the encrypted file
* @return this
*/
public ProducerOptions setFileName(@Nonnull String fileName) {
this.fileName = fileName;
return this;
}
/**
* Return the encrypted files name.
*
* @return file name
*/
public String getFileName() {
return fileName;
}
/**
* Mark the encrypted message as for-your-eyes-only by setting a special file name.
* Note: Therefore this method cannot be used simultaneously with {@link #setFileName(String)}.
*
* @return this
*/
public ProducerOptions setForYourEyesOnly() {
this.fileName = PGPLiteralData.CONSOLE;
return this;
}
/**
* Set the modification date of the encrypted file.
*
* @param modificationDate Modification date of the encrypted file.
* @return this
*/
public ProducerOptions setModificationDate(@Nonnull Date modificationDate) {
this.modificationDate = modificationDate;
return this;
}
/**
* Return the modification date of the encrypted file.
*
* @return modification date
*/
public Date getModificationDate() {
return modificationDate;
}
/**
* Set the format of the literal data packet.
* Defaults to {@link StreamEncoding#BINARY}.
*
* @see <a href="https://datatracker.ietf.org/doc/html/rfc4880#section-5.9">RFC4880 §5.9. Literal Data Packet</a>
*
* @param encoding encoding
* @return this
*/
public ProducerOptions setEncoding(@Nonnull StreamEncoding encoding) {
this.streamEncoding = encoding;
return this;
}
public StreamEncoding getEncoding() {
return streamEncoding;
}
/**
* Override which compression algorithm shall be used.
*
* @param compressionAlgorithm compression algorithm override
* @return builder
*/
public ProducerOptions overrideCompressionAlgorithm(CompressionAlgorithm compressionAlgorithm) {
if (compressionAlgorithm == null) {
throw new NullPointerException("Compression algorithm cannot be null.");
}
this.compressionAlgorithmOverride = compressionAlgorithm;
return this;
}
public CompressionAlgorithm getCompressionAlgorithmOverride() { public CompressionAlgorithm getCompressionAlgorithmOverride() {
return compressionAlgorithmOverride; return compressionAlgorithmOverride;
} }

View file

@ -66,11 +66,14 @@ public class FileInfoTest {
ByteArrayInputStream dataIn = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); ByteArrayInputStream dataIn = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
ByteArrayOutputStream dataOut = new ByteArrayOutputStream(); ByteArrayOutputStream dataOut = new ByteArrayOutputStream();
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign() EncryptionStream encryptionStream = PGPainless.encryptAndOrSign()
.onOutputStream(dataOut, fileInfo) .onOutputStream(dataOut)
.withOptions(ProducerOptions.encrypt( .withOptions(ProducerOptions.encrypt(
EncryptionOptions EncryptionOptions
.encryptCommunications() .encryptCommunications()
.addRecipient(publicKeys)) .addRecipient(publicKeys))
.setEncoding(fileInfo.getStreamFormat())
.setFileName(fileInfo.getFileName())
.setModificationDate(fileInfo.getModificationDate())
); );
Streams.pipeAll(dataIn, encryptionStream); Streams.pipeAll(dataIn, encryptionStream);