Making my Yubikey work reasonably with my X screen locking
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 '
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
-pipepassCmd argument) and uses it to decrypt the PIN file
and feed it to
ssh-add. It looks like this:
CRYPTLOC=/u/cks/lib/crypt/... # drop PKCS#11 stuff; required to re-add it ssh-add -e /usr/lib64/opensc-pkcs11.so >/dev/null 2>&1 # give ssh-add no way to ask us for the passphrase unset DISPLAY; unset SSH_ASKPASS (sed 1q; cat $CRYPTLOC) | ccat -k - | \ notty ssh-add -s /usr/lib64/opensc-pkcs11.so
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.)