Skip to content

Commit

Permalink
Remove wildcard method overloads and add more KeyIdentifier methods
Browse files Browse the repository at this point in the history
  • Loading branch information
vanitasvitae committed Jul 23, 2024
1 parent ff32c54 commit 6b7df29
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 50 deletions.
95 changes: 51 additions & 44 deletions pg/src/main/java/org/bouncycastle/openpgp/KeyIdentifier.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package org.bouncycastle.openpgp;

import org.bouncycastle.bcpg.FingerprintUtil;
import org.bouncycastle.bcpg.SignatureSubpacket;
import org.bouncycastle.bcpg.SignatureSubpacketTags;
import org.bouncycastle.bcpg.sig.IssuerFingerprint;
import org.bouncycastle.bcpg.sig.IssuerKeyID;
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.encoders.Hex;
Expand Down Expand Up @@ -155,21 +159,7 @@ public long getKeyId()
*/
public boolean matches(PGPPublicKey key)
{
return matches(key, true);
}

/**
* Return true, if this {@link KeyIdentifier} matches the given {@link PGPPublicKey}.
* This will return true if the fingerprint matches, or if the key-id matches,
* or - in case that {@code matchWildcard} is true - if {@link #isWildcard()} returns true.
*
* @param key key
* @param matchWildcard whether to match wildcards
* @return whether the identifier matches the key
*/
public boolean matches(PGPPublicKey key, boolean matchWildcard)
{
if (matchWildcard && isWildcard())
if (isWildcard())
{
return true;
}
Expand Down Expand Up @@ -197,20 +187,6 @@ public boolean matches(PGPSecretKey key)
return matches(key.getPublicKey());
}

/**
* Return true, if this {@link KeyIdentifier} matches the given {@link PGPSecretKey}.
* This will return true if the fingerprint matches, or if the key-id matches,
* or - in case that {@code matchWildcard} is true - if {@link #isWildcard()} returns true.
*
* @param key key
* @param matchWildcard whether to match wildcards
* @return whether the identifier matches the key
*/
public boolean matches(PGPSecretKey key, boolean matchWildcard)
{
return matches(key.getPublicKey(), matchWildcard);
}

/**
* Return true if this {@link KeyIdentifier} matches the given {@link PGPPrivateKey}.
* This will return true if the fingerprint matches, or if the key-id matches,
Expand All @@ -228,22 +204,53 @@ public boolean matches(PGPPrivateKey key,
return matches(new PGPPublicKey(key.getPublicKeyPacket(), fingerprintCalculator));
}

/**
* Return true if this {@link KeyIdentifier} matches the given {@link PGPPrivateKey}.
* This will return true if the fingerprint matches, or if the key-id matches,
* or - in case that {@code matchWildcard} is true - if {@link #isWildcard()} is true.
*
* @param key key
* @param fingerprintCalculator to calculate the fingerprint
* @return whether the identifier matches the key
* @throws PGPException if an exception happens while calculating the fingerprint
*/
public boolean matches(PGPPrivateKey key,
KeyFingerPrintCalculator fingerprintCalculator,
boolean matchWildcard)
throws PGPException
public boolean matches(PGPSignature sig)
{
if (isWildcard())
{
return true;
}

PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets();
PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();

return matches(hashed) || matches(unhashed);
}

