Setting up an OpenPGP SmartCard with gnupg

This rant is not about using gnupg and a smartcard in general, it only covers creating new keys in a secure way while keeping a backup of the public and private keys.

I got an email last year indicating that the public key I had posted on my website was not up-to-date anymore. I had to look it up as I had not used it in a while, and gpg public.asc gave me:

pub  1024R/146E6F3D 1993-09-04 Anthon van der Neut <anthon@acm.org>

I don’t own that email address anymore (the ACM` used to charge for forwarding addresses, and I got my own TLA domain name).

So when the question of sending something encrypted came up recently, I remembered having read that to the OpenPGP card supported more than RSA with 1024 bits (I had those in my old PGP key), which brought it outside the short term range of concern.

OpenPGP card

If you generate a public/private keypair on the card, and as long as you can trust the manufacturer of the card, the private key never leaves the card. So even if your computer is compromised, the software on it can only impersonate you as, long as the card is in the computer’s card reader.

This also hs the disadvantage that if you loose your card, you don’t have a full backup of your private keys that you can use with just software. This is because You can only create a backup that allows for reinitialisation of a new card [1]. That makes sense (otherwise a compromised computer could get at your private keys), but was somewhat to restrictive for me, as I was not sure if working with the card would work out. And if it would not, I would be stuck with regenerating keys once more.

So after reading up on the subject matter a bit I decided I wanted to:

  • use a secure environment to create keys and move the private keys from there to the card
  • generate gnupg RSA key pairs of lenght 2048 (4096 for the master key), and in general follow recommended practises and optimisations.
  • automate as far as possible, in case I had to redo the steps [2].

I did not find any up-to-date and complete manuals how to go about this so this document describes the things that I found and which I thought were interesting. It contains what I did to resolve the setup of my (now working) OpenPGP card. It also gives an overview of websites read (some of them not immediately in the detail that I should have).

[1]The information must be in the backup, so maybe this is encrypte with a private/public keypair the manufacturers put on the card.
[2]I will happily spent a few times the amount it takes to do something by hand, to write a program. This is not always a waste of time as the program documents the steps involved. In the end I had to run the program 3 times for real after finding missing stuff.

GnuPG versions

One of the first things I did was go to the GnuPG website and then directly to the download page without reading. There I saw that the latest version was 2.0.22 and on my (Ubuntu 12.04) work computer I have 1.4.11. So I downloaded and built the newer version only to realise, after reading the GnuPG front page, that these versions are largely compatible. And a relatively new version of 2.0 is only needed if you want to have 4096 bit keys on your card.

This might be the reason that the kernel concepts give notice that you need GnuPG version 2.0.13 on the V2.0 version of the OpenGPG card shop page. Although 4096 was not supported in GnuPG until version 2.0.18.

GnuPG 1.4.11 works with my V2.0 OpenPGP card, so for that there is no real need to use a later 1.4.X version or a 2.X version of the software. I downloaded the 1.4.16 source and looked at the ChangeLog to see if there were fixes for key generation problems, and I did not find anything that warranted updating a version 1.4.11 if not feasable as in my Secure environment. On my desktop system I did install and use 2.0.22 (in addition to 1.4.16).

Secure environment

Although I work on Linux, which I consider in a relatively secure environment (compared to some other operating systems), I realise that dangerous software, malware, can be on my system after downloading and installing software.

I do have packages installed which are not open source. Even if I did not have those and would compile everything myself from scratch I would not be safe. Ken Thompson pointed this out in his 1983 Turing award acceptance lecture [3] and since then I have been suspicous on what can be gleaned from my computer.

This is particularily relevant when being online, as malware can than directly upload something to a remote site. But even when unplugging the network, malware can just copy the information before you wipe it and upload it when you are back online.

To make things harder for the malware I looked for a solution where the secret information is only available on a system that doesn’t ever go online and where the copying of information to and from that system is done via a restricted medium. My initial thought was to:

  • boot from a Linux Live CD that is not online
  • generate the secret and public keys
  • make a backup of an SD that will never be inserted in anything but an Linux Live CD booted system that is not online.
  • store the secret keys on the OpenGPG card
  • delete the secret key information if possible
  • insert an SD and write the public key information I needed on my main computer
  • powerdown the system and leave it off a while so there are no leaks via the memory

So if the Live CD includes some malware smart enough to keep my secret keys in memory and write them to each-and-every SD card (or USB stick) in a secret way and if my main system would scan every SD/USB inserted the secret data would get transferred [4]. Another possibility is that such malware would write the private data to some persistent memory (harddrive, BIOS?) on the machine from where it is later retrieved.

I stumbled upon Ubuntu Privacy Remix and since the version of this remix was based on Ubuntu and supported many of the concepts I wanted (including not supporting non-USB drives) I decided to try and work with that instead of a vanilla Ubuntu Live CD. Since then I have come across other, similar projects. A list of those can be found at the end of the tails page.

[3]Published in the very interesting read ACM Press Anthology Series’ “ACM Turing Award Lectures, The First Twenty Years 1966-1985”. p171-177. Also available online.
[4]If you are paranoid, you can of course dump the ASCII armored public key to the screen and type it in manually on a different system. Since I included a 4K picture, that would mean retyping 212 lines of random text (almost 13K bytes).

Generating a Ubuntu Privacy Remix DVD with smartcard support

I downloaded the UPR (Ubuntu Privacy Remix) 12.04.1 beta ISO image (UPR download page) and booted it in a new VirtualBox VM. It nicely warns that this is not a safe use of UPR. After connecting my USB based MSI StarReader SMART smartcard reader to the VM I noticed that gpg --card-status would not work. Since the UPR release doesn’t support additional downloads as it has not Internet connection, it is dificult to experiment. It also doesn’t allow sudo, so there is a bit a problem installing extra software.

Booting a VM from a (32 bit) version of Ubuntu 12.04, I found that the missing packages were pcscd and libccid. I download the i386 version of pcscd (1.7.4-2ubuntu2) and libccid (1.4.5-1) and decided not to start from scratch. So unpacked the UPR ISO inserted the two extra packages and repacked it to a UPRsc ISO.

After that I retested the UPRsc in a VM, found gpg --card-status to work and burned the image on a DVD.

Detailed steps

The follwing has only few steps that you need to change the rest should mostly be cut and paste into a bash shell if you run Ubuntu.

First set an shell varialble to determine the location where you want the ISO images:

# a new work dir adapt to your needs/disk layout, should be empty
WD=/extra/tmp/UPRsc
# where to store the original ISO, the extra packages and the result ISO
BD=/data1/ISO_IMAGE/Linux/

sudo apt-get install squashfs-tools
mkdir -p $WD $BD
pushd $BD
wget http://privacy-cd.morphium.info/upr-12.04r1beta1.iso
# you can check the downloaded ISO for signature
mkdir sc_extra
cd sc_extra
wget http://de.archive.ubuntu.com/ubuntu/pool/universe/p/pcsc-lite/pcscd_1.7.4-2ubuntu2_i386.deb
wget http://de.archive.ubuntu.com/ubuntu/pool/universe/c/ccid/libccid_1.4.5-1_i386.deb
cd $WD

You should now have everything you need to continue:

SOURCE_ISO=$BR/upr-12.04r1beta1.iso
TARGET_ISO=$BR/upr-12.04r1beta1sc.iso

mkdir mnt extracted-cd
sudo mount -o loop,ro "$SOURCE_ISO" mnt
sudo rsync --exclude=/casper/filesystem.squashfs -a mnt/ extracted-cd
# you can change the disc-name:
# sudo vi extracted-cd/README.diskdefines
# extract the bootable system, you can also mount and copy
# unsquashfs uses 8 processors and cp only one, it gives out warnings
# about interrupted system calls, doesn't help to limit number
# of processors
sudo unsquashfs mnt/casper/filesystem.squashfs
sudo umount mnt
sudo mv squashfs-root edit
# copy the packages in before chroot
sudo cp $BR/sc_extra/*.deb edit/tmp
sudo mount --bind /dev/ edit/dev  # not sure if needed
sudo chroot edit
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts
# to prevent locale issues and importing GPG keys
export HOME=/root
export LC_ALL=C
dpgk -i /tmp/*.deb
rm -rf /tmp/*
umount /proc || umount -lf /proc
umount /sys
umount /dev/pts
exit
sudo umount edit/dev
sudo rm edit/root/.bash_history  # probably not created
sudo  bash -c "echo -n "" > edit/etc/resolv.conf"
sudo  bash -c "echo -n "" > edit/etc/hosts"
# upgrade the live kernel::
sudo cp edit/boot/vmlinuz-3.8.0-33-generic extracted-cd/casper/vmlinuz
sudo cp edit/boot/initrd.img-*-generic extracted-cd/casper/initrd.lz
#
sudo chmod +w extracted-cd/casper/filesystem.manifest
sudo chroot edit dpkg-query -W --showformat='${Package} ${Version}\n' | sudo tee extracted-cd/casper/filesystem.manifest > /dev/null
sudo cp extracted-cd/casper/filesystem.manifest extracted-cd/casper/filesystem.manifest-desktop
#sudo sed -i '/ubiquity/d' extracted-cd/casper/filesystem.manifest-desktop
#sudo sed -i '/casper/d' extracted-cd/casper/filesystem.manifest-desktop
sudo rm extracted-cd/casper/filesystem.squashfs
sudo mksquashfs edit extracted-cd/casper/filesystem.squashfs
printf $(sudo du -sx --block-size=1 edit | cut -f1) | sudo tee extracted-cd/casper/filesystem.size > /dev/null
cd extracted-cd
sudo rm md5sum.txt
find -type f -print0 | sudo xargs -0 md5sum | grep -v isolinux/boot.cat | sudo tee md5sum.txt > /dev/null
sudo mkisofs -D -r -V "UPR1204B1SC" -cache-inodes -J -l -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -quiet -o "$TARGET_ISO" .

popd

You can try out the ISO you just created in a VM and when it works burn it on a DVD (if you need to work with CDs you can remove some packages as I have done during the creation of my special rescue cd:

apt-get remove -y --purge libreoffice-*
# probably need to remove more ....
sudo apt-get clean
sudo apt-get -y autoremove

Securily creating the keys

There are many recommendations, some referring to restrictions of older versions ( DSA based keys) based on that I decided on doing the following:

  • generate a master key with RSA and 4096 bits
  • attach two text IDs and an image (a 244*280 pixel JPEG file)
  • give the master key Certification capabilities only
  • create three RSA 2048 keys with Sign, Encrypt resp. Authenticate capabilities.
  • all the keys should expire, extending is easy, you don’t have to regenerate the keys.
  • provide a link to the ASCII armored public key on my website, for ease of bootstrapping opengpg on a new machine.

The gpg defaults are non-optimal, therefore, before you begin you should have a gpg.conf file in the directory where you generate you public and private key rings (from riseup.net), with the following content:

cert-digest-algo SHA512
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed

Prepare two SD cards (I used the otherwise unused 16Mb SD cards that came with my digital cameras) or USB sticks. One is for backup of the private and public data (and should go to a safe place), the other for transfer of the public key data, the JPEG image and the Setup Script.

Boot the UPRsc iso

After booting from UPRsc ISO check the time, the system is not connected to the internet and the system doesn’t know in which timezone it is. I generate public keys that my main system thought were createed an hour in the future (and had to wait to be able to import them). Also check that the Ethernet cable is disconnnected and/or your wireless module not working.

Set the data for your card

You should at least set a new PIN and ADMIN PIN. For this use gpg --card-edit:

$  gpg --card-edit
gpg: detected reader `MSI StarReader SMART [Smart Card Reader Interface] (20070818000000000) 00 00'
Application ID ...: D27600012401020000050000201C0000
Version ..........: 2.0
Manufacturer .....: ZeitControl
Serial number ....: 0000201C
Name of cardholder: [not set]
Language prefs ...: de
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Private DO 1 .....: [not set]
Private DO 2 .....: [not set]
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 32 32 32
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

and switch on the admin commands:

gpg/card> admin
Admin commands are allowed

gpg/card> help
quit       quit this menu
admin      show admin commands
help       show this help
list       list all available data
name       change card holder's name
url        change URL to retrieve key
fetch      fetch the key specified in the card URL
login      change the login name
lang       change the language preferences
sex        change card holder's sex
cafpr      change a CA fingerprint
forcesig   toggle the signature force PIN flag
generate   generate new keys
passwd     menu to change or unblock the PIN
verify     verify the PIN and list all data
unblock    unblock the PIN using a Reset Code

first set the PIN:

gpg/card> passwd
gpg: OpenPGP card no. D27600012401020000050000201C0000 detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Use option 3 and then option 1 to set the passwords. These do not need to be numeric, unless you want to use them on a smartcard reader with built in (numeric) keypad. The default Admin PIN is 12345678. If you mistype the Admin PIN three times, the card becomes irrevocably blocked.

In the fetch entry you can provide a URL from which (later) your public keys can be download.

The forcesig field determines if the gpg-agent can cache your PIN [6].

The other fields are not used by GnuPG, but I also decided to set the name, lang, sex (cannot be set to “Yes, please!”) and login values.

[5]The standard interface for communicating with GnuPG does require compilation, something that would have compilicated the adaptation of the UPR ISO to my needs. The gnupg package on python-gnupg 0.3.6 wrapper package does not support --edit-key so was useless for this application. Apart from that it has RSA 1024 as “sensible” default.
[6]From this blog: “forcesig” toggles a flag inside the card that has been introduced because of German legislative requirements for some smartcard applications. Normally, once you have inserted the card into the reader, you enter the PIN once for unlocking e.g. the encryption or the signature key, and then the key remains open for the moment. If the signature PIN is “forced”, you will have to reenter the PIN again each time you want to make a signature

Generating the keys

Please note that the password prompts by the program are overwritten if you do this on the terminal, so the prompt(s) might no longer show after “You need a Passphrase to protect your secret key.”.

In the following I use a directory gpgtest which contains the gpg.conf from the section Securily creating the keys. Instead of using --homedir on every invocation you do:

$ rm -rf gpgtest/
$ mkdir -m 700 gpgtest
$ export GNUPGHOME=$(pwd)/gpgtest

If you leave both out you will default to using ~/.gnupg

If you get the message: “Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy! (Need X more bytes)”, you should move the mouse, type something in a different window, and/or do some activity that includes disk access.

First generate a master key with only Certify capabilities:

$ gpg --homedir gpgtest --expert --gen-key
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: keyring `gpgtest/secring.gpg' created
gpg: keyring `gpgtest/pubring.gpg' created
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 8

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? e

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at 2015-02-28T09:16:00 CET
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: Anthon van der Neut
Email address: anthon@mnt.org
Comment:
You selected this USER-ID:
    "Anthon van der Neut <anthon@mnt.org>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

Enter passphrase:

Repeat passphrase:

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.


Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 243 more bytes)

