Using an OpenPGP Smart Card on Mac OS X

Posted 2015-05-22, revised: 2016-10-01

I no longer use this OpenPGP card or this setup - I'll do a writeup of my new setup shortly.

I use an OpenPGP smart card with a Gemalto IDBridge K50 USB card reader.

This post details how I configure my Mac OS X install for SSH authentication using the smart card.

Prerequsites

This post doesn't explain how to create your GPG key or how to move it to the card.

If you need to know how to create your keys, I used http://www.bootc.net/archives/2013/06/07/generating-a-new-gnupg-key/ as a guide to create mine (this assumes you're running Debian).

This post assumes you have:

  • a Mac running OS X 10.10 Yosemite
  • a Gemalto IDBridge K50 USB smart card reader containing a OpenPGP smart card
  • your GPG keys already loaded on to your smart card

Setting it up

  1. First off, install GPG Suite from gpgtools.org.
  2. Once you've installed the GPG Suite, open a Terminal.
  3. We need to disable the standard SSH agent, so run:
    sudo launchctl unload -w /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist
  4. I found that my GPG agent would randomly die unless I disable the org.gpgtools.macgpg2.shutdown-gpg-agent.plist LaunchAgent. To disable this, run:
    sudo launchctl unload -w /Library/LaunchAgents/org.gpgtools.macgpg2.shutdown-gpg-agent.plist
  5. We'll need to edit your gpg-agent.conf. Open it in your favourite editor and make sure it contains:
    enable-ssh-support
    pinentry-program /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac
    write-env-file
    use-standard-socket
  6. To have apps on the console work correctly that expect to use the GPG or SSH agent, you'll need to add some lines to the .profile file in your home directory. Open ~/.profile in your favourite editor and make sure it contains the following:
    export SSH_AUTH_SOCK=~/.gnupg/S.gpg-agent.ssh
    GPG_TTY=`tty`
    export GPG_TTY
    To apply this to your current console, run source ~/.profile.
  7. For OSX GUI applications to see the GPG agent properly, you'll need to create your own LaunchAgent plist file that sets the environment variable. After doing this, you can (for example) use the GPG key to authenticate in SourceTree.
    The normal naming scheme for plists is to use your domain name backwards, then a description of the purpose of the file. In this example, my file is called uk.tomjepp.sshenv.plist.
    Open ~/Library/LaunchAgents/uk.tomjepp.sshenv.plist in your favourite editor and insert the following:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
      <dict>
      <key>Label</key>
      <string>setenv.SSH_AUTH_SOCK</string>
      <key>ProgramArguments</key>
      <array>
        <string>/bin/launchctl</string>
        <string>setenv</string>
        <string>SSH_AUTH_SOCK</string>
        <string>/Users/thomas/.gnupg/S.gpg-agent.ssh</string>
      </array>
      <key>RunAtLoad</key>
      <true/>
      <key>ServiceIPC</key>
      <false/>
    </dict>
    </plist>
    
    Replace thomas in the /Users/thomas/.gnupg/S.gpg-agent.ssh with your own username.
  8. To enable that new plist, run:
    launchctl load -w ~/Library/LaunchAgents/uk.tomjepp.sshenv.plist

At this point, you should be able to freely unplug and plug back in your GPG card - and it should keep working whenever you do!

This setup works nicely for me on two Macs - for SSH auth using the command line SSH client as well as pushing and pulling source code over Git/SSH using SourceTree.