2016-03-17 GPG Agent and Emacs

I updated Gmail, Gnus and GPG on a Mac, on Emacs Wiki, with the information I discovered below.

Gmail, Gnus and GPG on a Mac

In my Gmail Gnus GPG Guide I don’t mention `gpg-agent` because I never managed to set it up correctly for OSX.

Gmail Gnus GPG Guide

Well, perhaps things will change. I followed the instructions on this blog post, I think, and it works on the command line. I can encrypt a text to myself, when I decrypt it, I’m asked for my passphrase, and when I decrypt it again, I’m not asked for my passphrase because the agent handles it.

instructions on this blog post

This requires my `gpg-agent.conf` file to contain the line `pinentry-program /usr/local/bin/pinentry` which is the equivalent to `pinentry-curses`.

It used to say `pinentry-program /usr/local/bin/pinentry-mac`, however!

If I use `pinentry-mac`:

alex@Megabombus:~$ gpg -d test.txt.gpg

You need a passphrase to unlock the secret key for
user: "Alex Schroeder <kensanata@keybase.io>"
8192-bit RSA key, ID 4529A45C, created 2015-03-01 (main key ID ACECFEAE)

gpg: problem with the agent: No pinentry
gpg: encrypted with 8192-bit RSA key, ID 4529A45C, created 2015-03-01
      "Alex Schroeder <kensanata@keybase.io>"
gpg: public key decryption failed: Operation cancelled
gpg: decryption failed: No secret key

If I use `pinentry-curses`:

alex@Megabombus:~$ echo RELOADAGENT | gpg-connect-agent
OK
alex@Megabombus:~$ gpg -d test.txt.gpg
   ┌───────────────────────────────────────────────────────────────────────┐
   │ Please enter the passphrase to unlock the secret key for the OpenPGP  │
   │ certificate:                                                          │
   │ "Alex Schroeder <kensanata@keybase.io>"                               │
   │ 8192-bit RSA key, ID 4529A45C,                                        │
   │ created 2015-03-01 (main key ID ACECFEAE).                            │
   │                                                                       │
   │                                                                       │
   │ Passphrase __________________________________________________________ │
   │                                                                       │
   │          <OK>                                         <Cancel>        │
   └───────────────────────────────────────────────────────────────────────┘

Within Emacs

Without the agent running, and with `pinentry-mac`, it would work from within Emacs (which is what I want to get working). When the agent is running, no matter what the `pinentry-program` line says, it won’t work.

This is what the `*Messages*` buffer says:

Decrypting /Users/alex/test.txt.gpg...done
epa-file--find-file-not-found-function: Opening input file: Decryption failed,

I’m guessing this is a pinentry problem. Not *exactly* the same string, though. So... Any ideas? What’s wrong? Should I be setting `GPG_TTY`? The problem appears to be that if I don’t use gpg-agent, Emacs using gpg knows how to call pinentry-mac. If I do use the gpg-agent, then the gpg-agent tries to call pinentry-mac and fails.

Currently the environment for my Emacs session has the following, as determined by running `printenv` in `*eshell*`:

GPG_TTY=not a tty
GPG_AGENT_INFO=/tmp/gpg-oqrtL2/S.gpg-agent:40161:1

That looks wrong... I’m surprised that GPG_TTY is set in the first place. I’m setting it in my `.bashrc` file! So starting Emacs uses a shell? I don’t know how Emacs does that.

alex@Megabombus:~$ ps -fx|grep emacs
  502 42011     1   0  7:34am ??         0:02.88 /usr/local/Cellar/emacs-mac/emacs-24.5-z-mac-5.15/Emacs.app/Contents/MacOS/Emacs

My Config

In `~/Library/LaunchAgents/org.gnupg.gpg-agent.plist`:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
   "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>org.gnupg.gpg-agent</string>
    <key>ProgramArguments</key>
    <array>
      <string>/Users/alex/bin/start-gpg-agent.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
  </dict>
</plist>

In `~/bin/startup-gpg-agent.sh`:

1. ${HOME}/.gpg-agent-info is the default filename
if test -f $HOME/.gpg-agent-info && \
	kill -0 `cut -d: -f 2 $HOME/.gpg-agent-info` 2>/dev/null; then
    GPG_AGENT_INFO=`cat $HOME/.gpg-agent-info`
    export GPG_AGENT_INFO
else
    eval `/usr/local/bin/gpg-agent --daemon --write-env-file`
