We are introducing a method of verifying Haskell packages with OpenPGP signatures. The initial code to sign your packages has been included in Stack as an experimental feature for some time. We are going to be improving it and included verification options soon. However, we need signatures from package authors before verification is useful.
The first step in submitting package signatures is to create a secure OpenPGP key for yourself and publish it. This post will walk you through creating an offline master OpenPGP key-set with GnuPG.
If you've never used GPG before and need to generate a secure set of keys, then continue reading.
If you already have GPG keys that you are happy with, continue to 'Signing Packages with Stack' towards the bottom of this article.
Choosing a version of GPG
There are 3 main flavors of GnuPG:
It is recommended by the GnuPG project version to use the Stable GPG-2 release (2.0). I've included instructions for using GPG 1.4 but I don't recommend using such an old version unless you have no choice. I've also included instructions for GnuPG 2.1 because I use it personally and find the new features useful.
Offline machine for GPG key management
Ideally your offline keys will never be on a machine connected to the outside world. The offline box will be the place where you keep your master key, manage your keys & sign other keys. This assures that you can always revoke keys and recover if your online machine(s) are somehow compromised.
To have an offline box you'll need two "machines". These can just be the same machine if you utilize a "live" Linux USB/DVD boot drive and a USB stick for the "sneaker net".
We'll follow the same procedure to generate your keys, even if you don't want to use an offline machine to generate them. It's highly recommended using an offline master though and keeping secure backups. It's the least hassle for everyone else in your "web of trust" in an event where keys are compromised.
With an offline master key, if your laptop is compromised, you can just revoke the compromised sub-keys, create new sub-keys and publish them. If you get into the situation where your master key is compromised, you will have to revoke all your keys, approach people about your new keys & going through the process of reestablishing trust with people in your web-of-trust.
Setup $GNUPGHOME directory
Install the secure key-server certificate (Ubuntu/Debian):
Put some or all of the following in your $GNUPGHOME/gpg.conf file: (taken from the riseup.net best gpg practices page)
Public and Secret
Switching Secret Key Sets
Using your offline secret keys
Delete your secret keys and re-import the offline secret keys (the full set).
GPG 2.0 or 2.1
With the full set in use (offline only of course!) you can import your buddy's keys, sign them and trust them. Use gpg –import and gpg –export to move keys around to/from USB drives to/from your online machine.
If you list your secret keys you should see a plain "sec" next to your key. This indicates a full secret key is present. You may now manage keys and sign other keys.
GPG 2.0 or 2.1
Using your online secret keys
Delete your secret keys and re-import the online secret keys (the subset).
GPG 2.0 or 2.1
You won't be able to sign other people's keys or create/revoke keys with this key-set. (This is a good thing in case your online machine and it's subkeys are compromised later.)
If you list your secret keys you should see a "sec#" next to your key. The '#' indicates that the secret is missing for your master key. If you are following good practices, from now on, it will only be available on your offline computer.
GPG 2.0 or 2.1
Signing Packages with Stack
Now that we have our online secret keys ready, we can sign our Hackage-bound packages with Stack. There are currently two methods to sign keys in Stack. The first is to sign your package while uploading (the default). Just perform an upload as you might have in the past.
This will upload your package to Hackage just like it did before. After that finishes it will GPG detach-sign the package and send that signature to sig-service. This service just collects signatures & periodically commits them to sig-archive. Later we will use these signatures and our web of trust to verify package contents as they download with stack.
If you don't want to sign for some reason. You can just skip the signature by adding a flag.
Another way to sign is to create an sdist file. If you add a flag you can publish a signature at the same time.
For those package authors out there with more than a few packages to sign, we have written a simple tool to bulk sign all your packages published to Hackage. It's called sig-tool.
To bootstrap you need to run the following:
This will download all of your packages to the current directory & generate a manifest with SHA256 sums for all the releases. You should inspect the files to make sure they are correct at this stage. You can sign all of the releases or you can trim the manifest file if you like.
To begin signing run the following:
Posted by Tim Dysinger - 05 May, 2016