mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-22 19:08:00 +01:00
Add util methods
This commit is contained in:
parent
396590f4c2
commit
29fbf21d01
2 changed files with 166 additions and 3 deletions
|
@ -20,18 +20,33 @@ import java.lang.reflect.Constructor;
|
|||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import de.vanitasvitae.crypto.pgpainless.algorithm.KeyFlag;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||
import org.bouncycastle.openpgp.PGPSignature;
|
||||
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
|
||||
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
|
||||
|
||||
public class BCUtil {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(BCUtil.class.getName());
|
||||
|
||||
/*
|
||||
PGPXxxKeyRing -> PGPXxxKeyRingCollection
|
||||
*/
|
||||
public static PGPPublicKeyRingCollection keyRingsToKeyRingCollection(PGPPublicKeyRing... rings)
|
||||
throws IOException, PGPException {
|
||||
return new PGPPublicKeyRingCollection(Arrays.asList(rings));
|
||||
|
@ -42,6 +57,10 @@ public class BCUtil {
|
|||
return new PGPSecretKeyRingCollection(Arrays.asList(rings));
|
||||
}
|
||||
|
||||
/*
|
||||
PGPSecretKeyRing -> PGPPublicKeyRing
|
||||
*/
|
||||
|
||||
public static PGPPublicKeyRing publicKeyRingFromSecretKeyRing(PGPSecretKeyRing secring) {
|
||||
List<PGPPublicKey> list = new ArrayList<>();
|
||||
for (Iterator<PGPPublicKey> i = secring.getPublicKeys(); i.hasNext(); ) {
|
||||
|
@ -60,4 +79,111 @@ public class BCUtil {
|
|||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
PGPXxxKeyRingCollection -> PGPXxxKeyRing
|
||||
*/
|
||||
|
||||
public static PGPSecretKeyRing getKeyRingFromCollection(PGPSecretKeyRingCollection collection, Long id)
|
||||
throws PGPException {
|
||||
PGPSecretKeyRing uncleanedRing = collection.getSecretKeyRing(id);
|
||||
PGPPublicKeyRing publicKeys = publicKeyRingFromSecretKeyRing(uncleanedRing);
|
||||
|
||||
// Determine ids of signed keys
|
||||
Set<Long> signedKeyIds = new HashSet<>();
|
||||
signedKeyIds.add(id); // Add the signing key itself
|
||||
Iterator<PGPPublicKey> signedPubKeys = publicKeys.getKeysWithSignaturesBy(id);
|
||||
while (signedPubKeys.hasNext()) {
|
||||
signedKeyIds.add(signedPubKeys.next().getKeyID());
|
||||
}
|
||||
|
||||
PGPSecretKeyRing cleanedRing = uncleanedRing;
|
||||
Iterator<PGPSecretKey> secretKeys = uncleanedRing.getSecretKeys();
|
||||
while (secretKeys.hasNext()) {
|
||||
PGPSecretKey secretKey = secretKeys.next();
|
||||
if (!signedKeyIds.contains(secretKey.getKeyID())) {
|
||||
cleanedRing = PGPSecretKeyRing.removeSecretKey(cleanedRing, secretKey);
|
||||
}
|
||||
}
|
||||
return cleanedRing;
|
||||
}
|
||||
|
||||
public static PGPPublicKeyRing getKeyRingFromCollection(PGPPublicKeyRingCollection collection, Long id)
|
||||
throws PGPException {
|
||||
return removeUnsignedKeysFromKeyRing(collection.getPublicKeyRing(id), id);
|
||||
}
|
||||
|
||||
public static PGPPublicKeyRing removeUnsignedKeysFromKeyRing(PGPPublicKeyRing ring, Long masterKeyId) {
|
||||
|
||||
Set<Long> signedKeyIds = new HashSet<>();
|
||||
signedKeyIds.add(masterKeyId);
|
||||
Iterator<PGPPublicKey> signedKeys = ring.getKeysWithSignaturesBy(masterKeyId);
|
||||
while (signedKeys.hasNext()) {
|
||||
signedKeyIds.add(signedKeys.next().getKeyID());
|
||||
}
|
||||
|
||||
PGPPublicKeyRing cleaned = ring;
|
||||
|
||||
Iterator<PGPPublicKey> publicKeys = ring.getPublicKeys();
|
||||
while (publicKeys.hasNext()) {
|
||||
PGPPublicKey publicKey = publicKeys.next();
|
||||
if (!signedKeyIds.contains(publicKey.getKeyID())) {
|
||||
cleaned = PGPPublicKeyRing.removePublicKey(cleaned, publicKey);
|
||||
}
|
||||
}
|
||||
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
public static PGPPublicKey getMasterKeyFrom(PGPPublicKeyRing ring) {
|
||||
Iterator<PGPPublicKey> it = ring.getPublicKeys();
|
||||
while (it.hasNext()) {
|
||||
PGPPublicKey k = it.next();
|
||||
if (k.isMasterKey()) {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Set<Long> signingKeyIds(PGPSecretKeyRing ring) {
|
||||
Set<Long> ids = new HashSet<>();
|
||||
Iterator<PGPPublicKey> it = ring.getPublicKeys();
|
||||
while (it.hasNext()) {
|
||||
PGPPublicKey k = it.next();
|
||||
|
||||
boolean signingKey = false;
|
||||
|
||||
Iterator sit = k.getSignatures();
|
||||
while (sit.hasNext()) {
|
||||
Object n = sit.next();
|
||||
if (!(n instanceof PGPSignature)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PGPSignature s = (PGPSignature) n;
|
||||
if (!s.hasSubpackets()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
s.verifyCertification(ring.getPublicKey(s.getKeyID()));
|
||||
} catch (PGPException e) {
|
||||
LOGGER.log(Level.WARNING, "Could not verify signature on " + Long.toHexString(k.getKeyID()) + " made by " + Long.toHexString(s.getKeyID()));
|
||||
continue;
|
||||
}
|
||||
|
||||
PGPSignatureSubpacketVector hashed = s.getHashedSubPackets();
|
||||
if (KeyFlag.fromInteger(hashed.getKeyFlags()).contains(KeyFlag.SIGN_DATA)) {
|
||||
signingKey = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (signingKey) {
|
||||
ids.add(k.getKeyID());
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
}
|
|
@ -22,36 +22,73 @@ import java.security.InvalidAlgorithmParameterException;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.util.Iterator;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import de.vanitasvitae.crypto.pgpainless.util.BCUtil;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BCUtilTest extends AbstractPGPainlessTest {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(BCUtil.class.getName());
|
||||
|
||||
@Test
|
||||
public void test()
|
||||
throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
|
||||
throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException,
|
||||
IOException {
|
||||
PGPSecretKeyRing sec = PGPainless.generateKeyRing().simpleEcKeyRing("donald@duck.tails");
|
||||
PGPPublicKeyRing pub = BCUtil.publicKeyRingFromSecretKeyRing(sec);
|
||||
|
||||
LOGGER.log(Level.INFO, "Main ID: " + sec.getPublicKey().getKeyID() + " " + pub.getPublicKey().getKeyID());
|
||||
|
||||
int secSize = 0;
|
||||
Iterator<PGPPublicKey> secPubIt = sec.getPublicKeys();
|
||||
while (secPubIt.hasNext()) {
|
||||
secPubIt.next();
|
||||
PGPPublicKey k = secPubIt.next();
|
||||
LOGGER.log(Level.INFO, "" + k.getKeyID() + " " + k.isEncryptionKey() + " " + k.isMasterKey());
|
||||
secSize++;
|
||||
}
|
||||
|
||||
LOGGER.log(Level.INFO, "After BCUtil.publickKeyRingFromSecretKeyRing()");
|
||||
int pubSize = 0;
|
||||
Iterator<PGPPublicKey> pubPubIt = pub.getPublicKeys();
|
||||
while (pubPubIt.hasNext()) {
|
||||
pubPubIt.next();
|
||||
PGPPublicKey k = pubPubIt.next();
|
||||
LOGGER.log(Level.INFO, "" + k.getKeyID() + " " + k.isEncryptionKey() + " " + k.isMasterKey());
|
||||
pubSize++;
|
||||
}
|
||||
|
||||
LOGGER.log(Level.INFO, " Pub: " + pubSize + " Sec: " + secSize);
|
||||
assertEquals(secSize, pubSize);
|
||||
|
||||
PGPSecretKeyRingCollection secCol = BCUtil.keyRingsToKeyRingCollection(sec);
|
||||
|
||||
int secColSize = 0;
|
||||
Iterator<PGPSecretKeyRing> secColIt = secCol.getKeyRings();
|
||||
while (secColIt.hasNext()) {
|
||||
PGPSecretKeyRing r = secColIt.next();
|
||||
LOGGER.log(Level.INFO, "" + r.getPublicKey().getKeyID());
|
||||
secColSize++;
|
||||
}
|
||||
|
||||
LOGGER.log(Level.INFO, "SecCol: " + secColSize);
|
||||
|
||||
PGPPublicKeyRingCollection pubCol = BCUtil.keyRingsToKeyRingCollection(pub);
|
||||
|
||||
int pubColSize = 0;
|
||||
Iterator<PGPPublicKeyRing> pubColIt = pubCol.getKeyRings();
|
||||
while (pubColIt.hasNext()) {
|
||||
PGPPublicKeyRing r = pubColIt.next();
|
||||
LOGGER.log(Level.INFO, "" + r.getPublicKey().getKeyID());
|
||||
pubColSize++;
|
||||
}
|
||||
|
||||
LOGGER.log(Level.INFO, "PubCol: " + pubColSize);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue