1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-27 06:42:05 +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; package org.pgpainless.key.modification.secretkeyring;
import static org.pgpainless.key.util.KeyRingUtils.unlockSecretKey; import static org.pgpainless.key.util.KeyRingUtils.unlockSecretKey;
import static org.pgpainless.util.CollectionUtils.iteratorToList;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -65,6 +66,7 @@ import org.pgpainless.key.util.RevocationAttributes;
import org.pgpainless.key.util.SignatureUtils; import org.pgpainless.key.util.SignatureUtils;
import org.pgpainless.util.Passphrase; import org.pgpainless.util.Passphrase;
import org.pgpainless.util.SignatureSubpacketGeneratorUtil; import org.pgpainless.util.SignatureSubpacketGeneratorUtil;
import org.pgpainless.util.selection.userid.UserIdSelectionStrategy;
public class SecretKeyRingEditor implements SecretKeyRingEditorInterface { public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
@ -146,7 +148,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
} }
@Override @Override
public SecretKeyRingEditorInterface deleteUserId(long keyId, String userId, SecretKeyRingProtector secretKeyRingProtector) { public SecretKeyRingEditorInterface deleteUserIds(long keyId, UserIdSelectionStrategy selectionStrategy, SecretKeyRingProtector secretKeyRingProtector) {
List<PGPPublicKey> publicKeys = new ArrayList<>(); List<PGPPublicKey> publicKeys = new ArrayList<>();
Iterator<PGPPublicKey> publicKeyIterator = secretKeyRing.getPublicKeys(); Iterator<PGPPublicKey> publicKeyIterator = secretKeyRing.getPublicKeys();
boolean foundKey = false; boolean foundKey = false;
@ -154,10 +156,13 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
PGPPublicKey publicKey = publicKeyIterator.next(); PGPPublicKey publicKey = publicKeyIterator.next();
if (publicKey.getKeyID() == keyId) { if (publicKey.getKeyID() == keyId) {
foundKey = true; foundKey = true;
if (!hasUserId(userId, publicKey)) { List<String> matchingUserIds = selectionStrategy.selectUserIds(iteratorToList(publicKey.getUserIDs()));
throw new NoSuchElementException("Key " + Long.toHexString(keyId) + " does not have a user-id attribute of value '" + userId + "'"); 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);
} }
publicKey = PGPPublicKey.removeCertification(publicKey, userId);
} }
publicKeys.add(publicKey); publicKeys.add(publicKey);
} }

View file

@ -32,6 +32,7 @@ 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.UserIdSelectionStrategy;
public interface SecretKeyRingEditorInterface { public interface SecretKeyRingEditorInterface {
@ -75,7 +76,11 @@ public interface SecretKeyRingEditorInterface {
return deleteUserId(fingerprint.getKeyId(), userId, secretKeyRingProtector); 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. * Add a subkey to the key ring.

View file

@ -83,4 +83,39 @@ public abstract class UserIdSelectionStrategy {
public static UserIdSelectionStrategy containsEmailAddress(String email) { public static UserIdSelectionStrategy containsEmailAddress(String email) {
return containsSubstring(email.matches("^<.+>$") ? email : '<' + 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;
}
};
}
} }