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-agentwhen 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@myhostssh-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.)
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 12345678Generate 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.pubIn case you don't have the newer
ykman, you can use the olderyubico-piv-toolor even various generic PKCS#11 tools (e.g. OpenSCpkcs11-toolor GnuTLSp11tool):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.crtExport the public key in authorized_keys format:
ssh-keygen -D opensc-pkcs11.so > Yubikey.pubUse the
ssh -Ioption or thePKCS11Providersetting 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