Proposal: cabal-install: verify OpenPGP signatures

Nikita Karetnikov nikita at karetnikov.org
Tue Jul 29 22:17:56 UTC 2014


I’ve just pushed the commit [1] allowing to cache OpenPGP public keys on
‘cabal update’.  (Note that I haven’t written the needed code for ‘cabal
install’ yet, so the rest of this message is only about ‘update’.)

After talking to people on #gnupg (thanks!), I decided to abandon the
previous idea of relying on a “positive certification of a User ID and
Public-Key packet” [2] in order to determine whether a certain key is
trusted.  Key changes must be treated with care, so now a user must
manually mark each key contained in the index tarball [3] as trusted or
untrusted.  This is tedious, but there are workarounds (like sharing the
list of (un)trusted keys with people you trust).  I also assume this
should happen rarely after the initial update.  A short demo follows.

First, you need to obtain the source code from this repository [4] and
switch to the ‘openpgp’ branch.  Configure and install as usual, then
run these commands:

$ dist/build/hackage-server/hackage-server init
$ dist/build/hackage-server/hackage-server run --static-dir=datafiles

Register a couple of test accounts [5] (this process requires sendmail).
And don’t forget to upload a public key at the temporary page.  Keep the
server running because it currently cannot recover public keys after
shutdown.

Clone this repository [6], checkout the ‘openpgp’ branch, and build it.
Create a test config file.  In mine, these lines differ from the
defaults:

remote-repo: localhost:http://localhost:8080/packages/archive
remote-repo-cache: /home/nikita/cabal/test-cabal-dir/packages
world-file: /home/nikita/cabal/test-cabal-dir/world

After that you should be able to see something similar:

$ dist/build/cabal/cabal \
>   --config-file=/home/nikita/cabal/test-cabal-dir/test-cabal-config \
>   --ignore-sandbox update
Downloading the latest package list from localhost
Do you trust the following key of test01? (yes/no/Skip)
Test Key (do not use) <root at localhost>
  1024 bit RSA key B10D 6514 06C6 9846 F0BF  C2E6 1E50 C29A F1EE 591F, created: 2014-06-21 11:38:39 UTC
yes
Marking the key as trusted.
Do you trust the following key of test02? (yes/no/Skip)
Test Key2 (do not use) <root at localhost>
  1024 bit RSA key E2C2 CA45 9442 3F0D 58D3  059A EFAC 5E0D E4B2 0BFE, created: 2014-06-21 23:39:41 UTC
s
Skipping the key.

(See the code in ‘IndexUtils.hs’ for the list of supported commands.)

“Yes” writes the key into
‘test-cabal-dir/packages/localhost/public-keys’, which may later be used
by ‘cabal install’ to verify a signature.  (This is not implemented
yet.)

“Skip” (or any unrecognized command) simply prints the message.  So
the question will be asked again when ‘cabal update’ is run:

$ dist/build/cabal/cabal \
>   --config-file=/home/nikita/cabal/test-cabal-dir/test-cabal-config \
>   --ignore-sandbox update
Downloading the latest package list from localhost
Do you trust the following key of test02? (yes/no/Skip)
Test Key2 (do not use) <root at localhost>
  1024 bit RSA key E2C2 CA45 9442 3F0D 58D3  059A EFAC 5E0D E4B2 0BFE, created: 2014-06-21 23:39:41 UTC
no
Marking the key as untrusted.

“No” adds the fingerprint to
‘test-cabal-dir/packages/localhost/untrusted-fingerprints’.  After that
a user will never be asked about this key:

$ dist/build/cabal/cabal \
>   --config-file=/home/nikita/cabal/test-cabal-dir/test-cabal-config \
>   --ignore-sandbox update
Downloading the latest package list from localhost

A warning is raised if a trusted key is already present in the cache:

$ cd /home/nikita/cabal/test-cabal-dir/packages/localhost/public-keys
$ mv test02-public.txt test01-public.txt
$ cd -
$ dist/build/cabal/cabal \
>   --config-file=/home/nikita/cabal/test-cabal-dir/test-cabal-config \
>   --ignore-sandbox update
Downloading the latest package list from localhost
Warning: the cache already contains the following public key corresponding to test01:
Test Key2 (do not use) <root at localhost>
  1024 bit RSA key E2C2 CA45 9442 3F0D 58D3  059A EFAC 5E0D E4B2 0BFE, created: 2014-06-21 23:39:41 UTC
Do you trust the following key of test01? (yes/no/Skip)
Test Key (do not use) <root at localhost>
  1024 bit RSA key B10D 6514 06C6 9846 F0BF  C2E6 1E50 C29A F1EE 591F, created: 2014-06-21 11:38:39 UTC
  C-c C-c

(“Yes” would replace the existing key.)

That’s all for now.  Any comments are appreciated.

Next I’m planning to make this process optional (via a command line
flag) and augment ‘cabal install’ to use this.

It also bothers me that ‘hackage-server’ and ‘cabal-install’ have nearly
the same code in ‘OpenPGP.hs’.  I’ll try to contribute it to ‘hOpenPGP’,
so it can be imported from there.

[1] https://gitorious.org/cabal/cabal/commits/openpgp
[2] https://tools.ietf.org/html/rfc4880#section-5.2.1
[3] http://localhost:8080/packages/index.tar.gz
[4] https://git.gitorious.org/hackage-server/hackage-server.git
[5] http://localhost:8080/users/register-request
[6] https://git.gitorious.org/cabal/cabal.git
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/cabal-devel/attachments/20140730/0fdb4b34/attachment.sig>


More information about the cabal-devel mailing list