diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java b/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java index 1a6585b9..4cafe337 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditor.java @@ -59,7 +59,6 @@ import org.pgpainless.key.util.RevocationAttributes; import org.pgpainless.signature.SignatureUtils; import org.pgpainless.signature.builder.RevocationSignatureBuilder; import org.pgpainless.signature.builder.SelfSignatureBuilder; -import org.pgpainless.signature.builder.SignatureFactory; import org.pgpainless.signature.subpackets.RevocationSignatureSubpackets; import org.pgpainless.signature.subpackets.SelfSignatureSubpackets; import org.pgpainless.signature.subpackets.SignatureSubpacketGeneratorUtil; @@ -102,12 +101,11 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface { KeyRingInfo info = PGPainless.inspectKeyRing(secretKeyRing); List keyFlags = info.getKeyFlagsOf(info.getKeyId()); - SelfSignatureBuilder builder = SignatureFactory.selfCertifyUserId( - primaryKey, - protector, - signatureSubpacketCallback, - keyFlags); + SelfSignatureBuilder builder = new SelfSignatureBuilder(primaryKey, protector); builder.setSignatureType(SignatureType.POSITIVE_CERTIFICATION); + builder.getHashedSubpackets().setKeyFlags(keyFlags); + builder.applyCallback(signatureSubpacketCallback); + PGPSignature signature = builder.build(primaryKey.getPublicKey(), userId); secretKeyRing = KeyRingUtils.injectCertification(secretKeyRing, userId, signature); diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/protection/BaseSecretKeyRingProtector.java b/pgpainless-core/src/main/java/org/pgpainless/key/protection/BaseSecretKeyRingProtector.java new file mode 100644 index 00000000..6df10082 --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/key/protection/BaseSecretKeyRingProtector.java @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: 2021 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.key.protection; + +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; +import org.pgpainless.implementation.ImplementationFactory; +import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider; +import org.pgpainless.util.Passphrase; + +import javax.annotation.Nullable; + +public class BaseSecretKeyRingProtector implements SecretKeyRingProtector { + + private final SecretKeyPassphraseProvider passphraseProvider; + private final KeyRingProtectionSettings protectionSettings; + + public BaseSecretKeyRingProtector(SecretKeyPassphraseProvider passphraseProvider) { + this(passphraseProvider, KeyRingProtectionSettings.secureDefaultSettings()); + } + + public BaseSecretKeyRingProtector(SecretKeyPassphraseProvider passphraseProvider, KeyRingProtectionSettings protectionSettings) { + this.passphraseProvider = passphraseProvider; + this.protectionSettings = protectionSettings; + } + + @Override + public boolean hasPassphraseFor(Long keyId) { + return passphraseProvider.hasPassphrase(keyId); + } + + @Override + @Nullable + public PBESecretKeyDecryptor getDecryptor(Long keyId) throws PGPException { + Passphrase passphrase = passphraseProvider.getPassphraseFor(keyId); + return passphrase == null ? null : + ImplementationFactory.getInstance().getPBESecretKeyDecryptor(passphrase); + } + + @Override + @Nullable + public PBESecretKeyEncryptor getEncryptor(Long keyId) throws PGPException { + Passphrase passphrase = passphraseProvider.getPassphraseFor(keyId); + return passphrase == null ? null : + ImplementationFactory.getInstance().getPBESecretKeyEncryptor( + protectionSettings.getEncryptionAlgorithm(), + protectionSettings.getHashAlgorithm(), + protectionSettings.getS2kCount(), + passphrase); + } +} diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/protection/PasswordBasedSecretKeyRingProtector.java b/pgpainless-core/src/main/java/org/pgpainless/key/protection/PasswordBasedSecretKeyRingProtector.java index d198c187..c5745068 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/protection/PasswordBasedSecretKeyRingProtector.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/protection/PasswordBasedSecretKeyRingProtector.java @@ -4,17 +4,13 @@ package org.pgpainless.key.protection; -import java.util.Iterator; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyRing; -import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; -import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider; import org.pgpainless.util.Passphrase; @@ -22,10 +18,11 @@ import org.pgpainless.util.Passphrase; * Provides {@link PBESecretKeyDecryptor} and {@link PBESecretKeyEncryptor} objects while getting the passphrases * from a {@link SecretKeyPassphraseProvider} and using settings from an {@link KeyRingProtectionSettings}. */ -public class PasswordBasedSecretKeyRingProtector implements SecretKeyRingProtector { +public class PasswordBasedSecretKeyRingProtector extends BaseSecretKeyRingProtector { - protected final KeyRingProtectionSettings protectionSettings; - protected final SecretKeyPassphraseProvider passphraseProvider; + public PasswordBasedSecretKeyRingProtector(@Nonnull SecretKeyPassphraseProvider passphraseProvider) { + super(passphraseProvider); + } /** * Constructor. @@ -36,23 +33,15 @@ public class PasswordBasedSecretKeyRingProtector implements SecretKeyRingProtect * @param passphraseProvider provider which provides passphrases. */ public PasswordBasedSecretKeyRingProtector(@Nonnull KeyRingProtectionSettings settings, @Nonnull SecretKeyPassphraseProvider passphraseProvider) { - this.protectionSettings = settings; - this.passphraseProvider = passphraseProvider; + super(passphraseProvider, settings); } public static PasswordBasedSecretKeyRingProtector forKey(PGPKeyRing keyRing, Passphrase passphrase) { - KeyRingProtectionSettings protectionSettings = KeyRingProtectionSettings.secureDefaultSettings(); SecretKeyPassphraseProvider passphraseProvider = new SecretKeyPassphraseProvider() { @Override @Nullable public Passphrase getPassphraseFor(Long keyId) { - for (Iterator it = keyRing.getPublicKeys(); it.hasNext(); ) { - PGPPublicKey key = it.next(); - if (key.getKeyID() == keyId) { - return passphrase; - } - } - return null; + return hasPassphrase(keyId) ? passphrase : null; } @Override @@ -60,7 +49,7 @@ public class PasswordBasedSecretKeyRingProtector implements SecretKeyRingProtect return keyRing.getPublicKey(keyId) != null; } }; - return new PasswordBasedSecretKeyRingProtector(protectionSettings, passphraseProvider); + return new PasswordBasedSecretKeyRingProtector(passphraseProvider); } public static PasswordBasedSecretKeyRingProtector forKey(PGPSecretKey key, Passphrase passphrase) { @@ -68,7 +57,6 @@ public class PasswordBasedSecretKeyRingProtector implements SecretKeyRingProtect } public static PasswordBasedSecretKeyRingProtector forKeyId(long singleKeyId, Passphrase passphrase) { - KeyRingProtectionSettings protectionSettings = KeyRingProtectionSettings.secureDefaultSettings(); SecretKeyPassphraseProvider passphraseProvider = new SecretKeyPassphraseProvider() { @Nullable @Override @@ -84,31 +72,7 @@ public class PasswordBasedSecretKeyRingProtector implements SecretKeyRingProtect return keyId == singleKeyId; } }; - return new PasswordBasedSecretKeyRingProtector(protectionSettings, passphraseProvider); + return new PasswordBasedSecretKeyRingProtector(passphraseProvider); } - @Override - public boolean hasPassphraseFor(Long keyId) { - return passphraseProvider.hasPassphrase(keyId); - } - - @Override - @Nullable - public PBESecretKeyDecryptor getDecryptor(Long keyId) throws PGPException { - Passphrase passphrase = passphraseProvider.getPassphraseFor(keyId); - return passphrase == null ? null : - ImplementationFactory.getInstance().getPBESecretKeyDecryptor(passphrase); - } - - @Override - @Nullable - public PBESecretKeyEncryptor getEncryptor(Long keyId) throws PGPException { - Passphrase passphrase = passphraseProvider.getPassphraseFor(keyId); - return passphrase == null ? null : - ImplementationFactory.getInstance().getPBESecretKeyEncryptor( - protectionSettings.getEncryptionAlgorithm(), - protectionSettings.getHashAlgorithm(), - protectionSettings.getS2kCount(), - passphrase); - } } diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/protection/SecretKeyRingProtector.java b/pgpainless-core/src/main/java/org/pgpainless/key/protection/SecretKeyRingProtector.java index b1cb7fdf..a77e4486 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/protection/SecretKeyRingProtector.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/protection/SecretKeyRingProtector.java @@ -7,6 +7,7 @@ package org.pgpainless.key.protection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.bouncycastle.openpgp.PGPException; @@ -15,6 +16,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider; +import org.pgpainless.key.protection.passphrase_provider.SolitaryPassphraseProvider; import org.pgpainless.util.Passphrase; /** @@ -66,7 +68,23 @@ public interface SecretKeyRingProtector { } /** - * Use the provided passphrase to lock/unlock all subkeys in the provided key ring. + * Use the provided passphrase to lock/unlock all keys in the provided key ring. + * + * This protector will use the provided passphrase to lock/unlock all subkeys present in the provided keys object. + * For other keys that are not present in the ring, it will return null. + * + * @param passphrase passphrase + * @param keys key ring + * @return protector + * @deprecated use {@link #unlockEachKeyWith(Passphrase, PGPSecretKeyRing)} instead. + */ + @Deprecated + static SecretKeyRingProtector unlockAllKeysWith(@Nonnull Passphrase passphrase, @Nonnull PGPSecretKeyRing keys) { + return unlockEachKeyWith(passphrase, keys); + } + + /** + * Use the provided passphrase to lock/unlock all keys in the provided key ring. * * This protector will use the provided passphrase to lock/unlock all subkeys present in the provided keys object. * For other keys that are not present in the ring, it will return null. @@ -75,7 +93,7 @@ public interface SecretKeyRingProtector { * @param keys key ring * @return protector */ - static SecretKeyRingProtector unlockAllKeysWith(Passphrase passphrase, PGPSecretKeyRing keys) { + static SecretKeyRingProtector unlockEachKeyWith(@Nonnull Passphrase passphrase, @Nonnull PGPSecretKeyRing keys) { Map map = new ConcurrentHashMap<>(); for (PGPSecretKey secretKey : keys) { map.put(secretKey.getKeyID(), passphrase); @@ -83,6 +101,16 @@ public interface SecretKeyRingProtector { return fromPassphraseMap(map); } + /** + * Use the provided passphrase to unlock any key. + * + * @param passphrase passphrase + * @return protector + */ + static SecretKeyRingProtector unlockAnyKeyWith(@Nonnull Passphrase passphrase) { + return new BaseSecretKeyRingProtector(new SolitaryPassphraseProvider(passphrase)); + } + /** * Use the provided passphrase to lock/unlock only the provided (sub-)key. * This protector will only return a non-null encryptor/decryptor based on the provided passphrase if @@ -94,11 +122,11 @@ public interface SecretKeyRingProtector { * @param key key to lock/unlock * @return protector */ - static SecretKeyRingProtector unlockSingleKeyWith(Passphrase passphrase, PGPSecretKey key) { + static SecretKeyRingProtector unlockSingleKeyWith(@Nonnull Passphrase passphrase, @Nonnull PGPSecretKey key) { return PasswordBasedSecretKeyRingProtector.forKey(key, passphrase); } - static SecretKeyRingProtector unlockSingleKeyWith(Passphrase passphrase, long keyId) { + static SecretKeyRingProtector unlockSingleKeyWith(@Nonnull Passphrase passphrase, long keyId) { return PasswordBasedSecretKeyRingProtector.forKeyId(keyId, passphrase); } @@ -123,7 +151,7 @@ public interface SecretKeyRingProtector { * @param passphraseMap map of key ids and their respective passphrases * @return protector */ - static SecretKeyRingProtector fromPassphraseMap(Map passphraseMap) { + static SecretKeyRingProtector fromPassphraseMap(@Nonnull Map passphraseMap) { return new CachingSecretKeyRingProtector(passphraseMap, KeyRingProtectionSettings.secureDefaultSettings(), null); } } diff --git a/pgpainless-core/src/main/java/org/pgpainless/signature/builder/SignatureFactory.java b/pgpainless-core/src/main/java/org/pgpainless/signature/builder/SignatureFactory.java deleted file mode 100644 index 9bcac504..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/signature/builder/SignatureFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.signature.builder; - -import java.util.List; -import javax.annotation.Nullable; - -import org.bouncycastle.openpgp.PGPSecretKey; -import org.pgpainless.algorithm.KeyFlag; -import org.pgpainless.algorithm.SignatureType; -import org.pgpainless.exception.WrongPassphraseException; -import org.pgpainless.key.protection.SecretKeyRingProtector; -import org.pgpainless.signature.subpackets.SelfSignatureSubpackets; - -public final class SignatureFactory { - - private SignatureFactory() { - - } - - public static SelfSignatureBuilder selfCertifyUserId( - PGPSecretKey primaryKey, - SecretKeyRingProtector primaryKeyProtector, - @Nullable SelfSignatureSubpackets.Callback selfSignatureCallback, - List keyFlags) - throws WrongPassphraseException { - KeyFlag[] keyFlagArray = keyFlags.toArray(new KeyFlag[0]); - return selfCertifyUserId(primaryKey, primaryKeyProtector, selfSignatureCallback, keyFlagArray); - } - - public static SelfSignatureBuilder selfCertifyUserId( - PGPSecretKey primaryKey, - SecretKeyRingProtector primaryKeyProtector, - @Nullable SelfSignatureSubpackets.Callback selfSignatureCallback, - KeyFlag... flags) throws WrongPassphraseException { - - SelfSignatureBuilder certifier = new SelfSignatureBuilder(SignatureType.POSITIVE_CERTIFICATION, primaryKey, primaryKeyProtector); - certifier.getHashedSubpackets().setKeyFlags(flags); - - certifier.applyCallback(selfSignatureCallback); - - return certifier; - } - -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SelfSignatureSubpackets.java b/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SelfSignatureSubpackets.java index 1ff45ae4..02cc5e93 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SelfSignatureSubpackets.java +++ b/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SelfSignatureSubpackets.java @@ -5,6 +5,7 @@ package org.pgpainless.signature.subpackets; import java.util.Date; +import java.util.List; import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -30,6 +31,11 @@ public interface SelfSignatureSubpackets extends BaseSignatureSubpackets { SelfSignatureSubpackets setKeyFlags(KeyFlag... keyFlags); + default SelfSignatureSubpackets setKeyFlags(List keyFlags) { + KeyFlag[] flags = keyFlags.toArray(new KeyFlag[0]); + return setKeyFlags(flags); + } + SelfSignatureSubpackets setKeyFlags(boolean isCritical, KeyFlag... keyFlags); SelfSignatureSubpackets setKeyFlags(@Nullable KeyFlags keyFlags); diff --git a/pgpainless-core/src/test/java/org/bouncycastle/AsciiArmorCRCTests.java b/pgpainless-core/src/test/java/org/bouncycastle/AsciiArmorCRCTests.java index 19d72dda..8fa1bd9d 100644 --- a/pgpainless-core/src/test/java/org/bouncycastle/AsciiArmorCRCTests.java +++ b/pgpainless-core/src/test/java/org/bouncycastle/AsciiArmorCRCTests.java @@ -546,7 +546,7 @@ public class AsciiArmorCRCTests { DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify() .onInputStream(new ByteArrayInputStream(message.getBytes(StandardCharsets.UTF_8))) .withOptions(new ConsumerOptions().addDecryptionKey( - key, SecretKeyRingProtector.unlockAllKeysWith(passphrase, key) + key, SecretKeyRingProtector.unlockAnyKeyWith(passphrase) )); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); diff --git a/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/ModificationDetectionTests.java b/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/ModificationDetectionTests.java index 2a2a0844..2eb870cb 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/ModificationDetectionTests.java +++ b/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/ModificationDetectionTests.java @@ -537,7 +537,7 @@ public class ModificationDetectionTests { assertThrows(MessageNotIntegrityProtectedException.class, () -> PGPainless.decryptAndOrVerify() .onInputStream(new ByteArrayInputStream(ciphertext.getBytes(StandardCharsets.UTF_8))) .withOptions(new ConsumerOptions().addDecryptionKey(secretKeyRing, - SecretKeyRingProtector.unlockAllKeysWith(passphrase, secretKeyRing))) + SecretKeyRingProtector.unlockAnyKeyWith(passphrase))) ); } diff --git a/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/PostponeDecryptionUsingKeyWithMissingPassphraseTest.java b/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/PostponeDecryptionUsingKeyWithMissingPassphraseTest.java index 4aad6c9e..fc3f7163 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/PostponeDecryptionUsingKeyWithMissingPassphraseTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/decryption_verification/PostponeDecryptionUsingKeyWithMissingPassphraseTest.java @@ -132,7 +132,7 @@ public class PostponeDecryptionUsingKeyWithMissingPassphraseTest { return false; } }); - SecretKeyRingProtector protector2 = SecretKeyRingProtector.unlockAllKeysWith(p2, k2); + SecretKeyRingProtector protector2 = SecretKeyRingProtector.unlockEachKeyWith(p2, k2); DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify() .onInputStream(new ByteArrayInputStream(ENCRYPTED_FOR_K1_K2.getBytes(StandardCharsets.UTF_8))) @@ -149,7 +149,7 @@ public class PostponeDecryptionUsingKeyWithMissingPassphraseTest { @Test public void missingPassphraseSecond() throws PGPException, IOException { - SecretKeyRingProtector protector1 = SecretKeyRingProtector.unlockAllKeysWith(p1, k1); + SecretKeyRingProtector protector1 = SecretKeyRingProtector.unlockEachKeyWith(p1, k1); SecretKeyRingProtector protector2 = new CachingSecretKeyRingProtector(new SecretKeyPassphraseProvider() { @Nullable @Override diff --git a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/SigningTest.java b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/SigningTest.java index 89531220..6a73152d 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/SigningTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/SigningTest.java @@ -54,7 +54,8 @@ public class SigningTest { @ParameterizedTest @MethodSource("org.pgpainless.util.TestImplementationFactoryProvider#provideImplementationFactories") - public void testEncryptionAndSignatureVerification(ImplementationFactory implementationFactory) throws IOException, PGPException { + public void testEncryptionAndSignatureVerification(ImplementationFactory implementationFactory) + throws IOException, PGPException { ImplementationFactory.setFactoryImplementation(implementationFactory); PGPPublicKeyRing julietKeys = TestKeys.getJulietPublicKeyRing(); @@ -73,12 +74,13 @@ public class SigningTest { EncryptionOptions.encryptDataAtRest() .addRecipients(keys) .addRecipient(KeyRingUtils.publicKeyRingFrom(cryptieKeys)), - new SigningOptions() - .addInlineSignature(SecretKeyRingProtector.unlockSingleKeyWith(TestKeys.CRYPTIE_PASSPHRASE, cryptieSigningKey), + new SigningOptions().addInlineSignature( + SecretKeyRingProtector.unlockSingleKeyWith(TestKeys.CRYPTIE_PASSPHRASE, cryptieSigningKey), cryptieKeys, TestKeys.CRYPTIE_UID, DocumentSignatureType.CANONICAL_TEXT_DOCUMENT) ).setAsciiArmor(true)); - byte[] messageBytes = "This message is signed and encrypted to Romeo and Juliet.".getBytes(StandardCharsets.UTF_8); + byte[] messageBytes = "This message is signed and encrypted to Romeo and Juliet." + .getBytes(StandardCharsets.UTF_8); ByteArrayInputStream message = new ByteArrayInputStream(messageBytes); Streams.pipeAll(message, encryptionStream); @@ -90,8 +92,10 @@ public class SigningTest { PGPSecretKeyRing romeoSecret = TestKeys.getRomeoSecretKeyRing(); PGPSecretKeyRing julietSecret = TestKeys.getJulietSecretKeyRing(); - PGPSecretKeyRingCollection secretKeys = new PGPSecretKeyRingCollection(Arrays.asList(romeoSecret, julietSecret)); - PGPPublicKeyRingCollection verificationKeys = new PGPPublicKeyRingCollection(Arrays.asList(KeyRingUtils.publicKeyRingFrom(cryptieKeys), romeoKeys)); + PGPSecretKeyRingCollection secretKeys = new PGPSecretKeyRingCollection( + Arrays.asList(romeoSecret, julietSecret)); + PGPPublicKeyRingCollection verificationKeys = new PGPPublicKeyRingCollection( + Arrays.asList(KeyRingUtils.publicKeyRingFrom(cryptieKeys), romeoKeys)); DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify() .onInputStream(cryptIn) @@ -114,22 +118,26 @@ public class SigningTest { } @Test - public void testSignWithInvalidUserIdFails() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { + public void testSignWithInvalidUserIdFails() + throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() .modernKeyRing("alice", "password123"); - SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword("password123"), secretKeys); + SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("password123")); SigningOptions opts = new SigningOptions(); // "bob" is not a valid user-id assertThrows(KeyValidationError.class, - () -> opts.addInlineSignature(protector, secretKeys, "bob", DocumentSignatureType.CANONICAL_TEXT_DOCUMENT)); + () -> opts.addInlineSignature(protector, secretKeys, "bob", + DocumentSignatureType.CANONICAL_TEXT_DOCUMENT)); } @Test - public void testSignWithRevokedUserIdFails() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { + public void testSignWithRevokedUserIdFails() + throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() .modernKeyRing("alice", "password123"); - SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword("password123"), secretKeys); + SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith( + Passphrase.fromPassword("password123")); secretKeys = PGPainless.modifyKeyRing(secretKeys) .revokeUserId("alice", protector) .done(); @@ -139,7 +147,8 @@ public class SigningTest { SigningOptions opts = new SigningOptions(); // "alice" has been revoked assertThrows(KeyValidationError.class, - () -> opts.addInlineSignature(protector, fSecretKeys, "alice", DocumentSignatureType.CANONICAL_TEXT_DOCUMENT)); + () -> opts.addInlineSignature(protector, fSecretKeys, "alice", + DocumentSignatureType.CANONICAL_TEXT_DOCUMENT)); } @Test @@ -174,14 +183,18 @@ public class SigningTest { } @Test - public void negotiateHashAlgorithmChoseFallbackIfEmptyPreferences() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { + public void negotiateHashAlgorithmChoseFallbackIfEmptyPreferences() + throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing() - .setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA).overridePreferredHashAlgorithms()) + .setPrimaryKey(KeySpec.getBuilder( + KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA) + .overridePreferredHashAlgorithms()) .addUserId("Alice") .build(); SigningOptions options = new SigningOptions() - .addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, DocumentSignatureType.BINARY_DOCUMENT); + .addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, + DocumentSignatureType.BINARY_DOCUMENT); String data = "Hello, World!\n"; EncryptionStream signer = PGPainless.encryptAndOrSign() .onOutputStream(new ByteArrayOutputStream()) @@ -194,19 +207,23 @@ public class SigningTest { SubkeyIdentifier signingKey = sigs.keySet().iterator().next(); PGPSignature signature = sigs.get(signingKey).iterator().next(); - assertEquals(PGPainless.getPolicy().getSignatureHashAlgorithmPolicy().defaultHashAlgorithm().getAlgorithmId(), signature.getHashAlgorithm()); + assertEquals(PGPainless.getPolicy().getSignatureHashAlgorithmPolicy().defaultHashAlgorithm().getAlgorithmId(), + signature.getHashAlgorithm()); } @Test - public void negotiateHashAlgorithmChoseFallbackIfUnacceptablePreferences() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { + public void negotiateHashAlgorithmChoseFallbackIfUnacceptablePreferences() + throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing() - .setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA) + .setPrimaryKey( + KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA) .overridePreferredHashAlgorithms(HashAlgorithm.MD5)) .addUserId("Alice") .build(); SigningOptions options = new SigningOptions() - .addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, DocumentSignatureType.BINARY_DOCUMENT); + .addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, + DocumentSignatureType.BINARY_DOCUMENT); String data = "Hello, World!\n"; EncryptionStream signer = PGPainless.encryptAndOrSign() .onOutputStream(new ByteArrayOutputStream()) @@ -219,33 +236,41 @@ public class SigningTest { SubkeyIdentifier signingKey = sigs.keySet().iterator().next(); PGPSignature signature = sigs.get(signingKey).iterator().next(); - assertEquals(PGPainless.getPolicy().getSignatureHashAlgorithmPolicy().defaultHashAlgorithm().getAlgorithmId(), signature.getHashAlgorithm()); + assertEquals(PGPainless.getPolicy().getSignatureHashAlgorithmPolicy().defaultHashAlgorithm().getAlgorithmId(), + signature.getHashAlgorithm()); } @Test - public void signingWithNonCapableKeyThrowsKeyCannotSignException() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { + public void signingWithNonCapableKeyThrowsKeyCannotSignException() + throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing() .setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER)) .addUserId("Alice") .build(); SigningOptions options = new SigningOptions(); - assertThrows(KeyCannotSignException.class, () -> options.addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, DocumentSignatureType.BINARY_DOCUMENT)); - assertThrows(KeyCannotSignException.class, () -> options.addInlineSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, DocumentSignatureType.BINARY_DOCUMENT)); + assertThrows(KeyCannotSignException.class, () -> options.addDetachedSignature( + SecretKeyRingProtector.unprotectedKeys(), secretKeys, DocumentSignatureType.BINARY_DOCUMENT)); + assertThrows(KeyCannotSignException.class, () -> options.addInlineSignature( + SecretKeyRingProtector.unprotectedKeys(), secretKeys, DocumentSignatureType.BINARY_DOCUMENT)); } @Test - public void signWithInvalidUserIdThrowsKeyValidationError() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { + public void signWithInvalidUserIdThrowsKeyValidationError() + throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing() - .setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)) + .setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), + KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)) .addUserId("Alice") .build(); SigningOptions options = new SigningOptions(); assertThrows(KeyValidationError.class, () -> - options.addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, "Bob", DocumentSignatureType.BINARY_DOCUMENT)); + options.addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, "Bob", + DocumentSignatureType.BINARY_DOCUMENT)); assertThrows(KeyValidationError.class, () -> - options.addInlineSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, "Bob", DocumentSignatureType.BINARY_DOCUMENT)); + options.addInlineSignature(SecretKeyRingProtector.unprotectedKeys(), secretKeys, "Bob", + DocumentSignatureType.BINARY_DOCUMENT)); } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/example/ModifyKeys.java b/pgpainless-core/src/test/java/org/pgpainless/example/ModifyKeys.java index 51d1d2a6..f8096dba 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/example/ModifyKeys.java +++ b/pgpainless-core/src/test/java/org/pgpainless/example/ModifyKeys.java @@ -50,7 +50,8 @@ public class ModifyKeys { private long signingSubkeyId; @BeforeEach - public void generateKey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { + public void generateKey() + throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { secretKey = PGPainless.generateKeyRing() .modernKeyRing(userId, originalPassphrase); @@ -128,10 +129,13 @@ public class ModifyKeys { // encryption key can now only be unlocked using the new passphrase assertThrows(WrongPassphraseException.class, () -> - UnlockSecretKey.unlockSecretKey(secretKey.getSecretKey(encryptionSubkeyId), Passphrase.fromPassword(originalPassphrase))); - UnlockSecretKey.unlockSecretKey(secretKey.getSecretKey(encryptionSubkeyId), Passphrase.fromPassword("cryptP4ssphr4s3")); + UnlockSecretKey.unlockSecretKey( + secretKey.getSecretKey(encryptionSubkeyId), Passphrase.fromPassword(originalPassphrase))); + UnlockSecretKey.unlockSecretKey( + secretKey.getSecretKey(encryptionSubkeyId), Passphrase.fromPassword("cryptP4ssphr4s3")); // primary key remains unchanged - UnlockSecretKey.unlockSecretKey(secretKey.getSecretKey(primaryKeyId), Passphrase.fromPassword(originalPassphrase)); + UnlockSecretKey.unlockSecretKey( + secretKey.getSecretKey(primaryKeyId), Passphrase.fromPassword(originalPassphrase)); } /** @@ -141,7 +145,8 @@ public class ModifyKeys { */ @Test public void addUserId() throws PGPException { - SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword(originalPassphrase), secretKey); + SecretKeyRingProtector protector = + SecretKeyRingProtector.unlockEachKeyWith(Passphrase.fromPassword(originalPassphrase), secretKey); secretKey = PGPainless.modifyKeyRing(secretKey) .addUserId("additional@user.id", protector) .done(); @@ -172,7 +177,8 @@ public class ModifyKeys { @Test public void addSubkey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { // Protector for unlocking the existing secret key - SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword(originalPassphrase), secretKey); + SecretKeyRingProtector protector = + SecretKeyRingProtector.unlockEachKeyWith(Passphrase.fromPassword(originalPassphrase), secretKey); Passphrase subkeyPassphrase = Passphrase.fromPassword("subk3yP4ssphr4s3"); secretKey = PGPainless.modifyKeyRing(secretKey) .addSubKey( @@ -202,16 +208,19 @@ public class ModifyKeys { Date expirationDate = DateUtil.parseUTCDate("2030-06-24 12:44:56 UTC"); SecretKeyRingProtector protector = SecretKeyRingProtector - .unlockAllKeysWith(Passphrase.fromPassword(originalPassphrase), secretKey); + .unlockEachKeyWith(Passphrase.fromPassword(originalPassphrase), secretKey); secretKey = PGPainless.modifyKeyRing(secretKey) .setExpirationDate(expirationDate, protector) .done(); KeyRingInfo info = PGPainless.inspectKeyRing(secretKey); - assertEquals(DateUtil.formatUTCDate(expirationDate), DateUtil.formatUTCDate(info.getPrimaryKeyExpirationDate())); - assertEquals(DateUtil.formatUTCDate(expirationDate), DateUtil.formatUTCDate(info.getExpirationDateForUse(KeyFlag.ENCRYPT_COMMS))); - assertEquals(DateUtil.formatUTCDate(expirationDate), DateUtil.formatUTCDate(info.getExpirationDateForUse(KeyFlag.SIGN_DATA))); + assertEquals(DateUtil.formatUTCDate(expirationDate), + DateUtil.formatUTCDate(info.getPrimaryKeyExpirationDate())); + assertEquals(DateUtil.formatUTCDate(expirationDate), + DateUtil.formatUTCDate(info.getExpirationDateForUse(KeyFlag.ENCRYPT_COMMS))); + assertEquals(DateUtil.formatUTCDate(expirationDate), + DateUtil.formatUTCDate(info.getExpirationDateForUse(KeyFlag.SIGN_DATA))); } /** @@ -223,7 +232,7 @@ public class ModifyKeys { public void setSubkeyExpirationDate() throws PGPException { Date expirationDate = DateUtil.parseUTCDate("2032-01-13 22:30:01 UTC"); SecretKeyRingProtector protector = SecretKeyRingProtector - .unlockAllKeysWith(Passphrase.fromPassword(originalPassphrase), secretKey); + .unlockEachKeyWith(Passphrase.fromPassword(originalPassphrase), secretKey); secretKey = PGPainless.modifyKeyRing(secretKey) .setExpirationDate( @@ -237,7 +246,8 @@ public class ModifyKeys { KeyRingInfo info = PGPainless.inspectKeyRing(secretKey); assertNull(info.getPrimaryKeyExpirationDate()); assertNull(info.getExpirationDateForUse(KeyFlag.SIGN_DATA)); - assertEquals(DateUtil.formatUTCDate(expirationDate), DateUtil.formatUTCDate(info.getExpirationDateForUse(KeyFlag.ENCRYPT_COMMS))); + assertEquals(DateUtil.formatUTCDate(expirationDate), + DateUtil.formatUTCDate(info.getExpirationDateForUse(KeyFlag.ENCRYPT_COMMS))); } /** @@ -247,7 +257,7 @@ public class ModifyKeys { */ @Test public void revokeUserId() throws PGPException { - SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith( + SecretKeyRingProtector protector = SecretKeyRingProtector.unlockEachKeyWith( Passphrase.fromPassword(originalPassphrase), secretKey); secretKey = PGPainless.modifyKeyRing(secretKey) .addUserId("alcie@pgpainless.org", protector) diff --git a/pgpainless-core/src/test/java/org/pgpainless/example/UnlockSecretKeys.java b/pgpainless-core/src/test/java/org/pgpainless/example/UnlockSecretKeys.java index 784cff61..a7b056b7 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/example/UnlockSecretKeys.java +++ b/pgpainless-core/src/test/java/org/pgpainless/example/UnlockSecretKeys.java @@ -58,10 +58,10 @@ public class UnlockSecretKeys { @Test public void unlockWholeKeyWithSamePassphrase() throws PGPException, IOException { PGPSecretKeyRing secretKey = TestKeys.getCryptieSecretKeyRing(); - // Unlock all subkeys in the secret key with the same passphrase - SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith( - Passphrase.fromPassword(TestKeys.CRYPTIE_PASSWORD), secretKey); + Passphrase passphrase = TestKeys.CRYPTIE_PASSPHRASE; + // Unlock all subkeys in the secret key with the same passphrase + SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(passphrase); assertProtectorUnlocksAllSecretKeys(secretKey, protector); } diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/modification/AddSubKeyTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/modification/AddSubKeyTest.java index 406d300c..0fb9a5ec 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/modification/AddSubKeyTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/modification/AddSubKeyTest.java @@ -65,7 +65,7 @@ public class AddSubKeyTest { long subKeyId = keyIdsAfter.get(0); PGPSecretKey subKey = secretKeys.getSecretKey(subKeyId); - SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith( + SecretKeyRingProtector protector = SecretKeyRingProtector.unlockEachKeyWith( Passphrase.fromPassword("subKeyPassphrase"), secretKeys); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(subKey, protector); diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/protection/SecretKeyRingProtectorTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/protection/SecretKeyRingProtectorTest.java index 1a8a3231..037d996d 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/protection/SecretKeyRingProtectorTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/protection/SecretKeyRingProtectorTest.java @@ -36,11 +36,13 @@ public class SecretKeyRingProtectorTest { @ParameterizedTest @MethodSource("org.pgpainless.util.TestImplementationFactoryProvider#provideImplementationFactories") - public void testUnlockAllKeysWithSamePassword(ImplementationFactory implementationFactory) throws IOException, PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { + public void testUnlockAllKeysWithSamePassword(ImplementationFactory implementationFactory) + throws IOException, PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { ImplementationFactory.setFactoryImplementation(implementationFactory); PGPSecretKeyRing secretKeys = TestKeys.getCryptieSecretKeyRing(); - SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(TestKeys.CRYPTIE_PASSPHRASE, secretKeys); + SecretKeyRingProtector protector = + SecretKeyRingProtector.unlockEachKeyWith(TestKeys.CRYPTIE_PASSPHRASE, secretKeys); for (PGPSecretKey secretKey : secretKeys) { PBESecretKeyDecryptor decryptor = protector.getDecryptor(secretKey.getKeyID()); assertNotNull(decryptor); @@ -51,7 +53,8 @@ public class SecretKeyRingProtectorTest { for (PGPSecretKey unrelatedKey : unrelatedKeys) { PBESecretKeyDecryptor decryptor = protector.getDecryptor(unrelatedKey.getKeyID()); assertNull(decryptor); - assertThrows(PGPException.class, () -> unrelatedKey.extractPrivateKey(protector.getDecryptor(unrelatedKey.getKeyID()))); + assertThrows(PGPException.class, + () -> unrelatedKey.extractPrivateKey(protector.getDecryptor(unrelatedKey.getKeyID()))); } } @@ -68,7 +71,8 @@ public class SecretKeyRingProtectorTest { @ParameterizedTest @MethodSource("org.pgpainless.util.TestImplementationFactoryProvider#provideImplementationFactories") - public void testUnlockSingleKeyWithPassphrase(ImplementationFactory implementationFactory) throws IOException, PGPException { + public void testUnlockSingleKeyWithPassphrase(ImplementationFactory implementationFactory) + throws IOException, PGPException { ImplementationFactory.setFactoryImplementation(implementationFactory); PGPSecretKeyRing secretKeys = TestKeys.getCryptieSecretKeyRing(); @@ -76,7 +80,8 @@ public class SecretKeyRingProtectorTest { PGPSecretKey secretKey = iterator.next(); PGPSecretKey subKey = iterator.next(); - SecretKeyRingProtector protector = SecretKeyRingProtector.unlockSingleKeyWith(TestKeys.CRYPTIE_PASSPHRASE, secretKey); + SecretKeyRingProtector protector = + SecretKeyRingProtector.unlockSingleKeyWith(TestKeys.CRYPTIE_PASSPHRASE, secretKey); assertNotNull(protector.getDecryptor(secretKey.getKeyID())); assertNotNull(protector.getEncryptor(secretKey.getKeyID())); assertNull(protector.getEncryptor(subKey.getKeyID())); @@ -87,7 +92,8 @@ public class SecretKeyRingProtectorTest { public void testFromPassphraseMap() { Map passphraseMap = new ConcurrentHashMap<>(); passphraseMap.put(1L, Passphrase.emptyPassphrase()); - CachingSecretKeyRingProtector protector = (CachingSecretKeyRingProtector) SecretKeyRingProtector.fromPassphraseMap(passphraseMap); + CachingSecretKeyRingProtector protector = + (CachingSecretKeyRingProtector) SecretKeyRingProtector.fromPassphraseMap(passphraseMap); assertNotNull(protector.getPassphraseFor(1L)); assertNull(protector.getPassphraseFor(5L)); diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/protection/UnlockSecretKeyTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/protection/UnlockSecretKeyTest.java index 9e4c0984..c6a35ea9 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/protection/UnlockSecretKeyTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/protection/UnlockSecretKeyTest.java @@ -27,12 +27,17 @@ public class UnlockSecretKeyTest { .simpleEcKeyRing("alice@wonderland.lit", "heureka!"); PGPSecretKey secretKey = secretKeyRing.getSecretKey(); - SecretKeyRingProtector correctPassphrase = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword("heureka!"), secretKeyRing); - SecretKeyRingProtector incorrectPassphrase = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword("bazinga!"), secretKeyRing); - SecretKeyRingProtector emptyPassphrase = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.emptyPassphrase(), secretKeyRing); + SecretKeyRingProtector correctPassphrase = SecretKeyRingProtector + .unlockAnyKeyWith(Passphrase.fromPassword("heureka!")); + SecretKeyRingProtector incorrectPassphrase = SecretKeyRingProtector + .unlockAnyKeyWith(Passphrase.fromPassword("bazinga!")); + SecretKeyRingProtector emptyPassphrase = SecretKeyRingProtector + .unlockAnyKeyWith(Passphrase.emptyPassphrase()); Passphrase cleared = Passphrase.fromPassword("cleared"); cleared.clear(); - SecretKeyRingProtector invalidPassphrase = SecretKeyRingProtector.unlockAllKeysWith(cleared, secretKeyRing); + SecretKeyRingProtector invalidPassphrase = SecretKeyRingProtector + .unlockAnyKeyWith(cleared); + // Correct passphrase works PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, correctPassphrase); assertNotNull(privateKey); @@ -41,7 +46,7 @@ public class UnlockSecretKeyTest { UnlockSecretKey.unlockSecretKey(secretKey, incorrectPassphrase)); assertThrows(WrongPassphraseException.class, () -> UnlockSecretKey.unlockSecretKey(secretKey, emptyPassphrase)); - assertThrows(WrongPassphraseException.class, () -> + assertThrows(IllegalStateException.class, () -> UnlockSecretKey.unlockSecretKey(secretKey, invalidPassphrase)); } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/protection/fixes/S2KUsageFixTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/protection/fixes/S2KUsageFixTest.java index d5956da4..f324892f 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/protection/fixes/S2KUsageFixTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/protection/fixes/S2KUsageFixTest.java @@ -67,7 +67,8 @@ public class S2KUsageFixTest { private static final String MESSAGE_PLAIN = "Hello, World!\n"; @Test - public void verifyOutFixInChangePassphraseWorks() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { + public void verifyOutFixInChangePassphraseWorks() + throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { PGPSecretKeyRing before = PGPainless.generateKeyRing().modernKeyRing("Alice", "before"); for (PGPSecretKey key : before) { assertEquals(SecretKeyPacket.USAGE_SHA1, key.getS2KUsage()); @@ -93,9 +94,10 @@ public class S2KUsageFixTest { } @Test - public void testFixS2KUsageFrom_USAGE_CHECKSUM_to_USAGE_SHA1() throws IOException, PGPException { + public void testFixS2KUsageFrom_USAGE_CHECKSUM_to_USAGE_SHA1() + throws IOException, PGPException { PGPSecretKeyRing keys = PGPainless.readKeyRing().secretKeyRing(KEY_WITH_USAGE_CHECKSUM); - SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword("after"), keys); + SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("after")); PGPSecretKeyRing fixed = S2KUsageFix.replaceUsageChecksumWithUsageSha1(keys, protector); for (PGPSecretKey key : fixed) { @@ -105,7 +107,8 @@ public class S2KUsageFixTest { testCanStillDecrypt(keys, protector); } - private void testCanStillDecrypt(PGPSecretKeyRing keys, SecretKeyRingProtector protector) throws PGPException, IOException { + private void testCanStillDecrypt(PGPSecretKeyRing keys, SecretKeyRingProtector protector) + throws PGPException, IOException { ByteArrayInputStream in = new ByteArrayInputStream(MESSAGE.getBytes(StandardCharsets.UTF_8)); DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify() .onInputStream(in)