3 Comments

Using a Smartcard with a VirtualBox-based Vagrant Virtual Machine

Lately, I’ve been working on setting up a Personal Package Archive (PPA) to use when provisioning servers with custom packages.

In order to host packages on a Launchpad PPA, one must first upload signed source packages. Since I use a Mac and keep my PGP signing key on a Smartcard, I needed to find a way to connect my Smartcard reader to a virtual machine running Ubuntu. After a bit of research, I found an easy way to do this with Vagrant, VirtualBox, and the standard precise64 basebox.

1. Pre-reqs

First, we need to download and install Vagrant (version 1.4.1 at the time of this writing), and Virtualbox (version 4.3.8 at the time of this writing).

Then add the precise64 basebox:

vagrant box add precise64 http://files.vagrantup.com/precise64.box

2. Finding the VendorId and ProductId

Next we need to connect our USB device to our VM. VirtualBox gives us several ways of doing so. The most convenient one, in my opinion, is to use a “usbfilter” to automatically connect the device to our guest whenever it is attached to the host.

Attach the device to the host and run VBoxManage list usbhost to get a detailed description of all of the USB devices attached to the host. Make note of the VendorId and ProductId. We will use those to add the filter. Here’s what the entry for my Smartcard looks like:

$ VBoxManage list usbhost
...
UUID:               2058baec-34f0-43d8-be51-cd12449ebea4
VendorId:           0x08e6 (08E6)
ProductId:          0x3438 (3438)
Revision:           2.0 (0200)
Port:               3
USB version/speed:  0/1
Manufacturer:       Gemalto
Product:            USB SmartCard Reader
SerialNumber:       3C8DXXXX
Address:            p=0x3438;v=0x08e6;s=0x0000707e98379971;l=0xfa130000
Current State:      Captured

3. Adding a usbfilter to a Vagrantfile

Now that we have the VendorId and ProductId, we can add a ‘usbfilter’ as a VBoxManage Customization to our Vagrantfile:

 # Add usb filter to attach SmartCard reader
 config.vm.provider :virtualbox do |vb|
   vb.customize ['modifyvm', :id, '--usb', 'on']
   vb.customize ['usbfilter', 'add', '0', '--target', :id, '--name', 'SmartCard', '--vendorid', '0x08e6', '--productid', '0x3438']
 end

Where the --vendorid(e.g.0x08e6) and --productid (0x3438) come from the listing for our device we found above.

Here’s a complete Vagrantfile:

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "precise64"
  config.vm.box_url = "http://files.vagrantup.com/precise64.box"
  # Add usb filter to attach SmartCard reader
  config.vm.provider :virtualbox do |vb|
    vb.customize ['modifyvm', :id, '--usb', 'on']
    vb.customize ['usbfilter', 'add', '0', '--target', :id, '--name', 'SmartCard', '--vendorid', '0x08e6', '--productid', '0x3438']
  end
end

If we vagrant up with this Vagrantfile, plug in our device, and vagrant ssh into the VM, we should be able to see it:

$ vagrant ssh
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)

 * Documentation:  https://help.ubuntu.com/
Welcome to your Vagrant-built virtual machine.
Last login: Fri Sep 14 06:23:18 2012 from 10.0.2.2
vagrant@precise64:~$ lsusb
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 002: ID 08e6:3438 Gemplus GemPC Key SmartCard Reader
vagrant@precise64:~$

4. Using the Smartcard Reader with Ubuntu

Now that we have our device attached, we need to do a few more things to be able to use it with GnuPG. First, we need to install pcscd the PC/SC Daemon.

sudo apt-get install pcscd

(This will also install libccid, the library which happens to support my reader.)

Then, we need to reload udev so that it will load the new rules provided by the libccid package:

sudo reload udev

These rules (in /lib/udev/rules.d/92-libccid.rules) will automatically change the permissions on our USB device as soon as it is attached so that the pcscd process can access it.

Now, if we unplug our device and plug it back in, we should be able to use it with GnuPG:

gpg --card-status

We should see our card details and the list of keys it holds.

In order to get stubs added to ~/.gnupg/secring.gpg, do the following dance:

$ gpg --card-edit
> fetch
...
> quit
$ gpg --card-status


Now we should see the stubs for our keys in our keyring (gpg -K) and be able to use them for signing and decryption.

References