GPG signature verification fails for Ed25519 keys — commits always show "Unsupported signature"
Hi, I found a bug with GPG signature verification for Ed25519 keys.
What happens:
When a user signs commits with an Ed25519 GPG key and uploads the key to GitLab, all commits show
"Unsupported signature" instead of "Verified". This happens even for new commits made after the
key was uploaded.
Why it happens:
In lib/gitlab/gpg/signature.rb, the fingerprint method calls GPGME to extract the fingerprint
from the signature. For RSA/DSA signatures, GPGME can return the fingerprint even without the
public key in the keychain. But for Ed25519 signatures, GPGME returns nothing (empty result) if
the public key is not already in the keychain.
Because of this, fingerprint always returns nil for Ed25519 signatures. The code does return
unless gpg_signature.fingerprint in create_cached_signature!, so it exits early and never writes
the verification result to the database.
How to fix:
When GPGME returns no result, parse the OpenPGP signature packet directly (pure Ruby, no GPGME
needed) to extract the fingerprint from the Issuer Fingerprint subpacket (type 33) or the key ID
from the Issuer Key ID subpacket (type 16). Then use this as a fallback value for fingerprint.
Example fix in fingerprint:
def fingerprint
verified_signature&.fingerprint || extract_fingerprint_from_signature
end
Steps to reproduce:
1. Generate an Ed25519 GPG key: gpg --quick-gen-key "Test User <test@example.com>" ed25519
2. Upload the public key to GitLab (User Settings → GPG Keys)
3. Sign a commit with this key and push it
4. Open the commit in GitLab — it shows "Unsupported signature"
Environment:
- GitLab version: 18.9.1 (CE, self-hosted)
- GPG key type: Ed25519 (EDDSA)
- GPGME gem version: 2.0.25
Extra info:
The API endpoint GET /projects/:id/repository/commits/:sha/signature returns only signature_type
and commit_source with no verification_status field, which confirms the database record is never
created.
Thanks!
issue