Making my Yubikey work reasonably with my X screen locking

October 17, 2016

When I moved from unencrypted SSH keys to encrypted SSH keys held in a running ssh-agent process, I arranged things so that the keys would be removed when I locked my screen (which I do frequently) and then unlocked and added again when I unlocked my screen; I wrote this up as part of this entry. Soon after I started playing around with having SSH keys in my Yubikey, it became clear to me that I needed to do the same thing with the Yubikey's SSH keys. More specifically, I needed to automatically re-add the Yubikey's keys when I unlocked the screen, which means (automatically) providing the Yubikey's PIN code to ssh-add instead of being constantly prompted for it every time I unlocked my screen. Typing two passwords at screen unlock time is just a bit too irritating for me; inevitably it would discourage me from routinely using the Yubikey.

(Removing the Yubikey keys from ssh-agent happens automatically when I run 'ssh-add -D' as part of starting the screen locker, although I've added specifically removing the PKCS#11 SSH agent stuff as well. You actually want to do this because otherwise the PKCS#11 SSH agent stuff gets into a weird state where it's non-functional but loaded, so you can't just do 'ssh-add -s' to get it going again.)

As I sort of mentioned in passing in my entry on how I set up SSH keys on my Yubikey, the Yubikey's PIN code allows more or less full alphanumerics, so in theory I could just make the PIN code the same as my regular SSH key password and then use the obvious extension of the Perl script from this entry to also feed it to ssh-add when I re-enable PKCS#11 stuff. However, after thinking about it I decided that I wasn't entirely comfortable with that; too many tools for dealing with the Yubikey are just a little bit too casual with the PIN code for me to make it something as powerful and dangerous as my regular password.

(For example, a number of them want the PIN provided in plain text on the command line. I'm not doing that with my regular password.)

This left me with the problem of going from my regular password to the Yubikey PIN. The obvious answer is to encrypt a file with the PIN in it with my regular password, then decrypt it on the fly in order to feed it to ssh-add. After some searching I settled on doing this with ccrypt, which is packaged for Fedora and which has an especially convenient mode where you can feed it the key as the first line of input, with the encrypted file following immediately afterwards.

So now I have a little script that takes my regular password on standard input (fed from the Perl script I run via xlock's -pipepassCmd argument) and uses it to decrypt the PIN file and feed it to ssh-add. It looks like this:

# drop PKCS#11 stuff; required to re-add it
ssh-add -e /usr/lib64/ >/dev/null 2>&1
# give ssh-add no way to ask us for the passphrase
(sed 1q; cat $CRYPTLOC) | ccat -k - | \
   notty ssh-add -s /usr/lib64/

The one peculiar bit is notty, which is a little utility program to run another program without a controlling terminal. If you run ssh-add this way, it reads the PKCS#11 PIN from standard input, which is just what I want here. I need to use notty at all because the Perl script runs this script via (Perl) Expect, which means that it's running with a pty.

(There are alternate ways to arrange things here, but right now I prefer this approach.)

(See my first Yubikey entry for a discussion of when you need to remove and re-add the PKCS#11 SSH agent stuff. The short version is any time that you remove and reinsert the Yubikey, drop SSH keys with 'ssh-add -D' (as we're doing during screen locking), or run various commands to poke at the Yubikey directly.)

PS: I've come around to doing 'ssh-add -e' before almost any attempt to do 'ssh-add -s'. It's a hack and in an ideal world it wouldn't be necessary, but there's just too many situations where ssh-agent can wind up with PKCS#11 stuff loaded but non-functional and the best (and sometimes only) way to clean this up is to remove it and theoretically start from scratch again. Maybe someday all of this will be handled better. (Perhaps gpg-agent is better here.)

Written on 17 October 2016.
« Why we care about long uptimes
Writing in Python 3 has been a positive experience so far »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Oct 17 23:10:52 2016
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.