15

I have been using gpg for encryption for a while. Someone suggested that I should use gpg2 instead. When I went to use gpg2, I could do almost nothing; it would complain that access to private keys was required, but I could not seem to get it to use the private keys without gpg-agent running.

It turns out that I intentionally disabled gpg-agent (by using chmod -x /usr/bin/gpg-agent); this caused gpg2 to have very limited functionality and complain to stderr.

The reasons I disabled gpg-agent was following a chain of events.

First, I would SSH into a remote machine and "an agent" would open a popup asking for me to unlock my SSH keys. I did not like this because:

  • A pop-up on my screen interrupts my workflow
  • A pop-up on my screen is unlikely to be noticed, so it would appear instead that the connection is stalling instead of querying to unlock an encryption key
  • The agent appeared to cache my password when I absolutely do not want my password cached (much like sudo's annoying use of password caching, I can disable that in its config); I will always want to enter the passphrase for my encryption keys every time they are used for whatever program is using them.
  • The pop-up appeared to be owned by a separate process, while I want the specific process using the key to query for the passphrase (even if it's a library that does the actual querying); since I spend most of my activities using command-line tools, that means a GUI application isn't ideal because not everything I do will have access to X11
  • Automatically starting a separate process in the background removes the concept of "one command, one process", especially if that backgrounded process then lingers after the original command has exited

It turned out to be GNOME's key agent and that I could not uninstall the agent without uninstalling GNOME. So I simply disabled it by chmod -x /usr/bin/gnome-keyring*. I then found that SSH would fall back to another agent so I disabled that too using the same method chmod -x /usr/bin/ssh-agent*

When I started using gpg, I found it had a similar agent, the same one I am asking about. I disabled it immediately for the same reasons; I want software to always ask me for passphrases in order to use a private key. I do not want the passphrase to be cached for any reason whatsoever.

So with gpg2 appearing to require gpg-agent, I would like to ask:

  • Am I being overly paranoid about the use of passphrase caching? I would be curious to see or be pointed to a discussion of it.
  • Is there a best practice that enables a better way to avoid even accidentally enabling the use of a cached passphrase?
  • Is there a way to use gpg2 without gpg-agent ever running?
  • Given that agents are daemons which are expected to be able to answer queries, what prevents another user or service running on the local machine from being able to access my cached or stored credentials?
inetknght
  • 4,300
  • 1
  • 26
  • 52
  • 4
    Just want to point out that I emphatically agree with the sentiments here. This is the reason why I still continue to use and install only `gpg` instead of `gpg2` where I can. – mtraceur Dec 15 '17 at 09:36
  • 1
    Besides the possibility of a rouge processes accessing the socket, there is possibility of installed tools monitoring everything that goes over d-bus. d-bus is used to enable socket communication. When I installed Ubuntu 16.04, I found a lot information being stored automatically in a database file about what applications and files were being used, and also another database file which seemed to be storing information about what went over the dbus. Of course I disabled them all. – Craig Hicks Aug 21 '18 at 00:08

2 Answers2

8

Am I being overly paranoid about the use of passphrase caching? I would be curious to see or be pointed to a discussion of it.

Your concerns are certainly valid IMO. The good news is that there are ways to customize gpg-agent behaviour to suit your needs. For example, use a terminal-based passphrase prompt (PIN entry) instead of a GUI prompt and do not cache passphrases.

Is there a best practice that enables a better way to avoid even accidentally enabling the use of a cached passphrase?

A quick solution, likely not a best practice, is to customize your ~/.gnupg/gpg-agent.conf with the following options:

# Expire cached PINs (passphrases) after zero seconds
default-cache-ttl 0
max-cache-ttl 0

# If you use your GPG keys for SSH auth...
default-cache-ttl-ssh 0
max-cache-ttl-ssh 0
enable-ssh-support

# Use TTY-based PIN entry program (I see pinentry, 
# pinentry-curses, pinentry-gnome3, pinentry-tty and 
# pinentry-x11 on my system)
pinentry-program /usr/bin/pinentry-tty

I found the following guides on GPG key best practices (more of a general guide around key management, not exactly what you're asking) fairly informative and easy to follow:

Is there a way to use gpg2 without gpg-agent ever running?

Not with gpg 2.x as far as I am aware of. The man page states the following:

   --use-agent
   --no-use-agent
          This is dummy option. gpg always requires the agent.

I have gpg 2.1.15.

Given that agents are daemons which are expected to be able to answer queries, what prevents another user or service running on the local machine from being able to access my cached or stored credentials?

Good question... By default, gpg-agent uses a socket, so technically any process running as your user could in theory hijack your keys. Don't quote me on this, though. Here's an overview of how the gpg-agent works that will hopefully get you started on finding out the real answer: https://unix.stackexchange.com/questions/188668/how-does-gpg-agent-work

  • 1
    I have gpg2 provided by Ubuntu 16.04 LTS as 2.1.11; I have already set all options except the pinentry program. It seems that `gpg-agent` _does not respect these options_. Setting the pinentry program to `/usr/bin/pinentry-tty` seems to invoke the pinentry program on the daemon's terminal (or else _fail_ to use agent if the agent's daemon doesn't have an attached terminal) and it nukes the terminal's ability to be interacted with (even to enter the PIN it's asking for). This whole process seems really clunky and feels as if it's not designed well. – inetknght Nov 28 '17 at 15:54
  • ...after writing that comment, `pinentry-tty` segfaulted which certainly doesn't help foster feelings of it being a good program – inetknght Nov 28 '17 at 15:56
  • One thing I forgot to mention is that you will need to restart gpg-agent after editing its config file. You can do it using the usual kill method, or use this command to do it nicely: gpg-connect-agent reloadagent /bye – Rouben Tchakhmakhtchian Nov 28 '17 at 16:10
  • @inetknght I hear you, I’m not a big fan of the new gpg architecture myself. I prefer the single binary approach to having multiple executables that do specialized things (for example key server/directory manager to get keys from keyservers), gpg-agent, etc all talking to gpg vs. just having a capable gpg binary. – Rouben Tchakhmakhtchian Nov 28 '17 at 16:14
  • With regards to TTY woes, the comments in this question may prove useful. You can either use X forwarding with SSH or try and control TTY ownership if invoking gpg with su or sudo... https://superuser.com/questions/520980/how-to-force-gpg-to-use-console-mode-pinentry-to-prompt-for-passwords How are you invoking gpg exactly to cause the TTY ownership issue? – Rouben Tchakhmakhtchian Nov 28 '17 at 16:22
  • I did `killall -9 gpg-agent` and restarted it. It still caches my PIN even after a reboot. – inetknght Nov 28 '17 at 19:55
  • Invoking gpg? All I do is call `ssh `. OpenSSH client then queries its agent (which is `gpg-agent`, as pointed by environment variable `SSH_AUTH_SOCK=${HOME}/.gnupg/S.gpg-agent.ssh` in my `.bashrc` as described in `man gpg-agent`). GPG agent then notices I have a Yubikey (GPG card) authentication token and wants to present that; this is when the pinentry is invoked. Previously, an X11 window would pop up. With `pinentry-tty`, the terminal I had started the gpg-agent daemon on is queried (which isn't the same terminal as the one I'm trying to use SSH with). – inetknght Nov 28 '17 at 19:56
  • 1
    Thanks for the overview. After some digging, I found an answer, but it’s a rather clunky one: https://unix.stackexchange.com/questions/280879/how-to-get-pinentry-curses-to-start-on-the-correct-tty – Rouben Tchakhmakhtchian Dec 02 '17 at 18:07
  • @RoubenTchakhmakhtchian gpg-agent will never give out your keys to any process. It simply performs operation with the use of cached key, e.g. signing. So some nasty process can sign something on your behalf (theoretically), but will not get your keys. – Cromax Oct 03 '20 at 21:46
2

According to https://wiki.archlinux.org/index.php/GnuPG#Unattended_passphrase in order to provide password directly to gpg - without gpg-agent running - you need to run with following options:

gpg --passphrase-fd 0 --pinentry-mode loopback ...

You need to provide password in console right after running this command. No password prompt will be visible during typing, but you will see typed password.

To hide password while typing you can wrap command in stty:

stty -echo ; gpg ... ; stty echo

I tested this with GnuPG v. 2.2.4: killed gpg-agent, shredded /usr/bin/gpg-agent, then run as described above. Worked well.

  • 1
    Using GNuPG 2.2.7 and using `--passphrase-fd 0 --pinentry-mode loopback` doesn't work for me: `Password: gpg: failed to start agent '/usr/local/bin/gpg-agent': No such file or directory // gpg: can't connect to the agent: No such file or directory // gpg: problem with the agent: No agent running` – Craig Hicks Aug 20 '18 at 17:30
  • 1
    The documentation you mentioned (Unattended passphrase) does say **"Restart the gpg-agent process if it is running to let the change take effect. "** . This seems to imply that `gpg-agent` is still serving as the receptor of input (via console instead on GUI) and that it will be passed via the socket. How does one feel about the `zeitgeist` of that? – Craig Hicks Aug 20 '18 at 17:58
  • @CraigHicks As I wrote: I shredded gpg-agent executable and removed it. It was impossible for gpg-agent to run after that, so it did not serve as an input receptor. – cryptogopher Sep 15 '18 at 19:38