gopass icon indicating copy to clipboard operation
gopass copied to clipboard

Versions >= 1.7 loses support for subkeys

Open malramsay64 opened this issue 6 years ago • 23 comments

Summary

Gopass 1.6.12 has support for subkeys added to a .gpg-id file, this no longer works for either the 1.8 or 1.7 versions.

Steps To Reproduce

$ gopass-1.8 generate test
How long should the password be? [24]:

$ gopass-1.8 test
gpg: decryption failed: No secret key

Expected behavior

Environment

  • OS: Fedora
  • OS version: Linux
  • gopass Version: 1.7, 1.8
  • Installation method: rpm

Additional context

This is mostly a note to anyone else that comes across this problem since I didn't find any specific note about this in the docs or release notes.

malramsay64 avatar Aug 04 '18 01:08 malramsay64

Actually I'm not aware of any such changes. Are you sure that only the gopass version changed? Sure we changed a lot for 1.7 and upwards but I wonder how that interacts with subkeys.

dominikschulz avatar Aug 08 '18 19:08 dominikschulz

I tried it again with a new password store. 1.6.12 works, and 1.8.2 doesn't (more details below). It is entirely possible I am doing something wrong cause I don't really understand gpg.

I have two yubikeys configured as per this guide each with different keys. To get them both decrypting the keystore I have added their encryption public keys to the .gpg-id file within the store followed by an exclamation mark, i.e. 0xE51234567890A!. The .gpg-id file then contains the master key fingerprint and two encryption subkeys.

Passwords generated on 1.8.2 will only decrpyt with one of the two yubikeys. While those generated on 1.6.12 are decrypted by both, which still holds on 1.8.2.

malramsay64 avatar Aug 08 '18 22:08 malramsay64

@malramsay64, are you saying that you have added the fingerprints directly to the .gpg-id file? Can you try using gopass recipients add ... instead?

metalmatze avatar Aug 12 '18 13:08 metalmatze

Yes I have been adding the fingerprints of the encryption subkeys to the .gpg-id file. When using gopass recipients add

$ gopass recipients add B2CBB103E7169567964C1F24B1125D5C5F57A29A
Do you want to add '0x8C945615619236BA - Malcolm Ramsay <[email protected]>' as an recipient to the store ''? [y/N/q]: y

Error: failed to add recipient 'B2CBB103E7169567964C1F24B1125D5C5F57A29A': Recipient already in store

I was editing the .gpg-id file since I initially set the store up with pass and then migrated to gopass with everything just working until the 1.7.0 release. I noticed now because I needed to use my backup key after leaving the primary one at work.

malramsay64 avatar Aug 12 '18 23:08 malramsay64