.  ........+++  ++


Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 188 more bytes)

.  ........  .........  ...+++++
gpg: gpgtest/trustdb.gpg: trustdb created
gpg: key 0E516F42 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2015-02-28
pub   4096R/0E516F42 2014-02-28 [expires: 2015-02-28]
      Key fingerprint = BD48 EF3C 91CC 42C1 AE05  3762 609E BC6C 0E51 6F42
uid                  Anthon van der Neut <anthon@mnt.org>

Do not leave a comment. You don’t need to and if you are following these instruction you probably do not have enough understanding of why you should have a comment or not. So leave it out, at least until reading OpenPGP User ID Comments considered harmful

The calculation is fast, but the gathering of random data might take a while. I have considered installing Solitaire on the UPRsc DVD.

Add an ID, set first ID as the primary one:

$ gpg --homedir gpgtest --no-greeting --edit-key anthon@mnt.org
Secret key is available.

pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>

gpg> adduid
Real name: Anthon van der Neut
Email address: a.van.der.neut@ruamel.eu
Comment:
You selected this USER-ID:
    "Anthon van der Neut <a.van.der.neut@ruamel.eu>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

You need a passphrase to unlock the secret key for
user: "Anthon van der Neut <anthon@mnt.org>"
4096-bit RSA key, ID 0E516F42, created 2014-02-28

