‹ back home

Using a Yubikey for both GPG and TOTP

2023-03-13 #gpg #notes #yubikey

I’ve written before on how I use a Yubikey for hardware-based GPG and 2FA on the web. I also use it for TOTP. That is, the Yubikey itself generates those common “authenticator codes” like many other Authenticator apps. But the secret seed is saved into hardware that does not support revealing it, instead of being handled by a regular app on a network-connected device.

A nasty issue I’ve been dealing with is that when I signed something using GPG, the key would no longer work for TOTP unless I killed the gpg-agent. And if I used the key for TOTP, it wouldn’t work for GPG until I killed pcscd.

For example, after having used gpg, trying to access the key for it TOTP functionality yields:

> ykman oath info
ERROR: Failed to connect to YubiKey.

And trying to use gpg after having used the key for TOTP resulted in gpg asking me to insert the key (even if it was right there).

The cause of the issue

pcscd is a daemon allowing userspace applications to communicate with smartcards (a Yubikey presents itself as a smartcard to the OS, so existing tools just work with it). Tools that generate TOTP codes via the Yubikey (e.g.: ykman) use pcscd to talk to the Yubikey itself.

gpg however, uses scdaemon to talk to the Yubikey, and scdaemon tries to use an “exclusive lock” on the key (this is because it caches data so wants to make sure no other process is using the key). This is a problem, because if it holds an exclusive lock, then it will work if and only if no other application are holding a lock.

To be honest, I don’t really get why any of these applications hold ANY lock on the card when it’s not being used.

The Solution

scdaemon needs to be configured to use only a shared lock. This can be done by editing the file $GNUPGHOME/scdaemon.conf and adding the line:

pcsc-shared

Note that, as the man page indicates, this has some caveats.

However, this was not enough in my case. This is because scdaemon can use its built-in support to talk to cards directly rather than via pcscd. This can be disabled by adding the follow extra directive to the same configuration file:

disable-ccid

For more notes on this, see the related issue in aports.

— § —