gopass
gopass copied to clipboard
gopass recipients rm causes inconsistent state when git commit fails
Summary
I'm currently rolling over to a new PGP key, and one of the steps there is to add the new key as a gopass recipient, and then remove the old key. However, I've also configured git to sign my commits with the old keys, and had forgotten to update my ~/.gitconfig with the new key after deleting the new secret key. This causes git commit
s to fail, one of them in gopass recipients rm
:
$ gopass recipients remove --store root OLDKEYFPR
Error: failed to remove recipient "OLDKEYFPR": failed to save recipients: failed to commit changes to git: exit status 128: error: gpg failed to sign the data
fatal: failed to write commit object
This leaves the repo in an inconsistent state, however gopass believes it has removed the recipient. After fixing my ~/.gitconfig
, i retried:
$ gopass recipients remove --store root OLDKEYFPR
Error: failed to remove recipient "OLDKEYFPR": recipient not in store
This is what the root store repo looked like:
root $ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: .gpg-id
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: a/single/modified/secret
.gpg-id
now contained ONLY the new key id, hoever, every secret, including the modified one was still encrypted with BOTH keys:
root $ gpg --list-packets <a/single/modified/secret
gpg: encrypted with 4096-bit RSA key, ID OLDKEYFPR, created 2019-04-01
gpg: encrypted with 4096-bit RSA key, ID NEWKEYFPR, created 2022-04-01
# off=0 ctb=85 tag=1 hlen=3 plen=524
:pubkey enc packet: version 3, algo 1, keyid OLDKEYFPR
data: [4095 bits]
# off=527 ctb=85 tag=1 hlen=3 plen=524
:pubkey enc packet: version 3, algo 1, keyid NEWKEYFPR
data: [4096 bits]
# off=1054 ctb=d2 tag=18 hlen=2 plen=61 new-ctb
:encrypted data packet:
length: 61
mdc_method: 2
# off=1075 ctb=cb tag=11 hlen=2 plen=18 new-ctb
:literal data packet:
mode b (62), created 1648820902, name="",
raw data: 12 bytes
After resetting the uncommitted changes, gopass was happy again:
root $ git reset --hard HEAD
root $ gopass recipients remove --store root OLDKEYFPR
Starting reencrypt
[WARNING snipped]
Removed 1 recipients
You need to run 'gopass sync' to push these changes
Steps To Reproduce
- Configure git to sign commits using a specific keyid:
-
git config --global commit.gpgsign true
-
git config --global user.signingkey OLDKEYFPR
-
- Create a new PGP key
- Add new recipient:
gopass recipients add --store root NEWKEYFPR
- Remove old secret key (AFTER MAKING A BACKUP):
gpg --delete-secret-keys OLDKEYFPR
- Remove the old key from gopass:
gopass recipients remove --store root OLDKEYFPR
Expected behavior
The gopass repo should not end up in an inconsistent state
Environment
- OS: Arch Linux
- OS version:
Linux MYHOSTNAME 5.15.31-1-lts #1 SMP Wed, 23 Mar 2022 09:55:25 +0000 x86_64 GNU/Linux
- gopass Version:
gopass 1.14.0 go1.18 linux amd64
- Installation method:
pacman -S gopass
Yeah, we had similar issues before.
I wonder how much gopass fsck
would have helped. It would be nice if it could help recover such situations.
Would be nice if we could gracefully abort after a failed commit.