mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-30 08:12:06 +01:00
Allow the user to specify a purpose for encryption
This commit is contained in:
parent
8df752e995
commit
11c41e7ba7
4 changed files with 67 additions and 4 deletions
|
@ -66,12 +66,26 @@ 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.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
* @return builder
|
* @return builder
|
||||||
*/
|
*/
|
||||||
public static EncryptionBuilder encryptAndOrSign() {
|
public static EncryptionBuilder encryptAndOrSign() {
|
||||||
return new EncryptionBuilder();
|
return new EncryptionBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an {@link EncryptionStream}, that can be used to encrypt and/or sign data using OpenPGP.
|
||||||
|
*
|
||||||
|
* @param purpose how will the data be used?
|
||||||
|
* @return builder
|
||||||
|
*/
|
||||||
|
public static EncryptionBuilder encryptAndOrSign(EncryptionStream.Purpose purpose) {
|
||||||
|
return new EncryptionBuilder(purpose);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link DecryptionStream}, which can be used to decrypt and/or verify data using OpenPGP.
|
* Create a {@link DecryptionStream}, which can be used to decrypt and/or verify data using OpenPGP.
|
||||||
*
|
*
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
|
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
|
||||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
import org.pgpainless.algorithm.HashAlgorithm;
|
import org.pgpainless.algorithm.HashAlgorithm;
|
||||||
|
import org.pgpainless.algorithm.KeyFlag;
|
||||||
import org.pgpainless.algorithm.SignatureType;
|
import org.pgpainless.algorithm.SignatureType;
|
||||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
import org.pgpainless.exception.SecretKeyNotFoundException;
|
import org.pgpainless.exception.SecretKeyNotFoundException;
|
||||||
|
@ -55,6 +56,7 @@ import org.pgpainless.util.Passphrase;
|
||||||
|
|
||||||
public class EncryptionBuilder implements EncryptionBuilderInterface {
|
public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
|
|
||||||
|
private final EncryptionStream.Purpose purpose;
|
||||||
private OutputStream outputStream;
|
private OutputStream outputStream;
|
||||||
private final Set<PGPPublicKey> encryptionKeys = new HashSet<>();
|
private final Set<PGPPublicKey> encryptionKeys = new HashSet<>();
|
||||||
private final Set<Passphrase> encryptionPassphrases = new HashSet<>();
|
private final Set<Passphrase> encryptionPassphrases = new HashSet<>();
|
||||||
|
@ -67,6 +69,14 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
private CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.UNCOMPRESSED;
|
private CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.UNCOMPRESSED;
|
||||||
private boolean asciiArmor = false;
|
private boolean asciiArmor = false;
|
||||||
|
|
||||||
|
public EncryptionBuilder() {
|
||||||
|
this.purpose = EncryptionStream.Purpose.COMMUNICATIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EncryptionBuilder(@Nonnull EncryptionStream.Purpose purpose) {
|
||||||
|
this.purpose = purpose;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ToRecipients onOutputStream(@Nonnull OutputStream outputStream) {
|
public ToRecipients onOutputStream(@Nonnull OutputStream outputStream) {
|
||||||
this.outputStream = outputStream;
|
this.outputStream = outputStream;
|
||||||
|
@ -425,9 +435,28 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
PublicKeySelectionStrategy encryptionKeySelector() {
|
PublicKeySelectionStrategy encryptionKeySelector() {
|
||||||
|
KeyFlag[] flags = mapPurposeToKeyFlags(purpose);
|
||||||
return new And.PubKeySelectionStrategy(
|
return new And.PubKeySelectionStrategy(
|
||||||
new NoRevocation.PubKeySelectionStrategy(),
|
new NoRevocation.PubKeySelectionStrategy(),
|
||||||
new EncryptionKeySelectionStrategy());
|
new EncryptionKeySelectionStrategy(flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static KeyFlag[] mapPurposeToKeyFlags(EncryptionStream.Purpose purpose) {
|
||||||
|
KeyFlag[] flags;
|
||||||
|
switch (purpose) {
|
||||||
|
case COMMUNICATIONS:
|
||||||
|
flags = new KeyFlag[] {KeyFlag.ENCRYPT_COMMS};
|
||||||
|
break;
|
||||||
|
case STORAGE:
|
||||||
|
flags = new KeyFlag[] {KeyFlag.ENCRYPT_STORAGE};
|
||||||
|
break;
|
||||||
|
case STORAGE_AND_COMMUNICATIONS:
|
||||||
|
flags = new KeyFlag[] {KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new AssertionError("Illegal purpose enum value encountered.");
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
SecretKeySelectionStrategy signingKeySelector() {
|
SecretKeySelectionStrategy signingKeySelector() {
|
||||||
|
|
|
@ -59,6 +59,23 @@ import org.pgpainless.util.Passphrase;
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,14 @@ import org.pgpainless.key.selection.key.PublicKeySelectionStrategy;
|
||||||
*/
|
*/
|
||||||
public class EncryptionKeySelectionStrategy extends PublicKeySelectionStrategy {
|
public class EncryptionKeySelectionStrategy extends PublicKeySelectionStrategy {
|
||||||
|
|
||||||
private static final HasKeyFlagSelectionStrategy.PublicKey HAS_ENCRYPT_COMMS_FLAG =
|
private final HasKeyFlagSelectionStrategy.PublicKey keyFlagSelector;
|
||||||
new HasKeyFlagSelectionStrategy.PublicKey(KeyFlag.ENCRYPT_COMMS);
|
|
||||||
|
public EncryptionKeySelectionStrategy(KeyFlag... flags) {
|
||||||
|
this.keyFlagSelector = new HasKeyFlagSelectionStrategy.PublicKey(flags);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(@Nonnull PGPPublicKey key) {
|
public boolean accept(@Nonnull PGPPublicKey key) {
|
||||||
return key.isEncryptionKey() && HAS_ENCRYPT_COMMS_FLAG.accept(key);
|
return key.isEncryptionKey() && keyFlagSelector.accept(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue