jamessan / vim-gnupg

This script implements transparent editing of gpg encrypted files.
http://www.vim.org/scripts/script.php?script_id=3645
728 stars 73 forks source link

Recipients lost after opening file. #125

Open oddlama opened 2 years ago

oddlama commented 2 years ago

Hi! When I open a file with vim-gnupg, the decryption works fine but the plugin has issues to reencrypt it on writing. I get a similar message that I've seen in several issues here (Unable to write to encrypted file. Error: Message could not be encrypted! (Press ENTER)).

I can assure you that there is nothing wrong with my gpg setup. I use a pretty basic and standard setup - just a gpg-agent to access my yubikey, nothing else. Even the TTY pinentry for decryption worked fine for me (I'm on neovim). Instead, what seems to be the problem is that the plugin is unable to gather the original recipients.

I've done some tests and found that they just seem to be left out from the encrypted file altogether, and instead show an anonymous recipient (which is good for privacy IMO). But if vim-gnupg succeeds to decrypt the file, it should know the correct key for decryption. See the following example where after successful decryption the associated secret key id 0xABCDABCDABCDABCD is shown, which can also be used as an argument to --recipients.

$ echo test | gpg --encrypt --armor --recipient <mykeyid> | gpg --list-packets
gpg: encrypted with ECDH key, ID 0x0000000000000000
gpg: anonymous recipient; trying secret key `0xABCDABCDABCDABCD` ...
gpg: okay, we are the anonymous recipient.
# ...

I can manually work around the issue by specifying the correct keyid in :GPGEditRecipients. Afterwards writing works fine.

While I think parsing this information from gpg is the correct approach to this problem, I came up with an alternative idea: By supporting vim modelines in the encrypted content, it would be easy to specifiy a list of recipients in the decrypted content. Not sure whether this is feasible though.

jamessan commented 2 years ago

Can you show the output of the following commands on a file where you're experiencing this issue?

jamessan commented 2 years ago

By supporting vim modelines in the encrypted content, it would be easy to specifiy a list of recipients in the decrypted content. Not sure whether this is feasible though.

Even if it were, it's not something I would do. I find modelines problematic from a security perspective in general and would not want to implement my own ad-hoc modeline-like support for this plugin.

oddlama commented 2 years ago

Here's the output you asked for:

$ gpg --verbose --decrypt --list-only --dry-run foo.gpg
gpg: Note: RFC4880bis features are enabled.
gpg: public key is 0x0000000000000000

$ gpg --verbose --decrypt --list-only --dry-run --status-fd 2 foo.gpg >/dev/null
gpg: Note: RFC4880bis features are enabled.
gpg: public key is 0x0000000000000000
[GNUPG:] ENC_TO 0000000000000000 18 0
[GNUPG:] BEGIN_DECRYPTION
[GNUPG:] END_DECRYPTION

$ gpg --verbose --decrypt --status-fd 2 foo.gpg > /dev/null
gpg: Note: RFC4880bis features are enabled.
gpg: public key is 0x0000000000000000
[GNUPG:] ENC_TO 0000000000000000 18 0
gpg: encrypted with ECDH key, ID 0x0000000000000000
[GNUPG:] KEY_CONSIDERED 680AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 0
gpg: anonymous recipient; trying secret key 0x4255XXXXXXXXXXXX ...
gpg: pinentry launched (350008 qt:curses 1.2.0-unknown /dev/pts/0 xterm-256color - 20620/1000/5 1000/1000 0)
[GNUPG:] PINENTRY_LAUNCHED 350008 qt:curses 1.2.0-unknown /dev/pts/0 xterm-256color - 20620/1000/5 1000/1000 0
gpg: pinentry launched (350079 qt:curses 1.2.0-unknown /dev/pts/0 xterm-256color - 20620/1000/5 1000/1000 0)
[GNUPG:] PINENTRY_LAUNCHED 350079 qt:curses 1.2.0-unknown /dev/pts/0 xterm-256color - 20620/1000/5 1000/1000 0
gpg: pinentry launched (350099 qt:curses 1.2.0-unknown /dev/pts/0 xterm-256color - 20620/1000/5 1000/1000 0)
[GNUPG:] PINENTRY_LAUNCHED 350099 qt:curses 1.2.0-unknown /dev/pts/0 xterm-256color - 20620/1000/5 1000/1000 0
[GNUPG:] KEY_CONSIDERED 680AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 0
gpg: using pgp trust model
[GNUPG:] DECRYPTION_KEY EF5C0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 680AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX u
gpg: okay, we are the anonymous recipient.
[GNUPG:] BEGIN_DECRYPTION
gpg: AES256.CFB encrypted data
[GNUPG:] DECRYPTION_INFO 2 9 0
gpg: original file name=''
[GNUPG:] PLAINTEXT 62 1649002851
[GNUPG:] DECRYPTION_OKAY
[GNUPG:] GOODMDC
[GNUPG:] END_DECRYPTION

I've redacted my actual key id's by replacing some hex values with XXXX as you will see above. It might be noteworthy that only the last command requested access to my security key. Tell me if you need anything else.

Even if it were, it's not something I would do. I find modelines problematic from a security perspective in general and would not want to implement my own ad-hoc modeline-like support for this plugin.

I feel the same way security wise. Could've been a dirty workaround to the problem, if not fixable by other means.

jamessan commented 2 years ago

Ok, so the last option gives us some information to use. This basically boils down to a duplicate of #121. The plugin needs to change to use --status-fd.

However, even with those changes, recipients are still going to be "lost" since they're not recorded in the file. The only recipient that will be retained is you, and you can achieve the same by adding encrypt-to <your key> in ~/.gnupg/gpg.conf.

oddlama commented 2 years ago

Unfortunately I have several security keys and some files are encrypted with key A and others with key B. So an entry in ~/.gnupg/gpg.conf will not really work.

What would prevent this plugin from parsing which secret key worked for decryption and use that instead of an empty list of recepients? This would absolutely solve the problem for me.

jamessan commented 2 years ago

What would prevent this plugin from parsing which secret key worked for decryption and use that instead of an empty list of recepients?

Nothing. :) That's something I agree should be fixed. However, that will only preserve yourself as a recipient, not any of the other recipients. That's the only caveat I was pointing out.

oddlama commented 2 years ago

Ah I'm sorry. I interpreted your previous message as "[all] recipients would be lost", which we agree isn't the case. Thanks for clarifying. :)