Enigmail and the YubiKey

TL/DR

If you can’t sign/decrypt with a YubiKey and Thunderbird/Enigmail you might want to add --pinentry-mode=ask to the “additional parameters for GnuPG” in the Enigmail configuration

The Story

After setting up all the cool Encryption stuff using a YubiKey I was so happy that everything worked.

And then I set up using the YubiKey for SSH as well as described in the documents I linked in the last blogpost. It took a reboot for everything to work out as I wanted it, but I was happy. Until I wanted to send a signed Email using Thunderbird/Enigmail.

What shall I say… It didn’t work any more. Marco asked me that on Twitter when I published the last post but at that time everything was behaving as it should. I guess the tweaking to get the SSH stuff running broke something.

But today I took some time and dug into it. And it turned out that actually not Thnderbird/Enigmail was misbehaving but the underlying GPG was the root cause of the issue.

Technical background

Enigmail doesn’t do the Encryption/signing themselves but delegates that task to GPG by calling some CLI-commands and handling the return values. You can find out which commands Enigmail runs by opening up the Error-Hadling Console. The command run for the actual signing part is this:

/usr/bin/gpg --charset utf-8 \
--display-charset utf-8 \
--no-auto-check-trustdb \
--batch \
--no-tty \
--verbose \
--status-fd 2 \
--log-file [/path/to/a/logfile] \
-a \
-t \
--encrypt \
--sign \
--trust-model always \
--encrypt-to [key to encrypt to] \
-r [key to sign with] \
-u [key to encrypt to]

I tried to run that in my CLI like this:

$ echo "test" | /usr/bin/gpg --charset utf-8 \
--display-charset utf-8 \
--no-auto-check-trustdb \
--batch \
--no-tty \
--verbose \
--status-fd 2 \
--log-file [/path/to/a/logfile] \
-a \
-t \
--encrypt \
--sign \
--trust-model always \
--encrypt-to [key to encrypt to] \
-r [key to sign with] \
-u [key to encrypt to]

The result was the same as when trying to send a signed email via Thunderbird. No Prompt for the PIN of my YubiKey and an error.

Then I tried the whole thing a bit simpler and ran this on the CLI:

$ echo "test" | /usr/bin/gpg -s

And what the heck: There was the PIN-Entry. But wait. It was on the CLI. And I can understand that that doesn’t work when GPG is run in batch-mode. So After a bit of tweaking and checking my (least) favourite search engine (Why google finds better results than any other search engine I’ve so far tried is a different post) I found out about loopback-pinentry and the pinentry-mode.

To make a long story short: I now have the following entries in my gpg-agent.conf-file:

enable-ssh-support
pinentry-program /usr/bin/pinentry-gtk-2
default-cache-ttl 60
max-cache-ttl 120
extra-socket /run/user/1000/gnupg/S.gpg-agent.extra
browser-socket /run/user/1000/gnupg/S.gpg-agent.browser
no-allow-loopback-pinentry
ttytype xterm-256color
no-allow-external-cache

This sets the default pinentry-program to the gtk2. So now when I run echo "test" | gpg -s" I get a window prompting me for my YubiKey-PIN as I expected it.

The Solution

But the command from Enigmail sadly still failed. So there still seemed to be an issue with the pinentry-mode. So I searched for that and after a while I stumbled over an issue in the GPG-Bugtracker that showed me a different pinentry-mode. So I tried the GPG-Command on the CLI with the additional setting of --pinentry-mode=ask. And what shall I say. It worked immediately. I got a PIN-Entry window, could enter the PIN and the message was signed.

So I needed to add that option to the GPG-Command that Enigmail calls. So I went to “Enigmail-Settings” => “Extended” and added --pinentry-mode=ask to the “additional Parameters for GnuPG”, saved and tried to send a signed email. And voila! Here popes the PIN-Entry window up!