/release-sign

Tools and instructions to sign Github releases using the OpenPGP keys.

Primary LanguageShellOtherNOASSERTION

release-sign: tools for signing and verifying GitHub releases

Check signatures

Purpose

Tools and instructions for signing GitHub releases using OpenPGP keys.

Installation

Nix Flakes

If you have Nix Flakes installed, you can use the following command directly:

$ nix run github:rnpgp/release-sign -- # options and parameters...

Non-Nix Flakes

You will need to git clone this repository to your local machine, then CD into it.

Key generation

You will first need to generate a strong enough OpenPGP key with an email that corresponds to your repository/company name.

With RNP you can use the following command.

The syntax is:

$ rnpkeys --generate --expert --userid "{FULL_NAME} <{EMAIL_ADDRESS}>"

EXAMPLE:

$ rnpkeys --generate --expert --userid "Dummy Release Signing <dummy@example.com>"

Then choose an algorithm and the corresponding parameters:

  • for ECC, choose a curve

  • for RSA/DSA keypairs, specify a key size

Note
EdDSA/X25519 or RSA 3072 and up are considered safe today.

You may also want to add the --homedir {SOMEDIR} option, so that the generated keys will be saved in a folder outside your global key storage (~/${HOME}/.rnp, that is).

Once the keys are generated, you will be presented with such an output:

sec   3072/RSA (Encrypt or Sign) 2ba318771716f1c2 2021-07-01 [SC]
      91bd5489242b44def6cb633b2ba318771716f1c2
uid           Dummy Release Signing <dummy@example.com>
ssb   3072/RSA (Encrypt or Sign) bee55641c8403ae5 2021-07-01 [E]
      070139d64b594240141e6c18bee55641c8403ae5
Note

This output will be shown again by using the --list-keys command:

# When using key storage location "{SOMEDIR}""
$ rnpkeys --homedir {SOMEDIR} --list-keys
# Or if using the default key storage location at ~/.rnp:
# $ rnpkeys --list-keys

Some explanation for key generation output:

  • The text sec and ssb means that you have a secret key.

  • The hex digit blocks, 2ba318771716f1c2 and 91bd5489242b44def6cb633b2ba318771716f1c2 are your "keyid" and "key fingerprint". They are unique identifiers that identify your key.

  • The "keyid" is actually the rightmost 16 hex chars of the "key fingerprint".

Note

The same process can also be done with GnuPG:

gpg --full-generate-key --expert

The --homedir option applies to the gpg command, as well.

Key publication

General

Once your secret key is generated, you should announce your key to the public in order to allow others to verify your signatures.

Step 1: Exporting the public key

Export the "public key" of your key into a separate file.

The syntax is:

$ rnpkeys --homedir {HOMEDIR} --export {KEY_FINGERPRINT} > {PUBLIC_KEY_PATH}

EXAMPLE:

$ rnpkeys --homedir .rnp --export 2ba318771716f1c2 > release-key.asc
Note

If you use GnuPG, the following command.

gpg --homedir .gpg --armor --export 2ba318771716f1c2 > release-key.asc

Step 2: Making the public key known

  1. Supply your public key (the exported file) to your package, distribution, or upload it to a public keyserver.

    Note
    https://keys.openpgp.org/ is such a public keyserver.
  2. If the package provides release notes, do mention the signing key’s "key fingerprint" so that users can find your key on public keyservers or at least be able to identify your key for signature verification.

    Note
    For example, RNP publishes its release signing key’s public key online.

Signing

After releasing a new version of your software and pushing its release tag to GitHub, you can do the following.

  1. Download the released source tarball

  2. Sign the released source tarball

We recommend using the provided rel-sign.sh script to automatically run this process on a GitHub repository instead of doing this manually.

The syntax is:

rel-sign.sh --repo {GITHUB_REPO} -v {VERSION_TAG} --pparams --keyfile {PRIVATE_KEY_PATH}

EXAMPLE:

$ ./rel-sign.sh --repo rnpgp/rnp -v 0.15.1 --pparams --keyfile dummy-release-sec.asc
Signatures are stored in files v0.15.1.tar.gz.asc and v0.15.1.zip.asc.

On success of the command, the following signature files will be generated:

  • {VERSION_TAG}.tar.gz.asc: signature for the {VERSION_TAG}.tar.gz source tarball

  • {VERSION_TAG}.zip.asc: signature for the {VERSION_TAG}.zip source archive

The last step is to upload these signature files to the GitHub Release page.

  • Edit the corresponding Release page on GitHub

  • Add release notes and upload signature files

Verifying

To verify the signature of a source archive:

  1. Download the source archive.

  2. Download the signature file of the source archive.

  3. Download the public key used to sign the source archive.

  4. Run signature verification.

Note
Ensure the signature file is named as {ARCHIVE_PATH}.asc if the archive is called {ARCHIVE_PATH}, and that they are located in the same folder.

The syntax is:

$ rnp --keyfile {PUBLIC_KEY_PATH} -v {ARCHIVE_SIGNATURE_PATH}

EXAMPLE:

$ curl -sSL -o v0.15.1.tar.gz \
    https://github.com/rnpgp/rnp/archive/refs/tags/v0.15.1.tar.gz
$ curl -sSL -o v0.15.1.tar.gz.asc \
    https://github.com/rnpgp/rnp/archive/refs/tags/v0.15.1.tar.gz.asc
$ curl -sSL -o public-key.asc \
    https://www.rnpgp.org/openpgp_keys/BEDBA05C1E6EE2DFB4BA72E1EC5D520AD90A7262-A845A5BD622556E89D7763B5EB06D1696BEC4C90.asc
$ rnp --keyfile public-key.asc -v v0.15.1.tar.gz.asc

A successful verification will produce an output as the following.

Good signature made Thu Jul  1 16:03:15 2021
using RSA (Encrypt or Sign) key 2ba318771716f1c2

pub   3072/RSA (Encrypt or Sign) 2ba318771716f1c2 2021-07-01 [SC]
      91bd5489242b44def6cb633b2ba318771716f1c2
uid           Dummy Release Signing <dummy@example.com>
Signature(s) verified successfully

A failed verification will show a "BAD Signature" message…​

This script also provides verify-remote which does the above for you.

EXAMPLE:

# Import RNPGP's public key
$ curl -sSL -o public-key.asc \
    https://www.rnpgp.org/openpgp_keys/BEDBA05C1E6EE2DFB4BA72E1EC5D520AD90A7262-A845A5BD622556E89D7763B5EB06D1696BEC4C90.asc
$ rnpkeys --import public-key.asc

# Run verification
$ ./rel-sign.sh --repo rnpgp/rnp -v 0.15.1 verify-remote

# Or if using Nix:
$ nix run github:rnpgp/release-sign -- --repo rnpgp/rnp --v 0.15.1 verify-remote

License

Openly licensed. Ribose.