nfpm: NFPM cannot sign packages with only the subkey present

Describe the bug

When attempting to sign packages with subkeys only (no main key present) the signing fails with the following error message:

release failed after 11.33s error=nfpm failed: signing error: armored detach sign: decoding armored PGP keyring: openpgp: unsupported feature: hash for S2K function: 0

This is most likely due to golang/go#23226

To Reproduce

Steps to reproduce the behavior:

builds:
nfpms:
  - rpm:
      signature:
        key_file: /tmp/signing.gpg
    deb:
      signature:
        key_file: /tmp/signing.gpg
    apk:
      signature:
        key_file: /tmp/signing.gpg

The key needs to be generated with the following steps:

$ gpg --full-generate-key
# Complete the key setup
$ gpg --edit-key test@example.com
gpg> addkey
# Complete adding the subkey
gpg> quit
Save changes? (y/N) y
$ gpg --list-keys --with-keygrip
$ rm -rf ~/.gnupg/private-keys-v1.d/ADD-MAIN-KEY-KEYGRIP-HERE.key
$ gpg -a --export-secret-subkey test@example.com >/tmp/signing.gpg

Expected behavior

The signing should either work with the GnuPG agent instead of using a file, or it should read the GnuPG key correctly.

Environment (please complete the following information):

  • OS: linux
  • OS version: Linux janoszen-desktop 4.19.128-janoszen-wsl goreleaser/goreleaser#2 SMP Tue Dec 15 12:51:43 CET 2020 x86_64 x86_64 x86_64 GNU/Linux
  • GoReleaser Version 0.149.0

Additional context:

You can verify that the key is affected by this issue by running gpg --list-packets KEYFILE.gpg and looking for the gnu-dummy S2K packet.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 21 (11 by maintainers)

Most upvoted comments

According to the keybase bug report and pr it is mostly an issue for hardware keys where the primary key is on the hardware then the signing subkeys are used offline in build pipelines and such.

I am hopeful I will be able to get a patch into the golang/crypto as I can present it as a security issue at my company and they can work with Google directly to get it merged. We have done this in the past so there are already channels we can use, but it’s not a guarantee.

A little update on this issue. I did some digging into how to rotate keys properly and it seems that I was a bit off track. Using subkeys only does not solve the problem.

My current plan is creating one repo that will be signed by the main key and contains a single package: containerssh-keyring. This will install the keys and the repo for the normal packages and updates to this repo will rotate the keys. It’s clunky as hell, but I have found no better way.

This somewhat mitigates the need for signing with subkeys as I can just create separate keys for signing the day-to-day packages. It would still be nice to be able to sign with subkeys.

Ok so clarified a bit with the team and we do have a master key that is used for generating all the signing keys, and we rotate out our signing keys every 90 days. So not a big deal for us to just invalidate one early. Now if the master key got compromised then it would be an issue, though I am sure our IT department has plans for that, though I don’t get to know those =p

Also, the team clarified that you CANNOT use the master public key to verify something signed by a subkey which is what this test is doing. So I will work on the crypto code a little more to get things cleaned up there, and I will export the public subkey which will be needed to validate against and it should work.

Talking to the team at my company responsible for signing the artifacts we ship to customers being able to sign without access to the primary private key does not make any sense at all. They understood the desire for security, but they said it should still be needed to be paired with the hardware key or special machine that had access to the primary key that you secured in another way.

I will talk to a few other teams as well who work more on building and shipping stuff from github, but if I remember correctly they were doing all the signing on a jenkins VM hosted inside our internal network.

For posterity I’d like to leave this link here, it helped me a lot in figuring out what the problem was: https://davesteele.github.io/gpg/2014/09/20/anatomy-of-a-gpg-key/