Enter passphrase:


pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
[ultimate] (1)  Anthon van der Neut <anthon@mnt.org>
[ unknown] (2). Anthon van der Neut <a.van.der.neut@ruamel.eu>

gpg> uid 1

pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
[ultimate] (1)* Anthon van der Neut <anthon@mnt.org>
[ unknown] (2). Anthon van der Neut <a.van.der.neut@ruamel.eu>

gpg> primary

You need a passphrase to unlock the secret key for
user: "Anthon van der Neut <anthon@mnt.org>"
4096-bit RSA key, ID 0E516F42, created 2014-02-28

Enter passphrase:


pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
[ultimate] (1)* Anthon van der Neut <anthon@mnt.org>
[ unknown] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>

gpg> save

Add Photo ID, you can leave out the --photo-viewer "" to have the image pop up with confirmation (not so handy for automation though):

$ gpg --homedir gpgtest --no-greeting --photo-viewer  --edit-key anthon@mnt.org
Secret key is available.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2015-02-28
pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>

gpg> addphoto

Pick an image to use for your photo ID.  The image must be a JPEG file.
Remember that the image is stored within your public key.  If you use a
very large picture, your key will become very large as well!
Keeping the image close to 240x288 is a good size to use.

Enter JPEG filename for photo ID: /home/a114/src/Python/gnupg/anthon@mnt.org.jpg
gpg: no photo viewer set
gpg: unable to display photo ID!
Is this photo correct (y/N/q)? y

