Reputation: 607
Is there a quick command to check if I signed a specific commit?
(notice I'm not asking how to verify a signature. I just want to know: is the commit signed? yes or no)
I tried the following, but all of them tell me the commit is NOT signed:
git log --show-signature HEAD -1
git verify-commit HEAD
git log --pretty="format:%h (%aN) %G? %GG %GK %GF" HEAD -1
All of the above show something for GPG signatures, but tell me "No signature" if the commit was signed with an SSH key.
The only command that tells the whole truth is cat-file commit
:
$ git cat-file commit HEAD
tree 896fba0491baa9f122a2eae5bcd8b052c6481272
parent 97031bccd6744e24028be294059e5a24a454cb58
author [...]
committer [...]
gpgsig -----BEGIN SSH SIGNATURE-----
[...]
-----END SSH SIGNATURE-----
[...]
My signed commits get marked as Verified
on GitHub, as expected.
I am guessing SSH signature checks are not as well supported by as GPG signature checks. I can even imagine why more security-conscious maintainers of git may dislike SSH signing support.
But my original, practical question remains. Is there a more convenient way than cat-file
to verify I signed a commit?
Upvotes: 1
Views: 495
Reputation: 4128
If you only need to verify the signature of some users (eg, double check if your commit is signed before pushing it to GitHub). These are the steps.
When I run git verify-commit HEAD
the error message gives a hint of the necessary actions:
error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification
It seems git ignores a signature it cannot verify, ie, it does not report an existing signature that could not be verified.
In order to allow git to recognize the SSH signature, you need to tell if that SSH key is valid for a given user.
For that need to create a file in the format of "ALLOWED SIGNERS" from man ssh-keygen
.
For example, create a file ~/.config/git/allowed_signers
with content:
[email protected] ssh-ed25519 AAAB4..
Then configure git to use it for SSH signature verification:
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers
Now, git log --show-signature
would show that a commit is signed:
$ git log --show-signature -1
commit 9c4cbb031d1d6c49dee19713747a828702a8e42a
Good "git" signature for [email protected] with ED25519 key ...
Author: User <[email protected]>
Date: ...
Also, git would report if a commit has a valid SSH signature.
$ git verify-commit HEAD
Good "git" signature for [email protected] with ED25519 key ...
Or course, you would need to add each trusted user and its key.
Source: https://blog.dbrgn.ch/2021/11/16/git-ssh-signatures/
Upvotes: 1
Reputation: 60487
Git's checking signature validity, if you want to check a much more primitive requirement, the presence of something that appears to be a signature, without verifying that is actually is one, it's only a question of when you stop looking.
Simplest that passes my personal sniff test, on GNU/anything:
didisign() {
if sed -n '0,/^$/ { /^gpgsig -----BEGIN /,/^ -----END / {//q}; };$q1' <<EOD
$(git cat-file commit ${1-HEAD})
EOD
then echo ${1-HEAD} appears to have been signed
else echo ${1-HEAD} has not been signed
fi
}
and Git's generating and checking the commit headers anyway, so there's no particular reason to get too specific about what kind of signature it is, Git said gpgsig
and what follows looks conventional enough. Anybody putting any real effort into forging a signature, your only recourse is to check its validity the real way anyway, anything between a glance and full validity checking is a half-measure.
edit: not to put too fine a point on it,
Is there a more convenient way than cat-file to verify I signed a commit?
well, no, this could easily be misleading in general use, nothing wrong with the quick check but you're going to have to look at the commit.
Upvotes: -1
Reputation: 142532
You are on the right track.
git show
will show you if the commit is signed or not
Here is a demo which i assume is similar to what you did, and you will see that the commit is signed
#!/bin/bash
# Prepare repo
cd /tmp
rm -rf /tmp/local-repo
git init /tmp/local-repo
# Switch to the new repo
cd /tmp/local-repo
# Set up local repository flags fo sign
git config user.name "user"
git config user.email "email"
git config gpg.format ssh
git config user.signingkey ~/.ssh/id_rsa.pub
# Add some dummy content
echo a > a.txt
# Commit the changes
git add .
git commit -s -m "Initial commit"
echo -e ""
echo -e "----------------------------------------------------------------"
echo -e ""
echo -e "$ git verify-commit HEAD"
git verify-commit HEAD
echo -e ""
echo -e "----------------------------------------------------------------"
echo -e ""
echo -e "$ git show HEAD"
git show HEAD
Initialized empty Git repository in /private/tmp/local-repo/.git/
[main (root-commit) 623ab49] Initial commit
1 file changed, 1 insertion(+)
create mode 100644 a.txt
----------------------------------------------------------------
$ git verify-commit HEAD
----------------------------------------------------------------
$ git show HEAD
commit 623ab49b6fe911960494006ee0b80a7cd982b6a2 (HEAD -> main)
Author: user <email>
Date: Sat Apr 27 01:21:12 2024 +0300
Initial commit
Signed-off-by: user <email>
diff --git a/a.txt b/a.txt
new file mode 100644
index 0000000..7898192
--- /dev/null
+++ b/a.txt
@@ -0,0 +1 @@
+a
Upvotes: -1