4

Is there any way to sign multiple files with GPG when the signing key is stored on a keycard? (Or more specifically in my case, a Yubikey).

Currently, I have a script where I loop over a number of files that I want to sign, e.g.:

for pkg in html/packages/*.tar;
do
    gpg2 --detach-sign --armor -o $pkg.sig $pkg
done

This works, but as there is a pin-code on my keycard I'm being prompted to enter my pin for each file which gets very tiresome after just a few files.

Is there any way to sign all files at once? Alternatively, is there some workaround for the signing process such that the pin-code can be cached between invocations?

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
Xaldew
  • 193
  • 6
  • It appears that what you want (`--sign` + `--multifile`) is not currently implemented, https://dev.gnupg.org/T4930. – einfeyn496 Jun 11 '20 at 14:04
  • Can you add a variable to your script (or pass it in at invocation) to hold the PIN and then pass to `gpg` in batch mode? – einfeyn496 Jun 11 '20 at 14:07
  • Modifying the script with a variable is fine, although passing the pin on the command-line is probably not advised, as it could be stored in the history file. I believe I could use `pinentry` to get the pin securely, but how would I tell `gpg` to use it? – Xaldew Jun 12 '20 at 17:01

1 Answers1

2

If you can get the PIN into a variable your script can use, you can do something like:

for pkg in html/packages/*.tar;
do
  echo ${PIN} | gpg --batch --yes --passphrase-fd 0 --detach-sign --armor -o $pkg.sig $pkg
done

From the man page:

--passphrase-fd n
       Read the passphrase from file descriptor n. Only the first line will be read
       from file descriptor n. If you use 0 for n, the passphrase will be read from
       STDIN. This can only be used if only one passphrase is supplied.

       Note that since Version 2.0 this passphrase is only used if the option --batch
       has also been given. Since Version 2.1 the --pinentry-mode also needs to be set
       to loopback.

For more details on the passphrase-fd (where gpg should expect to receive the passphrase from) option, https://stackoverflow.com/questions/19895122/how-to-use-gnupgs-passphrase-fd-argument is probably helpful

einfeyn496
  • 357
  • 2
  • 6