mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-26 14:22:05 +01:00
Move EncryptionPurpose to own class
This commit is contained in:
parent
3edaa60b52
commit
9883d1537b
9 changed files with 55 additions and 34 deletions
|
@ -22,6 +22,7 @@ import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPKeyRing;
|
import org.bouncycastle.openpgp.PGPKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
|
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
import org.pgpainless.decryption_verification.DecryptionBuilder;
|
import org.pgpainless.decryption_verification.DecryptionBuilder;
|
||||||
import org.pgpainless.decryption_verification.DecryptionStream;
|
import org.pgpainless.decryption_verification.DecryptionStream;
|
||||||
|
@ -71,7 +72,7 @@ public class PGPainless {
|
||||||
* Create an {@link EncryptionStream}, which can be used to encrypt and/or sign data using OpenPGP.
|
* Create an {@link EncryptionStream}, which can be used to encrypt and/or sign data using OpenPGP.
|
||||||
* This method assumes that the stream will be used to encrypt data for communication purposes.
|
* This method assumes that the stream will be used to encrypt data for communication purposes.
|
||||||
* If you instead want to encrypt data that will be saved on disk (eg. a backup), use
|
* If you instead want to encrypt data that will be saved on disk (eg. a backup), use
|
||||||
* {@link #encryptAndOrSign(EncryptionStream.Purpose)} and chose an appropriate purpose.
|
* {@link #encryptAndOrSign(EncryptionPurpose)} and chose an appropriate purpose.
|
||||||
*
|
*
|
||||||
* @return builder
|
* @return builder
|
||||||
*/
|
*/
|
||||||
|
@ -85,7 +86,7 @@ public class PGPainless {
|
||||||
* @param purpose how will the data be used?
|
* @param purpose how will the data be used?
|
||||||
* @return builder
|
* @return builder
|
||||||
*/
|
*/
|
||||||
public static EncryptionBuilder encryptAndOrSign(EncryptionStream.Purpose purpose) {
|
public static EncryptionBuilder encryptAndOrSign(EncryptionPurpose purpose) {
|
||||||
return new EncryptionBuilder(purpose);
|
return new EncryptionBuilder(purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.algorithm;
|
||||||
|
|
||||||
|
public enum EncryptionPurpose {
|
||||||
|
/**
|
||||||
|
* The stream will encrypt communication that goes over the wire.
|
||||||
|
* Eg. EMail, Chat...
|
||||||
|
*/
|
||||||
|
COMMUNICATIONS,
|
||||||
|
/**
|
||||||
|
* The stream will encrypt data that is stored on disk.
|
||||||
|
* Eg. Encrypted backup...
|
||||||
|
*/
|
||||||
|
STORAGE,
|
||||||
|
/**
|
||||||
|
* The stream will use keys with either flags to encrypt the data.
|
||||||
|
*/
|
||||||
|
STORAGE_AND_COMMUNICATIONS
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
import org.pgpainless.algorithm.DocumentSignatureType;
|
import org.pgpainless.algorithm.DocumentSignatureType;
|
||||||
|
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||||
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.decryption_verification.OpenPgpMetadata;
|
||||||
|
@ -47,10 +48,10 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
private OpenPgpMetadata.FileInfo fileInfo;
|
private OpenPgpMetadata.FileInfo fileInfo;
|
||||||
|
|
||||||
public EncryptionBuilder() {
|
public EncryptionBuilder() {
|
||||||
this.encryptionOptions = new EncryptionOptions(EncryptionStream.Purpose.COMMUNICATIONS);
|
this.encryptionOptions = new EncryptionOptions(EncryptionPurpose.COMMUNICATIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EncryptionBuilder(@Nonnull EncryptionStream.Purpose purpose) {
|
public EncryptionBuilder(@Nonnull EncryptionPurpose purpose) {
|
||||||
this.encryptionOptions = new EncryptionOptions(purpose);
|
this.encryptionOptions = new EncryptionOptions(purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||||
import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator;
|
import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator;
|
||||||
import org.bouncycastle.openpgp.operator.PGPKeyEncryptionMethodGenerator;
|
import org.bouncycastle.openpgp.operator.PGPKeyEncryptionMethodGenerator;
|
||||||
|
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;
|
||||||
|
@ -64,7 +65,7 @@ import org.pgpainless.util.Passphrase;
|
||||||
*/
|
*/
|
||||||
public class EncryptionOptions {
|
public class EncryptionOptions {
|
||||||
|
|
||||||
private final EncryptionStream.Purpose purpose;
|
private final EncryptionPurpose purpose;
|
||||||
private final Set<PGPKeyEncryptionMethodGenerator> encryptionMethods = new LinkedHashSet<>();
|
private final Set<PGPKeyEncryptionMethodGenerator> encryptionMethods = new LinkedHashSet<>();
|
||||||
private final Set<SubkeyIdentifier> encryptionKeys = new LinkedHashSet<>();
|
private final Set<SubkeyIdentifier> encryptionKeys = new LinkedHashSet<>();
|
||||||
private final Map<SubkeyIdentifier, KeyRingInfo> keyRingInfo = new HashMap<>();
|
private final Map<SubkeyIdentifier, KeyRingInfo> keyRingInfo = new HashMap<>();
|
||||||
|
@ -78,10 +79,10 @@ public class EncryptionOptions {
|
||||||
* or {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_STORAGE}.
|
* or {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_STORAGE}.
|
||||||
*/
|
*/
|
||||||
public EncryptionOptions() {
|
public EncryptionOptions() {
|
||||||
this(EncryptionStream.Purpose.STORAGE_AND_COMMUNICATIONS);
|
this(EncryptionPurpose.STORAGE_AND_COMMUNICATIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EncryptionOptions(EncryptionStream.Purpose purpose) {
|
public EncryptionOptions(EncryptionPurpose purpose) {
|
||||||
this.purpose = purpose;
|
this.purpose = purpose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ public class EncryptionOptions {
|
||||||
* @return encryption options
|
* @return encryption options
|
||||||
*/
|
*/
|
||||||
public static EncryptionOptions encryptCommunications() {
|
public static EncryptionOptions encryptCommunications() {
|
||||||
return new EncryptionOptions(EncryptionStream.Purpose.COMMUNICATIONS);
|
return new EncryptionOptions(EncryptionPurpose.COMMUNICATIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,7 +103,7 @@ public class EncryptionOptions {
|
||||||
* @return encryption options
|
* @return encryption options
|
||||||
*/
|
*/
|
||||||
public static EncryptionOptions encryptDataAtRest() {
|
public static EncryptionOptions encryptDataAtRest() {
|
||||||
return new EncryptionOptions(EncryptionStream.Purpose.STORAGE);
|
return new EncryptionOptions(EncryptionPurpose.STORAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -46,23 +46,6 @@ import org.pgpainless.util.ArmoredOutputStreamFactory;
|
||||||
*/
|
*/
|
||||||
public final class EncryptionStream extends OutputStream {
|
public final class EncryptionStream extends OutputStream {
|
||||||
|
|
||||||
public enum Purpose {
|
|
||||||
/**
|
|
||||||
* The stream will encrypt communication that goes over the wire.
|
|
||||||
* Eg. EMail, Chat...
|
|
||||||
*/
|
|
||||||
COMMUNICATIONS,
|
|
||||||
/**
|
|
||||||
* The stream will encrypt data that is stored on disk.
|
|
||||||
* Eg. Encrypted backup...
|
|
||||||
*/
|
|
||||||
STORAGE,
|
|
||||||
/**
|
|
||||||
* The stream will use keys with either flags to encrypt the data.
|
|
||||||
*/
|
|
||||||
STORAGE_AND_COMMUNICATIONS
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(EncryptionStream.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(EncryptionStream.class.getName());
|
||||||
private static final Level LEVEL = Level.FINE;
|
private static final Level LEVEL = Level.FINE;
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,11 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSignature;
|
import org.bouncycastle.openpgp.PGPSignature;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
|
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||||
import org.pgpainless.algorithm.HashAlgorithm;
|
import org.pgpainless.algorithm.HashAlgorithm;
|
||||||
import org.pgpainless.algorithm.KeyFlag;
|
import org.pgpainless.algorithm.KeyFlag;
|
||||||
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
||||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
import org.pgpainless.encryption_signing.EncryptionStream;
|
|
||||||
import org.pgpainless.exception.KeyValidationException;
|
import org.pgpainless.exception.KeyValidationException;
|
||||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
import org.pgpainless.key.SubkeyIdentifier;
|
import org.pgpainless.key.SubkeyIdentifier;
|
||||||
|
@ -691,7 +691,7 @@ public class KeyRingInfo {
|
||||||
* @param purpose purpose (encrypt data at rest / communications)
|
* @param purpose purpose (encrypt data at rest / communications)
|
||||||
* @return encryption subkeys
|
* @return encryption subkeys
|
||||||
*/
|
*/
|
||||||
public @Nonnull List<PGPPublicKey> getEncryptionSubkeys(EncryptionStream.Purpose purpose) {
|
public @Nonnull List<PGPPublicKey> getEncryptionSubkeys(EncryptionPurpose purpose) {
|
||||||
Iterator<PGPPublicKey> subkeys = keys.getPublicKeys();
|
Iterator<PGPPublicKey> subkeys = keys.getPublicKeys();
|
||||||
List<PGPPublicKey> encryptionKeys = new ArrayList<>();
|
List<PGPPublicKey> encryptionKeys = new ArrayList<>();
|
||||||
while (subkeys.hasNext()) {
|
while (subkeys.hasNext()) {
|
||||||
|
@ -737,7 +737,7 @@ public class KeyRingInfo {
|
||||||
* @param purpose encryption purpose
|
* @param purpose encryption purpose
|
||||||
* @return encryption subkeys
|
* @return encryption subkeys
|
||||||
*/
|
*/
|
||||||
public @Nonnull List<PGPPublicKey> getEncryptionSubkeys(String userId, EncryptionStream.Purpose purpose) {
|
public @Nonnull List<PGPPublicKey> getEncryptionSubkeys(String userId, EncryptionPurpose purpose) {
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
if (!isUserIdValid(userId)) {
|
if (!isUserIdValid(userId)) {
|
||||||
throw new KeyValidationException(userId, getLatestUserIdCertification(userId), getUserIdRevocation(userId));
|
throw new KeyValidationException(userId, getLatestUserIdCertification(userId), getUserIdRevocation(userId));
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.algorithm.DocumentSignatureType;
|
import org.pgpainless.algorithm.DocumentSignatureType;
|
||||||
|
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||||
import org.pgpainless.decryption_verification.DecryptionStream;
|
import org.pgpainless.decryption_verification.DecryptionStream;
|
||||||
import org.pgpainless.decryption_verification.OpenPgpMetadata;
|
import org.pgpainless.decryption_verification.OpenPgpMetadata;
|
||||||
import org.pgpainless.implementation.ImplementationFactory;
|
import org.pgpainless.implementation.ImplementationFactory;
|
||||||
|
@ -64,7 +65,7 @@ public class SigningTest {
|
||||||
PGPPublicKeyRingCollection keys = new PGPPublicKeyRingCollection(Arrays.asList(julietKeys, romeoKeys));
|
PGPPublicKeyRingCollection keys = new PGPPublicKeyRingCollection(Arrays.asList(julietKeys, romeoKeys));
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign(EncryptionStream.Purpose.STORAGE)
|
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign(EncryptionPurpose.STORAGE)
|
||||||
.onOutputStream(out)
|
.onOutputStream(out)
|
||||||
.toRecipients(keys)
|
.toRecipients(keys)
|
||||||
.and()
|
.and()
|
||||||
|
|
|
@ -27,9 +27,9 @@ import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||||
import org.pgpainless.algorithm.KeyFlag;
|
import org.pgpainless.algorithm.KeyFlag;
|
||||||
import org.pgpainless.encryption_signing.EncryptionBuilderInterface;
|
import org.pgpainless.encryption_signing.EncryptionBuilderInterface;
|
||||||
import org.pgpainless.encryption_signing.EncryptionStream;
|
|
||||||
import org.pgpainless.key.generation.KeySpec;
|
import org.pgpainless.key.generation.KeySpec;
|
||||||
import org.pgpainless.key.generation.type.KeyType;
|
import org.pgpainless.key.generation.type.KeyType;
|
||||||
import org.pgpainless.key.generation.type.rsa.RsaLength;
|
import org.pgpainless.key.generation.type.rsa.RsaLength;
|
||||||
|
@ -52,7 +52,7 @@ public class TestEncryptCommsStorageFlagsDifferentiated {
|
||||||
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
|
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
EncryptionBuilderInterface.ToRecipients builder = PGPainless.encryptAndOrSign(EncryptionStream.Purpose.COMMUNICATIONS)
|
EncryptionBuilderInterface.ToRecipients builder = PGPainless.encryptAndOrSign(EncryptionPurpose.COMMUNICATIONS)
|
||||||
.onOutputStream(out);
|
.onOutputStream(out);
|
||||||
|
|
||||||
// since the key does not carry the flag ENCRYPT_COMMS, it cannot be used by the stream.
|
// since the key does not carry the flag ENCRYPT_COMMS, it cannot be used by the stream.
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.util.io.Streams;
|
import org.bouncycastle.util.io.Streams;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||||
import org.pgpainless.encryption_signing.EncryptionOptions;
|
import org.pgpainless.encryption_signing.EncryptionOptions;
|
||||||
import org.pgpainless.encryption_signing.EncryptionResult;
|
import org.pgpainless.encryption_signing.EncryptionResult;
|
||||||
import org.pgpainless.encryption_signing.EncryptionStream;
|
import org.pgpainless.encryption_signing.EncryptionStream;
|
||||||
|
@ -58,10 +59,10 @@ public class TestTwoSubkeysEncryption {
|
||||||
PGPSecretKeyRing twoSuitableSubkeysKeyRing = WeirdKeys.getTwoCryptSubkeysKey();
|
PGPSecretKeyRing twoSuitableSubkeysKeyRing = WeirdKeys.getTwoCryptSubkeysKey();
|
||||||
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(twoSuitableSubkeysKeyRing);
|
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(twoSuitableSubkeysKeyRing);
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign(EncryptionStream.Purpose.STORAGE)
|
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign(EncryptionPurpose.STORAGE)
|
||||||
.onOutputStream(out)
|
.onOutputStream(out)
|
||||||
.withOptions(
|
.withOptions(
|
||||||
ProducerOptions.encrypt(new EncryptionOptions(EncryptionStream.Purpose.STORAGE_AND_COMMUNICATIONS)
|
ProducerOptions.encrypt(new EncryptionOptions(EncryptionPurpose.STORAGE_AND_COMMUNICATIONS)
|
||||||
.addRecipient(publicKeys, EncryptionOptions.encryptToAllCapableSubkeys())
|
.addRecipient(publicKeys, EncryptionOptions.encryptToAllCapableSubkeys())
|
||||||
)
|
)
|
||||||
.setAsciiArmor(false)
|
.setAsciiArmor(false)
|
||||||
|
|
Loading…
Reference in a new issue