I can confirm the issue, I am pretty much in same situation as @malramsay64. It seems to encrypt only for the last sub key which happens to be my backup :-(

RageZBla avatar Aug 13 '18 08:08 RageZBla

I can't speak to existing gopass stores, as I am starting to explore gopass myself.

However, has anyone tried PGP's default-key option?

On Qubes OS and with Keybase.io, I too have had issues with sub-keys. I usually get around it by specifying my exact/default Subkey I want to use on the machine with default-key in the ~/.gnupg/gpg.conf file.

However, best practices of PGP dictates to only have short-expiring sub-keys on your daily-driver (the machines you use every day) to limit your attack surface. E.g. sub-keys that expire every 30 days or so. Your master private key should be kept on an air-gapped machine, where you only fire it up to generate new sub-keys or to revoke old sub-keys if a machine was compromised.

With that said, I have on my work machines and laptops only the sub-key I want to use on that machine - and no other private keys. I usually don't run into problems with QubesOS or Keybase.io with this setup. Only on my desktop where I have multiple private keys in the air-gapped vaultVM.

So... I wonder if setting default-key would be best here for users with multiple private keys?

I'll experiment as well as I'm looking at gopass to switch to myself - and I exclusively only use sub-keys. 👍


The only other thing related may be the use of PGP's hidden-recipient. I don't think gopass uses hidden-recipients as you can see the current users a store can decrypt for?

But as a long-time users of PGP, what I have seen is when using hidden-recipients with PGP for encrypted messages, the receiving users must cycle through all Private keys on their local machine until a match is found - as the message only has 0x00 as the target ID to decode to - since it's hidden and unknown the the receiver's PGP decoding.

eduncan911 avatar Aug 20 '18 16:08 eduncan911

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Nov 18 '18 16:11 stale[bot]

Same issue here, have setup 2 yubikeys and have only the public master key and 3 subkeys in each yubikey (one for Encription, other for Signing and other for Authentication). Currently I am unable to decrypt any secret I just created... Anyone found a solution?

I found out that I can only decrypt the secrets with the last subkey which in fact is stored in my backup yubikey, so I can only decrypt the secrets with that one and not with the main one. Which defeats the purpose of having only one Key with several subkeys for daily use stored in yubikeys...

I followed too the guide in https://github.com/drduh/YubiKey-Guide

dgsardina avatar Nov 30 '18 09:11 dgsardina

As a quick follow-up, when I was testing gopass 1.7, I only had a subkey on my test domain (VM). Gopass worked fine with only my 1 private key.

My guess of the root problem per the error message above that @malramsay64 posted is that the add recipient function checks to see if any existing keys match the same email, and then errors.

It's just a guess, but would make sense since I am able to use a subkey with 1.7 - because that is the only key on the entire system (no master key).

eduncan911 avatar Nov 30 '18 12:11 eduncan911

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Feb 28 '19 12:02 stale[bot]

Just found this project and got excited about the audit feature. I'm on macOS, and this happens. Only for the audit command however. Per earlier comments, I tried 1.6.10, and that could run audit without any warnings. The entries that yielded decryption failure with latest version are still possible to unlock with latest version if I use the plain access gopass folder/entry. I'm sure you need more details, so please ask. Mac GPGTools are of the latest version, same with gpg from homebrew. Private key is fully trusted. Correct key in .gpg-id I guess, as regular decryption works fine, just the audit command that fails, gpg --list-packets for any given file matches the key in .gpg-id.

dsvensson avatar Mar 14 '19 08:03 dsvensson

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jun 12 '19 11:06 stale[bot]

Still broken. Audit fails to decode. Linux as well.

dsvensson avatar Jun 12 '19 11:06 dsvensson

My use-case is using the password store on my phone, but I don't trust the "key provider" app with my root key. So I'd create a subkey and encrypt the password store against it and only put that to the phone. Worst case I lose all my passwords... /shrug

Fuco1 avatar Nov 26 '19 15:11 Fuco1

Uh-oh, I am migrating my password to password-store and I was excited to use gopass rather than standard pass, but this is a deal-breaker. How do people backup their password stores if subkeys do not work? Anyway, having support for subkeys sounds pretty essential...

kirelagin avatar Mar 15 '21 02:03 kirelagin

I mentioned, a few years ago above lol, that when I only had my subkey (no master key) I was able to use gopass successfully.

I've since moved on from gopass though. So hope that helps someone.

eduncan911 avatar Mar 15 '21 02:03 eduncan911

I'm using Gopass exclusively with a hardware token that's only containing an encryption subkey and a signature&authn one, and it works. So I'm not sure what's happening here.

As far as I know we should still be honoring .gpg-id files, but I haven't tested.

Anyone got some easy to do steps to reproduce the problem?

AnomalRoil avatar Mar 15 '21 08:03 AnomalRoil

Also it seems we are compatible with throw-keyid and hidden recipients as far as I can tell: #1756 (which makes sense since we are delegating encryption and decryption to the gpg binary itself)

AnomalRoil avatar Mar 15 '21 08:03 AnomalRoil

Here is what I am seeing.

My setup is this:

  • 0x90D516249B728BE6 is the “primary” certification key (no encryption)
    • 047A7B2FB0E96F07F9C216DCB3D9F87D907DC8B1 is its encryption-only subkey (the one I actively use)
    • FBE0EC61EDA03749197C34D785D128E1B30E1931 is another encryption-only subkey (for backups)

(Not sure if it matters, but the certification and backup-encryption key are on one YubiKey, and active-encryption key is on another YubiKey.)

Problem 1: can’t use the CLI to add different subkeys as recipients

$ gopass init
[init] Initializing a new password store ...
Please select a private key for encrypting secrets:
[0] gpg - 0x90D516249B728BE6 - Kirill Elagin <[email protected]>
Please enter the number of a key (0-0, [q]uit) [0]: 0
[init] Initializing git repository (gitfs) for kirelagin / ...
Please enter an email address for password store git config []: 
[init] git initialized at /home/kirelagin/.local/lib/gopass
[init] Git Email not set
[init] git configured at /home/kirelagin/.local/lib/gopass
[init] Git initialized
[init] Password store /home/kirelagin/.local/lib/gopass initialized for:
[init]   0x90D516249B728BE6 - Kirill Elagin <[email protected]>

$ gopass recipients add 'FBE0EC61EDA03749197C34D785D128E1B30E1931!'
Do you want to add '0x90D516249B728BE6 - Kirill Elagin <[email protected]>' as a recipient to the store ''? [y/N/q]: y

Error: failed to add recipient 'FBE0EC61EDA03749197C34D785D128E1B30E1931!': Recipient already in store

This is clearly a UX problem, since this is something that should work. Compare to pass:

$ pass init '047A7B2FB0E96F07F9C216DCB3D9F87D907DC8B1!' 'FBE0EC61EDA03749197C34D785D128E1B30E1931!'

and it does exactly what I need. gopass is being smart and, as a result, I could not find any way to init a repo to a specific subkey. Furthermore, since I can’t remove the only recipient, the UI does not allow me to change the recipients list to be made of specific subkeys.

Problem 2: identifying encryption keys by their certifying key does not seem to be future-proof

I am pretty new to using Password Store in general, and I am a bit confused as to what will happen when I phase out my current encryption subkey and switch to using a new one (I rotate the active encryption key yearly). Since .gpg-id created by gopass contains only the ID of my certifying primary key, it seems to me that it means that if the most-recent encryption subkey changes, gopass will silently start encrypting new passwords to the new subkey, while old passwords will remain encrypted to the phased-out subkey.

In other words, the problem here is that I can (easily and without noticing myself) change the actual encryption key used without editing the list of recipients, since the choice of the encryption key is “impure”.

With pass it all is pretty much my responsibility, so by explicitly starting with specific subkeys I will then be forced to edit the list of recipients once I rotate they keys.

My proposal would be to make gopass always store the exact encryption subkey chosen, even when I do gopass init and select the identity, it should resolve the exact encryption key GPG will use by default, and instead of storing the fingerprint of the certification key, store the fingerprint of that specific encryption key.

Problem 3: ignoring multiple subkeys in .gpg-id

This is, arguably, the worst, since I have manual overrides to deal with the two previous ones and I can teach myself to never trust gopass recipients list and instead inspect .gpg-id manually, but this problem threatens the integrity of the store and makes gopass incompatible (unusable) with pass.

So, suppose, I initialised the repository using pass as above, so that now I have:

$ cat ~/.local/lib/gopass/.gpg-id 
047A7B2FB0E96F07F9C216DCB3D9F87D907DC8B1!
FBE0EC61EDA03749197C34D785D128E1B30E1931!

I want to switch to using gopass now. Let’s see:

$ gopass recipients list
Hint: run 'gopass sync' to import any missing public keys
gopass
└── 0x90D516249B728BE6 - Kirill Elagin <[email protected]>

It just hides the fact the there are, in fact, two encryption keys in the recipients list. I would prefer it to just show two encryption subkeys, or, maybe a two-level tree (but this might be confusing to some users).

$ gopass generate 
Which name do you want to use? []: hello
How long should the password be? [24]: 
Password for hello generated
$ cat ~/.local/lib/gopass/hello.gpg | gpg --list-packets 2>/dev/null | grep keyid
:pubkey enc packet: version 3, algo 1, keyid B3D9F87D907DC8B1

Ooops! My password store is supposed to be encrypted to BOTH my active and backup encryption keys, but gopass only encrypted it to the active key (just as in https://github.com/gopasspw/gopass/issues/909#issuecomment-412451829, except that it is not the last sub-key, but, rather, I guess, the newest one? that’s what gpg would do if not given a specific subkey when encrypting).

So, I’ve just got a password encrypted to a set of keys different from what pass would do, and, even worse, just lost a backup encryption of my password.

I am not sure how this is possible: if gopass would simply encrypt to the list of recipients specified in .gpg-id (as pass does) everything would be fine. It seems to somehow resolve the subkeys to their “root” certifying keys, and the encrypting to the certifying keys instead of the subkeys specified.


At this point I realised that my gopass is outdated (v1.10.1), so I am not even sure how relevant to the current version what I just wrote is, but, I hope, not much has changed since and my explanation will still be useful.

kirelagin avatar Mar 15 '21 14:03 kirelagin

Yes, thank you for the detailed walk-through. We haven't worked significantly on subkeys, recipients and gpg since 1.10.1.

It seems we have multiple problems, here, indeed. That's not going to be fixed overnight, I'm afraid! We'll dig into it and hopefully correct this for v1.13.0

AnomalRoil avatar Mar 15 '21 15:03 AnomalRoil

We've removed some of the unnecessary indirection when handling recipients. It would be nice if someone could verify if the latest commits still suffer from this issue. It have long been fixed already.

dominikschulz avatar Dec 26 '22 20:12 dominikschulz

I ran into this problem when I figured out after rotating my keys gopass has now encrypted all (new/after fsck) passwords for a public key I don't have the private key for (on my laptop).

I'm lucky I found this issue, and will share my investigations so far (& I'm happy to support further)

1. problem: Missing choice of encryption key

I have a main key with some subkeys (showing only the relevant ones here), for only some of them I have the private key (others are for other devices):

$ gpg -K --keyid-format 0xlong
/home/manu/.gnupg/pubring.kbx
-----------------------------
sec#  ed25519/0xFFD59E5D2343CE94 2023-02-19 [SC] [expires: 2025-02-18]
      AD23C5B72147C2XXXXXXXXXXXXXXXXXXXXXXXXXX
uid                   [ultimate] Manu [tennox] (Main) <[email protected]>
ssb#  cv25519/0x2387EB8XXXXXXXXX 2023-02-19 [E] [expires: 2023-11-16]
ssb   cv25519/0x37F4E8B8XXXXXXXX 2023-02-19 [E] [expires: 2024-02-19]

(the ssb# means there is no secret key)

gopass setup offers no choice and thus the secrets will be encrypted for just the first available one:

$ echo "e9duifwerf" | pass insert test
$ cat .password-store/test.gpg | gpg --list-packets 2>/dev/null | grep keyid
:pubkey enc packet: version 3, algo 18, keyid 2387EB8XXXXXXXXX

=> decryption fails (pass === gopass)

$ pass show test
gpg: public key decryption failed: Bad secret key
gpg: decryption failed: Bad secret key
❌ Decryption failed: exit status 2

potential solution

I sadly could not find any config in gpg to use a specific encryption subkey by default. (there's an open stackexchange question) Okay, now I figured out how to tell gpg to use the right key with the help of another StackExchange post and ChatGPT :yum:.

It will use the correct one if I specify the exact subkey with an exclamation mark:

echo test | gpg --encrypt -r 37F4E8B8XXXXXXXX! | gpg --list-packets
gpg: encrypted with cv25519 key, ID 37F4E8B8XXXXXXXX, created 2023-02-19

but not when gopass calls it with the primary key as recipient - wrong one:

echo test | gpg --encrypt -r FFD59E5D2343CE94 | gpg --list-packets
gpg: encrypted with cv25519 key, ID 2387EB8XXXXXXXXX, created 2023-02-19

So if I could just choose a subkey for gopass, that would be a great step!

I dug into your implementation, and found you parse the colons format, so I thought I post my output, in case you need it:

``` sec:u:255:22:FFD59XXXXXXXXXXXX:1676822339:1739895633::u:::scESCA:::#::ed25519:::0: fpr:::::::::AD23C5B72XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX: grp:::::::::356B6E590XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX: uid:u::::1676823633::EAAA0AC818xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx::Manu [tennox] ::::::::::0: ssb:u:255:22:2F004F9849B91FB0:1676847492:1700175492:::::s:::#::ed25519:: fpr:::::::::612A8E94XXXXXXXXXXXXXXXXXXXXXXXXXXXXXFB0: grp:::::::::799A570DXXXXXXXXXXXXXXXXXXXXX2D6B817F21A: ssb:u:255:18:2387EB8xxxxxxxxE:1676847664:1700175664:::::e:::#::cv25519:: fpr:::::::::1431694EF2E8E9XXXXXXXXXXXXXXXXXXXXX178FE: grp:::::::::EE6BEDA2C06FXXXXXXXXXXXXXXXXXXXXXXX49ACE: ssb:u:255:22:B13E450XXXXXXXXD:1676853009:1700181009:::::a:::#::ed25519:: fpr:::::::::54CB5739XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX2D: grp:::::::::634A7255XXXXXXXXXXXXXXXXXXXXXXXXB6A9F2BC: ssb:u:255:18:37F4E8BXXXXXXXXX:1676822339:1708358339:::::e:::+::cv25519:: fpr:::::::::08E33517FEXXXXXXXXXXXXXXXXXXXXXXXXXXX2FE: grp:::::::::227E1C7C0DXXXXXXXXXXXXXXXXXXXXXXXXXA4752: ssb:u:255:22:6B7259XXXXXXXXXX:1676823245:1708359245:::::s:::+::ed25519:: fpr:::::::::E1CDC957xxxxxxxxxxxxxxxxxxxxxxxxxxB809E0: grp:::::::::E1D20D77XXXXXXXXXXXXXXXXXXXXXXXXXXXXA36C: ```

tennox avatar Feb 20 '23 03:02 tennox

I just found a workaround - adding the subkey id with an exclamation mark to .gpg-id :nerd_face: :

37F4E8B8XXXXXXXX!

gopass will then add the primary key in ensureOurKeyID, but at least I can decrypt my passwords again :yum: Let's see if that breaks the android app or other stuff :sweat_smile:

I also created a request for that option on gnupg

tennox avatar Feb 20 '23 03:02 tennox