You need a passphrase to unlock the secret key for
user: "Anthon van der Neut <anthon@mnt.org>"
4096-bit RSA key, ID 0E516F42, created 2014-02-28

Enter passphrase:


pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ unknown] (3)  [jpeg image of size 4283]

gpg> save

Add a Signature subkey (I am using the order of the keys as listed on the output of viewing the card):

$ gpg --homedir gpgtest --no-greeting --edit-key anthon@mnt.org
Secret key is available.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2015-02-28
pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ultimate] (3)  [jpeg image of size 4283]

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Anthon van der Neut <anthon@mnt.org>"
4096-bit RSA key, ID 0E516F42, created 2014-02-28

Enter passphrase:

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at 2015-02-28T09:18:41 CET
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 280 more bytes)

.  ..........+++++
.................+++++

pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
sub  2048R/DAEDD647  created: 2014-02-28  expires: 2015-02-28  usage: S
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ultimate] (3)  [jpeg image of size 4283]

gpg> save

The Encryption key:

$ gpg --homedir gpgtest --no-greeting --edit-key anthon@mnt.org
Secret key is available.

pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
sub  2048R/DAEDD647  created: 2014-02-28  expires: 2015-02-28  usage: S
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ultimate] (3)  [jpeg image of size 4283]

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Anthon van der Neut <anthon@mnt.org>"
4096-bit RSA key, ID 0E516F42, created 2014-02-28

Enter passphrase:

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
Your selection? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at 2015-02-28T09:19:29 CET
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
................+++++
+++++

pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
sub  2048R/DAEDD647  created: 2014-02-28  expires: 2015-02-28  usage: S
sub  2048R/B55789F3  created: 2014-02-28  expires: 2015-02-28  usage: E
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ultimate] (3)  [jpeg image of size 4283]

gpg> save

And the Authentication key (needs expert mode):

$ gpg --homedir gpgtest --no-greeting --expert --edit-key anthon@mnt.org
Secret key is available.

pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
sub  2048R/DAEDD647  created: 2014-02-28  expires: 2015-02-28  usage: S
sub  2048R/B55789F3  created: 2014-02-28  expires: 2015-02-28  usage: E
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ultimate] (3)  [jpeg image of size 4283]

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Anthon van der Neut <anthon@mnt.org>"
4096-bit RSA key, ID 0E516F42, created 2014-02-28

Enter passphrase:

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? e

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions:

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? a

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at 2015-02-28T09:19:38 CET
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.


Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 281 more bytes)

.  ...+++++
....+++++

pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
sub  2048R/DAEDD647  created: 2014-02-28  expires: 2015-02-28  usage: S
sub  2048R/B55789F3  created: 2014-02-28  expires: 2015-02-28  usage: E
sub  2048R/FAEEE0C0  created: 2014-02-28  expires: 2015-02-28  usage: A
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ultimate] (3)  [jpeg image of size 4283]

gpg> save

