From e4d1aa7edfe3949edf50f42ca36f646ca0a4109c Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Fri, 12 Nov 2021 16:14:08 +0100 Subject: [PATCH] Remove support for deleting user-ids and subkeys. Use revoke* instead. --- .../secretkeyring/SecretKeyRingEditor.java | 54 ------------------- .../SecretKeyRingEditorInterface.java | 53 ------------------ .../key/modification/AddUserIdTest.java | 24 +++++---- 3 files changed, 15 insertions(+), 116 deletions(-) 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 a83b4abd..9c991c08 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 @@ -4,8 +4,6 @@ package org.pgpainless.key.modification.secretkeyring; -import static org.pgpainless.util.CollectionUtils.iteratorToList; - import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; @@ -56,7 +54,6 @@ import org.pgpainless.key.util.RevocationAttributes; import org.pgpainless.signature.SignatureUtils; import org.pgpainless.signature.subpackets.SignatureSubpacketGeneratorUtil; import org.pgpainless.util.Passphrase; -import org.pgpainless.util.selection.userid.SelectUserId; public class SecretKeyRingEditor implements SecretKeyRingEditorInterface { @@ -122,34 +119,6 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface { return userId; } - @Override - public SecretKeyRingEditorInterface deleteUserId(String userId, SecretKeyRingProtector protector) { - return deleteUserIds(SelectUserId.exactMatch(userId), protector); - } - - @Override - public SecretKeyRingEditorInterface deleteUserIds(SelectUserId selectionStrategy, SecretKeyRingProtector secretKeyRingProtector) { - List publicKeys = new ArrayList<>(); - Iterator publicKeyIterator = secretKeyRing.getPublicKeys(); - PGPPublicKey primaryKey = publicKeyIterator.next(); - List matchingUserIds = selectionStrategy.selectUserIds(iteratorToList(primaryKey.getUserIDs())); - if (matchingUserIds.isEmpty()) { - throw new NoSuchElementException("Key does not have a matching user-id attribute."); - } - for (String userId : matchingUserIds) { - primaryKey = PGPPublicKey.removeCertification(primaryKey, userId); - } - publicKeys.add(primaryKey); - - while (publicKeyIterator.hasNext()) { - publicKeys.add(publicKeyIterator.next()); - } - - PGPPublicKeyRing publicKeyRing = new PGPPublicKeyRing(publicKeys); - secretKeyRing = PGPSecretKeyRing.replacePublicKeys(secretKeyRing, publicKeyRing); - return this; - } - @Override public SecretKeyRingEditorInterface addSubKey(@Nonnull KeySpec keySpec, @Nonnull Passphrase subKeyPassphrase, @@ -213,29 +182,6 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface { return secretKey; } - @Override - public SecretKeyRingEditorInterface deleteSubKey(OpenPgpFingerprint fingerprint, - SecretKeyRingProtector protector) { - return deleteSubKey(fingerprint.getKeyId(), protector); - } - - @Override - public SecretKeyRingEditorInterface deleteSubKey(long subKeyId, - SecretKeyRingProtector protector) { - if (secretKeyRing.getSecretKey().getKeyID() == subKeyId) { - throw new IllegalArgumentException("You cannot delete the primary key of this key ring."); - } - - PGPSecretKey deleteMe = secretKeyRing.getSecretKey(subKeyId); - if (deleteMe == null) { - throw new NoSuchElementException("KeyRing does not contain a key with keyId " + Long.toHexString(subKeyId)); - } - - PGPSecretKeyRing newKeyRing = PGPSecretKeyRing.removeSecretKey(secretKeyRing, deleteMe); - secretKeyRing = newKeyRing; - return this; - } - @Override public SecretKeyRingEditorInterface revoke(SecretKeyRingProtector secretKeyRingProtector, RevocationAttributes revocationAttributes) diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditorInterface.java b/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditorInterface.java index fc78f95c..b45f7523 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditorInterface.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/modification/secretkeyring/SecretKeyRingEditorInterface.java @@ -22,7 +22,6 @@ import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.util.RevocationAttributes; import org.pgpainless.key.util.UserId; import org.pgpainless.util.Passphrase; -import org.pgpainless.util.selection.userid.SelectUserId; public interface SecretKeyRingEditorInterface { @@ -46,35 +45,6 @@ public interface SecretKeyRingEditorInterface { */ SecretKeyRingEditorInterface addUserId(String userId, SecretKeyRingProtector secretKeyRingProtector) throws PGPException; - /** - * Remove a user-id from the key ring. - * - * @param userId exact user-id to be removed - * @param secretKeyRingProtector protector to unlock the secret key - * @return the builder - */ - SecretKeyRingEditorInterface deleteUserId(String userId, SecretKeyRingProtector secretKeyRingProtector); - - /** - * Remove a user-id from the key ring. - * - * @param userId exact user-id to be removed - * @param secretKeyRingProtector protector to unlock the secret key - * @return the builder - */ - default SecretKeyRingEditorInterface deleteUserId(UserId userId, SecretKeyRingProtector secretKeyRingProtector) { - return deleteUserId(userId.toString(), secretKeyRingProtector); - } - - /** - * Delete all user-ids from the key, which match the provided {@link SelectUserId} strategy. - * - * @param selectionStrategy strategy to select user-ids - * @param secretKeyRingProtector protector to unlock the secret key - * @return the builder - */ - SecretKeyRingEditorInterface deleteUserIds(SelectUserId selectionStrategy, SecretKeyRingProtector secretKeyRingProtector); - /** * Add a subkey to the key ring. * The subkey will be generated from the provided {@link KeySpec}. @@ -94,29 +64,6 @@ public interface SecretKeyRingEditorInterface { PGPSignatureSubpacketVector unhashedSubpackets, SecretKeyRingProtector subKeyProtector, SecretKeyRingProtector keyRingProtector) throws PGPException; - - /** - * Delete a subkey from the key ring. - * The subkey with the provided fingerprint will be remove from the key ring. - * If no suitable subkey is found, a {@link java.util.NoSuchElementException} will be thrown. - * - * @param fingerprint fingerprint of the subkey to be removed - * @param secretKeyRingProtector protector to unlock the secret key ring - * @return the builder - */ - SecretKeyRingEditorInterface deleteSubKey(OpenPgpFingerprint fingerprint, SecretKeyRingProtector secretKeyRingProtector); - - /** - * Delete a subkey from the key ring. - * The subkey with the provided key-id will be removed from the key ring. - * If no suitable subkey is found, a {@link java.util.NoSuchElementException} will be thrown. - * - * @param subKeyId id of the subkey - * @param secretKeyRingProtector protector to unlock the secret key ring - * @return the builder - */ - SecretKeyRingEditorInterface deleteSubKey(long subKeyId, SecretKeyRingProtector secretKeyRingProtector); - /** * Revoke the key ring. * The revocation will be a hard revocation, rendering the whole key invalid for any past or future signatures. diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/modification/AddUserIdTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/modification/AddUserIdTest.java index afb761ef..f8998c2b 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/modification/AddUserIdTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/modification/AddUserIdTest.java @@ -21,6 +21,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.pgpainless.PGPainless; import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.key.TestKeys; +import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.UnprotectedKeysProtector; @@ -30,11 +31,12 @@ public class AddUserIdTest { @ParameterizedTest @MethodSource("org.pgpainless.util.TestImplementationFactoryProvider#provideImplementationFactories") - public void addUserIdToExistingKeyRing(ImplementationFactory implementationFactory) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException { + public void addUserIdToExistingKeyRing(ImplementationFactory implementationFactory) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, InterruptedException { ImplementationFactory.setFactoryImplementation(implementationFactory); PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().simpleEcKeyRing("alice@wonderland.lit", "rabb1th0le"); - Iterator userIds = secretKeys.getSecretKey().getPublicKey().getUserIDs(); + KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys); + Iterator userIds = info.getValidUserIds().iterator(); assertEquals("alice@wonderland.lit", userIds.next()); assertFalse(userIds.hasNext()); @@ -43,16 +45,18 @@ public class AddUserIdTest { .addUserId("cheshirecat@wonderland.lit", protector) .done(); - userIds = secretKeys.getPublicKey().getUserIDs(); + info = PGPainless.inspectKeyRing(secretKeys); + userIds = info.getValidUserIds().iterator(); assertEquals("alice@wonderland.lit", userIds.next()); assertEquals("cheshirecat@wonderland.lit", userIds.next()); assertFalse(userIds.hasNext()); secretKeys = PGPainless.modifyKeyRing(secretKeys) - .deleteUserId("cheshirecat@wonderland.lit", protector) + .revokeUserId("cheshirecat@wonderland.lit", protector) .done(); - userIds = secretKeys.getPublicKey().getUserIDs(); + info = PGPainless.inspectKeyRing(secretKeys); + userIds = info.getValidUserIds().iterator(); assertEquals("alice@wonderland.lit", userIds.next()); assertFalse(userIds.hasNext()); } @@ -64,7 +68,7 @@ public class AddUserIdTest { PGPSecretKeyRing secretKeys = TestKeys.getCryptieSecretKeyRing(); assertThrows(NoSuchElementException.class, () -> PGPainless.modifyKeyRing(secretKeys) - .deleteUserId("invalid@user.id", new UnprotectedKeysProtector())); + .revokeUserId("invalid@user.id", new UnprotectedKeysProtector())); } @ParameterizedTest @@ -89,17 +93,19 @@ public class AddUserIdTest { "-----END PGP PRIVATE KEY BLOCK-----\r\n"; PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(ARMORED_PRIVATE_KEY); - Iterator userIds = secretKeys.getSecretKey().getPublicKey().getUserIDs(); + KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys); + Iterator userIds = info.getValidUserIds().iterator(); assertEquals("", userIds.next()); assertFalse(userIds.hasNext()); SecretKeyRingProtector protector = new UnprotectedKeysProtector(); secretKeys = PGPainless.modifyKeyRing(secretKeys) - .deleteUserId("", protector) + .revokeUserId("", protector) .addUserId("cheshirecat@wonderland.lit", protector) .done(); - userIds = secretKeys.getSecretKey().getPublicKey().getUserIDs(); + info = PGPainless.inspectKeyRing(secretKeys); + userIds = info.getValidUserIds().iterator(); assertEquals("cheshirecat@wonderland.lit", userIds.next()); assertFalse(userIds.hasNext()); }