Skip to content

GPG commit not verified if signed with a subkey

Summary

I have a gpg key (0xBB2D962FB828400F). This key has a signing subkey (0xA0796D16BD3D3DAE) which signs my commits.

$ gpg --list-key --keyid-format 0xlong 0xBB2D962FB828400F                                                                                                                                            [master]
pub   rsa4032/0xBB2D962FB828400F 2016-09-30 [C] [verfällt: 2021-09-29]
      1FBEF31917445E37C4778F8DBB2D962FB828400F
[...]
sub   rsa4096/0xA0796D16BD3D3DAE 2016-09-30 [S] [verfällt: 2017-09-30]
sub   rsa4096/0x291C2A0869243220 2016-09-30 [E] [verfällt: 2017-09-30]
sub   rsa4096/0xF1EDDAB4122C984B 2016-09-30 [A] [verfällt: 2017-09-30]

I added the key to my gpg settings in gitlab and it correctly lists it, including my primary e-mail address.

Still, when I sign my commits it always displays unverified.

The unverified badge says the commit was signed with A0796D16BD3D3DAE, so the keyid is correct (even though the leading 0x is missing).

Looks like gitlab cannot derive the the signing key is a subkey of the master key and therefore displays unverified.

I tested it with a key where signing and certification are in the master (only encryption is a subkey, which is the default if you generate a gpg key). Here it works and correctly verifies my commits:

pub   rsa4096/0x584610AF7977479B 2017-08-22 [SC]
      B615A48454478898BD9177B5584610AF7977479B
[...]
sub   rsa4096/0xD6903A682A1C7A64 2017-08-22 [E]

Steps to reproduce

This is a little bit complicated, because you need a master key with only certification capabilities and a subkey with signing capabilities. It is not so easy to create this with gpg, I'll try to summarize the commands (using gpg 2.1.23):

$ gpg --full-gen-key --expert
--> choose 8 (RSA own capabilities)
--> remove everything by pressing S and E, so it only has Certify, then press Q
--> create the key with your primary gitlab e-mail address (the rest does not matter)

You now should have a key with only Certifiy capabilities (only [C]):

pub   rsa2048 2017-08-22 [C]

Now add a signing subkey:

$ gpg --expert --edit-key <YOUR KEY ID>
--> type "addkey"
--> choose 8 (RSA own capabilities)
--> press E to remove encryption, so it only display Sign, then press Q
--> create the key by finishing the dialog (rest does not matter)

In the end you should have a master key with a signing subkey:

$ gpg --list-key --keyid-format 0xlong <YOUR KEY ID>

pub   rsa2048/0x5479D623A1F00C4A 2017-08-22 [C]
[...]
sub   rsa2048/0xC9B8D4223BC13E64 2017-08-22 [S]

Use this key to sign your commits and add it to your gpg profile.

Example Project

See this project with that unverified commit:

https://gitlab.com/doits/gitlab-subkey-gpg-issue/commits/master

What is the current bug behavior?

Commit is unverified.

What is the expected correct behavior?

Commit should be verified.

Output of checks

This bug happens on GitLab.com (and on my own instance).

Edited by Markus Doits