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

Add deleteUserIds(keyId, userIdSelectionStrategy, protector) method to SecretKeyRingEditor

This commit is contained in:
Paul Schaub 2021-02-03 16:26:15 +01:00
parent eaee5a27fc
commit 449881bd8d
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
3 changed files with 50 additions and 5 deletions

View file

@ -16,6 +16,7 @@
package org.pgpainless.key.modification.secretkeyring;
import static org.pgpainless.key.util.KeyRingUtils.unlockSecretKey;
import static org.pgpainless.util.CollectionUtils.iteratorToList;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
@ -65,6 +66,7 @@ import org.pgpainless.key.util.RevocationAttributes;
import org.pgpainless.key.util.SignatureUtils;
import org.pgpainless.util.Passphrase;
import org.pgpainless.util.SignatureSubpacketGeneratorUtil;
import org.pgpainless.util.selection.userid.UserIdSelectionStrategy;
public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
@ -146,7 +148,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
}
@Override
public SecretKeyRingEditorInterface deleteUserId(long keyId, String userId, SecretKeyRingProtector secretKeyRingProtector) {
public SecretKeyRingEditorInterface deleteUserIds(long keyId, UserIdSelectionStrategy selectionStrategy, SecretKeyRingProtector secretKeyRingProtector) {
List<PGPPublicKey> publicKeys = new ArrayList<>();
Iterator<PGPPublicKey> publicKeyIterator = secretKeyRing.getPublicKeys();
boolean foundKey = false;
@ -154,11 +156,14 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
PGPPublicKey publicKey = publicKeyIterator.next();
if (publicKey.getKeyID() == keyId) {
foundKey = true;
if (!hasUserId(userId, publicKey)) {
throw new NoSuchElementException("Key " + Long.toHexString(keyId) + " does not have a user-id attribute of value '" + userId + "'");
List<String> matchingUserIds = selectionStrategy.selectUserIds(iteratorToList(publicKey.getUserIDs()));
if (matchingUserIds.isEmpty()) {
throw new NoSuchElementException("Key " + Long.toHexString(keyId) + " does not have a matching user-id attribute.");
}
for (String userId : matchingUserIds) {
publicKey = PGPPublicKey.removeCertification(publicKey, userId);
}
}
publicKeys.add(publicKey);
}
if (!foundKey) {

View file

@ -32,6 +32,7 @@ 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.UserIdSelectionStrategy;
public interface SecretKeyRingEditorInterface {
@ -75,7 +76,11 @@ public interface SecretKeyRingEditorInterface {
return deleteUserId(fingerprint.getKeyId(), userId, secretKeyRingProtector);
}
SecretKeyRingEditorInterface deleteUserId(long keyId, String userId, SecretKeyRingProtector secretKeyRingProtector);
default SecretKeyRingEditorInterface deleteUserId(long keyId, String userId, SecretKeyRingProtector secretKeyRingProtector) {
return deleteUserIds(keyId, UserIdSelectionStrategy.exactMatch(userId), secretKeyRingProtector);
}
SecretKeyRingEditorInterface deleteUserIds(long keyId, UserIdSelectionStrategy selectionStrategy, SecretKeyRingProtector secretKeyRingProtector);
/**
* Add a subkey to the key ring.

View file

@ -83,4 +83,39 @@ public abstract class UserIdSelectionStrategy {
public static UserIdSelectionStrategy containsEmailAddress(String email) {
return containsSubstring(email.matches("^<.+>$") ? email : '<' + email + '>');
}
public static UserIdSelectionStrategy validUserId(PGPKeyRing keyRing) {
return new UserIdSelectionStrategy() {
@Override
protected boolean accept(String userId) {
return PGPainless.inspectKeyRing(keyRing).isUserIdValid(userId);
}
};
}
public static UserIdSelectionStrategy and(UserIdSelectionStrategy... strategies) {
return new UserIdSelectionStrategy() {
@Override
protected boolean accept(String userId) {
boolean accept = true;
for (UserIdSelectionStrategy strategy : strategies) {
accept &= strategy.accept(userId);
}
return accept;
}
};
}
public static UserIdSelectionStrategy or(UserIdSelectionStrategy... strategies) {
return new UserIdSelectionStrategy() {
@Override
protected boolean accept(String userId) {
boolean accept = false;
for (UserIdSelectionStrategy strategy : strategies) {
accept |= strategy.accept(userId);
}
return accept;
}
};
}
}