$ gpg --homedir gpgtest --no-greeting --edit-key anthon@mnt.org
Secret key is available.

pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
sub  2048R/DAEDD647  created: 2014-02-28  expires: 2015-02-28  usage: S
sub  2048R/B55789F3  created: 2014-02-28  expires: 2015-02-28  usage: E
sub  2048R/FAEEE0C0  created: 2014-02-28  expires: 2015-02-28  usage: A
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ultimate] (3)  [jpeg image of size 4283]

gpg> showpref
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
     Cipher: AES256, AES192, AES, CAST5, 3DES
     Digest: SHA512, SHA384, SHA256, SHA224, SHA1
     Compression: ZLIB, BZIP2, ZIP, Uncompressed
     Features: MDC, Keyserver no-modify
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
     Cipher: AES256, AES192, AES, CAST5, 3DES
     Digest: SHA512, SHA384, SHA256, SHA224, SHA1
     Compression: ZLIB, BZIP2, ZIP, Uncompressed
     Features: MDC, Keyserver no-modify
[ultimate] (3)  [jpeg image of size 4283]
     Cipher: AES256, AES192, AES, CAST5, 3DES
     Digest: SHA512, SHA384, SHA256, SHA224, SHA1
     Compression: ZLIB, BZIP2, ZIP, Uncompressed
     Features: MDC, Keyserver no-modify

gpg> quit

Create a backup of your keyrings:

$ tar c --directory gpgtest --xz -f full_key_ring_backup.tar.xz secring.gpg pubring.gpg

and copy the compressed tar file to the SD card designated for the backup of the private and public data. This is the data that you need to restore if you have to certify keys. The tar archive forces you to extract the keyrings when you need them, so you cannot modify them accidently as you could (using --homedir /path/to/your/backup) if they are copied directly.

Testing the keys

What you can do now is check the generated keys (if you do it later after import your keys on the your main machine like I did, you might have to restart the UPR. You should follow the OpenPGP key checks from RiseUp Labs. You will have an OpenPGPv4 key, but the self-signature will be SHA1 if cert-digest-algo SHA512 was not set in gpg.conf. And if the default-preference-list was not set then SHA1 is IIRC in the second position.

The cert-digest-algo is particularly bad, for AFAIK this requires regeneration of the keys. The preferences, however can be changed afterwards as described in Ana’s blog in the setion “Change preferences”.

Moving the private keys to the card

The exact process of moving the keys, depends on what is on the card. If there are no keys on there yet, you will not be prompted to replace the existing keys. Also if you have moved a secret key, then restored your secret keyring and try to move the same key again to the card, you will not be prompted for your ADMIN PIN, as the move would not change anything.

The following is based on writing the keys to a card that has already got some:

$ gpg --homedir gpgtest --edit-key anthon@mnt.org
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28  usage: C
                     trust: ultimate      validity: ultimate
sub  2048R/DAEDD647  created: 2014-02-28  expires: 2015-02-28  usage: S
sub  2048R/B55789F3  created: 2014-02-28  expires: 2015-02-28  usage: E
sub  2048R/FAEEE0C0  created: 2014-02-28  expires: 2015-02-28  usage: A
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ultimate] (3)  [jpeg image of size 4283]

gpg> toggle

