SSH authentication using gpg-agent and another source for keys?

tl;dr: Is there a way to either disable the persistent import functionality of gpg-agent or work around that to allow using different sources for SSH keys?

Situation

I use GnuPG 2 keys (on a YubiKey) for SSH authentication through gpg-agent's enable-ssh-support. This works fine.

I do have other keys available (filesystem and KeePassXC). When using ssh-add or KeePassXC to add those, they are imported by gpg-agent and stored in ~/.gnupg/private-keys-v1.d/. I need to provide an additional password for encrypting those.

The problem

This works as advertised, but defeats the purpose of having keys stored elsewhere:

  • I want KeePassXC to temporarily add keys to the current ssh-agent when it unlocks the password database. The keys shouldn't be permanently available afterwards.
  • Similar for ssh-adding key files from the shell: I do not want to import and persist those while having to provide even more passwords.

How do I avoid the import while allowing all sources of keys to be used? One idea that I was having was to set up multiple agents on the same machine, possibly gpg-agent forwarding to a local ssh-agent, but this sounds like it may be overly complicated.

A similar problem is part of this KeePassXC issue, but no solution was suggested.

1 Answer

Third option: Instead of using the Yubikey via gpg-agent, use its PIV smartcard support via PKCS#11. This is natively supported by OpenSSH via PKCS11Provider:

ssh -I opensc-pkcs11.so root@myhost

ssh-agent can be made aware of PKCS#11 keys as well:

ssh-add -s opensc-pkcs11.so

(Yubico also provides its own Yubikey-specific libykcs11.so module as part of yubico-piv-tool, but as the latter is now deprecated, I would assume that libykcs11.so is also deprecated and that you should just use OpenSC's generic PIV support. In practice the two modules are interchangeable and will recognize each other's objects without any problems.)

Note that Yubikey's OpenPGP and PIV applets are completely separate and you cannot move a key between them, so if it's a hardware-generated keypair you'll unfortunately need to create a new one using ykman piv. (Yubikey allows you to import software-generated keys though.)

  1. Set a PIN (and a PUK for unblocking a forgotten PIN). Both must be alphanumeric, and must be 6–8 characters long:

    ykman piv change-pin -P 123456
    ykman piv change-puk -p 12345678
  2. Generate a key, together with a self-signed certificate (which SSH won't care about):

    ykman piv info
    ykman piv generate-key -a ECCP256 9a /tmp/9a.pub
    ykman piv generate-certificate 9a /tmp/9a.pub -s "Thomas" -d 3650
    rm /tmp/9a.pub

    In case you don't have the newer ykman, you can use the older yubico-piv-tool or even various generic PKCS#11 tools (e.g. OpenSC pkcs11-tool or GnuTLS p11tool):

    yubico-piv-tool -a change-pin -P 123456
    yubico-piv-tool -a change-puk -P 12345678
    yubico-piv-tool -a status
    yubico-piv-tool -a generate -A ECCP256 -s 9a -o /tmp/9a.pub
    yubico-piv-tool -a verify-pin -a selfsign-certificate \ -s 9a -S "/CN=Thomas" -i /tmp/9a.pub -o /tmp/9a.crt
    yubico-piv-tool -a import-certificate -s 9a -i /tmp/9a.crt
  3. Export the public key in authorized_keys format:

    ssh-keygen -D opensc-pkcs11.so > Yubikey.pub
  4. Use the ssh -I option or the PKCS11Provider setting when connecting. (You will be prompted for the smartcard PIN every time – set up SSH connection multiplexing if needed to reduce this.)

This approach has other advantages: it is very easy to use on Windows as well, due to Windows already having a driver for PIV smartcards (e.g. through PuTTY-CAC or several other projects which bridge CAPI/CNG key storage to SSH clients).

5

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like