fi

In `~/.bashrc`, which is also sourced from `~/.bash_profile`:

1. GPG
if [ -f "${HOME}/.gpg-agent-info" ]; then
    . "${HOME}/.gpg-agent-info"
    export GPG_AGENT_INFO
    export SSH_AUTH_SOCK
fi
GPG_TTY=$(tty)
export GPG_TTY

In `~/.gnupg/gnu-agent.conf`:

pinentry-program /usr/local/bin/pinentry-mac
enable-ssh-support

Result

OK, this is weird.

In a terminal, it works, if I provide `--pinentry-program=/usr/local/bin/pinentry-mac` as a startup parameter to `gpg-agent`.

In Emacs, it works, if I use `pinentry-program /usr/local/bin/pinentry-mac` in my `gpg-agent.conf` file.

One would think that the two affect the same thing, but not so. I have no idea why that is so. I’ll have to test this.

Log out and log back in. Nope, nothing works. So, at least I know that there is a way to fix this, even if I don’t know what it is!

gpg: problem with the agent: No pinentry

So here’s how I managed to “fix” it again, in a terminal:

1. use `ps aux | grep gpg` to determine the process id of `gpg-agent`

2. use `kill` to kill it

3. run `bin/start-gpg-agent.sh` again

4. run `source ~/.gpg-agent-info` to set the environment variables again

5. try `gpg -d test.txt.gpg` to decrypt my test file – and the GUI pinentry opens!

So. What changed? I have no idea.

Within Emacs, I used `setenv` to set the `GPG_AGENT_INFO` to the new value, and it worked: I could open my test file, got asked for my passphrase, killed the buffer, reopened it, and was no longer asked for a passphrase.

So now I’m going to revert the addition of `--pinentry-program` to the `start-gpg-agent.sh` script, and see whether simply killing and restarting it from a terminal also “fixes” it. And then we’ll start worrying about the difference between all this stuff.

OK, so restarting this Mac apparently “fixed” all the issues I was having.

​#Emacs ​#GPG ​#Cryptography

Comments

(Please contact me if you want to remove your comment.)

I recently stumbled over this somewhere: https://github.com/ecraven/pinentry-emacs

https://github.com/ecraven/pinentry-emacs

Works great for me (especilly when ssh’ing with X-forwarding) - might be worth trying as well.

– Adam 2016-03-18 20:08 UTC

Adam

---

Haha, “This is probably totally insecure, and your passphrase may be leaked! Use at your own risk!” Also, what happens when you’re in a terminal and use gpg – does it start Emacs, or the Emacs Client, and thus you need to be running Emacs somewhere?

– Alex Schroeder 2016-03-18 21:32 UTC

---

There is also an ELPA package called “pinentry”; as the note in the package description says, it works “with GnuPG (2.1.5+) and Pinentry (not yet released, possibly 0.9.5+)”. It works here.

– Sam 2016-03-19 10:21 UTC

---

Is that the same pinentry-emacs as https://bugs.gnupg.org/gnupg/issue2034 ? I see a pinentry-emacs is installed by pinentry 0.9.7 on my Arch box.

https://bugs.gnupg.org/gnupg/issue2034

I have the same question about what happens when if using that when *outside* emacs (would prefer having both possibilities).

– Kevin Unhammer 2016-04-25 07:28 UTC

---

pinentry.el works for me 😄 http://unix.stackexchange.com/questions/55638/can-emacs-use-gpg-agent-in-a-terminal-at-all/278875​#278875

http://unix.stackexchange.com/questions/55638/can-emacs-use-gpg-agent-in-a-terminal-at-all/278875​#278875

– Kevin Unhammer 2016-04-25 08:04 UTC

---

I could not get passphrase entry to work, so I installed MacGPG2 from https://gpgtools.org/ and now I have a graphical prompt on Mac OS X.

https://gpgtools.org/

– Anonymous 2016-10-25 02:05 UTC

---

Here are gotchas that can help others (already included in Alex’s instructions)

1. Uncomment use-agent in `~/.gnupg/gpg.conf`

2. Add enable-ssh-support to `~/.gnupg/gpg-agent.conf`

3. Change your start-script for `gpg-agent` to `gpg-agent --daemon --write-env-file` ¹ (this will create a `~/.gpg-agent-info` file)

4. Load this file in your emacs init to `setenv GPG_AGENT_INFO` ²

¹

²