1

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 1

1

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
  • Given that this does not depend on gpg-agent and I am not actually forced to use PGP, this sounds like a good alternative. Also, didn't know that PKCS#11 works with ECC. Forwarding to WSL2 seems to be possible, too. Thanks, will return to this answer once I tried it. Commented Mar 12, 2021 at 15:38
  • The API does support ECC, it's just that many smartcards don't. You can use pkcs11-tool --module <path> --list-mechanisms to see what is supported by a specific device. (Note that for some Yubikey models, the OpenPGP applet and the PIV applet can actually differ in algorithm support even though the hardware is the same.) Commented Mar 12, 2021 at 15:57
  • One more thing to keep in mind: PIV has designated key slots with different PIN policies. Some slots require a PIN for every single operation (9c), others only once per session (9a), others don't require a PIN at all (9e). In the NEO they are hardcoded; in the 5 they are customizable. I'll eventually add this to the post. Commented Mar 12, 2021 at 16:09
  • After looking into the gpg-agent source code I feel this is the most viable alternative solution, even if it might be possible to have gpg-agent forward to a local ssh-agent with some hackery. PIV is somewhat clunky with the PKCS setup, but works. U2F looks like a simple alternative, but many servers (OpenSSH <8.2) and tools like KeePassXC don't yet support for that. Still need to check whether an Android SSH client can use PIV and U2F, guess there might be no access to the device. Commented Mar 17, 2021 at 0:47
  • My phone has its own software-based key that has minimal access, which I use to connect to a server which has a TPM holding a second copy of the "full access" key (PIN-protected). Commented Mar 17, 2021 at 8:53

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.