Using an OpenPGP card/Yubikey with SSH authentication? Don’t forget about sshcontrol!

Here’s yet another thing that hit me at work today, and getting the answer involved annoying searching & testing, so here it is for you!

I use a Debian jessie workstation, and my SSH key lives on a Yubikey.  We don’t really use pubkey-based authentication in my area (we use Kerberos), so the first time I needed to do a pubkey-authenticated SSH connection was to clone one of my Github repositories.  When doing the clone, I got the mysterious message “Agent admitted failure to sign”.  GitHub talks about this error, but their article only talks about locally-stored keys (like id_rsa keys).  My private key lives on the Yubikey, so their article didn’t really work for me.

Doing some investigation, I could see that my SSH client was trying to authenticate, and it did see my Yubikey, but still the authentication was failing.  If you have this problem, there are two important things to check:

  1. Your GPG Agent must be running with SSH support.
  2. Your authentication key’s keygrip needs to be loaded in the .gnupg/sshcontrol file.

My problem was actually #2, but #1 is important to mention!

SSH Support in GPG Agent

The GPG Agent is able to act as an SSH Agent, speaking the ssh-agent protocol, as long as it has been told to do so.  In order for this to work, you need to specify –enable-ssh-support in the gpg-agent command line, or add “enable-ssh-support” in ~/.gnupg/gpg-agent.conf.

To confirm this, check your gpg-agent, and check for the appropriate environment variables:

blargh:~> env | grep SSH
SSH_AGENT_PID=7631
SSH_AUTH_SOCK=/tmp/gpg-VRUFdK/S.gpg-agent.ssh
blargh:~> ps xaw | grep gpg-agent
7631 ?        Ss     0:00 gpg-agent -c --daemon --enable-ssh-support
9425 pts/6    S+     0:00 grep gpg-agent

SSH_AGENT_PID contains the process ID of the ssh-agent, which is actually gpg-agent.  Also, SSH_AUTH_SOCK points to a special socket that gpg-agent creates, meant for connections speaking the ssh-agent protocol.

If SSH_AGENT_PID is pointing to a different process, you may have ssh-agent running somewhere else.  You should find out what is running ssh-agent, and stop it.  gpg-agent is able to manage locally-stored keys (like id_rsa), so I don’t think there’s a need to run ssh-agent, as long as you are running gpg-agent with SSH support.

If SSH_AGENT_PID isn’t specified at all, or you just added “enable-ssh-support” to ~/.gnupg/gpg-agent.conf, then you’ll need to restart gpg-agent.  In many cases, it’s easier to log out and log back in, so that everything picks up the new gpg-agent.

The sshcontrol File

This is what affected me.

The file at path ~/.gnupg/sshcontrol contains a list of “keygrips” for SSH that gpg-agent will use for ssh-agent authentication.  Even if gpg-agent is configured and can see your key, it will not work unless it’s listed in the sshcontrol file!  For local keys, running ssh-add will automatically add them to the sshcontrol file, but that doesn’t work for keys that live on an OpenPGP card.

I had gpg-agent running with SSH support, but gpg-agent does not automatically add keys that are already on an OpenPGP card, so it’s up to you.  What you need to do is…

  1. Extract the keygrip.
  2. Add the keygrip to the sshcontrol file.
  3. Restart gpg-agent.

Extracking the keygrip is pretty easy to do, using this string of commands:

blargh:~> echo 'scd learn --force' | gpg-connect-agent | grep KEYPAIRINFO
S KEYPAIRINFO 6E6D1675B29724F4D4A2250EDE5A0634B4E06884 OPENPGP.1
S KEYPAIRINFO 83D4B4FA304DC7F74FD930B052D1694C0B0CEBB0 OPENPGP.2
S KEYPAIRINFO E1846F4F5B1D6ABF537BC738CC3E840106457F13 OPENPGP.3

Each line of output contains the keygrip for one of the three keys on your OpenPGP card: The encryption key, the signing key, and the authentication key (which is the one we want).  The third line, for “OPENPGP.3”, contains the keygrip for the authentication key.

To update the sshcontrol file, simply add the keygrip to the file, on its own line.  So, in my case I would add the following line to ~/.gnupg/sshcontrol:

E1846F4F5B1D6ABF537BC738CC3E840106457F13

After you update the sshcontrol file, you need to restart gpg-agent.  Again, the safest way of doing that is to log out and log back in, so that everything picks up the new gpg-agent environment variables.

One thought on “Using an OpenPGP card/Yubikey with SSH authentication? Don’t forget about sshcontrol!

  1. Thank you thank you thank you thank you thank you thank you!!!!!!

    Many days spent trying to track this down.

    Just so others know. I’m working on Windows 10 with a YubiKey 4 and NEO. I was able to use the smartcard-agent replacement for pageant but couldn’t get the “native” support for putty in GPG4Win to work. I put gpg-agent into debug mode. If you don’t know what the smartcard-agent replace for pageant is don’t worry about it.

    gpg-agent –vv –daemon –enable-putty-support –debug-level guru

    and wouldn’t see anything happen when I attempted my putty connection. I wrongly assumed the gpg-agent wasn’t being contacted at all but I was wrong. I guess “guru” mode doesn’t show everything.

    With the debug gpg-agent still running I also tried to start the pageant service and received a message that it was already running. This was my first clue that gpg-agent was in fact providing the pageant service.

    Found this article and BAM! I’m in!

    powershell command I used
    gpg-connect-agent
    scd learn –force

    *I’m sure a powershell guru can provide a better command.

    oh! One more thing I found. Make sure if you have the x86 version of GPG4Win running that you also use the x86 putty. At least that was my experience at this point but I could be wrong. I’m overwhelmed with excitement right now.

    Thanks again for sharing this post

Leave a Reply to TreborTech Cancel reply

Your email address will not be published. Required fields are marked *