Gpg-agent and yubikey

,

Hey all, I’m on Fedora 38, upgraded from 37.

I have a Yubikey 5 NFC which I use to authenticate myself on github.

On Fedora 38 I have trouble, but on Fedora 37 I did it like so:

  • My ~/.ssh/config contains
Host github.com
    IdentitiesOnly yes
    IdentityFile ~/.ssh/id_rsa_yubikey.pub
  • My ~/.ssh/id_rsa_yubikey.pub contains the output of ssh-add -L.

When I use ssh -T git@github.com to test my ssh connection, I get the window popup that asks me to insert my hardware key. However, even after I insert it and press OK, the prompt simply repeats itself, as if it cannot see the key.

I tried stopping the pcscd service in case there is an issue and I restarted scdaemon and gpg-agent with gpgconf --kill scdaemon and gpgconf --kill gpg-agent, but nothing has worked so far.

Does gpg --card-status see your YubiKey?

Also, you might need to make sure your SSH_AUTH_SOCK environment variable is pointing to your running gpg-agent (e.g. export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"). See the gpg-agent man page for an example snippet that you might need to add to your bashrc file.

You only want one of the keys that ssh-add -L lists in your ~/.ssh/id_rsa_yubikey.pub file. On my system, the rsa public key that ssh-add -L shows and that comes from my gpg-agent has a comment at the end that starts with cardno: followed by my YubiKey’s serial number.

Hello Gregory,

Thanks for the quick response. I’ve read some of your articles on the Fedora magazine!

The command does not see my YubiKey. The SSH_AUTH_SOCK variable is set in my .bashrc as

# See the info page of gnupg, `info "(gnupg)Agent Examples"`
unset SSH_AGENT_PID
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
  export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi

The ssh-add -L command lists a single key; shows a (none) but isn’t that just a comment?

Is the gpg agent running? What is the output of ps -f -C gpg-agent?

FWIW, I have the following in my ~/.bashrc file to make sure the agent is running (after setting the environment variables).

if [[ -t 1 ]]; then
	gpg-connect-agent updatestartuptty /bye &> /dev/null
fi

As far as I can tell it is running. The output is

nchatz      7546    2543  0 03:12 ?        00:00:00 gpg-agent --homedir /home/nchatz/.gnupg --use-standard-socket --daemon

It is odd that gpg --card-status doesn’t see the yubikey if gpg-agent is running. Maybe gpg --debug-level guru --card-status would give some clues?

Do you have export GPG_TTY="$(tty)" in your .bashrc? If not, that might help.

I have that export in my .bashrc. The debug output mentions gpg: DBG: chan_3 <- ERR 100696144 No such device <SCD>. Is it related? The debug output is:

gpg: enabled debug flags: packet mpi crypto filter iobuf memory cache memstat trust hashing ipc clock lookup extprog
gpg: enabled compatibility flags:
gpg: DBG: [no clock] start
gpg: DBG: chan_3 <- OK Pleased to meet you, process 18825
gpg: DBG: connection to the gpg-agent established
gpg: DBG: chan_3 -> RESET
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION ttyname=/dev/pts/0
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION ttytype=xterm-256color
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION display=:0
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION xauthority=/run/user/1000/.mutter-Xwaylandauth.5GFO51
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION putenv=XMODIFIERS=@im=ibus
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION putenv=WAYLAND_DISPLAY=wayland-0
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION putenv=XDG_SESSION_TYPE=wayland
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION putenv=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION putenv=QT_IM_MODULE=ibus
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION lc-ctype=en_US.UTF-8
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION lc-messages=en_US.UTF-8
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> GETINFO version
gpg: DBG: chan_3 <- D 2.4.0
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION allow-pinentry-notify
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION agent-awareness=2.1.0
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> SCD GETINFO version
gpg: DBG: chan_3 <- D 2.4.0
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> SCD SERIALNO
gpg: DBG: chan_3 <- ERR 100696144 No such device <SCD>
gpg: selecting card failed: No such device
gpg: OpenPGP card not available: No such device
gpg: DBG: [no clock] stop
gpg: keydb: handles=0 locks=0 parse=0 get=0
gpg:        build=0 update=0 insert=0 delete=0
gpg:        reset=0 found=0 not=0 cache=0 not=0
gpg: kid_not_found_cache: count=0 peak=0 flushes=0
gpg: sig_cache: total=0 cached=0 good=0 bad=0
gpg: objcache: keys=0/0/0 chains=0,0..0 buckets=0/0 attic=0
gpg: objcache: uids=0/0/0 chains=0,0..0 buckets=0/0
gpg: random usage: poolsize=600 mixed=0 polls=0/0 added=0/0
              outmix=0 getlvl1=0/0 getlvl2=0/0
gpg: rndjent stat: collector=0x0000000000000000 calls=0 bytes=0
gpg: secmem usage: 0/65536 bytes in 0 blocks

Does the device show up in dmesg and have access nodes under /dev?

$ dmesg | grep Yubico
[  911.819397] usb 1-2.4: Manufacturer: Yubico
[  911.863297] input: Yubico YubiKey OTP+FIDO+CCID as /devices/pci0000:00/0000:00:10.0/usb1/1-2/1-2.4/1-2.4:1.0/0003:1050:0407.0006/input/input25
[  911.915537] hid-generic 0003:1050:0407.0006: input,hidraw3: USB HID v1.10 Keyboard [Yubico YubiKey OTP+FIDO+CCID] on usb-0000:00:10.0-2.4/input0
[  911.917978] hid-generic 0003:1050:0407.0007: hiddev97,hidraw4: USB HID v1.10 Device [Yubico YubiKey OTP+FIDO+CCID] on usb-0000:00:10.0-2.4/input1
$ ls -lZ /dev/hidraw*
crw-rw----+ 1 root root system_u:object_r:usb_device_t:s0 241, 0 Jun  3 18:04 /dev/hidraw0
crw-rw----+ 1 root root system_u:object_r:usb_device_t:s0 241, 1 Jun  3 18:04 /dev/hidraw1
crw-rw----+ 1 root root system_u:object_r:usb_device_t:s0 241, 2 Jun  3 18:04 /dev/hidraw2
crw-rw----+ 1 root root system_u:object_r:usb_device_t:s0 241, 3 Jun  3 18:19 /dev/hidraw3
crw-rw----+ 1 root root system_u:object_r:usb_device_t:s0 241, 4 Jun  3 18:19 /dev/hidraw4

Edit: It looks like ACLs are being used to grant access on those device nodes (indicated by the + in the above ls output). You might also verify that your account is listed as having access to whatever device nodes are mapped to your YubiKey.

$ getfacl /dev/hidraw{3,4}
getfacl: Removing leading '/' from absolute path names
# file: dev/hidraw3
# owner: root
# group: root
user::rw-
user:gregory:rw-
group::---
mask::rw-
other::---

# file: dev/hidraw4
# owner: root
# group: root
user::rw-
user:gregory:rw-
group::---
mask::rw-
other::---

Yes it does show up and it seems to have the right ACLs. I can use the YubiKey manager (from flatpak) fine and Firefox also recognizes the YubiKey.

It seems that something is blocking gpg-agent from accessing the yubikey. Maybe SELinux?

Edit: Also, try running gpg-connect-agent updatestartuptty /bye right before running gpg --card-status to be sure that the agent is using the current tty.

You might try running gpg --card-status without other programs that access the YubiKey running. Sometimes one program can hold a “lock” on a file that prevents other programs from accessing it at the same time.

Also, if you are trying to access the YubiKey from within a container, there may be container-level sandboxing rules that are blocking access to the device.

I found an older bug report that suggests rngd and/or gsd-smartcard can cause this error.

https://bugzilla.redhat.com/show_bug.cgi?id=1893131 (comment #22 looks very much like your situation)

You might try running lsof /dev/hidraw{3,4} (substituting the numbers with those from your dmesg output) to see if any running daemons are holding locks on the YubiKey.

I tried your SELinux suggestion but reading the AVC logs instead of disabling enforcement with ausearch -m avc --start recent, however there was nothing related in the output. I’ve tried disabling the PCSC daemon (and then YubiKey Authenticator doesn’t work) but still nothing.

I’m not trying to access the YubiKey from a container, in fact it works from the YubiKey Auth flatpak and from native Firefox, but not from native gpg.

There are no locks reported on the YubiKeys with lsof.

I will go through the bugzilla thread and try their suggestions and will report back with results.

I fixed this problem with

echo disable-ccid >> ~/.gnupg/scdaemon.conf

This seems to be an scdaemon issue with Fedora 38, but I don’t know if other users are experiencing it. Thank you for the help @glb !

1 Like

disable-ccid doesn’t work for me.
gpg --card-status works but after a couple of minutes I’ve got:
gpg: OpenPGP card not available: Card error

It also stop working when I close and open Firefox again.
Is there any working-for-all solution?

There is a non-trivial workaround mentioned in comments #24 and #25 of the aforementioned bugzilla report.

I don’t know if it would make any difference to the problem you are experiencing, but I use a different variable to point ssh at my gpg-agent. I haven’t experienced the problem you mention. But my setup is quite different in many other ways. (I mostly use the Chrome browser and the Sway window manager.) But I do use both gpg-agent and ssh-agent at the same time with my YubiKey. To do so, I set SSH_AUTH_SOCK_GPG instead of SSH_AUTH_SOCK in my bash startup scripts.

export GPG_TTY="$(tty)"
if [[ -z $SSH_AUTH_SOCK_GPG ]]; then
	export SSH_AUTH_SOCK_GPG="$(gpgconf --list-dirs agent-ssh-socket)"
fi
gpg-connect-agent updatestartuptty /bye &> /dev/null

Then, for the servers that I want to use my gpg rsa key, I put the following in my ~/.ssh/config.

Host one.example.edu two.example.edu three.example.edu
	IdentitiesOnly yes
	IdentityAgent $SSH_AUTH_SOCK_GPG
	IdentityFile ~/.ssh/my-gpg.pub
	User meusername

Uninstalling opensc is not a solution - I would like to use PIV support of my Yubikey in Firefox and Thunderbird.
I’ve tried to install scute, but couldn’t to configure it to work. I’ll try it again when I get some spare time.