aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.gpg.bc
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2020-06-17 18:43:32 +0200
committerMatthias Sohn <matthias.sohn@sap.com>2020-09-05 21:03:38 +0200
commit38015e3d36369c7e43916117df7d0f2f8da8344b (patch)
treefdfc4b52ae6df2676f48d4af34afd0e99d033707 /org.eclipse.jgit.gpg.bc
parent920442ff42f2656ca4c9a748a05409baa5b16706 (diff)
downloadjgit-38015e3d36369c7e43916117df7d0f2f8da8344b.tar.gz
jgit-38015e3d36369c7e43916117df7d0f2f8da8344b.zip
GPG: include signer's user ID in the signature
Signing a commit with command line git and gpg 2.2.20 includes the e-mail part of the key's user ID as a "Signer's User ID" subpacket on the signature. Implement this for signing via Bouncy Castle. Bug: 564386 Change-Id: I68906b895349359596cf3451d65f2840c60df856 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit.gpg.bc')
-rw-r--r--org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java39
1 files changed, 34 insertions, 5 deletions
diff --git a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java
index c6ecdbe6da..ea159c547d 100644
--- a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java
+++ b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java
@@ -15,6 +15,7 @@ import java.net.URISyntaxException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
+import java.util.Iterator;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.BCPGOutputStream;
@@ -22,6 +23,7 @@ import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey;
+import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
@@ -38,6 +40,7 @@ import org.eclipse.jgit.lib.GpgSignature;
import org.eclipse.jgit.lib.GpgSigner;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.util.StringUtils;
/**
* GPG Signer using BouncyCastle library
@@ -126,17 +129,32 @@ public class BouncyCastleGpgSigner extends GpgSigner {
privateKey = secretKey
.extractPrivateKey(decryptorBuilder.build(passphrase));
}
+ PGPPublicKey publicKey = secretKey.getPublicKey();
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
new JcaPGPContentSignerBuilder(
- secretKey.getPublicKey().getAlgorithm(),
+ publicKey.getAlgorithm(),
HashAlgorithmTags.SHA256).setProvider(
BouncyCastleProvider.PROVIDER_NAME));
signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
- PGPSignatureSubpacketGenerator subpacketGenerator = new PGPSignatureSubpacketGenerator();
- subpacketGenerator.setIssuerFingerprint(false,
- secretKey.getPublicKey());
+ PGPSignatureSubpacketGenerator subpackets = new PGPSignatureSubpacketGenerator();
+ subpackets.setIssuerFingerprint(false, publicKey);
+ // Also add the signer's user ID. Note that GPG uses only the e-mail
+ // address part.
+ String userId = committer.getEmailAddress();
+ Iterator<String> userIds = publicKey.getUserIDs();
+ if (userIds.hasNext()) {
+ String keyUserId = userIds.next();
+ if (!StringUtils.isEmptyOrNull(keyUserId)
+ && (userId == null || !keyUserId.contains(userId))) {
+ // Not the committer's key?
+ userId = extractSignerId(keyUserId);
+ }
+ }
+ if (userId != null) {
+ subpackets.setSignerUserID(false, userId);
+ }
signatureGenerator
- .setHashedSubpackets(subpacketGenerator.generate());
+ .setHashedSubpackets(subpackets.generate());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try (BCPGOutputStream out = new BCPGOutputStream(
new ArmoredOutputStream(buffer))) {
@@ -149,4 +167,15 @@ public class BouncyCastleGpgSigner extends GpgSigner {
throw new JGitInternalException(e.getMessage(), e);
}
}
+
+ private String extractSignerId(String pgpUserId) {
+ int from = pgpUserId.indexOf('<');
+ if (from >= 0) {
+ int to = pgpUserId.indexOf('>', from + 1);
+ if (to > from + 1) {
+ return pgpUserId.substring(from + 1, to);
+ }
+ }
+ return pgpUserId;
+ }
}