Kristian Lyngstøl's Blog

Using an OpenPGP Smartcard on Ubuntu 10.04

Posted on 2010-04-24

We recently bought a few OpenPGP SmartCard version 2.0 at Varnish Software, with card readers to match, and I've been using mine for a month or so now. However, there are a few challenges involved, specially with the PCMCIA-based Omnikey CM4040 card reader. Until today, mine has been flaky at best.

The use case for this is to store your ssh key on a smart card, along with your encryption and signature key.

In addition to hardware, the version 2.0 of the OpenPGP card requires gnupg 1.4.10 or gnupg 2.0.10 or newer, which is not necessarily easily available. It is available on Ubuntu 10.04, however.

I've tried to describe the necessary steps, though I might have forgotten some elements of it. That being said, this isn't meant to be a recipe for people who don't know what they are doing, it's intended for those of you who understand what's actually being done. Let me know if anything crucial is missing.

Setting up the software

You will need gnupg2, gnupg-agent, pcscd and libpcsclite1 to begin with. If you are using th Omnikey CM4040, you will most likely also need pcsc-omnikey. The software stack works by having gpg2 or ssh talk to the gpg-agent (which will also act as an ssh-agent), this in turn will spawn scdaemon which talks to pcscd which talks to the actual card, if my understanding is correct.

apt-get install gnupg2 gnupg-agent pcscd libpcsclite1

To be able to use the ssh bit, you have to remove the ssh-agent from /etc/X11/Xsession.d/, simply copy it out of the way: cp /etc/X11/Xsession.d/90x11-common_ssh-agent /etc/X11/ . Now edit /etc/X11/Xsession.d/90gpg-agent and find the STARTUP="$GPGAGENT --daemon ..." line and add --enable-ssh-support. After that, you'll be using gpg as your ssh agent when you next log in.

Setting up the Omnikey CM4040

To get the 4040 up and working, you need to install the pcsc-omnikey package if you didn't already do that. Unfortunately, it doesn't drop the required config in /etc/reader.conf.d/ as it's supposed to, so grab it from the example doc, then regenerate /etc/reader.conf (which is just a collection of /etc/reader.conf.d/) and restart pcscd:

# cp /usr/share/doc/pcsc-omnikey/examples/reader.conf /etc/reader.conf.d/
# update-reader.conf
# service pcscd restart

If you had already tried gpg2 --card-status or similar, you will most likely have to kill scdaemon, and it's fairly stubborn, so it typically takes 3-4 SIGTERMs before it dies.

After this, though, you should be all set up.

Trying the card

gpg2 --card-status

A couple of things can happen:

  • You get card information and it's all nice and dandy
  • You get most of the card information, but things like vendor ID is blank or incorrect - upgrade gnupg.
  • It hangs - kill scdaemon.
  • You get a "no card found" error: remove and reinsert the card, restart pcscd and kill scdaemon, then pound your head into the wall if it still doesn't change.
  • You get a more generic error: see point 4.

To make sure the card isn't caching, try removing it then typing gpg2 --card-status. You should obviously get an error, and if you don't, it's likely scdaemon that needs a kill. This typically happens if you remove the card reader or restart pcscd.

Assuming the card is showing up, it's time to use it: gpg2 --card-edit

Setting up most of this should be easy, but there's at least one point that needs an explanation: Your public key is _NOT_ stored on the card! After you've created a new key (or imported one), you will have to send it to a key server the normal way and set the url on the card to match. The reason you want to set the url is because it makes it far easier when you use your card on a different machine: All you do is run --edit-card and type 'fetch' and it will download your public keys.

The other thing you must remember, which you probably already know from reading the notes that came with your card: If you type the admin pin code wrong more than 3 times in a row, your card is essentially bust. Luckily, you rarely need the admin pin.

If you haven't managed to set your pin yet, type help and read. To generate a new set of keys, simply type generate. You can also move the keys using normal gpg2 commands, but as I haven't done that myself, I can't rule out pit falls.

Once your keys are generated, that's really all there is. You can add uids later like you would with any other gpg key (ie: gpg2 --edit-key Your-fpr-here).

Using ssh

This should already Just Work, but to verify that ssh can see your key, use: ssh-add -l. You can also add your old ssh keys to gpg that way. You'll be prompted for pass phrase two times: The original pass phrase and the new one. See gpg-agents man pages for details.

Exporting the public key can either be done by ssh-copy-id,  or ssh-add -L.

Using GPG

You probably want to make sure you set up key trust for your key (gpg2 --edit-key ..;   trust) when you're on a new computer, but besides that, it'll be just like normal GPG. I'd post a pretty picture of the PIN-dialog, but it seems it grabs most of the screen, so that's a bit difficult.

Hooking it up to PAM

I've had moderate success with libpam-poldi. I'm saying moderate because only one application can hold your card at any given time, which is fine as long as everything goes through gpg2-agent and scdaemon, but if you try to use your smartcard  for sudo, you'll likely find it doesn't do you much good. The poldi-package worked pretty much out of the box for me, after gluing it in to pam. It has fairly good instructions, so I'll leave it as an exercise to the reader to actually set it up.

One interesting thing, though, is that if you hook it up to gnome-screen-saver, it'll work flawlessly, and even take pin-cache into consideration. Login also works fine, as gpg-agent hasn't started yet.