April 25, 2016

Fedora 23 (KDE): Using GPG + YubiKey4 + PCSCD

For those who have problems with integration of gpg and yubikey 4, this post is for you. Most problems come from idea, that gpg agent runs scdaemon, which prevents other processes to read yubikey usb device. Solution is to run pcscd and let only that handle all communication to yubikey. Now gpg commands like "gpg2 --card-status" can be run right after yubioath tool exited and there is no need to manually cleaning of scdaemon processes.

Here are configs, which are needed to run:

Modify file /etc/X11/xinit/xinitrc-common to contain last 2 lines:
$ tail /etc/X11/xinit/xinitrc-common 
    if [ "x$TMPDIR" != "x" ]; then
        SSH_AGENT="/usr/bin/ssh-agent /bin/env TMPDIR=$TMPDIR"

SSH_AGENT="/usr/bin/gpg-agent --daemon --enable-ssh-support --homedir $HOME/.gnupg"; export SSH_AGENT;
SSH_AUTH_SOCK=$HOME/.gnupg/S.gpg-agent.ssh; export SSH_AUTH_SOCK;

Make sure file $HOME/.gnupg/gpg.conf contains line use-agent:
$ tail -5  $HOME/.gnupg/gpg.conf 
keyid-format 0xlong


Create file .gnupg/scdaemon.conf (I have 2 readers in notebook):
$ cat $HOME/.gnupg/scdaemon.conf 
reader-port "Yubico Yubikey 4 OTP+U2F+CCID 00 00"
reader-port "Yubico Yubikey 4 OTP+U2F+CCID 01 00"
pcsc-driver /usr/lib64/
card-timeout 5

Create file .gnupg/scd-event and make it executable. This will trigger when yubikey is removed from computer.
$ cat $HOME/.gnupg/scd-event 

if [ "$state" = "NOCARD" ]; then
  pkill -9 scdaemon

Modify .gnupg/gpg-agent.conf to include ssh-support:
$ cat .gnupg/gpg-agent.conf
###+++--- GPGConf ---+++###
###+++--- GPGConf ---+++### Thu Mar 12 10:53:37 2015 CET
# GPGConf edited this configuration file.
# It will disable options before this marked block, but it will
# never change anything below these lines.
default-cache-ttl-ssh 1209600
default-cache-ttl 1209600
max-cache-ttl 1209600
pinentry-program /usr/bin/pinentry-qt

Now udev rules for local users access are defined in 2 files:
$ cat /etc/udev/rules.d/69-yubikey.rules 
ACTION!="add|change", GOTO="yubico_end"
ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0010|0110|0111|0114|0116|0401|0403|0405|0407|0410", \

$ cat /etc/udev/rules.d/70-u2f.rules 
ACTION!="add|change", GOTO="u2f_end"
# Yubico YubiKey
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0113|0114|0115|0116|0120|0402|0403|0406|0407|0410", TAG+="uaccess"
# Alcor Micro Corp. AU9540 Smartcard Reader
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="058f", ATTRS{idProduct}=="9540", TAG+="uaccess"
# Happlink (formerly Plug-Up) Security KEY
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2581", ATTRS{idProduct}=="f1d0", TAG+="uaccess"
#  Neowave Keydo and Keydo AES
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1e0d", ATTRS{idProduct}=="f1d0|f1ae", TAG+="uaccess"
# HyperSecu HyperFIDO
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0880", TAG+="uaccess"

Create file /etc/polkit-1/rules.d/99-smartcard.rules and substitute username with loginname of desired user:
# cat /etc/polkit-1/rules.d/99-smartcard.rules
polkit.addRule(function(action, subject) {
    if ( == "org.debian.pcsc-lite.access_pcsc" &&
        subject.user == "username") {
            return polkit.Result.YES;

polkit.addRule(function(action, subject) {
    if ( == "org.debian.pcsc-lite.access_card" &&
        action.lookup("reader") == 'Yubico Yubikey 4 OTP+U2F+CCID 00 00' &&
        subject.user == "username") {
            return polkit.Result.YES;    }

polkit.addRule(function(action, subject) {
    if ( == "org.debian.pcsc-lite.access_card" &&
        action.lookup("reader") == 'Yubico Yubikey 4 OTP+U2F+CCID 01 00' &&
        subject.user == "username") {
            return polkit.Result.YES;    }

Make sure environment variables are set correctly for local user (in .bashrc)
export GPG_SOCKET_FILE=$HOME/.gnupg/S.gpg-agent
export GPG_TTY=$(tty)
export SSH_AUTH_SOCK="$HOME/.gnupg/S.gpg-agent.ssh"

Enable pcscd:
systemctl enable pcscd.socket
systemctl enable pcscd.service

And reboot. Now you should have in KDE everything ready to run oathtool and gpg agent with yubikey 4 smartcard support. If there is error that yubikey is already in use, just reinsert it.