private boolean matches(PGPSignatureSubpacketVector subpackets)
{
return matches(new PGPPublicKey(key.getPublicKeyPacket(), fingerprintCalculator), matchWildcard);
if (fingerprint != null)
{
for (SignatureSubpacket subpacket : subpackets.getSubpackets(SignatureSubpacketTags.ISSUER_FINGERPRINT))
{
IssuerFingerprint issuer = (IssuerFingerprint) subpacket;
if (Arrays.constantTimeAreEqual(fingerprint, issuer.getFingerprint()))
{
return true;
}
// wildcard fingerprint
if (issuer.getFingerprint().length == 0)
{
return true;
}
}
}

for (SignatureSubpacket subpacket : subpackets.getSubpackets(SignatureSubpacketTags.ISSUER_KEY_ID))
{
IssuerKeyID issuer = (IssuerKeyID) subpacket;
if (issuer.getKeyID() == keyId)
{
return true;
}
// wildcard key-id
if (issuer.getKeyID() == 0)
{
return true;
}
}

return false;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions pg/src/main/java/org/bouncycastle/openpgp/PGPKeyRing.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,19 @@ static void readUserIDs(
*/
public abstract PGPPublicKey getPublicKey(byte[] fingerprint);

public abstract PGPPublicKey getPublicKey(KeyIdentifier identifier);

public abstract Iterator<PGPPublicKey> getPublicKeys(KeyIdentifier identifier);

/**
* Return an iterator containing all the public keys carrying signatures issued from key keyID.
*
* @return an iterator (possibly empty) of the public keys associated with keyID.
*/
public abstract Iterator<PGPPublicKey> getKeysWithSignaturesBy(long keyID);

public abstract Iterator<PGPPublicKey> getKeysWithSignaturesBy(KeyIdentifier identifier);

/**
* Return the number of keys in the key ring.
*
Expand Down
14 changes: 14 additions & 0 deletions pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,20 @@ public Iterator<PGPSignature> getSignaturesForKeyID(
return sigs.iterator();
}

public Iterator<PGPSignature> getSignaturesForKey(KeyIdentifier identifier)
{
List<PGPSignature> sigs = new ArrayList<>();
for (Iterator<PGPSignature> it = getSignatures(); it.hasNext(); )
{
PGPSignature sig = it.next();
if (identifier.matches(sig))
{
sigs.add(sig);
}
}
return sigs.iterator();
}

private Iterator<PGPSignature> getSignaturesForID(
UserIDPacket id)
{
Expand Down
41 changes: 41 additions & 0 deletions pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyRing.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,33 @@ public PGPPublicKey getPublicKey(byte[] fingerprint)
return null;
}

@Override
public PGPPublicKey getPublicKey(KeyIdentifier identifier)
{
for (PGPPublicKey k : keys)
{
if (identifier.matches(k))
{
return k;
}
}
return null;
}

@Override
public Iterator<PGPPublicKey> getPublicKeys(KeyIdentifier identifier)
{
List<PGPPublicKey> matches = new ArrayList<>();
for (PGPPublicKey k : keys)
{
if (identifier.matches(k))
{
matches.add(k);
}
}
return matches.iterator();
}

/**
* Return any keys carrying a signature issued by the key represented by keyID.
*
Expand All @@ -217,6 +244,20 @@ public Iterator<PGPPublicKey> getKeysWithSignaturesBy(long keyID)
return keysWithSigs.iterator();
}

@Override
public Iterator<PGPPublicKey> getKeysWithSignaturesBy(KeyIdentifier identifier) {
List<PGPPublicKey> keysWithSigs = new ArrayList<>();
for (PGPPublicKey k : keys)
{
Iterator<PGPSignature> sigIt = k.getSignaturesForKey(identifier);
if (sigIt.hasNext())
{
keysWithSigs.add(k);
}
}
return keysWithSigs.iterator();
}

/**
* Return an iterator containing all the public keys.
*
Expand Down
94 changes: 94 additions & 0 deletions pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKeyRing.java
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,74 @@ public PGPPublicKey getPublicKey(byte[] fingerprint)
return null;
}

@Override
public PGPPublicKey getPublicKey(KeyIdentifier identifier)
{
for (PGPSecretKey k : keys)
{
if (k.getPublicKey() != null && identifier.matches(k))
{
return k.getPublicKey();
}
}

for (PGPPublicKey k : extraPubKeys)
{
if (identifier.matches(k))
{
return k;
}
}
return null;
}

@Override
public Iterator<PGPPublicKey> getPublicKeys(KeyIdentifier identifier)
{
List<PGPPublicKey> matches = new ArrayList<>();
for (PGPSecretKey k : keys)
{
if (k.getPublicKey() != null && identifier.matches(k))
{
matches.add(k.getPublicKey());
}
}

for (PGPPublicKey k : extraPubKeys)
{
if (identifier.matches(k))
{
matches.add(k);
}
}
return matches.iterator();
}

public PGPSecretKey getSecretKey(KeyIdentifier identifier)
{
for (PGPSecretKey k : keys)
{
if (identifier.matches(k))
{
return k;
}
}
return null;
}

public Iterator<PGPSecretKey> getSecretKeys(KeyIdentifier identifier)
{
List<PGPSecretKey> matches = new ArrayList<>();
for (PGPSecretKey k : keys)
{
if (identifier.matches(k))
{
matches.add(k);
}
}
return matches.iterator();
}

/**
* Return any keys carrying a signature issued by the key represented by keyID.
*
Expand All @@ -279,6 +347,32 @@ public Iterator<PGPPublicKey> getKeysWithSignaturesBy(long keyID)
return keysWithSigs.iterator();
}

@Override
public Iterator<PGPPublicKey> getKeysWithSignaturesBy(KeyIdentifier identifier) {
List<PGPPublicKey> keysWithSigs = new ArrayList<>();
for (PGPSecretKey k : keys)
{
if (k.getPublicKey() == null)
{
continue;
}
Iterator<PGPSignature> sigIt = k.getPublicKey().getSignaturesForKey(identifier);
if (sigIt.hasNext())
{
keysWithSigs.add(k.getPublicKey());
}
}
for (PGPPublicKey k : extraPubKeys)
{
Iterator<PGPSignature> sigIt = k.getSignaturesForKey(identifier);
if (sigIt.hasNext())
{
keysWithSigs.add(k);
}
}
return keysWithSigs.iterator();
}

/**
* Return an iterator containing all the public keys.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,6 @@ private void testMatchV4Key()
isTrue(wildcard.matches(primaryKey));
isTrue(wildcard.matches(subkey));
isTrue(wildcard.matches(privateKey, new JcaKeyFingerprintCalculator()));
isTrue(!wildcard.matches(primaryKey, false));
isTrue(!wildcard.matches(subkey, false));
isTrue(!wildcard.matches(privateKey, new JcaKeyFingerprintCalculator(), false));

isTrue(KeyIdentifier.matches(
java.util.Arrays.asList(primaryIdentifier, subkeyIdentifier),
Expand Down Expand Up @@ -182,9 +179,6 @@ private void testMatchV6Key()
isTrue(wildcard.matches(primaryKey));
isTrue(wildcard.matches(subkey));
isTrue(wildcard.matches(privateKey, new BcKeyFingerprintCalculator()));
isTrue(!wildcard.matches(primaryKey, false));
isTrue(!wildcard.matches(subkey, false));
isTrue(!wildcard.matches(privateKey, new BcKeyFingerprintCalculator(), false));

isTrue(KeyIdentifier.matches(
java.util.Arrays.asList(primaryIdentifier, subkeyIdentifier),
Expand Down

0 comments on commit 6b7df29

Please sign in to comment.