diff --git a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java
index ed6dbf0e..34adacdd 100644
--- a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java
+++ b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java
@@ -15,10 +15,12 @@
*/
package org.pgpainless.encryption_signing;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -32,15 +34,46 @@ import org.pgpainless.key.SubkeyIdentifier;
import org.pgpainless.key.info.KeyRingInfo;
import org.pgpainless.util.Passphrase;
+/**
+ * Options for the encryption process.
+ * This class can be used to set encryption parameters, like encryption keys and passphrases, algorithms etc.
+ *
+ * A typical use might look like follows:
+ *
+ * {@code
+ * EncryptionOptions opt = new EncryptionOptions();
+ * opt.addRecipient(aliceKey, "Alice ");
+ * opt.addPassphrase(Passphrase.fromPassword("AdditionalDecryptionPassphrase123"));
+ * }
+ *
+ *
+ * To use a custom symmetric encryption algorithm, use {@link #overrideEncryptionAlgorithm(SymmetricKeyAlgorithm)}.
+ * This will cause PGPainless to use the provided algorithm for message encryption, instead of negotiating an algorithm
+ * by inspecting the provided recipient keys.
+ *
+ * By default, PGPainless will only encrypt to a single encryption capable subkey per recipient key.
+ * This behavior can be changed, eg. by calling
+ *
+ * {@code
+ * opt.addRecipient(aliceKey, EncryptionOptions.encryptToAllCapableSubkeys());
+ * }
+ *
+ * when adding the recipient key.
+ */
public class EncryptionOptions {
private final EncryptionStream.Purpose purpose;
private final Set encryptionMethods = new LinkedHashSet<>();
private final Set encryptionKeys = new LinkedHashSet<>();
private final Map keyRingInfo = new HashMap<>();
+ private final EncryptionKeySelector encryptionKeySelector = encryptToFirstSubkey();
private SymmetricKeyAlgorithm encryptionAlgorithmOverride = null;
+ /**
+ * Encrypt to keys both carrying the key flag {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_COMMS}
+ * or {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_STORAGE}.
+ */
public EncryptionOptions() {
this(EncryptionStream.Purpose.STORAGE_AND_COMMUNICATIONS);
}
@@ -49,10 +82,22 @@ public class EncryptionOptions {
this.purpose = purpose;
}
+ /**
+ * Factory method to create an {@link EncryptionOptions} object which will encrypt for keys
+ * which carry the flag {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_COMMS}.
+ *
+ * @return encryption options
+ */
public static EncryptionOptions encryptCommunications() {
return new EncryptionOptions(EncryptionStream.Purpose.COMMUNICATIONS);
}
+ /**
+ * Factory method to create an {@link EncryptionOptions} object which will encrypt for keys
+ * which carry the flag {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_STORAGE}.
+ *
+ * @return encryption options
+ */
public static EncryptionOptions encryptDataAtRest() {
return new EncryptionOptions(EncryptionStream.Purpose.STORAGE);
}
@@ -64,14 +109,32 @@ public class EncryptionOptions {
* @param key key ring
* @param userId user id
*/
- public void addRecipient(PGPPublicKeyRing key, String userId) {
+ public EncryptionOptions addRecipient(PGPPublicKeyRing key, String userId) {
+ return addRecipient(key, userId, encryptionKeySelector);
+ }
+
+ /**
+ * Add a recipient by providing a key and recipient user-id, as well as a strategy for selecting one or multiple
+ * encryption capable subkeys from the key.
+ *
+ * @param key key
+ * @param userId user-id
+ * @param encryptionKeySelectionStrategy strategy to select one or more encryption subkeys to encrypt to
+ */
+ public EncryptionOptions addRecipient(PGPPublicKeyRing key, String userId, EncryptionKeySelector encryptionKeySelectionStrategy) {
KeyRingInfo info = new KeyRingInfo(key, new Date());
- PGPPublicKey encryptionSubkey = info.getEncryptionSubkey(userId, purpose);
- if (encryptionSubkey == null) {
- throw new AssertionError("Key has no encryption subkey.");
+ List encryptionSubkeys = encryptionKeySelectionStrategy
+ .selectEncryptionSubkeys(info.getEncryptionSubkeys(userId, purpose));
+ if (encryptionSubkeys.isEmpty()) {
+ throw new AssertionError("Key has no suitable encryption subkeys.");
}
- addRecipientKey(key, encryptionSubkey);
+
+ for (PGPPublicKey encryptionSubkey : encryptionSubkeys) {
+ addRecipientKey(key, encryptionSubkey);
+ }
+
+ return this;
}
/**
@@ -79,13 +142,30 @@ public class EncryptionOptions {
*
* @param key key ring
*/
- public void addRecipient(PGPPublicKeyRing key) {
+ public EncryptionOptions addRecipient(PGPPublicKeyRing key) {
+ return addRecipient(key, encryptionKeySelector);
+ }
+
+ /**
+ * Add a recipient by providing a key and an encryption key selection strategy.
+ *
+ * @param key key ring
+ * @param encryptionKeySelectionStrategy strategy used to select one or multiple encryption subkeys.
+ */
+ public EncryptionOptions addRecipient(PGPPublicKeyRing key, EncryptionKeySelector encryptionKeySelectionStrategy) {
KeyRingInfo info = new KeyRingInfo(key, new Date());
- PGPPublicKey encryptionSubkey = info.getEncryptionSubkey(purpose);
- if (encryptionSubkey == null) {
- throw new IllegalArgumentException("Key has no encryption subkey.");
+
+ List encryptionSubkeys = encryptionKeySelectionStrategy
+ .selectEncryptionSubkeys(info.getEncryptionSubkeys(purpose));
+ if (encryptionSubkeys.isEmpty()) {
+ throw new IllegalArgumentException("Key has no suitable encryption subkeys.");
}
- addRecipientKey(key, encryptionSubkey);
+
+ for (PGPPublicKey encryptionSubkey : encryptionSubkeys) {
+ addRecipientKey(key, encryptionSubkey);
+ }
+
+ return this;
}
private void addRecipientKey(PGPPublicKeyRing keyRing, PGPPublicKey key) {
@@ -100,13 +180,13 @@ public class EncryptionOptions {
*
* @param passphrase passphrase
*/
- public void addPassphrase(Passphrase passphrase) {
+ public EncryptionOptions addPassphrase(Passphrase passphrase) {
if (passphrase.isEmpty()) {
throw new IllegalArgumentException("Passphrase must not be empty.");
}
PBEKeyEncryptionMethodGenerator encryptionMethod = ImplementationFactory
.getInstance().getPBEKeyEncryptionMethodGenerator(passphrase);
- addEncryptionMethod(encryptionMethod);
+ return addEncryptionMethod(encryptionMethod);
}
/**
@@ -119,8 +199,9 @@ public class EncryptionOptions {
*
* @param encryptionMethod encryption method
*/
- public void addEncryptionMethod(PGPKeyEncryptionMethodGenerator encryptionMethod) {
+ public EncryptionOptions addEncryptionMethod(PGPKeyEncryptionMethodGenerator encryptionMethod) {
encryptionMethods.add(encryptionMethod);
+ return this;
}
public Set getEncryptionMethods() {
@@ -141,4 +222,38 @@ public class EncryptionOptions {
}
this.encryptionAlgorithmOverride = encryptionAlgorithm;
}
+
+ public interface EncryptionKeySelector {
+ List selectEncryptionSubkeys(List encryptionCapableKeys);
+ }
+
+ /**
+ * Only encrypt to the first valid encryption capable subkey we stumble upon.
+ *
+ * @return encryption key selector
+ */
+ public static EncryptionKeySelector encryptToFirstSubkey() {
+ return new EncryptionKeySelector() {
+ @Override
+ public List selectEncryptionSubkeys(List encryptionCapableKeys) {
+ return encryptionCapableKeys.isEmpty() ? Collections.emptyList() : Collections.singletonList(encryptionCapableKeys.get(0));
+ }
+ };
+ }
+
+ /**
+ * Encrypt to any valid, encryption capable subkey on the key ring.
+ *
+ * @return encryption key selector
+ */
+ public static EncryptionKeySelector encryptToAllCapableSubkeys() {
+ return new EncryptionKeySelector() {
+ @Override
+ public List selectEncryptionSubkeys(List encryptionCapableKeys) {
+ return encryptionCapableKeys;
+ }
+ };
+ }
+
+ // TODO: Create encryptToBestSubkey() method
}
diff --git a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java
index b6f62063..870388b6 100644
--- a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java
+++ b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java
@@ -82,18 +82,21 @@ public final class SigningOptions {
KeyRingInfo keyRingInfo = new KeyRingInfo(secretKey, new Date());
if (userId != null) {
if (!keyRingInfo.isUserIdValid(userId)) {
- throw new KeyValidationException(userId, keyRingInfo.getCurrentUserIdCertification(userId), keyRingInfo.getUserIdRevocation(userId));
+ throw new KeyValidationException(userId, keyRingInfo.getLatestUserIdCertification(userId), keyRingInfo.getUserIdRevocation(userId));
}
}
- PGPPublicKey signingPubKey = keyRingInfo.getSigningSubkey();
- if (signingPubKey == null) {
+ List signingPubKeys = keyRingInfo.getSigningSubkeys();
+ if (signingPubKeys.isEmpty()) {
throw new AssertionError("Key has no valid signing key.");
}
- PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID());
- PGPPrivateKey signingSubkey = signingSecKey.extractPrivateKey(secretKeyDecryptor.getDecryptor(signingPubKey.getKeyID()));
- List hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(userId, signingPubKey.getKeyID());
- addSigningMethod(secretKey, signingSubkey, hashAlgorithms.get(0), signatureType, false);
+
+ for (PGPPublicKey signingPubKey : signingPubKeys) {
+ PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID());
+ PGPPrivateKey signingSubkey = signingSecKey.extractPrivateKey(secretKeyDecryptor.getDecryptor(signingPubKey.getKeyID()));
+ List hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(userId, signingPubKey.getKeyID());
+ addSigningMethod(secretKey, signingSubkey, hashAlgorithms.get(0), signatureType, false);
+ }
}
public void addDetachedSignature(SecretKeyRingProtector secretKeyDecryptor,
@@ -111,18 +114,21 @@ public final class SigningOptions {
KeyRingInfo keyRingInfo = new KeyRingInfo(secretKey, new Date());
if (userId != null) {
if (!keyRingInfo.isUserIdValid(userId)) {
- throw new KeyValidationException(userId, keyRingInfo.getCurrentUserIdCertification(userId), keyRingInfo.getUserIdRevocation(userId));
+ throw new KeyValidationException(userId, keyRingInfo.getLatestUserIdCertification(userId), keyRingInfo.getUserIdRevocation(userId));
}
}
- PGPPublicKey signingPubKey = keyRingInfo.getSigningSubkey();
- if (signingPubKey == null) {
+ List signingPubKeys = keyRingInfo.getSigningSubkeys();
+ if (signingPubKeys.isEmpty()) {
throw new AssertionError("Key has no valid signing key.");
}
- PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID());
- PGPPrivateKey signingSubkey = signingSecKey.extractPrivateKey(secretKeyDecryptor.getDecryptor(signingPubKey.getKeyID()));
- List hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(userId, signingPubKey.getKeyID());
- addSigningMethod(secretKey, signingSubkey, hashAlgorithms.get(0), signatureType, true);
+
+ for (PGPPublicKey signingPubKey : signingPubKeys) {
+ PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID());
+ PGPPrivateKey signingSubkey = signingSecKey.extractPrivateKey(secretKeyDecryptor.getDecryptor(signingPubKey.getKeyID()));
+ List hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(userId, signingPubKey.getKeyID());
+ addSigningMethod(secretKey, signingSubkey, hashAlgorithms.get(0), signatureType, true);
+ }
}
private void addSigningMethod(PGPSecretKeyRing secretKey,
diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java
index b4d1c9bf..fa874157 100644
--- a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java
+++ b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java
@@ -29,7 +29,6 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.bouncycastle.bcpg.sig.KeyFlags;
import org.bouncycastle.bcpg.sig.PrimaryUserID;
import org.bouncycastle.openpgp.PGPKeyRing;
import org.bouncycastle.openpgp.PGPPublicKey;
@@ -116,7 +115,7 @@ public class KeyRingInfo {
* @return public key or null
*/
public PGPPublicKey getPublicKey(long keyId) {
- return keys.getPublicKey(keyId);
+ return getPublicKey(keys, keyId);
}
/**
@@ -143,12 +142,36 @@ public class KeyRingInfo {
}
if (publicKey == getPublicKey()) {
+ if (signatures.primaryKeyRevocation != null) {
+ if (SignatureUtils.isHardRevocation(signatures.primaryKeyRevocation)) {
+ return false;
+ }
+ }
return signatures.primaryKeyRevocation == null;
}
PGPSignature binding = signatures.subkeyBindings.get(keyId);
PGPSignature revocation = signatures.subkeyRevocations.get(keyId);
- return binding != null && revocation == null;
+
+ // No valid binding
+ if (binding == null || SignatureUtils.isSignatureExpired(binding)) {
+ return false;
+ }
+
+ // Revocation
+ if (revocation != null) {
+ if (SignatureUtils.isHardRevocation(revocation)) {
+ // Subkey is hard revoked
+ return false;
+ } else {
+ if (!SignatureUtils.isSignatureExpired(revocation) && revocation.getCreationTime().after(binding.getCreationTime())) {
+ // Key is soft-revoked, not yet re-bound
+ return false;
+ }
+ }
+ }
+
+ return true;
}
/**
@@ -322,11 +345,13 @@ public class KeyRingInfo {
}
/**
- * Return the current direct-key self signature.
+ * Return the latest direct-key self signature.
*
- * @return
+ * Note: This signature might be expired (check with {@link SignatureUtils#isSignatureExpired(PGPSignature)}).
+ *
+ * @return latest direct key self-signature
*/
- public PGPSignature getCurrentDirectKeySelfSignature() {
+ public PGPSignature getLatestDirectKeySelfSignature() {
return signatures.primaryKeySelfSignature;
}
@@ -334,7 +359,7 @@ public class KeyRingInfo {
return signatures.primaryKeyRevocation;
}
- public PGPSignature getCurrentUserIdCertification(String userId) {
+ public PGPSignature getLatestUserIdCertification(String userId) {
return signatures.userIdCertifications.get(userId);
}
@@ -353,27 +378,28 @@ public class KeyRingInfo {
public List getKeyFlagsOf(long keyId) {
if (getPublicKey().getKeyID() == keyId) {
- PGPSignature directKeySignature = getCurrentDirectKeySelfSignature();
+ PGPSignature directKeySignature = getLatestDirectKeySelfSignature();
if (directKeySignature != null) {
- KeyFlags flags = SignatureSubpacketsUtil.getKeyFlags(directKeySignature);
- if (flags != null) {
- return KeyFlag.fromBitmask(flags.getFlags());
+ List keyFlags = SignatureSubpacketsUtil.parseKeyFlags(directKeySignature);
+ if (keyFlags != null) {
+ return keyFlags;
}
}
String primaryUserId = getPrimaryUserId();
if (primaryUserId != null) {
- KeyFlags flags = SignatureSubpacketsUtil.getKeyFlags(getCurrentUserIdCertification(primaryUserId));
- if (flags != null) {
- return KeyFlag.fromBitmask(flags.getFlags());
+ PGPSignature userIdSignature = getLatestUserIdCertification(primaryUserId);
+ List keyFlags = SignatureSubpacketsUtil.parseKeyFlags(userIdSignature);
+ if (keyFlags != null) {
+ return keyFlags;
}
}
} else {
PGPSignature bindingSignature = getCurrentSubkeyBindingSignature(keyId);
if (bindingSignature != null) {
- KeyFlags flags = SignatureSubpacketsUtil.getKeyFlags(bindingSignature);
- if (flags != null) {
- return KeyFlag.fromBitmask(flags.getFlags());
+ List keyFlags = SignatureSubpacketsUtil.parseKeyFlags(bindingSignature);
+ if (keyFlags != null) {
+ return keyFlags;
}
}
}
@@ -385,14 +411,14 @@ public class KeyRingInfo {
return Collections.emptyList();
}
- PGPSignature userIdCertification = getCurrentUserIdCertification(userId);
+ PGPSignature userIdCertification = getLatestUserIdCertification(userId);
if (userIdCertification == null) {
- return Collections.emptyList();
+ throw new AssertionError("While user-id '" + userId + "' was reported as valid, there appears to be no certification for it.");
}
- KeyFlags keyFlags = SignatureSubpacketsUtil.getKeyFlags(userIdCertification);
+ List keyFlags = SignatureSubpacketsUtil.parseKeyFlags(userIdCertification);
if (keyFlags != null) {
- return KeyFlag.fromBitmask(keyFlags.getFlags());
+ return keyFlags;
}
return Collections.emptyList();
}
@@ -428,7 +454,7 @@ public class KeyRingInfo {
private PGPSignature getMostRecentSignature() {
Set allSignatures = new HashSet<>();
- PGPSignature mostRecentSelfSignature = getCurrentDirectKeySelfSignature();
+ PGPSignature mostRecentSelfSignature = getLatestDirectKeySelfSignature();
PGPSignature revocationSelfSignature = getRevocationSelfSignature();
if (mostRecentSelfSignature != null) allSignatures.add(mostRecentSelfSignature);
if (revocationSelfSignature != null) allSignatures.add(revocationSelfSignature);
@@ -462,12 +488,12 @@ public class KeyRingInfo {
*/
public Date getPrimaryKeyExpirationDate() {
Date lastExpiration = null;
- if (getCurrentDirectKeySelfSignature() != null) {
- lastExpiration = SignatureUtils.getKeyExpirationDate(getCreationDate(), getCurrentDirectKeySelfSignature());
+ if (getLatestDirectKeySelfSignature() != null) {
+ lastExpiration = SignatureUtils.getKeyExpirationDate(getCreationDate(), getLatestDirectKeySelfSignature());
}
for (String userId : getValidUserIds()) {
- PGPSignature signature = getCurrentUserIdCertification(userId);
+ PGPSignature signature = getLatestUserIdCertification(userId);
Date expiration = SignatureUtils.getKeyExpirationDate(getCreationDate(), signature);
if (expiration != null && (lastExpiration == null || expiration.after(lastExpiration))) {
lastExpiration = expiration;
@@ -543,8 +569,9 @@ public class KeyRingInfo {
return false;
}
- public PGPPublicKey getEncryptionSubkey(EncryptionStream.Purpose purpose) {
+ public List getEncryptionSubkeys(EncryptionStream.Purpose purpose) {
Iterator subkeys = keys.getPublicKeys();
+ List encryptionKeys = new ArrayList<>();
while (subkeys.hasNext()) {
PGPPublicKey subKey = subkeys.next();
@@ -560,36 +587,37 @@ public class KeyRingInfo {
switch (purpose) {
case COMMUNICATIONS:
if (keyFlags.contains(KeyFlag.ENCRYPT_COMMS)) {
- return subKey;
+ encryptionKeys.add(subKey);
}
break;
case STORAGE:
if (keyFlags.contains(KeyFlag.ENCRYPT_STORAGE)) {
- return subKey;
+ encryptionKeys.add(subKey);
}
break;
case STORAGE_AND_COMMUNICATIONS:
if (keyFlags.contains(KeyFlag.ENCRYPT_COMMS) || keyFlags.contains(KeyFlag.ENCRYPT_STORAGE)) {
- return subKey;
+ encryptionKeys.add(subKey);
}
break;
}
}
- return null;
+ return encryptionKeys;
}
- public PGPPublicKey getEncryptionSubkey(String userId, EncryptionStream.Purpose purpose) {
+ public List getEncryptionSubkeys(String userId, EncryptionStream.Purpose purpose) {
if (userId != null) {
if (!isUserIdValid(userId)) {
- throw new KeyValidationException(userId, getCurrentUserIdCertification(userId), getUserIdRevocation(userId));
+ throw new KeyValidationException(userId, getLatestUserIdCertification(userId), getUserIdRevocation(userId));
}
}
- return getEncryptionSubkey(purpose);
+ return getEncryptionSubkeys(purpose);
}
- public PGPPublicKey getSigningSubkey() {
+ public List getSigningSubkeys() {
Iterator subkeys = keys.getPublicKeys();
+ List signingKeys = new ArrayList<>();
while (subkeys.hasNext()) {
PGPPublicKey subKey = subkeys.next();
@@ -599,16 +627,16 @@ public class KeyRingInfo {
List keyFlags = getKeyFlagsOf(subKey.getKeyID());
if (keyFlags.contains(KeyFlag.SIGN_DATA)) {
- return subKey;
+ signingKeys.add(subKey);
}
}
- return null;
+ return signingKeys;
}
public List getPreferredHashAlgorithms(String userId, long keyID) {
- PGPSignature signature = getCurrentUserIdCertification(userId == null ? getPrimaryUserId() : userId);
+ PGPSignature signature = getLatestUserIdCertification(userId == null ? getPrimaryUserId() : userId);
if (signature == null) {
- signature = getCurrentDirectKeySelfSignature();
+ signature = getLatestDirectKeySelfSignature();
}
if (signature == null) {
signature = getCurrentSubkeyBindingSignature(keyID);
diff --git a/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestTwoSubkeysEncryption.java b/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestTwoSubkeysEncryption.java
index 0220f6ec..750d1e23 100644
--- a/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestTwoSubkeysEncryption.java
+++ b/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestTwoSubkeysEncryption.java
@@ -26,11 +26,12 @@ import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.util.io.Streams;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless;
+import org.pgpainless.encryption_signing.EncryptionOptions;
import org.pgpainless.encryption_signing.EncryptionResult;
import org.pgpainless.encryption_signing.EncryptionStream;
+import org.pgpainless.encryption_signing.ProducerOptions;
import org.pgpainless.key.WeirdKeys;
import org.pgpainless.key.util.KeyRingUtils;
@@ -46,23 +47,25 @@ public class TestTwoSubkeysEncryption {
* {@link WeirdKeys#TWO_CRYPT_SUBKEYS} is a key that has two subkeys which both carry the key flags
* {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_COMMS} and {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_STORAGE}.
*
- * This test makes sure that both subkeys are used for encryption.
+ * This test verifies that {@link EncryptionOptions#addRecipient(PGPPublicKeyRing, EncryptionOptions.EncryptionKeySelector)}
+ * works properly, if {@link EncryptionOptions#encryptToAllCapableSubkeys()} is provided as argument.
*
* @throws IOException not expected
* @throws PGPException not expected
*/
@Test
- @Disabled("We may not want to encrypt to all enc capable subkeys.")
public void testEncryptsToBothSubkeys() throws IOException, PGPException {
PGPSecretKeyRing twoSuitableSubkeysKeyRing = WeirdKeys.getTwoCryptSubkeysKey();
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(twoSuitableSubkeysKeyRing);
ByteArrayOutputStream out = new ByteArrayOutputStream();
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign(EncryptionStream.Purpose.STORAGE)
.onOutputStream(out)
- .toRecipient(publicKeys)
- .and()
- .doNotSign()
- .noArmor();
+ .withOptions(
+ ProducerOptions.encrypt(new EncryptionOptions(EncryptionStream.Purpose.STORAGE_AND_COMMUNICATIONS)
+ .addRecipient(publicKeys, EncryptionOptions.encryptToAllCapableSubkeys())
+ )
+ .setAsciiArmor(false)
+ );
Streams.pipeAll(getPlainIn(), encryptionStream);
encryptionStream.close();