1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-23 12:52:07 +01:00

Remove support for deleting user-ids and subkeys. Use revoke* instead.

This commit is contained in:
Paul Schaub 2021-11-12 16:14:08 +01:00
parent 2ac10e7bc7
commit e4d1aa7edf
3 changed files with 15 additions and 116 deletions

View file

@ -4,8 +4,6 @@
package org.pgpainless.key.modification.secretkeyring; package org.pgpainless.key.modification.secretkeyring;
import static org.pgpainless.util.CollectionUtils.iteratorToList;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
@ -56,7 +54,6 @@ import org.pgpainless.key.util.RevocationAttributes;
import org.pgpainless.signature.SignatureUtils; import org.pgpainless.signature.SignatureUtils;
import org.pgpainless.signature.subpackets.SignatureSubpacketGeneratorUtil; import org.pgpainless.signature.subpackets.SignatureSubpacketGeneratorUtil;
import org.pgpainless.util.Passphrase; import org.pgpainless.util.Passphrase;
import org.pgpainless.util.selection.userid.SelectUserId;
public class SecretKeyRingEditor implements SecretKeyRingEditorInterface { public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
@ -122,34 +119,6 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
return userId; 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<PGPPublicKey> publicKeys = new ArrayList<>();
Iterator<PGPPublicKey> publicKeyIterator = secretKeyRing.getPublicKeys();
PGPPublicKey primaryKey = publicKeyIterator.next();
List<String> 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 @Override
public SecretKeyRingEditorInterface addSubKey(@Nonnull KeySpec keySpec, public SecretKeyRingEditorInterface addSubKey(@Nonnull KeySpec keySpec,
@Nonnull Passphrase subKeyPassphrase, @Nonnull Passphrase subKeyPassphrase,
@ -213,29 +182,6 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
return secretKey; 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 @Override
public SecretKeyRingEditorInterface revoke(SecretKeyRingProtector secretKeyRingProtector, public SecretKeyRingEditorInterface revoke(SecretKeyRingProtector secretKeyRingProtector,
RevocationAttributes revocationAttributes) RevocationAttributes revocationAttributes)

View file

@ -22,7 +22,6 @@ import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.util.RevocationAttributes; import org.pgpainless.key.util.RevocationAttributes;
import org.pgpainless.key.util.UserId; import org.pgpainless.key.util.UserId;
import org.pgpainless.util.Passphrase; import org.pgpainless.util.Passphrase;
import org.pgpainless.util.selection.userid.SelectUserId;
public interface SecretKeyRingEditorInterface { public interface SecretKeyRingEditorInterface {
@ -46,35 +45,6 @@ public interface SecretKeyRingEditorInterface {
*/ */
SecretKeyRingEditorInterface addUserId(String userId, SecretKeyRingProtector secretKeyRingProtector) throws PGPException; 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. * Add a subkey to the key ring.
* The subkey will be generated from the provided {@link KeySpec}. * The subkey will be generated from the provided {@link KeySpec}.
@ -94,29 +64,6 @@ public interface SecretKeyRingEditorInterface {
PGPSignatureSubpacketVector unhashedSubpackets, PGPSignatureSubpacketVector unhashedSubpackets,
SecretKeyRingProtector subKeyProtector, SecretKeyRingProtector keyRingProtector) SecretKeyRingProtector subKeyProtector, SecretKeyRingProtector keyRingProtector)
throws PGPException; 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. * Revoke the key ring.
* The revocation will be a hard revocation, rendering the whole key invalid for any past or future signatures. * The revocation will be a hard revocation, rendering the whole key invalid for any past or future signatures.

View file

@ -21,6 +21,7 @@ import org.junit.jupiter.params.provider.MethodSource;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.TestKeys; import org.pgpainless.key.TestKeys;
import org.pgpainless.key.info.KeyRingInfo;
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector; import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnprotectedKeysProtector; import org.pgpainless.key.protection.UnprotectedKeysProtector;
@ -30,11 +31,12 @@ public class AddUserIdTest {
@ParameterizedTest @ParameterizedTest
@MethodSource("org.pgpainless.util.TestImplementationFactoryProvider#provideImplementationFactories") @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); ImplementationFactory.setFactoryImplementation(implementationFactory);
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().simpleEcKeyRing("alice@wonderland.lit", "rabb1th0le"); PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().simpleEcKeyRing("alice@wonderland.lit", "rabb1th0le");
Iterator<String> userIds = secretKeys.getSecretKey().getPublicKey().getUserIDs(); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
Iterator<String> userIds = info.getValidUserIds().iterator();
assertEquals("alice@wonderland.lit", userIds.next()); assertEquals("alice@wonderland.lit", userIds.next());
assertFalse(userIds.hasNext()); assertFalse(userIds.hasNext());
@ -43,16 +45,18 @@ public class AddUserIdTest {
.addUserId("cheshirecat@wonderland.lit", protector) .addUserId("cheshirecat@wonderland.lit", protector)
.done(); .done();
userIds = secretKeys.getPublicKey().getUserIDs(); info = PGPainless.inspectKeyRing(secretKeys);
userIds = info.getValidUserIds().iterator();
assertEquals("alice@wonderland.lit", userIds.next()); assertEquals("alice@wonderland.lit", userIds.next());
assertEquals("cheshirecat@wonderland.lit", userIds.next()); assertEquals("cheshirecat@wonderland.lit", userIds.next());
assertFalse(userIds.hasNext()); assertFalse(userIds.hasNext());
secretKeys = PGPainless.modifyKeyRing(secretKeys) secretKeys = PGPainless.modifyKeyRing(secretKeys)
.deleteUserId("cheshirecat@wonderland.lit", protector) .revokeUserId("cheshirecat@wonderland.lit", protector)
.done(); .done();
userIds = secretKeys.getPublicKey().getUserIDs(); info = PGPainless.inspectKeyRing(secretKeys);
userIds = info.getValidUserIds().iterator();
assertEquals("alice@wonderland.lit", userIds.next()); assertEquals("alice@wonderland.lit", userIds.next());
assertFalse(userIds.hasNext()); assertFalse(userIds.hasNext());
} }
@ -64,7 +68,7 @@ public class AddUserIdTest {
PGPSecretKeyRing secretKeys = TestKeys.getCryptieSecretKeyRing(); PGPSecretKeyRing secretKeys = TestKeys.getCryptieSecretKeyRing();
assertThrows(NoSuchElementException.class, () -> PGPainless.modifyKeyRing(secretKeys) assertThrows(NoSuchElementException.class, () -> PGPainless.modifyKeyRing(secretKeys)
.deleteUserId("invalid@user.id", new UnprotectedKeysProtector())); .revokeUserId("invalid@user.id", new UnprotectedKeysProtector()));
} }
@ParameterizedTest @ParameterizedTest
@ -89,17 +93,19 @@ public class AddUserIdTest {
"-----END PGP PRIVATE KEY BLOCK-----\r\n"; "-----END PGP PRIVATE KEY BLOCK-----\r\n";
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(ARMORED_PRIVATE_KEY); PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(ARMORED_PRIVATE_KEY);
Iterator<String> userIds = secretKeys.getSecretKey().getPublicKey().getUserIDs(); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
Iterator<String> userIds = info.getValidUserIds().iterator();
assertEquals("<user@example.com>", userIds.next()); assertEquals("<user@example.com>", userIds.next());
assertFalse(userIds.hasNext()); assertFalse(userIds.hasNext());
SecretKeyRingProtector protector = new UnprotectedKeysProtector(); SecretKeyRingProtector protector = new UnprotectedKeysProtector();
secretKeys = PGPainless.modifyKeyRing(secretKeys) secretKeys = PGPainless.modifyKeyRing(secretKeys)
.deleteUserId("<user@example.com>", protector) .revokeUserId("<user@example.com>", protector)
.addUserId("cheshirecat@wonderland.lit", protector) .addUserId("cheshirecat@wonderland.lit", protector)
.done(); .done();
userIds = secretKeys.getSecretKey().getPublicKey().getUserIDs(); info = PGPainless.inspectKeyRing(secretKeys);
userIds = info.getValidUserIds().iterator();
assertEquals("cheshirecat@wonderland.lit", userIds.next()); assertEquals("cheshirecat@wonderland.lit", userIds.next());
assertFalse(userIds.hasNext()); assertFalse(userIds.hasNext());
} }