Thanks to @Joe Damato for pointing me toward the gpg-preset-passphrase
utility. The solution described below was developed and tested on a Fedora 25 host with gnupg2-2.1.x
installed.
(n.b. I haven't yet figured out how to determine the RPM signing key's keygrip value on platforms running older versions of GnuPG because they don't support the --with-keygrip
option. If someone would like to comment on a solution for this, please do.)
Ensure ~/.gnupg/gpg-agent.conf
contains the line.
allow-preset-passphrase
After modifying ~/.gnupg/gpg-agent.conf
reload the gpg-agent.
$ gpg-connect-agent reloadagent /bye
OK
List your GPG keys to obtain the eight hexidecimal digit key ID for your RPM signing key. In this excample, the key ID is 0123ABCD
.
$ gpg --list-keys
/home/me/.gnupg/pubring.gpg
-----------------------------------
pub 1024R/0123ABCD 2015-06-13
uid Test (rpm-sign)
Get the keygrip code for the RPM signing key. (n.b. On the RHEL 7.2 and Fedora 20 hosts I use for testing, the GPG2(1)
program on those hosts didn't recognize the --with-keygrip
option.)
$ gpg2 --with-keygrip -K 0123ABCD
sec rsa1024 2015-06-13 [SCEA]
0A1B2C3D4E5F6A7B8C9D0E0F1A2B3C4D0123ABCD
Keygrip = 2EACA0C5A4B46168EB91970B6715AF1AA52968BE
uid [ unknown] Test (rpm-sign)
Cache the passphrase for the RPM signing key. In the command line shown below, replace 'PASSPHRASE'
with the actual passphrase for the RPM signing key.
$ /usr/libexec/gpg-preset-passphrase --passphrase 'PASSPHRASE' --preset 2EACA0C5A4B46168EB91970B6715AF1AA52968BE
:: TEST ::
Create a test RPM file that is not signed. Verify that the test RPM file is not signed.
$ rpm --checksig test-1.0.0-1.f25.noarch.rpm
test-1.0.0-1.fc25.noarch.rpm: sha1 md5 OK
Verify that RPMSIGN(8)
uses the cached password--i.e., that RPMSIGN(8)
does not prompt you to enter the passphrase for the RPM signing key--when signing the test RPM file.
$ rpmsign --resign test-1.0.0-1.f25.noarch.rpm
Verify that the test RPM file is signed.
$ rpm --checksig test-1.0.0-1.f25.noarch.rpm
test-1.0.0-1.fc25.noarch.rpm: rsa sha1 (md5) pgp md5 OK
:: ADDENDUM 1 (2016-12-17) ::
According to this GnuPG Issue 2331 webpage:
gpg1 does not known about keygrips. Instead of the keygrip, gpg1 uses the fingerprint as cacheid for gpg-agent. The agent's command GET_PASSPHRAE, as used by gpg1, uses a different cache mode from what gpg-preset-passphrases uses. Thus even if you replace the keygrip with the fingerprint of the (sub)key, it won't work.
For what it's worth, I've done some testing with GnuPG version 2.0.x on RHEL7 hosts and gpg-preset-passphrase
doesn't seem to be supported. I can only get gpg-preset-passphrase
to work with GnuPG version 2.1.x.
References
GnuPG ArchWiki
I solved the problem by upgrading gnupg from 1.4 to 2.1 which seemed to simplify a lot the configuration.
However, it generated an error of migration of the secret key between gpg and
gpg2.
gpg2 generated the following error message when I was requiring password from
pass:
gpg: decryption failed: No secret key
The solution came from this previous issue:
gpg --export [ID] > public.key
gpg --export-secret-keys [ID] > private.key
gpg2 --import public.key
gpg2 --import private.key
rm public.key private.key
with [ID] being the id of my key. It imports correctly the keys from gpg to gpg2.
Finally I rebooted and now my passphrase is cached, which makes me a really happy user of pass.
Best Answer
I had the same issue; @Kusalananda is spot on - pass uses gpg2, which stores the key separately, so you have to change the passphrase for both versions.
The name of the key used by pass is stored in
~/.password-store/.gpg-id
.