Page MenuHome GnuPG

loopback pinentry mode asks passphrase twice on symmetric encryption
Closed, ResolvedPublic

Description

With --pinentry-mode=loopback GnuPG 2.1 asks passphrase
twice on symmetric encryption, while GnuPG 1.x does that only once (look
at the GET_HIDDEN lines below). Though I suppose the second GET_HIDDEN is a
confirmation, it is useless for clients since they already know if confirmation
is needed, and incompatible with the code working with GnuPG 1.x.

$ gpg2 --command-fd=1 --status-fd=1 --pinentry-mode=loopback --symmetric -o

/dev/null < /dev/null

  gpg: NOTE: THIS IS A DEVELOPMENT VERSION!
  gpg: It is only intended for test purposes and should NOT be
  gpg: used in a production environment or with production keys!
  [GNUPG:] NEED_PASSPHRASE_SYM 7 3 2
  [GNUPG:] GET_HIDDEN passphrase.enter
  test
  [GNUPG:] GOT_IT
  [GNUPG:] GET_HIDDEN passphrase.enter
  test
  [GNUPG:] GOT_IT
  [GNUPG:] BEGIN_ENCRYPTION 2 7
  [GNUPG:] END_ENCRYPTION

  $ gpg --command-fd=1 --status-fd=1 --symmetric -o /dev/null < /dev/null
  [GNUPG:] NEED_PASSPHRASE_SYM 3 3 2
  [GNUPG:] GET_HIDDEN passphrase.enter
  test
  [GNUPG:] GOT_IT
  [GNUPG:] BEGIN_ENCRYPTION 0 3
  [GNUPG:] END_ENCRYPTION

Event Timeline

ueno set Version to 2.1.
ueno set External Link to http://debbugs.gnu.org/cgi/bugreport.cgi?bug=20550#17.
ueno added a subscriber: ueno.
werner raised the priority of this task from Wishlist to Normal.May 18 2015, 12:38 PM
werner removed a project: Feature Request.
werner added a project: Bug Report.

Currently, I don't know the solution. Here is some information, while I'd
understand your implied request.

With use-agent, the behavior is same between 1.4 and 2.1. 2.0 and 2.1 has
similar behavior (although it doesn't support loopback mode).
In 1.4, with cpr_enabled, it stops reading repeated input, which makes sense.

BTW, I believe it would be better for Emacs to implement its own pinentry UI,
not using loopback mode.
I mean, something similar situation where we have emacsclient as an external editor.
If we have pinentry by Emacs, people will be able to invoke gpg on remote
machine and access local secret key by local gpg-agent which asks passphrase to
local Emacs's pinentry.

Regarding custom pinentry program, doesn't that mean to require a user to edit
gpg-agent.conf to enable/disable the custom pinentry program?

Yes, pinentry-emacs could implement the fallback mechanism to pinentry-gtk (i.e.
by checking if Emacs is running), but I think it is too much.

Perhaps gpg could have a --pinentry-program option too and pass the value to
gpg-agent?

Some initial findings:

gpg2 calls gpg-agent as follows:

  GET_PASSPHRASE --data --repeat=1 -- S5E0584FFBBEA6E79 X X Enter+passphrase%0A"

So the problem is with gpg2.

Here's the backtrace in gpg2:

#0 agent_get_passphrase at ../../../gnupg/g10/call-agent.c:1376
#1 passphrase_get at ../../../gnupg/g10/passphrase.c:312
#2 passphrase_to_dek_ext at ../../../gnupg/g10/passphrase.c:537
#3 passphrase_to_dek at ../../../gnupg/g10/passphrase.c:594
#4 encrypt_simple at ../../../gnupg/g10/encrypt.c:217
#5 encrypt_symmetric at ../../../gnupg/g10/encrypt.c:53
#6 main 0x000000000040cbc5 in

passphrase_to_dek_ext calls passphrase_get and passes it the repeat
mode, which it reads from opt.passphrase_repeat.

opt.passphrase_repeat defaults to 1 (g10/gpg.c:2152).

I see two solutions:

  • If we are in symmetric mode, then we set opt.passphrase_repeat to 0.
  • We introduce a new mode in passphrase_to_dek_ext: create new key, but don't

prompt the user to confirm the password.

The former is acceptable if we never need to repeat the passphrase for
operations on symmetric keys, which I think is the case. I've attached a patch
that implements this behavior.

The attached patch forces opt.passphrase_repeat to 0 if we are in pinentry
loopback mode.

I've now pushed this to master.

neal claimed this task.