Browse Source

GpgKeyLocator: Return a signing key for a user instead of the master key

Currently when a GPG key is looked up using a user identity the first
key from the keyring that has this user identity is returned.
The code was changed to instead return the first signing [S] key in this
keyring and only return the master key if no such signing key was found.
If the master key also does not have the signing flag set null is
returned instead.

Bug: 552288
Change-Id: I194862991d13c2c7ff34a60a54a227167f88f53b
Signed-off-by: Roan Hofland <roan.hofland@hotmail.com>
next
Roan Hofland 5 years ago
parent
commit
0902e060f7
No known key found for this signature in database
GPG Key ID: 69FDC17B7BFDF862
  1. 41
      org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java

41
org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java

@ -72,12 +72,14 @@ import org.bouncycastle.gpg.keybox.PublicKeyRingBlob;
import org.bouncycastle.gpg.keybox.UserID; import org.bouncycastle.gpg.keybox.UserID;
import org.bouncycastle.gpg.keybox.jcajce.JcaKeyBoxBuilder; import org.bouncycastle.gpg.keybox.jcajce.JcaKeyBoxBuilder;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyFlags;
import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory; import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
@ -212,7 +214,7 @@ class BouncyCastleGpgKeyLocator {
throws IOException { throws IOException {
for (UserID userID : keyBlob.getUserIds()) { for (UserID userID : keyBlob.getUserIds()) {
if (containsSigningKey(userID.getUserIDAsString())) { if (containsSigningKey(userID.getUserIDAsString())) {
return getFirstPublicKey(keyBlob); return getSigningPublicKey(keyBlob);
} }
} }
return null; return null;
@ -517,17 +519,44 @@ class BouncyCastleGpgKeyLocator {
return null; return null;
} }
private PGPPublicKey getFirstPublicKey(KeyBlob keyBlob) throws IOException {
return ((PublicKeyRingBlob) keyBlob).getPGPPublicKeyRing()
.getPublicKey();
}
private PGPPublicKey getPublicKey(KeyBlob blob, byte[] fingerprint) private PGPPublicKey getPublicKey(KeyBlob blob, byte[] fingerprint)
throws IOException { throws IOException {
return ((PublicKeyRingBlob) blob).getPGPPublicKeyRing() return ((PublicKeyRingBlob) blob).getPGPPublicKeyRing()
.getPublicKey(fingerprint); .getPublicKey(fingerprint);
} }
private PGPPublicKey getSigningPublicKey(KeyBlob blob) throws IOException {
PGPPublicKey masterKey = null;
Iterator<PGPPublicKey> keys = ((PublicKeyRingBlob) blob)
.getPGPPublicKeyRing().getPublicKeys();
while (keys.hasNext()) {
PGPPublicKey key = keys.next();
// only consider keys that have the [S] usage flag set
if (isSigningKey(key)) {
if (key.isMasterKey()) {
masterKey = key;
} else {
return key;
}
}
}
// return the master key if no other signing key was found or null if
// the master key did not have the signing flag set
return masterKey;
}
private boolean isSigningKey(PGPPublicKey key) {
Iterator signatures = key.getSignatures();
while (signatures.hasNext()) {
PGPSignature sig = (PGPSignature) signatures.next();
if ((sig.getHashedSubPackets().getKeyFlags()
& PGPKeyFlags.CAN_SIGN) > 0) {
return true;
}
}
return false;
}
private KeyBox readKeyBoxFile(Path keyboxFile) throws IOException, private KeyBox readKeyBoxFile(Path keyboxFile) throws IOException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchAlgorithmException, NoSuchProviderException,
NoOpenPgpKeyException { NoOpenPgpKeyException {

Loading…
Cancel
Save