Remove KeyRingUtils.deleteUserId() in favor of revoking SecretKeyRingEditor.removeUserId() methods

This commit is contained in:
Paul Schaub 2021-12-27 13:35:58 +01:00
parent 3a69f90401
commit 245376d7d0
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
4 changed files with 30 additions and 92 deletions

View File

@ -190,6 +190,28 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
return this;
}
@Override
public SecretKeyRingEditorInterface removeUserId(
SelectUserId userIdSelector,
SecretKeyRingProtector protector)
throws PGPException {
RevocationAttributes revocationAttributes = RevocationAttributes.createCertificateRevocation()
.withReason(RevocationAttributes.Reason.USER_ID_NO_LONGER_VALID)
.withoutDescription();
return revokeUserIds(userIdSelector,
protector,
revocationAttributes);
}
@Override
public SecretKeyRingEditorInterface removeUserId(
CharSequence userId,
SecretKeyRingProtector protector) throws PGPException {
return removeUserId(
SelectUserId.exactMatch(userId.toString()),
protector);
}
// TODO: Move to utility class?
private String sanitizeUserId(@Nonnull CharSequence userId) {
// TODO: Further research how to sanitize user IDs.

View File

@ -69,6 +69,14 @@ public interface SecretKeyRingEditorInterface {
@Nonnull SecretKeyRingProtector protector)
throws PGPException;
SecretKeyRingEditorInterface removeUserId(SelectUserId userIdSelector,
SecretKeyRingProtector protector)
throws PGPException;
SecretKeyRingEditorInterface removeUserId(CharSequence userId,
SecretKeyRingProtector protector)
throws PGPException;
/**
* Add a subkey to the key ring.
* The subkey will be generated from the provided {@link KeySpec}.

View File

@ -159,52 +159,6 @@ public final class KeyRingUtils {
return ring.getPublicKey(keyId) != null;
}
/**
* Delete the given user-id and its certification signatures from the given key.
*
* @deprecated Deleting user-ids is highly discouraged, since it might lead to all sorts of problems
* (e.g. lost key properties).
* Instead, user-ids should only be revoked.
*
* @param secretKeys secret keys
* @param userId user-id
* @return modified secret keys
*/
@Deprecated
public static PGPSecretKeyRing deleteUserId(PGPSecretKeyRing secretKeys, String userId) {
PGPSecretKey secretKey = secretKeys.getSecretKey(); // user-ids are located on primary key only
PGPPublicKey publicKey = secretKey.getPublicKey(); // user-ids are placed on the public key part
publicKey = PGPPublicKey.removeCertification(publicKey, userId);
if (publicKey == null) {
throw new NoSuchElementException("User-ID " + userId + " not found on the key.");
}
secretKey = PGPSecretKey.replacePublicKey(secretKey, publicKey);
secretKeys = PGPSecretKeyRing.insertSecretKey(secretKeys, secretKey);
return secretKeys;
}
/**
* Delete the given user-id and its certification signatures from the given certificate.
*
* @deprecated Deleting user-ids is highly discouraged, since it might lead to all sorts of problems
* (e.g. lost key properties).
* Instead, user-ids should only be revoked.
*
* @param publicKeys certificate
* @param userId user-id
* @return modified secret keys
*/
@Deprecated
public static PGPPublicKeyRing deleteUserId(PGPPublicKeyRing publicKeys, String userId) {
PGPPublicKey publicKey = publicKeys.getPublicKey(); // user-ids are located on primary key only
publicKey = PGPPublicKey.removeCertification(publicKey, userId);
if (publicKey == null) {
throw new NoSuchElementException("User-ID " + userId + " not found on the key.");
}
publicKeys = PGPPublicKeyRing.insertPublicKey(publicKeys, publicKey);
return publicKeys;
}
public static <T extends PGPKeyRing> T injectCertification(T keyRing, PGPPublicKey certifiedKey, PGPSignature certification) {
PGPSecretKeyRing secretKeys = null;
PGPPublicKeyRing publicKeys;

View File

@ -6,17 +6,14 @@ package org.pgpainless.key.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.util.NoSuchElementException;
import java.util.Random;
import org.bouncycastle.bcpg.attr.ImageAttribute;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
@ -33,49 +30,6 @@ import org.pgpainless.util.CollectionUtils;
public class KeyRingUtilTest {
@Test
public void testDeleteUserIdFromSecretKeyRing()
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("Alice", null);
secretKeys = PGPainless.modifyKeyRing(secretKeys)
.addUserId("Bob", SecretKeyRingProtector.unprotectedKeys())
.done();
assertEquals(2, CollectionUtils.iteratorToList(secretKeys.getPublicKey().getUserIDs()).size());
secretKeys = KeyRingUtils.deleteUserId(secretKeys, "Bob");
assertEquals(1, CollectionUtils.iteratorToList(secretKeys.getPublicKey().getUserIDs()).size());
}
@Test
public void testDeleteUserIdFromPublicKeyRing()
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("Alice", null);
secretKeys = PGPainless.modifyKeyRing(secretKeys)
.addUserId("Bob", SecretKeyRingProtector.unprotectedKeys())
.done();
PGPPublicKeyRing publicKeys = PGPainless.extractCertificate(secretKeys);
assertEquals(2, CollectionUtils.iteratorToList(publicKeys.getPublicKey().getUserIDs()).size());
publicKeys = KeyRingUtils.deleteUserId(publicKeys, "Alice");
assertEquals(1, CollectionUtils.iteratorToList(publicKeys.getPublicKey().getUserIDs()).size());
}
@Test
public void testDeleteNonexistentUserIdFromKeyRingThrows()
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("Alice", null);
assertThrows(NoSuchElementException.class,
() -> KeyRingUtils.deleteUserId(secretKeys, "Charlie"));
}
@Test
public void testInjectCertification() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()