From f79aba74ed2dde8a9b6277df9edfa05ad0dd3bfd Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Wed, 2 Apr 2025 20:54:19 +0200 Subject: [PATCH] Port a bunch of more tests --- .../encryption_signing/BcHashContextSigner.kt | 8 +- .../key/protection/UnlockSecretKey.kt | 5 +- .../EncryptionOptionsTest.java | 37 ++++---- .../FileInformationTest.java | 30 ++++--- .../HiddenRecipientEncryptionTest.java | 18 ++-- .../java/org/pgpainless/key/WeirdKeys.java | 41 ++++----- .../collection/PGPKeyRingCollectionTest.java | 8 +- .../parsing/KeyRingCollectionReaderTest.java | 11 ++- .../key/parsing/KeyRingReaderTest.java | 87 +++++++++---------- .../CachingSecretKeyRingProtectorTest.java | 27 +++--- .../weird_keys/TestTwoSubkeysEncryption.java | 15 ++-- 11 files changed, 148 insertions(+), 139 deletions(-) diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/BcHashContextSigner.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/BcHashContextSigner.kt index 18303dfc..8de2726b 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/BcHashContextSigner.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/BcHashContextSigner.kt @@ -4,6 +4,7 @@ package org.pgpainless.encryption_signing +import java.security.MessageDigest import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPSignatureGenerator import org.bouncycastle.openpgp.api.OpenPGPKey @@ -12,7 +13,6 @@ import org.pgpainless.PGPainless import org.pgpainless.algorithm.SignatureType import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.UnlockSecretKey -import java.security.MessageDigest class BcHashContextSigner { @@ -29,7 +29,8 @@ class BcHashContextSigner { .mapNotNull { info.getSecretKey(it.keyIdentifier) } .firstOrNull() ?.let { - signHashContext(hashContext, signatureType, UnlockSecretKey.unlockSecretKey(it, protector)) + signHashContext( + hashContext, signatureType, UnlockSecretKey.unlockSecretKey(it, protector)) } ?: throw PGPException("Key does not contain suitable signing subkey.") } @@ -49,8 +50,7 @@ class BcHashContextSigner { privateKey: OpenPGPKey.OpenPGPPrivateKey ): OpenPGPDocumentSignature { return PGPSignatureGenerator( - BcPGPHashContextContentSignerBuilder(hashContext), - privateKey.keyPair.publicKey) + BcPGPHashContextContentSignerBuilder(hashContext), privateKey.keyPair.publicKey) .apply { init(signatureType.code, privateKey.keyPair.privateKey) } .generate() .let { OpenPGPDocumentSignature(it, privateKey.publicKey) } diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/key/protection/UnlockSecretKey.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/key/protection/UnlockSecretKey.kt index dd2f7081..00ea9de9 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/key/protection/UnlockSecretKey.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/key/protection/UnlockSecretKey.kt @@ -113,7 +113,10 @@ class UnlockSecretKey { } @JvmStatic - fun unlockSecretKey(secretKey: OpenPGPSecretKey, passphrase: Passphrase): OpenPGPPrivateKey = + fun unlockSecretKey( + secretKey: OpenPGPSecretKey, + passphrase: Passphrase + ): OpenPGPPrivateKey = unlockSecretKey(secretKey, SecretKeyRingProtector.unlockAnyKeyWith(passphrase)) } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptionOptionsTest.java b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptionOptionsTest.java index d364a84d..7adfefd5 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptionOptionsTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/EncryptionOptionsTest.java @@ -16,7 +16,6 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPKey; @@ -31,7 +30,6 @@ import org.pgpainless.key.generation.KeySpec; import org.pgpainless.key.generation.type.KeyType; import org.pgpainless.key.generation.type.eddsa_legacy.EdDSALegacyCurve; import org.pgpainless.key.generation.type.xdh_legacy.XDHLegacySpec; -import org.pgpainless.key.util.KeyRingUtils; import org.pgpainless.util.Passphrase; import javax.annotation.Nonnull; @@ -43,10 +41,11 @@ public class EncryptionOptionsTest { private static OpenPGPCertificate.OpenPGPComponentKey primaryKey; private static OpenPGPCertificate.OpenPGPComponentKey encryptComms; private static OpenPGPCertificate.OpenPGPComponentKey encryptStorage; + private static final PGPainless api = PGPainless.getInstance(); @BeforeAll public static void generateKey() { - secretKeys = PGPainless.buildKeyRing() + secretKeys = api.buildKey() .setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER) .build()) .addSubkey(KeySpec.getBuilder(KeyType.XDH_LEGACY(XDHLegacySpec._X25519), KeyFlag.ENCRYPT_COMMS) @@ -66,7 +65,7 @@ public class EncryptionOptionsTest { @Test public void testOverrideEncryptionAlgorithmFailsForNULL() { - EncryptionOptions options = EncryptionOptions.get(); + EncryptionOptions options = EncryptionOptions.get(api); assertNull(options.getEncryptionAlgorithmOverride()); assertThrows(IllegalArgumentException.class, () -> options.overrideEncryptionAlgorithm(SymmetricKeyAlgorithm.NULL)); @@ -76,7 +75,7 @@ public class EncryptionOptionsTest { @Test public void testOverrideEncryptionOptions() { - EncryptionOptions options = EncryptionOptions.get(); + EncryptionOptions options = EncryptionOptions.get(api); assertNull(options.getEncryptionAlgorithmOverride()); options.overrideEncryptionAlgorithm(SymmetricKeyAlgorithm.AES_128); @@ -85,7 +84,7 @@ public class EncryptionOptionsTest { @Test public void testAddRecipients_EncryptCommunications() { - EncryptionOptions options = EncryptionOptions.encryptCommunications(); + EncryptionOptions options = EncryptionOptions.encryptCommunications(api); options.addRecipient(publicKeys); Set encryptionKeys = options.getEncryptionKeys(); @@ -95,7 +94,7 @@ public class EncryptionOptionsTest { @Test public void testAddRecipients_EncryptDataAtRest() { - EncryptionOptions options = EncryptionOptions.encryptDataAtRest(); + EncryptionOptions options = EncryptionOptions.encryptDataAtRest(api); options.addRecipient(publicKeys); Set encryptionKeys = options.getEncryptionKeys(); @@ -105,7 +104,7 @@ public class EncryptionOptionsTest { @Test public void testAddRecipients_AllKeys() { - EncryptionOptions options = EncryptionOptions.get(); + EncryptionOptions options = EncryptionOptions.get(api); options.addRecipient(publicKeys, EncryptionOptions.encryptToAllCapableSubkeys()); Set encryptionKeys = options.getEncryptionKeys(); @@ -115,9 +114,10 @@ public class EncryptionOptionsTest { assertTrue(encryptionKeys.contains(encryptStorage)); } + @SuppressWarnings("deprecation") @Test public void testAddEmptyRecipientsFails() { - EncryptionOptions options = EncryptionOptions.get(); + EncryptionOptions options = EncryptionOptions.get(api); assertThrows(IllegalArgumentException.class, () -> options.addRecipients(Collections.emptyList())); assertThrows(IllegalArgumentException.class, () -> options.addRecipients(Collections.emptyList(), ArrayList::new)); @@ -125,7 +125,7 @@ public class EncryptionOptionsTest { @Test public void testAddEmptyPassphraseFails() { - EncryptionOptions options = EncryptionOptions.get(); + EncryptionOptions options = EncryptionOptions.get(api); assertThrows(IllegalArgumentException.class, () -> options.addMessagePassphrase(Passphrase.emptyPassphrase())); } @@ -133,7 +133,7 @@ public class EncryptionOptionsTest { @Test public void testAddRecipient_KeyWithoutEncryptionKeyFails() { EncryptionOptions options = EncryptionOptions.get(); - OpenPGPKey secretKeys = PGPainless.buildKeyRing() + OpenPGPKey secretKeys = api.buildKey() .setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)) .addUserId("test@pgpainless.org") .build(); @@ -144,7 +144,7 @@ public class EncryptionOptionsTest { @Test public void testEncryptionKeySelectionStrategyEmpty_ThrowsAssertionError() { - EncryptionOptions options = EncryptionOptions.get(); + EncryptionOptions options = EncryptionOptions.get(api); assertThrows(KeyException.UnacceptableEncryptionKeyException.class, () -> options.addRecipient(publicKeys, new EncryptionOptions.EncryptionKeySelector() { @@ -157,6 +157,7 @@ public class EncryptionOptionsTest { assertThrows(KeyException.UnacceptableEncryptionKeyException.class, () -> options.addRecipient(publicKeys, "test@pgpainless.org", new EncryptionOptions.EncryptionKeySelector() { + @NotNull @Override public List selectEncryptionSubkeys(@Nonnull List encryptionCapableKeys) { return Collections.emptyList(); @@ -166,21 +167,21 @@ public class EncryptionOptionsTest { @Test public void testAddRecipients_PGPPublicKeyRingCollection() { - PGPPublicKeyRing secondKeyRing = KeyRingUtils.publicKeyRingFrom( - PGPainless.generateKeyRing().modernKeyRing("other@pgpainless.org") - .getPGPSecretKeyRing()); + OpenPGPKey secondKey = api.generateKey().modernKeyRing("Other "); + OpenPGPCertificate secondCert = secondKey.toCertificate(); PGPPublicKeyRingCollection collection = new PGPPublicKeyRingCollection( - Arrays.asList(publicKeys.getPGPPublicKeyRing(), secondKeyRing)); + Arrays.asList(publicKeys.getPGPPublicKeyRing(), secondCert.getPGPPublicKeyRing())); EncryptionOptions options = EncryptionOptions.get(); + // noinspection deprecation options.addRecipients(collection, EncryptionOptions.encryptToFirstSubkey()); assertEquals(2, options.getEncryptionKeyIdentifiers().size()); } @Test public void testAddRecipient_withValidUserId() { - EncryptionOptions options = EncryptionOptions.get(); + EncryptionOptions options = EncryptionOptions.get(api); options.addRecipient(publicKeys, "test@pgpainless.org", EncryptionOptions.encryptToFirstSubkey()); assertEquals(1, options.getEncryptionMethods().size()); @@ -188,7 +189,7 @@ public class EncryptionOptionsTest { @Test public void testAddRecipient_withInvalidUserId() { - EncryptionOptions options = EncryptionOptions.get(); + EncryptionOptions options = EncryptionOptions.get(api); assertThrows(KeyException.UnboundUserIdException.class, () -> options.addRecipient(publicKeys, "invalid@user.id")); } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/FileInformationTest.java b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/FileInformationTest.java index 0684c81e..7298c3d4 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/FileInformationTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/FileInformationTest.java @@ -17,8 +17,8 @@ import java.util.Date; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; -import org.bouncycastle.openpgp.PGPPublicKeyRing; -import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.api.OpenPGPCertificate; +import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.util.io.Streams; import org.junit.JUtils; import org.junit.jupiter.api.BeforeAll; @@ -32,14 +32,14 @@ import org.pgpainless.decryption_verification.MessageMetadata; public class FileInformationTest { private static final String data = "Hello, World!\n"; - private static PGPSecretKeyRing secretKey; - private static PGPPublicKeyRing certificate; + private static OpenPGPKey secretKey; + private static OpenPGPCertificate certificate; + private static final PGPainless api = PGPainless.getInstance(); @BeforeAll public static void generateKey() { - secretKey = PGPainless.generateKeyRing().modernKeyRing("alice@wonderland.lit") - .getPGPSecretKeyRing(); - certificate = PGPainless.extractCertificate(secretKey); + secretKey = api.generateKey().modernKeyRing("alice@wonderland.lit"); + certificate = secretKey.toCertificate(); } @Test @@ -50,11 +50,12 @@ public class FileInformationTest { ByteArrayInputStream dataIn = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); ByteArrayOutputStream dataOut = new ByteArrayOutputStream(); - EncryptionStream encryptionStream = PGPainless.encryptAndOrSign() + // noinspection deprecation + EncryptionStream encryptionStream = api.generateMessage() .onOutputStream(dataOut) .withOptions(ProducerOptions.encrypt( EncryptionOptions - .encryptCommunications() + .encryptCommunications(api) .addRecipient(certificate)) .setFileName(fileName) .setModificationDate(modificationDate) @@ -91,11 +92,11 @@ public class FileInformationTest { public void testDefaults() throws PGPException, IOException { ByteArrayInputStream dataIn = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); ByteArrayOutputStream dataOut = new ByteArrayOutputStream(); - EncryptionStream encryptionStream = PGPainless.encryptAndOrSign() + EncryptionStream encryptionStream = api.generateMessage() .onOutputStream(dataOut) .withOptions(ProducerOptions.encrypt( EncryptionOptions - .encryptCommunications() + .encryptCommunications(api) .addRecipient(certificate)) ); @@ -125,6 +126,7 @@ public class FileInformationTest { JUtils.assertDateEquals(PGPLiteralData.NOW, decResult.getModificationDate()); assertNotNull(decResult.getLiteralDataEncoding()); assertEquals(PGPLiteralData.BINARY, decResult.getLiteralDataEncoding().getCode()); + // noinspection deprecation assertFalse(decResult.isForYourEyesOnly()); } @@ -132,11 +134,12 @@ public class FileInformationTest { public void testForYourEyesOnly() throws PGPException, IOException { ByteArrayInputStream dataIn = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); ByteArrayOutputStream dataOut = new ByteArrayOutputStream(); - EncryptionStream encryptionStream = PGPainless.encryptAndOrSign() + // noinspection deprecation + EncryptionStream encryptionStream = api.generateMessage() .onOutputStream(dataOut) .withOptions(ProducerOptions.encrypt( EncryptionOptions - .encryptCommunications() + .encryptCommunications(api) .addRecipient(certificate)) .setForYourEyesOnly() ); @@ -167,6 +170,7 @@ public class FileInformationTest { JUtils.assertDateEquals(PGPLiteralData.NOW, decResult.getModificationDate()); assertNotNull(decResult.getLiteralDataEncoding()); assertEquals(PGPLiteralData.BINARY, decResult.getLiteralDataEncoding().getCode()); + // noinspection deprecation assertTrue(decResult.isForYourEyesOnly()); } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/HiddenRecipientEncryptionTest.java b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/HiddenRecipientEncryptionTest.java index af018584..5df689c5 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/HiddenRecipientEncryptionTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/encryption_signing/HiddenRecipientEncryptionTest.java @@ -13,8 +13,8 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPPublicKeyRing; -import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.api.OpenPGPCertificate; +import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.util.io.Streams; import org.junit.jupiter.api.Test; import org.pgpainless.PGPainless; @@ -30,18 +30,18 @@ public class HiddenRecipientEncryptionTest { @Test public void testAnonymousRecipientRoundtrip() throws PGPException, IOException { - PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() - .modernKeyRing("Alice ") - .getPGPSecretKeyRing(); - PGPPublicKeyRing certificate = PGPainless.extractCertificate(secretKeys); + PGPainless api = PGPainless.getInstance(); + OpenPGPKey secretKeys = api.generateKey() + .modernKeyRing("Alice "); + OpenPGPCertificate certificate = secretKeys.toCertificate(); String msg = "Hello, World!\n"; ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream(); - EncryptionStream encryptionStream = PGPainless.encryptAndOrSign() + EncryptionStream encryptionStream = api.generateMessage() .onOutputStream(ciphertextOut) .withOptions(ProducerOptions.encrypt( - EncryptionOptions.get() + EncryptionOptions.get(api) .addHiddenRecipient(certificate) )); encryptionStream.write(msg.getBytes(StandardCharsets.UTF_8)); @@ -65,6 +65,8 @@ public class HiddenRecipientEncryptionTest { assertEquals(msg, plaintextOut.toString()); assertTrue(metadata.getRecipientKeyIds().contains(0L)); + assertEquals(1, metadata.getRecipientKeyIdentifiers().size()); + assertTrue(metadata.getRecipientKeyIdentifiers().get(0).isWildcard()); assertEquals(actualEncryptionKey, metadata.getDecryptionKey()); } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/WeirdKeys.java b/pgpainless-core/src/test/java/org/pgpainless/key/WeirdKeys.java index 97637c99..e5d96bc0 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/WeirdKeys.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/WeirdKeys.java @@ -13,17 +13,17 @@ import java.util.Collections; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; -import org.bouncycastle.openpgp.PGPSecretKey; -import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; +import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPImplementation; +import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.util.Strings; import org.junit.jupiter.api.Test; import org.pgpainless.PGPainless; +import org.pgpainless.algorithm.OpenPGPKeyVersion; import org.pgpainless.algorithm.SignatureType; import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.protection.UnlockSecretKey; @@ -67,8 +67,8 @@ public class WeirdKeys { "=BlPm\n" + "-----END PGP PRIVATE KEY BLOCK-----\n"; - public static PGPSecretKeyRing getTwoCryptSubkeysKey() throws IOException { - return PGPainless.readKeyRing().secretKeyRing(TWO_CRYPT_SUBKEYS); + public static OpenPGPKey getTwoCryptSubkeysKey() throws IOException { + return PGPainless.getInstance().readKey().parseKey(TWO_CRYPT_SUBKEYS); } /** @@ -96,18 +96,18 @@ public class WeirdKeys { "=h6sT\n" + "-----END PGP PRIVATE KEY BLOCK-----\n"; - public static PGPSecretKeyRing getArchiveCommsSubkeysKey() throws IOException { - return PGPainless.readKeyRing().secretKeyRing(ARCHIVE_COMMS_SUBKEYS); + public static OpenPGPKey getArchiveCommsSubkeysKey() throws IOException { + return PGPainless.getInstance().readKey().parseKey(ARCHIVE_COMMS_SUBKEYS); } @Test public void generateCertAndTestWithNonUTF8UserId() throws PGPException, IOException { - PGPSecretKeyRing nakedKey = PGPainless.generateKeyRing().modernKeyRing(null) - .getPGPSecretKeyRing(); - PGPPublicKey pubKey = nakedKey.getPublicKey(); - PGPSecretKey secKey = nakedKey.getSecretKey(); - PGPPrivateKey privKey = UnlockSecretKey.unlockSecretKey(secKey, Passphrase.emptyPassphrase()); + OpenPGPKey nakedKey = PGPainless.getInstance() + .generateKey(OpenPGPKeyVersion.v4) // v4, since we manually craft the binding sig later on + .modernKeyRing(null); + OpenPGPKey.OpenPGPSecretKey primaryKey = nakedKey.getPrimarySecretKey(); + OpenPGPKey.OpenPGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(primaryKey, Passphrase.emptyPassphrase()); // Non-UTF8 User-ID ByteArrayOutputStream bOut = new ByteArrayOutputStream(); @@ -122,15 +122,15 @@ public class WeirdKeys { PGPSignatureGenerator sigGen = new PGPSignatureGenerator( OpenPGPImplementation.getInstance().pgpContentSignerBuilder( - pubKey.getAlgorithm(), + primaryKey.getAlgorithm(), HashAlgorithmTags.SHA512), - pubKey); - sigGen.init(SignatureType.GENERIC_CERTIFICATION.getCode(), privKey); + primaryKey.getPGPPublicKey()); + sigGen.init(SignatureType.GENERIC_CERTIFICATION.getCode(), privateKey.getKeyPair().getPrivateKey()); // We have to manually generate the signature over the user-ID // updateWithKey() - byte[] keyBytes = pubKey.getPublicKeyPacket().getEncodedContents(); - sigGen.update((byte) 0x99); + byte[] keyBytes = primaryKey.getPGPPublicKey().getPublicKeyPacket().getEncodedContents(); + sigGen.update((byte) 0x99); // 0x99 means v4 key sigGen.update((byte) (keyBytes.length >> 8)); sigGen.update((byte) (keyBytes.length)); sigGen.update(keyBytes); @@ -144,12 +144,13 @@ public class WeirdKeys { sigGen.update(idBytes); PGPSignature signature = sigGen.generate(); - pubKey = PGPPublicKey.addCertification(pubKey, idBytes, signature); + PGPPublicKey pubKey = PGPPublicKey.addCertification(primaryKey.getPGPPublicKey(), idBytes, signature); - PGPPublicKeyRing cert = new PGPPublicKeyRing(Collections.singletonList(pubKey)); + PGPPublicKeyRing pubRing = new PGPPublicKeyRing(Collections.singletonList(pubKey)); + OpenPGPCertificate cert = PGPainless.getInstance().toCertificate(pubRing); // This might fail - KeyRingInfo info = PGPainless.inspectKeyRing(cert); + KeyRingInfo info = PGPainless.getInstance().inspect(cert); assertTrue(info.getUserIds().isEmpty()); // Malformed ID is ignored } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/collection/PGPKeyRingCollectionTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/collection/PGPKeyRingCollectionTest.java index f356f007..769ead35 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/collection/PGPKeyRingCollectionTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/collection/PGPKeyRingCollectionTest.java @@ -54,10 +54,14 @@ public class PGPKeyRingCollectionTest { @Test public void testConstructorFromCollection() { - PGPSecretKeyRing first = PGPainless.generateKeyRing().simpleEcKeyRing("alice@wonderland.lit") + PGPainless api = PGPainless.getInstance(); + PGPSecretKeyRing first = api.generateKey() + .simpleEcKeyRing("alice@wonderland.lit") .getPGPSecretKeyRing(); - PGPSecretKeyRing second = PGPainless.generateKeyRing().simpleEcKeyRing("bob@the-builder.tv") + PGPSecretKeyRing second = api.generateKey() + .simpleEcKeyRing("bob@the-builder.tv") .getPGPSecretKeyRing(); + // noinspection deprecation PGPPublicKeyRing secondPub = KeyRingUtils.publicKeyRingFrom(second); Collection keys = Arrays.asList(first, second, secondPub); diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/parsing/KeyRingCollectionReaderTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/parsing/KeyRingCollectionReaderTest.java index c91186c7..5d8c8027 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/parsing/KeyRingCollectionReaderTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/parsing/KeyRingCollectionReaderTest.java @@ -23,10 +23,13 @@ public class KeyRingCollectionReaderTest { @Test public void writeAndParseKeyRingCollections() throws IOException { + PGPainless api = PGPainless.getInstance(); // secret keys - PGPSecretKeyRing alice = PGPainless.generateKeyRing().modernKeyRing("Alice ") + PGPSecretKeyRing alice = api.generateKey() + .modernKeyRing("Alice ") .getPGPSecretKeyRing(); - PGPSecretKeyRing bob = PGPainless.generateKeyRing().modernKeyRing("Bob ") + PGPSecretKeyRing bob = api.generateKey() + .modernKeyRing("Bob ") .getPGPSecretKeyRing(); PGPSecretKeyRingCollection collection = KeyRingUtils.keyRingsToKeyRingCollection(alice, bob); @@ -36,8 +39,8 @@ public class KeyRingCollectionReaderTest { assertEquals(collection.size(), parsed.size()); // public keys - PGPPublicKeyRing pAlice = KeyRingUtils.publicKeyRingFrom(alice); - PGPPublicKeyRing pBob = KeyRingUtils.publicKeyRingFrom(bob); + PGPPublicKeyRing pAlice = alice.toCertificate(); + PGPPublicKeyRing pBob = bob.toCertificate(); PGPPublicKeyRingCollection pCollection = KeyRingUtils.keyRingsToKeyRingCollection(pAlice, pBob); ascii = ArmorUtils.toAsciiArmoredString(pCollection); diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/parsing/KeyRingReaderTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/parsing/KeyRingReaderTest.java index 7bfffe92..7f0862d7 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/parsing/KeyRingReaderTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/parsing/KeyRingReaderTest.java @@ -6,6 +6,8 @@ package org.pgpainless.key.parsing; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -30,6 +32,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPImplementation; import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.util.io.Streams; @@ -38,13 +41,14 @@ import org.opentest4j.TestAbortedException; import org.pgpainless.PGPainless; import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.collection.PGPKeyRingCollection; -import org.pgpainless.key.util.KeyRingUtils; import org.pgpainless.signature.SignatureUtils; import org.pgpainless.util.ArmoredOutputStreamFactory; import org.pgpainless.util.TestUtils; class KeyRingReaderTest { + private final PGPainless api = PGPainless.getInstance(); + private InputStream requireResource(String resourceName) { InputStream inputStream = getClass().getClassLoader().getResourceAsStream(resourceName); if (inputStream == null) { @@ -81,9 +85,9 @@ class KeyRingReaderTest { Collection collection = new ArrayList<>(); for (int i = 0; i < 10; i++) { - PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().simpleEcKeyRing("user_" + i + "@encrypted.key") + PGPSecretKeyRing secretKeys = api.generateKey().simpleEcKeyRing("user_" + i + "@encrypted.key") .getPGPSecretKeyRing(); - collection.add(KeyRingUtils.publicKeyRingFrom(secretKeys)); + collection.add(secretKeys.toCertificate()); } PGPPublicKeyRingCollection originalRings = new PGPPublicKeyRingCollection(collection); @@ -275,7 +279,8 @@ class KeyRingReaderTest { "=9jtR\n" + "-----END PGP PRIVATE KEY BLOCK-----"; - PGPSecretKeyRing secretKey = PGPainless.readKeyRing().secretKeyRing(markerAndKey); + OpenPGPKey secretKey = api.readKey().parseKey(markerAndKey); + assertNotNull(secretKey); assertEquals( new OpenPgpV4Fingerprint("562584F8730F39FCB02AACAE735E5EB1C541C0CE"), new OpenPgpV4Fingerprint(secretKey)); @@ -304,7 +309,7 @@ class KeyRingReaderTest { "=6XFh\n" + "-----END PGP PUBLIC KEY BLOCK-----\n"; - PGPPublicKeyRing certificate = PGPainless.readKeyRing().publicKeyRing(markerAndCert); + OpenPGPCertificate certificate = api.readKey().parseCertificate(markerAndCert); assertEquals( new OpenPgpV4Fingerprint("4291C2BEF9B9209DF11128E7F6F2BBD4F5D29793"), @@ -450,10 +455,8 @@ class KeyRingReaderTest { @Test public void testReadSecretKeysIgnoresMultipleMarkers() throws IOException { - PGPSecretKeyRing alice = PGPainless.generateKeyRing().modernKeyRing("alice@pgpainless.org") - .getPGPSecretKeyRing(); - PGPSecretKeyRing bob = PGPainless.generateKeyRing().modernKeyRing("bob@pgpainless.org") - .getPGPSecretKeyRing(); + OpenPGPKey alice = api.generateKey().modernKeyRing("alice@pgpainless.org"); + OpenPGPKey bob = api.generateKey().modernKeyRing("bob@pgpainless.org"); MarkerPacket marker = TestUtils.getMarkerPacket(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); @@ -464,11 +467,11 @@ class KeyRingReaderTest { for (int i = 0; i < 25; i++) { marker.encode(outputStream); } - alice.encode(outputStream); + outputStream.write(alice.getEncoded()); for (int i = 0; i < 53; i++) { marker.encode(outputStream); } - bob.encode(outputStream); + outputStream.write(bob.getEncoded()); for (int i = 0; i < 102; i++) { marker.encode(outputStream); } @@ -479,15 +482,14 @@ class KeyRingReaderTest { PGPSecretKeyRingCollection secretKeys = PGPainless.readKeyRing().secretKeyRingCollection(armoredMess); assertEquals(2, secretKeys.size()); - assertTrue(secretKeys.contains(alice.getSecretKey().getKeyID())); - assertTrue(secretKeys.contains(bob.getSecretKey().getKeyID())); + assertTrue(secretKeys.contains(alice.getKeyIdentifier().getKeyId())); + assertTrue(secretKeys.contains(bob.getKeyIdentifier().getKeyId())); } @Test public void testReadingSecretKeysExceedsIterationLimit() throws IOException { - PGPSecretKeyRing alice = PGPainless.generateKeyRing().modernKeyRing("alice@pgpainless.org") - .getPGPSecretKeyRing(); + OpenPGPKey alice = api.generateKey().modernKeyRing("alice@pgpainless.org"); MarkerPacket marker = TestUtils.getMarkerPacket(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); @@ -497,7 +499,7 @@ class KeyRingReaderTest { for (int i = 0; i < 600; i++) { marker.encode(outputStream); } - alice.encode(outputStream); + outputStream.write(alice.getEncoded()); assertThrows(IOException.class, () -> KeyRingReader.readSecretKeyRing(new ByteArrayInputStream(bytes.toByteArray()), 512)); @@ -506,10 +508,8 @@ class KeyRingReaderTest { @Test public void testReadingSecretKeyCollectionExceedsIterationLimit() throws IOException { - PGPSecretKeyRing alice = PGPainless.generateKeyRing().modernKeyRing("alice@pgpainless.org") - .getPGPSecretKeyRing(); - PGPSecretKeyRing bob = PGPainless.generateKeyRing().modernKeyRing("bob@pgpainless.org") - .getPGPSecretKeyRing(); + OpenPGPKey alice = api.generateKey().modernKeyRing("alice@pgpainless.org"); + OpenPGPKey bob = api.generateKey().modernKeyRing("bob@pgpainless.org"); MarkerPacket marker = TestUtils.getMarkerPacket(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); @@ -519,8 +519,8 @@ class KeyRingReaderTest { for (int i = 0; i < 600; i++) { marker.encode(outputStream); } - alice.encode(outputStream); - bob.encode(outputStream); + outputStream.write(alice.getEncoded()); + outputStream.write(bob.getEncoded()); assertThrows(IOException.class, () -> KeyRingReader.readSecretKeyRingCollection(new ByteArrayInputStream(bytes.toByteArray()), 512)); @@ -530,9 +530,8 @@ class KeyRingReaderTest { @Test public void testReadingPublicKeysExceedsIterationLimit() throws IOException { - PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("alice@pgpainless.org") - .getPGPSecretKeyRing(); - PGPPublicKeyRing alice = PGPainless.extractCertificate(secretKeys); + OpenPGPKey secretKeys = api.generateKey().modernKeyRing("alice@pgpainless.org"); + OpenPGPCertificate alice = secretKeys.toCertificate(); MarkerPacket marker = TestUtils.getMarkerPacket(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); @@ -542,7 +541,7 @@ class KeyRingReaderTest { for (int i = 0; i < 600; i++) { marker.encode(outputStream); } - alice.encode(outputStream); + outputStream.write(alice.getEncoded()); assertThrows(IOException.class, () -> KeyRingReader.readPublicKeyRing(new ByteArrayInputStream(bytes.toByteArray()), 512)); @@ -551,12 +550,10 @@ class KeyRingReaderTest { @Test public void testReadingPublicKeyCollectionExceedsIterationLimit() throws IOException { - PGPSecretKeyRing sec1 = PGPainless.generateKeyRing().modernKeyRing("alice@pgpainless.org") - .getPGPSecretKeyRing(); - PGPSecretKeyRing sec2 = PGPainless.generateKeyRing().modernKeyRing("bob@pgpainless.org") - .getPGPSecretKeyRing(); - PGPPublicKeyRing alice = PGPainless.extractCertificate(sec1); - PGPPublicKeyRing bob = PGPainless.extractCertificate(sec2); + OpenPGPKey sec1 = api.generateKey().modernKeyRing("alice@pgpainless.org"); + OpenPGPKey sec2 = api.generateKey().modernKeyRing("bob@pgpainless.org"); + OpenPGPCertificate alice = sec1.toCertificate(); + OpenPGPCertificate bob = sec2.toCertificate(); MarkerPacket marker = TestUtils.getMarkerPacket(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); @@ -566,8 +563,8 @@ class KeyRingReaderTest { for (int i = 0; i < 600; i++) { marker.encode(outputStream); } - alice.encode(outputStream); - bob.encode(outputStream); + outputStream.write(alice.getEncoded()); + outputStream.write(bob.getEncoded()); assertThrows(IOException.class, () -> KeyRingReader.readPublicKeyRingCollection(new ByteArrayInputStream(bytes.toByteArray()), 512)); @@ -575,48 +572,44 @@ class KeyRingReaderTest { @Test public void testReadKeyRingWithBinaryPublicKey() throws IOException { - PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice ") - .getPGPSecretKeyRing(); - PGPPublicKeyRing publicKeys = PGPainless.extractCertificate(secretKeys); + OpenPGPKey secretKeys = api.generateKey().modernKeyRing("Alice "); + OpenPGPCertificate publicKeys = secretKeys.toCertificate(); byte[] bytes = publicKeys.getEncoded(); PGPKeyRing keyRing = PGPainless.readKeyRing() .keyRing(bytes); - assertTrue(keyRing instanceof PGPPublicKeyRing); + assertInstanceOf(PGPPublicKeyRing.class, keyRing); assertArrayEquals(keyRing.getEncoded(), publicKeys.getEncoded()); } @Test public void testReadKeyRingWithBinarySecretKey() throws IOException { - PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice ") - .getPGPSecretKeyRing(); + OpenPGPKey secretKeys = api.generateKey().modernKeyRing("Alice "); byte[] bytes = secretKeys.getEncoded(); PGPKeyRing keyRing = PGPainless.readKeyRing() .keyRing(bytes); - assertTrue(keyRing instanceof PGPSecretKeyRing); + assertInstanceOf(PGPSecretKeyRing.class, keyRing); assertArrayEquals(keyRing.getEncoded(), secretKeys.getEncoded()); } @Test public void testReadKeyRingWithArmoredPublicKey() throws IOException { - PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice ") - .getPGPSecretKeyRing(); - PGPPublicKeyRing publicKeys = PGPainless.extractCertificate(secretKeys); + OpenPGPKey secretKeys = api.generateKey().modernKeyRing("Alice "); + OpenPGPCertificate publicKeys = secretKeys.toCertificate(); String armored = PGPainless.asciiArmor(publicKeys); PGPKeyRing keyRing = PGPainless.readKeyRing() .keyRing(armored); - assertTrue(keyRing instanceof PGPPublicKeyRing); + assertInstanceOf(PGPPublicKeyRing.class, keyRing); assertArrayEquals(keyRing.getEncoded(), publicKeys.getEncoded()); } @Test public void testReadKeyRingWithArmoredSecretKey() throws IOException { - PGPainless api = PGPainless.getInstance(); OpenPGPKey secretKeys = api.generateKey().modernKeyRing("Alice "); // remove PacketFormat argument once https://github.com/bcgit/bc-java/pull/1993 lands in BC String armored = secretKeys.toAsciiArmoredString(PacketFormat.LEGACY); @@ -624,7 +617,7 @@ class KeyRingReaderTest { PGPKeyRing keyRing = PGPainless.readKeyRing() .keyRing(armored); - assertTrue(keyRing instanceof PGPSecretKeyRing); + assertInstanceOf(PGPSecretKeyRing.class, keyRing); assertArrayEquals(keyRing.getEncoded(), secretKeys.getEncoded()); } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/protection/CachingSecretKeyRingProtectorTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/protection/CachingSecretKeyRingProtectorTest.java index 18c341da..90acf6d5 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/protection/CachingSecretKeyRingProtectorTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/protection/CachingSecretKeyRingProtectorTest.java @@ -15,10 +15,10 @@ import java.util.Random; import org.bouncycastle.bcpg.KeyIdentifier; import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPKeyRing; -import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.api.OpenPGPCertificate; +import org.bouncycastle.openpgp.api.OpenPGPKey; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -78,40 +78,39 @@ public class CachingSecretKeyRingProtectorTest { @Test public void testAddPassphraseForKeyRing() throws PGPException { - PGPSecretKeyRing keys = PGPainless.generateKeyRing() - .modernKeyRing("test@test.test", "Passphrase123") - .getPGPSecretKeyRing(); + OpenPGPKey keys = PGPainless.getInstance().generateKey() + .modernKeyRing("test@test.test", "Passphrase123"); Passphrase passphrase = Passphrase.fromPassword("Passphrase123"); protector.addPassphrase(keys, passphrase); - Iterator it = keys.getSecretKeys(); + Iterator it = keys.getSecretKeys().values().iterator(); while (it.hasNext()) { - PGPSecretKey key = it.next(); + OpenPGPKey.OpenPGPSecretKey key = it.next(); assertEquals(passphrase, protector.getPassphraseFor(key)); - assertNotNull(protector.getEncryptor(key.getPublicKey())); - assertNotNull(protector.getDecryptor(key.getKeyIdentifier())); + assertNotNull(protector.getEncryptor(key)); + assertNotNull(protector.getDecryptor(key)); } long nonMatching = findNonMatchingKeyId(keys); assertNull(protector.getPassphraseFor(new KeyIdentifier(nonMatching))); protector.forgetPassphrase(keys); - it = keys.getSecretKeys(); + it = keys.getSecretKeys().values().iterator(); while (it.hasNext()) { - PGPSecretKey key = it.next(); + OpenPGPKey.OpenPGPSecretKey key = it.next(); assertNull(protector.getPassphraseFor(key)); assertNull(protector.getEncryptor(key.getPublicKey())); assertNull(protector.getDecryptor(key.getKeyIdentifier())); } } - private static long findNonMatchingKeyId(PGPKeyRing keyRing) { + private static long findNonMatchingKeyId(OpenPGPCertificate cert) { Random random = new Random(); long nonMatchingKeyId = 123L; outerloop: while (true) { - Iterator pubKeys = keyRing.getPublicKeys(); + Iterator pubKeys = cert.getKeys().iterator(); while (pubKeys.hasNext()) { - if (pubKeys.next().getKeyID() == nonMatchingKeyId) { + if (pubKeys.next().getKeyIdentifier().getKeyId() == nonMatchingKeyId) { nonMatchingKeyId = random.nextLong(); continue outerloop; } 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 373396df..f09f1445 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 @@ -12,8 +12,8 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPPublicKeyRing; -import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.api.OpenPGPCertificate; +import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.util.io.Streams; import org.junit.jupiter.api.Test; import org.pgpainless.PGPainless; @@ -22,7 +22,6 @@ 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; public class TestTwoSubkeysEncryption { @@ -35,8 +34,8 @@ 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 verifies that {@link EncryptionOptions#addRecipient(PGPPublicKeyRing, EncryptionOptions.EncryptionKeySelector)} + *

+ * This test verifies that {@link EncryptionOptions#addRecipient(OpenPGPCertificate, EncryptionOptions.EncryptionKeySelector)} * works properly, if {@link EncryptionOptions#encryptToAllCapableSubkeys()} is provided as argument. * * @throws IOException not expected @@ -44,10 +43,10 @@ public class TestTwoSubkeysEncryption { */ @Test public void testEncryptsToBothSubkeys() throws IOException, PGPException { - PGPSecretKeyRing twoSuitableSubkeysKeyRing = WeirdKeys.getTwoCryptSubkeysKey(); - PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(twoSuitableSubkeysKeyRing); + OpenPGPKey twoSuitableSubkeysKeyRing = WeirdKeys.getTwoCryptSubkeysKey(); + OpenPGPCertificate publicKeys = twoSuitableSubkeysKeyRing.toCertificate(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - EncryptionStream encryptionStream = PGPainless.encryptAndOrSign() + EncryptionStream encryptionStream = PGPainless.getInstance().generateMessage() .onOutputStream(out) .withOptions( ProducerOptions.encrypt(EncryptionOptions.get()