sec  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb  2048R/DAEDD647  created: 2014-02-28  expires: never
ssb  2048R/B55789F3  created: 2014-02-28  expires: never
ssb  2048R/FAEEE0C0  created: 2014-02-28  expires: never
(1)  Anthon van der Neut <anthon@mnt.org>
(2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
(3)  [jpeg image of size 4283]

gpg> key 1

sec  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb* 2048R/DAEDD647  created: 2014-02-28  expires: never
ssb  2048R/B55789F3  created: 2014-02-28  expires: never
ssb  2048R/FAEEE0C0  created: 2014-02-28  expires: never
(1)  Anthon van der Neut <anthon@mnt.org>
(2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
(3)  [jpeg image of size 4283]

gpg> keytocard
gpg: detected reader `MSI StarReader SMART [Smart Card Reader Interface] (20070818000000000) 00 00'

Signature key ....: DCC2 294A 88F2 1666 0BFF  D153 1AAC 469C AFC3 4D46
Encryption key....: 20A6 0EBB 404E 9135 65DE  F5C5 AD4A 3746 A573 6DE5
Authentication key: C5B9 305C B767 E1B5 54F4  B257 D5EB 2C06 4FFB 7AF3

Please select where to store the key:
   (1) Signature key
   (3) Authentication key
Your selection? 1

gpg: WARNING: such a key has already been stored on the card!

Replace existing key? (y/N) y

You need a passphrase to unlock the secret key for
user: "Anthon van der Neut <anthon@mnt.org>"
2048-bit RSA key, ID DAEDD647, created 2014-02-28

Enter passphrase:

gpg: existing key will be replaced
gpg: 3 Admin PIN attempts remaining before card is permanently locked

Please enter the Admin PIN
Enter Admin PIN:


sec  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb* 2048R/DAEDD647  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb  2048R/B55789F3  created: 2014-02-28  expires: never
ssb  2048R/FAEEE0C0  created: 2014-02-28  expires: never
(1)  Anthon van der Neut <anthon@mnt.org>
(2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
(3)  [jpeg image of size 4283]

gpg> key 1

sec  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb  2048R/DAEDD647  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb  2048R/B55789F3  created: 2014-02-28  expires: never
ssb  2048R/FAEEE0C0  created: 2014-02-28  expires: never
(1)  Anthon van der Neut <anthon@mnt.org>
(2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
(3)  [jpeg image of size 4283]

gpg> key 2

sec  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb  2048R/DAEDD647  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb* 2048R/B55789F3  created: 2014-02-28  expires: never
ssb  2048R/FAEEE0C0  created: 2014-02-28  expires: never
(1)  Anthon van der Neut <anthon@mnt.org>
(2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
(3)  [jpeg image of size 4283]

gpg> keytocard
Signature key ....: DCC2 294A 88F2 1666 0BFF  D153 1AAC 469C AFC3 4D46
Encryption key....: 20A6 0EBB 404E 9135 65DE  F5C5 AD4A 3746 A573 6DE5
Authentication key: C5B9 305C B767 E1B5 54F4  B257 D5EB 2C06 4FFB 7AF3

Please select where to store the key:
   (2) Encryption key
Your selection? 2

gpg: WARNING: such a key has already been stored on the card!

Replace existing key? (y/N) y

You need a passphrase to unlock the secret key for
user: "Anthon van der Neut <anthon@mnt.org>"
2048-bit RSA key, ID B55789F3, created 2014-02-28

Enter passphrase:

gpg: existing key will be replaced

sec  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb  2048R/DAEDD647  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb* 2048R/B55789F3  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb  2048R/FAEEE0C0  created: 2014-02-28  expires: never
(1)  Anthon van der Neut <anthon@mnt.org>
(2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
(3)  [jpeg image of size 4283]

gpg> key 2

sec  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb  2048R/DAEDD647  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb  2048R/B55789F3  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb  2048R/FAEEE0C0  created: 2014-02-28  expires: never
(1)  Anthon van der Neut <anthon@mnt.org>
(2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
(3)  [jpeg image of size 4283]

gpg> key 3

sec  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb  2048R/DAEDD647  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb  2048R/B55789F3  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb* 2048R/FAEEE0C0  created: 2014-02-28  expires: never
(1)  Anthon van der Neut <anthon@mnt.org>
(2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
(3)  [jpeg image of size 4283]

gpg> keytocard
Signature key ....: DCC2 294A 88F2 1666 0BFF  D153 1AAC 469C AFC3 4D46
Encryption key....: 20A6 0EBB 404E 9135 65DE  F5C5 AD4A 3746 A573 6DE5
Authentication key: C5B9 305C B767 E1B5 54F4  B257 D5EB 2C06 4FFB 7AF3

Please select where to store the key:
   (3) Authentication key
Your selection? 3

gpg: WARNING: such a key has already been stored on the card!

Replace existing key? (y/N) y

You need a passphrase to unlock the secret key for
user: "Anthon van der Neut <anthon@mnt.org>"
2048-bit RSA key, ID FAEEE0C0, created 2014-02-28

Enter passphrase:

gpg: existing key will be replaced

sec  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb  2048R/DAEDD647  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb  2048R/B55789F3  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb* 2048R/FAEEE0C0  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
(1)  Anthon van der Neut <anthon@mnt.org>
(2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
(3)  [jpeg image of size 4283]

gpg> key 3

sec  4096R/0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb  2048R/DAEDD647  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb  2048R/B55789F3  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
ssb  2048R/FAEEE0C0  created: 2014-02-28  expires: never
                     card-no: 0005 0000201C
(1)  Anthon van der Neut <anthon@mnt.org>
(2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
(3)  [jpeg image of size 4283]

gpg> save

You can check the secret keys, the > indicates the subkeys have been moved to the card.:

$ gpg --homedir gpgtest --list-secret-keys
gpgtest/secring.gpg
-------------------
sec   4096R/0E516F42 2014-02-28 [expires: 2015-02-28]
uid                  Anthon van der Neut <anthon@mnt.org>
uid                  Anthon van der Neut <a.van.der.neut@ruamel.eu>
uid                  [jpeg image of size 4283]
ssb>  2048R/DAEDD647 2014-02-28
ssb>  2048R/B55789F3 2014-02-28
ssb>  2048R/FAEEE0C0 2014-02-28

Saving and importing the public keys

Save the public keys by exporting them:

gpg --armor --export anthon@mnt.org > publickey.asc

copy the publickey.asc file to the other SD card, which is for public key data only. That one you will have to put in your computer when it is connected to the internet. It should not have the secret keys in any form, specifically it should not contain the tar file you created as a backup.

Shutdown the Live system, store the SD with the private information in a safe place (together with the UPR DVD).

Installing the key on a work computer

The private keys for Signing, Encryption and Authentication are on your OpenPGP card and our public key is on the USB stick, but your keyrings are empty.

You can directly import the public keys in your empty keyring (gpg --import publickey.asc, but to also test the URL stored on your card, copy the public key file to the place where it can be accessed via the URL on the card. In my case:

scp publickey.asc anthon@xs4all.nl:~/WWW/

After that use fetch to install the keys (the time no --homedir is specified):

$ gpg --card-edit

can't connect to `/home/a114/.cache/keyring-daGCSf/gpg': No such file or directory
gpg: detected reader `MSI StarReader SMART [Smart Card Reader Interface] (20070818000000000) 00 00'
Application ID ...: D27600012401020000050000201C0000
Version ..........: 2.0
Manufacturer .....: ZeitControl
Serial number ....: 0000201C
Name of cardholder: Anthony van der Neut
Language prefs ...: en
Sex ..............: male
URL of public key : http://anthon.home.xs4all.nl/publickey.asc
Login data .......: anthon
Private DO 1 .....: [not set]
Private DO 2 .....: [not set]
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 32 32 32
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: 34D4 B2A0 A196 5E9E CAB5  136B 0ECA 42C1 DAED D647
      created ....: 2014-02-28 08:18:41
Encryption key....: 0AB7 ACB2 B20D A0AA F9A6  5AF7 B79A 362B B557 89F3
      created ....: 2014-02-28 08:19:29
Authentication key: 46DC 7C96 AE17 A6C1 2EC3  E6E1 A834 B051 FAEE E0C0
      created ....: 2014-02-28 08:19:38
General key info..: [none]

gpg/card> fetch
gpg: requesting key 0x0ECA42C1DAEDD647 from http server anthon.home.xs4all.nl
gpg: key 0x609EBC6C0E516F42: public key "Anthon van der Neut <anthon@mnt.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

gpg/card> quit

Edit the imported keys to set the trust level (initially unknown):

$ gpg --no-greeting --edit-key anthon@mnt.org

pub  4096R/0x08AC9FA54C5C1553  created: 2014-02-24  expires: 2015-02-24  usage: C
                               trust: unknown       validity: unknown
sub  2048R/0x7768C4150857912F  created: 2014-02-24  expires: 2015-02-24  usage: S
sub  2048R/0xA811E4BFA051F0E7  created: 2014-02-24  expires: 2015-02-24  usage: E
sub  2048R/0x6D8DA893056486CC  created: 2014-02-24  expires: 2015-02-24  usage: A
[ unknown] (1). Anthon van der Neut <anthon@mnt.org>
[ unknown] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ unknown] (3)  [jpeg image of size 4283]


gpg> trust
pub  4096R/0x08AC9FA54C5C1553  created: 2014-02-24  expires: 2015-02-24  usage: C
                               trust: unknown       validity: unknown
sub  2048R/0x7768C4150857912F  created: 2014-02-24  expires: 2015-02-24  usage: S
sub  2048R/0xA811E4BFA051F0E7  created: 2014-02-24  expires: 2015-02-24  usage: E
sub  2048R/0x6D8DA893056486CC  created: 2014-02-24  expires: 2015-02-24  usage: A
[ unknown] (1). Anthon van der Neut <anthon@mnt.org>
[ unknown] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ unknown] (3)  [jpeg image of size 4283]

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

pub  4096R/0x08AC9FA54C5C1553  created: 2014-02-24  expires: 2015-02-24  usage: C
                               trust: ultimate      validity: unknown
sub  2048R/0x7768C4150857912F  created: 2014-02-24  expires: 2015-02-24  usage: S
sub  2048R/0xA811E4BFA051F0E7  created: 2014-02-24  expires: 2015-02-24  usage: E
sub  2048R/0x6D8DA893056486CC  created: 2014-02-24  expires: 2015-02-24  usage: A
[ unknown] (1). Anthon van der Neut <anthon@mnt.org>
[ unknown] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ unknown] (3)  [jpeg image of size 4283]
Please note that the shown key validity is not necessarily correct
unless you restart the program.

gpg> quit

Check if that worked:

$ gpg --no-greeting --edit-key anthon@mnt.org

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2015-02-24
pub  4096R/0x08AC9FA54C5C1553  created: 2014-02-24  expires: 2015-02-24  usage: C
                               trust: ultimate      validity: ultimate
sub  2048R/0x7768C4150857912F  created: 2014-02-24  expires: 2015-02-24  usage: S
sub  2048R/0xA811E4BFA051F0E7  created: 2014-02-24  expires: 2015-02-24  usage: E
sub  2048R/0x6D8DA893056486CC  created: 2014-02-24  expires: 2015-02-24  usage: A
[ultimate] (1). Anthon van der Neut <anthon@mnt.org>
[ultimate] (2)  Anthon van der Neut <a.van.der.neut@ruamel.eu>
[ultimate] (3)  [jpeg image of size 4283]

gpg> quit

A final gpg --card-status call seems to be necessary to allow gpg to realise the keys stubs are on the card:

$ gpg --no-use-agent --card-status
gpg: detected reader `MSI StarReader SMART [Smart Card Reader Interface] (20070818000000000) 00 00'
Application ID ...: D27600012401020000050000201C0000
Version ..........: 2.0
Manufacturer .....: ZeitControl
Serial number ....: 0000201C
Name of cardholder: Anthony van der Neut
Language prefs ...: en
Sex ..............: male
URL of public key : http://anthon.home.xs4all.nl/publickey.asc
Login data .......: anthon
Private DO 1 .....: [not set]
Private DO 2 .....: [not set]
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 32 32 32
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: 34D4 B2A0 A196 5E9E CAB5  136B 0ECA 42C1 DAED D647
      created ....: 2014-02-28 08:18:41
Encryption key....: 0AB7 ACB2 B20D A0AA F9A6  5AF7 B79A 362B B557 89F3
      created ....: 2014-02-28 08:19:29
Authentication key: 46DC 7C96 AE17 A6C1 2EC3  E6E1 A834 B051 FAEE E0C0
      created ....: 2014-02-28 08:19:38
General key info..: pub  2048R/0x0ECA42C1DAEDD647 2014-02-28 Anthon van der Neut <anthon@mnt.org>
sec#  4096R/0x609EBC6C0E516F42  created: 2014-02-28  expires: 2015-02-28
ssb>  2048R/0x0ECA42C1DAEDD647  created: 2014-02-28  expires: 2015-02-28
                      card-no: 0005 0000201C
ssb>  2048R/0xB79A362BB55789F3  created: 2014-02-28  expires: 2015-02-28
                      card-no: 0005 0000201C
ssb>  2048R/0xA834B051FAEEE0C0  created: 2014-02-28  expires: 2015-02-28
                      card-no: 0005 0000201C

Due to the keyid-format 0xlong entry in my gpg.conf the key signatures do not seem to correspond.

Consulted websites

There are many websites out there that described some of the aspects that filtered into the description of how to setup the card the way I wanted. The following is an overview of sites visited, the main idea I picked up from there and possible some critique. Even if I have not used them to the full extend, and even if I might have critical comments, these are sites with much valuable information.

This is all based on the state of the site in Feb. 2014

GnuPG

The Gnu Privacy Guard website has links to the latest sources of gpg both for the 1.4 and 2.0 series.

The GNU Privacy Handbook has some general information, but is hopelessly out of date (1999). No information on using smartcards. On page 30 it recommends “It is almost always the case that you will not want the master key to expire”, I don’t think that is good advice any more.

The GnuPG Smartcard HOWTO is a few years old as well (2005). It describes the older 1024 bit RSA version of the card, both generating keys on the card, as well as moving existing keys to the card.

The FAQ touches on many interesting points, including key size under the advance topics.

FSFE

The FSFE has many intersting card howtos. Although written for the FSFE card, most of the handling procedure applies to the OpenGPG card I have in use as well. The main article is Card with subkeys using backups which is very similar to my approach, except that the master key is allowed to sign as well, that there is a second (full software) encryption key and that Authentication is something not handled in the howto itself (go an surf is the recommendation).

Because the FSFE method doesn’t use a restricted computer to generate the keys (they just recommend to go off-line), their exporting and deleting of the master key and then reimporting subkeys etc. seem IMHO less transparent than using a disposible environment like the UPR in which the keys are generated.

The FSFE site has several recommendations on getting the gpg-agent to work with Gnome and Ubuntu 12.04. On this subject there is also an interesting blog on the FSFE site

Riseup

On the riseup.net site I found OpenPGP Best Practices had I read and understood the recommendations there from the start, I would not have had to regenerate my keys as my GPG defaults were not as they should be, resulting in the key checks failing (first the algorithm preferences then the self-signatures. Read, and then read once more!

On the site is also a transition statement for older PGP/GPG keys in case you generate a new master key.

Debian

There are several weblog entries and wiki pages from Debian related users/maintainers that touch on aspects of using GnuPG.

G10 and kernel concepts

Description for the OpenGPGv2 card can be found on the g10 site.

I bought my card (with a seperate RFID build into the card) at kernel concepts

Parcimonie

parcimonie.sh refreshes individual keys in your GnuPG keyring at randomized intervals. Each key is refreshed over a unique, single-use Tor circuit. This is a much more straighforward implementation then the original Perl based one.

Echoes/Corsac.net

One post Switching to OpenPGP smartcard <http://www.corsac.net/?rub=blog&post=1548> described how to use two smartcards and put the secret part of your master key on a second smartcard. Another deals with Expiration extension on PGP subkeys (2013-08-25).

OpenSC

I briefly looked at, but haven’t used, OpenSC – tools and libraries for smart cards. It implements the PKCS#11 API. They also have a wiki.

OpenPGP courses

Free courses (Germany) and other interesting material can be found on the OpenPGP courses and lobbying site. The more interesting parts are on the German version of the site, easy to miss if you rather read English.

Setup Script

I have used a setup script that drives gpg to generate the listings above (typing passphrases and PINs repeatedly until everything runs automatically is tedious). It is a Python script, relying only on the standard library [5], to drive gpg via subprocess. (and create some files).

My setup script does not do everything (yet), especially the interaction of moving the secret keys to the card depends on whether there are keys already on the card or not I have started implemented some check on responses, but since the card is no longer ‘emtpy’ I cannot check everything.

The script is hosted on bitbucket

If you want to use the script update the lines:

uids = Anthon van der Neut <anthon@mnt.org>
  Anthon van der Neut <a.van.der.neut@ruamel.eu>

in the .ini file and provide a anthon@mnt.org.jpg (adapted to your email address on the first line appended with .jpg) in the same directory as you store the script if you want a photo included (you can also use the script’s --photo option). I copied the script and the image from the SD card to the home directory of the user on the booted UPRsc image and ran them from there.

Posted on 2014-02-21.