From 715d055b412969f0a6e648ff39d30b99c0cbd4c3 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Tue, 15 Jun 2021 17:56:36 +0200 Subject: [PATCH] Add documentation and deprecate old methods --- .../ConsumerOptions.java | 60 ++++++++++--- .../DecryptionBuilderInterface.java | 88 ++++++++++++++++++- .../DecryptionStreamFactory.java | 9 +- 3 files changed, 135 insertions(+), 22 deletions(-) diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/ConsumerOptions.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/ConsumerOptions.java index e9f6c916..f0ae17f1 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/ConsumerOptions.java +++ b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/ConsumerOptions.java @@ -1,23 +1,32 @@ +/* + * Copyright 2021 Paul Schaub. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.pgpainless.decryption_verification; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKeyRing; -import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.util.Passphrase; @@ -31,8 +40,8 @@ public class ConsumerOptions { private Date verifyNotAfter; // Set of verification keys - private Set certificates = new HashSet<>(); - private Set detachedSignatures = new HashSet<>(); + private final Set certificates = new HashSet<>(); + private final Set detachedSignatures = new HashSet<>(); private MissingPublicKeyCallback missingCertificateCallback = null; // Session key for decryption without passphrase/key @@ -53,6 +62,10 @@ public class ConsumerOptions { return this; } + public Date getVerifyNotBefore() { + return verifyNotBefore; + } + /** * Consider signatures made after the given timestamp invalid. * @@ -64,6 +77,10 @@ public class ConsumerOptions { return this; } + public Date getVerifyNotAfter() { + return verifyNotAfter; + } + /** * Add a certificate (public key ring) for signature verification. * @@ -127,6 +144,21 @@ public class ConsumerOptions { return this; } + /** + * Return the session key. + * + * @return session key or null + */ + public @Nullable byte[] getSessionKey() { + if (sessionKey == null) { + return null; + } + + byte[] sk = new byte[sessionKey.length]; + System.arraycopy(sessionKey, 0, sk, 0, sessionKey.length); + return sk; + } + /** * Add a key for message decryption. * The key is expected to be unencrypted. @@ -162,27 +194,27 @@ public class ConsumerOptions { return this; } - public Set getDecryptionKeys() { + public @Nonnull Set getDecryptionKeys() { return Collections.unmodifiableSet(decryptionKeys.keySet()); } - public Set getDecryptionPassphrases() { + public @Nonnull Set getDecryptionPassphrases() { return Collections.unmodifiableSet(decryptionPassphrases); } - public Set getCertificates() { + public @Nonnull Set getCertificates() { return Collections.unmodifiableSet(certificates); } - public MissingPublicKeyCallback getMissingCertificateCallback() { + public @Nullable MissingPublicKeyCallback getMissingCertificateCallback() { return missingCertificateCallback; } - public SecretKeyRingProtector getSecretKeyProtector(PGPSecretKeyRing decryptionKeyRing) { + public @Nullable SecretKeyRingProtector getSecretKeyProtector(PGPSecretKeyRing decryptionKeyRing) { return decryptionKeys.get(decryptionKeyRing); } - public Set getDetachedSignatures() { + public @Nonnull Set getDetachedSignatures() { return Collections.unmodifiableSet(detachedSignatures); } } diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionBuilderInterface.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionBuilderInterface.java index 45717753..0b9a89e5 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionBuilderInterface.java +++ b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionBuilderInterface.java @@ -46,6 +46,14 @@ public interface DecryptionBuilderInterface { interface DecryptWith { + /** + * Add options for decryption / signature verification, such as keys, passphrases etc. + * + * @param consumerOptions consumer options + * @return decryption stream + * @throws PGPException in case of an OpenPGP related error + * @throws IOException in case of an IO error + */ DecryptionStream withOptions(ConsumerOptions consumerOptions) throws PGPException, IOException; /** @@ -56,7 +64,11 @@ public interface DecryptionBuilderInterface { * * @param secretKeyRings secret keys * @return api handle + * + * @deprecated use {@link ConsumerOptions#addDecryptionKey(PGPSecretKeyRing, SecretKeyRingProtector)} + * ({@link #withOptions(ConsumerOptions)}) instead. */ + @Deprecated default Verify decryptWith(@Nonnull PGPSecretKeyRingCollection secretKeyRings) { return decryptWith(new UnprotectedKeysProtector(), secretKeyRings); } @@ -68,7 +80,11 @@ public interface DecryptionBuilderInterface { * @param decryptor for unlocking locked secret keys * @param secretKeyRings secret keys * @return api handle + * + * @deprecated use {@link ConsumerOptions#addDecryptionKey(PGPSecretKeyRing, SecretKeyRingProtector)} + * ({@link #withOptions(ConsumerOptions)}) instead. */ + @Deprecated Verify decryptWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRingCollection secretKeyRings); /** @@ -78,8 +94,13 @@ public interface DecryptionBuilderInterface { * @param decryptor for unlocking locked secret key * @param secretKeyRing secret key * @return api handle + * + * @deprecated use {@link ConsumerOptions#addDecryptionKey(PGPSecretKeyRing, SecretKeyRingProtector)} + * ({@link #withOptions(ConsumerOptions)}) instead. */ - Verify decryptWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRing secretKeyRing) throws PGPException, IOException; + @Deprecated + Verify decryptWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRing secretKeyRing) + throws PGPException, IOException; /** * Decrypt the encrypted data using a passphrase. @@ -87,7 +108,11 @@ public interface DecryptionBuilderInterface { * * @param passphrase passphrase * @return api handle + * + * @deprecated use {@link ConsumerOptions#addDecryptionPassphrase(Passphrase)} + * ({@link #withOptions(ConsumerOptions)}) instead. */ + @Deprecated Verify decryptWith(@Nonnull Passphrase passphrase); /** @@ -95,32 +120,41 @@ public interface DecryptionBuilderInterface { * Useful for signature verification of signed-only data. * * @return api handle + * + * @deprecated use {@link #withOptions(ConsumerOptions)} instead and set no decryption keys. */ + @Deprecated Verify doNotDecrypt(); } + @Deprecated interface Verify extends VerifyWith { @Override + @Deprecated HandleMissingPublicKeys verifyWith(@Nonnull PGPPublicKeyRingCollection publicKeyRings); @Override + @Deprecated default HandleMissingPublicKeys verifyWith(@Nonnull OpenPgpV4Fingerprint trustedFingerprint, @Nonnull PGPPublicKeyRingCollection publicKeyRings) { return verifyWith(Collections.singleton(trustedFingerprint), publicKeyRings); } @Override + @Deprecated HandleMissingPublicKeys verifyWith(@Nonnull Set trustedFingerprints, @Nonnull PGPPublicKeyRingCollection publicKeyRings); @Override + @Deprecated default HandleMissingPublicKeys verifyWith(@Nonnull PGPPublicKeyRing publicKeyRing) { return verifyWith(Collections.singleton(publicKeyRing)); } @Override + @Deprecated HandleMissingPublicKeys verifyWith(@Nonnull Set publicKeyRings); /** @@ -130,7 +164,11 @@ public interface DecryptionBuilderInterface { * @return api handle * @throws IOException if some IO error occurs * @throws PGPException if the detached signatures are malformed + * + * @deprecated use {@link ConsumerOptions#addVerificationOfDetachedSignature(PGPSignature)} + * ({@link DecryptWith#withOptions(ConsumerOptions)}) instead. */ + @Deprecated default VerifyWith verifyDetachedSignature(@Nonnull byte[] bytes) throws IOException, PGPException { return verifyDetachedSignature(new ByteArrayInputStream(bytes)); } @@ -142,7 +180,11 @@ public interface DecryptionBuilderInterface { * @return api handle * @throws IOException in case something is wrong with the input stream * @throws PGPException if the detached signatures are malformed + * + * @deprecated use {@link ConsumerOptions#addVerificationOfDetachedSignature(PGPSignature)} + * ({@link DecryptWith#withOptions(ConsumerOptions)}) instead. */ + @Deprecated VerifyWith verifyDetachedSignature(@Nonnull InputStream inputStream) throws IOException, PGPException; /** @@ -150,7 +192,11 @@ public interface DecryptionBuilderInterface { * * @param signature detached signature * @return api handle + * + * @deprecated use {@link ConsumerOptions#addVerificationOfDetachedSignature(PGPSignature)} + * ({@link DecryptWith#withOptions(ConsumerOptions)}) instead. */ + @Deprecated default VerifyWith verifyDetachedSignature(@Nonnull PGPSignature signature) { return verifyDetachedSignatures(Collections.singletonList(signature)); } @@ -160,17 +206,25 @@ public interface DecryptionBuilderInterface { * * @param signatures detached signatures * @return api handle + * + * @deprecated use {@link ConsumerOptions#addVerificationOfDetachedSignature(PGPSignature)} + * ({@link DecryptWith#withOptions(ConsumerOptions)}) instead. */ + @Deprecated VerifyWith verifyDetachedSignatures(@Nonnull List signatures); /** * Instruct the {@link DecryptionStream} to not verify any signatures. * * @return api handle + * + * @deprecated use {@link DecryptWith#withOptions(ConsumerOptions)} instead and don't set verification keys. */ + @Deprecated Build doNotVerify(); } + @Deprecated interface VerifyWith { /** @@ -178,7 +232,11 @@ public interface DecryptionBuilderInterface { * * @param publicKeyRings public keys * @return api handle + * + * @deprecated use {@link ConsumerOptions#addVerificationCerts(PGPPublicKeyRingCollection)} + * ({@link DecryptWith#withOptions(ConsumerOptions)}) instead. */ + @Deprecated HandleMissingPublicKeys verifyWith(@Nonnull PGPPublicKeyRingCollection publicKeyRings); /** @@ -188,7 +246,10 @@ public interface DecryptionBuilderInterface { * @param trustedFingerprint {@link OpenPgpV4Fingerprint} of the public key that shall be used to verify the signatures. * @param publicKeyRings public keys * @return api handle + * @deprecated use {@link ConsumerOptions#addVerificationCert(PGPPublicKeyRing)} + * ({@link DecryptWith#withOptions(ConsumerOptions)}) instead. */ + @Deprecated default HandleMissingPublicKeys verifyWith(@Nonnull OpenPgpV4Fingerprint trustedFingerprint, @Nonnull PGPPublicKeyRingCollection publicKeyRings) { return verifyWith(Collections.singleton(trustedFingerprint), publicKeyRings); @@ -201,7 +262,11 @@ public interface DecryptionBuilderInterface { * @param trustedFingerprints set of trusted {@link OpenPgpV4Fingerprint OpenPgpV4Fingerprints}. * @param publicKeyRings public keys * @return api handle + * + * @deprecated use {@link ConsumerOptions#addVerificationCert(PGPPublicKeyRing)} + * ({@link DecryptWith#withOptions(ConsumerOptions)}) instead. */ + @Deprecated HandleMissingPublicKeys verifyWith(@Nonnull Set trustedFingerprints, @Nonnull PGPPublicKeyRingCollection publicKeyRings); @@ -210,7 +275,11 @@ public interface DecryptionBuilderInterface { * * @param publicKeyRing public key * @return api handle + * + * @deprecated use {@link ConsumerOptions#addVerificationCert(PGPPublicKeyRing)} + * ({@link DecryptWith#withOptions(ConsumerOptions)}) instead. */ + @Deprecated default HandleMissingPublicKeys verifyWith(@Nonnull PGPPublicKeyRing publicKeyRing) { return verifyWith(Collections.singleton(publicKeyRing)); } @@ -220,11 +289,16 @@ public interface DecryptionBuilderInterface { * * @param publicKeyRings public keys * @return api handle + * + * @deprecated use {@link ConsumerOptions#addVerificationCert(PGPPublicKeyRing)} + * ({@link DecryptWith#withOptions(ConsumerOptions)}) instead. */ + @Deprecated HandleMissingPublicKeys verifyWith(@Nonnull Set publicKeyRings); } + @Deprecated interface HandleMissingPublicKeys { /** @@ -232,17 +306,26 @@ public interface DecryptionBuilderInterface { * * @param callback callback * @return api handle + * + * @deprecated use {@link ConsumerOptions#setMissingCertificateCallback(MissingPublicKeyCallback)} + * ({@link DecryptWith#withOptions(ConsumerOptions)}) instead. */ + @Deprecated Build handleMissingPublicKeysWith(@Nonnull MissingPublicKeyCallback callback); /** * Instruct the {@link DecryptionStream} to ignore any missing public keys. * * @return api handle + * + * @deprecated simply do not set a {@link MissingPublicKeyCallback} and use + * {@link DecryptWith#withOptions(ConsumerOptions)} instead. */ + @Deprecated Build ignoreMissingPublicKeys(); } + @Deprecated interface Build { /** @@ -252,7 +335,10 @@ public interface DecryptionBuilderInterface { * @throws IOException in case of an I/O error * @throws PGPException if something is malformed * @throws org.pgpainless.exception.UnacceptableAlgorithmException if the message uses weak/unacceptable algorithms + * + * @deprecated use {@link DecryptWith#withOptions(ConsumerOptions)} instead. */ + @Deprecated DecryptionStream build() throws IOException, PGPException; } diff --git a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStreamFactory.java b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStreamFactory.java index 685417fa..f863ccf9 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStreamFactory.java +++ b/pgpainless-core/src/main/java/org/pgpainless/decryption_verification/DecryptionStreamFactory.java @@ -19,17 +19,13 @@ import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPEncryptedData; @@ -46,7 +42,6 @@ import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; -import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; @@ -66,7 +61,6 @@ import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.SubkeyIdentifier; import org.pgpainless.key.info.KeyRingInfo; -import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.signature.DetachedSignature; import org.pgpainless.signature.OnePassSignature; @@ -92,7 +86,8 @@ public final class DecryptionStreamFactory { } public static DecryptionStream create(@Nonnull InputStream inputStream, - @Nonnull ConsumerOptions options) throws PGPException, IOException { + @Nonnull ConsumerOptions options) + throws PGPException, IOException { BufferedInputStream bufferedIn = new BufferedInputStream(inputStream); bufferedIn.mark(200); DecryptionStreamFactory factory = new DecryptionStreamFactory(options);