From e9caa4af1f615c69196ab6aba8a584357f3797e6 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Fri, 1 Sep 2023 18:23:12 +0200 Subject: [PATCH] Kotlin conversion: EncryptionBuilder + Interface --- .../encryption_signing/EncryptionBuilder.java | 77 ------------------- .../EncryptionBuilderInterface.java | 38 --------- .../encryption_signing/EncryptionBuilder.kt | 59 ++++++++++++++ .../EncryptionBuilderInterface.kt | 36 +++++++++ 4 files changed, 95 insertions(+), 115 deletions(-) delete mode 100644 pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionBuilder.java delete mode 100644 pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionBuilderInterface.java create mode 100644 pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionBuilder.kt create mode 100644 pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionBuilderInterface.kt diff --git a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionBuilder.java b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionBuilder.java deleted file mode 100644 index 9490551b..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionBuilder.java +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: 2018 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.encryption_signing; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import javax.annotation.Nonnull; - -import org.bouncycastle.openpgp.PGPException; -import org.pgpainless.PGPainless; -import org.pgpainless.algorithm.CompressionAlgorithm; -import org.pgpainless.algorithm.SymmetricKeyAlgorithm; -import org.pgpainless.algorithm.negotiation.SymmetricKeyAlgorithmNegotiator; -import org.pgpainless.key.SubkeyIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class EncryptionBuilder implements EncryptionBuilderInterface { - - private static final Logger LOGGER = LoggerFactory.getLogger(EncryptionBuilder.class); - - private OutputStream outputStream; - - @Override - public WithOptions onOutputStream(@Nonnull OutputStream outputStream) { - this.outputStream = outputStream; - return new WithOptionsImpl(); - } - - class WithOptionsImpl implements WithOptions { - @Override - public EncryptionStream withOptions(ProducerOptions options) throws PGPException, IOException { - if (options == null) { - throw new NullPointerException("ProducerOptions cannot be null."); - } - return new EncryptionStream(outputStream, options); - } - } - - /** - * Negotiate the {@link SymmetricKeyAlgorithm} used for message encryption. - * - * @param encryptionOptions encryption options - * @return negotiated symmetric key algorithm - */ - public static SymmetricKeyAlgorithm negotiateSymmetricEncryptionAlgorithm(EncryptionOptions encryptionOptions) { - List> preferences = new ArrayList<>(); - for (SubkeyIdentifier key : encryptionOptions.getKeyViews().keySet()) { - preferences.add(encryptionOptions.getKeyViews().get(key).getPreferredSymmetricKeyAlgorithms()); - } - - SymmetricKeyAlgorithm algorithm = SymmetricKeyAlgorithmNegotiator - .byPopularity() - .negotiate( - PGPainless.getPolicy().getSymmetricKeyEncryptionAlgorithmPolicy(), - encryptionOptions.getEncryptionAlgorithmOverride(), - preferences); - LOGGER.debug("Negotiation resulted in {} being the symmetric encryption algorithm of choice.", algorithm); - return algorithm; - } - - public static CompressionAlgorithm negotiateCompressionAlgorithm(ProducerOptions producerOptions) { - CompressionAlgorithm compressionAlgorithmOverride = producerOptions.getCompressionAlgorithmOverride(); - if (compressionAlgorithmOverride != null) { - return compressionAlgorithmOverride; - } - - // TODO: Negotiation - - return PGPainless.getPolicy().getCompressionAlgorithmPolicy().defaultCompressionAlgorithm(); - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionBuilderInterface.java b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionBuilderInterface.java deleted file mode 100644 index c705c0b1..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionBuilderInterface.java +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-FileCopyrightText: 2018 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.encryption_signing; - -import java.io.IOException; -import java.io.OutputStream; -import javax.annotation.Nonnull; - -import org.bouncycastle.openpgp.PGPException; - -public interface EncryptionBuilderInterface { - - /** - * Create a {@link EncryptionStream} on an {@link OutputStream} that contains the plain data that - * shall be encrypted and or signed. - * - * @param outputStream output stream of the plain data. - * @return api handle - */ - WithOptions onOutputStream(@Nonnull OutputStream outputStream); - - interface WithOptions { - - /** - * Create an {@link EncryptionStream} with the given options (recipients, signers, algorithms...). - * - * @param options options - * @return encryption stream - * - * @throws PGPException if something goes wrong during encryption stream preparation - * @throws IOException if something goes wrong during encryption stream preparation (writing headers) - */ - EncryptionStream withOptions(ProducerOptions options) throws PGPException, IOException; - - } -} diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionBuilder.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionBuilder.kt new file mode 100644 index 00000000..324fcf3b --- /dev/null +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionBuilder.kt @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: 2023 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.encryption_signing + +import org.pgpainless.PGPainless.Companion.getPolicy +import org.pgpainless.algorithm.CompressionAlgorithm +import org.pgpainless.algorithm.SymmetricKeyAlgorithm +import org.pgpainless.algorithm.negotiation.SymmetricKeyAlgorithmNegotiator.Companion.byPopularity +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.io.OutputStream + +class EncryptionBuilder : EncryptionBuilderInterface { + override fun onOutputStream(outputStream: OutputStream): EncryptionBuilderInterface.WithOptions { + return WithOptionsImpl(outputStream) + } + + class WithOptionsImpl(val outputStream: OutputStream) : EncryptionBuilderInterface.WithOptions { + + override fun withOptions(options: ProducerOptions): EncryptionStream { + return EncryptionStream(outputStream, options) + } + } + + companion object { + + @JvmStatic + val LOGGER: Logger = LoggerFactory.getLogger(EncryptionBuilder::class.java) + + /** + * Negotiate the [SymmetricKeyAlgorithm] used for message encryption. + * + * @param encryptionOptions encryption options + * @return negotiated symmetric key algorithm + */ + @JvmStatic + fun negotiateSymmetricEncryptionAlgorithm(encryptionOptions: EncryptionOptions): SymmetricKeyAlgorithm { + val preferences = encryptionOptions.keyViews.values + .map { it.preferredSymmetricKeyAlgorithms } + .toList() + val algorithm = byPopularity().negotiate( + getPolicy().symmetricKeyEncryptionAlgorithmPolicy, + encryptionOptions.encryptionAlgorithmOverride, + preferences) + LOGGER.debug("Negotiation resulted in {} being the symmetric encryption algorithm of choice.", algorithm) + return algorithm + } + + @JvmStatic + fun negotiateCompressionAlgorithm(producerOptions: ProducerOptions): CompressionAlgorithm { + val compressionAlgorithmOverride = producerOptions.compressionAlgorithmOverride + return compressionAlgorithmOverride ?: getPolicy().compressionAlgorithmPolicy.defaultCompressionAlgorithm() + + // TODO: Negotiation + } + } +} \ No newline at end of file diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionBuilderInterface.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionBuilderInterface.kt new file mode 100644 index 00000000..2d42c68a --- /dev/null +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionBuilderInterface.kt @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2023 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.encryption_signing + +import org.bouncycastle.openpgp.PGPException +import java.io.IOException +import java.io.OutputStream + +fun interface EncryptionBuilderInterface { + + /** + * Create a [EncryptionStream] wrapping an [OutputStream]. Data that is piped through the + * [EncryptionStream] will be encrypted and/or signed. + * + * @param outputStream output stream which receives the encrypted / signed data. + * @return api handle + */ + fun onOutputStream(outputStream: OutputStream): WithOptions + + fun interface WithOptions { + + /** + * Create an [EncryptionStream] with the given options (recipients, signers, algorithms...). + * + * @param options options + * @return encryption stream + * + * @throws PGPException if something goes wrong during encryption stream preparation + * @throws IOException if something goes wrong during encryption stream preparation (writing headers) + */ + @Throws(PGPException::class, IOException::class) + fun withOptions(options: ProducerOptions): EncryptionStream + } +} \ No newline at end of file