FiloSottile / age

A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.
https://age-encryption.org
BSD 3-Clause "New" or "Revised" License
15.75k stars 475 forks source link

Plugin receives only one identity or recipient when there are multiple #526

Closed olastor closed 5 months ago

olastor commented 8 months ago

Environment

What were you trying to do

Creating a plugin according to the spec.

What happened

When providing multiple recipients, e.g.,

cat secret.txt | age -e -r age1my-plugin<recipient 1 data> -r age1my-plugin<recipient 2 data> -o secret.txt.enc

or doing the same via an identity file with two identities in it (one per line):

cat secret.txt | age -e -i ids.txt -o secret.txt.enc

the controller (age) only sends one recipient (or identity), e.g.,

-> add-identity AGE-PLUGIN-MY-PLUGIN<identity 1 data>

-> wrap-file-key
[...]
-> done

Checking the processes during encryption, it seems that age creates a new process for the second identity after it wrapped to the first identity, so each instance of the plugin seems to only always gets to see one recipient/identity. That makes it hard to implement the spec correctly:

Having assembled the full set of recipients and identities that the client wishes to wrap to, the plugin determines whether it can successfully wrap to all recipients and identities. The plugin MUST generate an error if one or more recipients or identities cannot be wrapped to.

It's also worth noting that for decryption also only one identity is sent to the plugin. In the case of encryption, it's not so bad because the key needs to be wrapped to all recipients/identities anyways (it has some other side-effects in my case though). But for decryption this limits the plugin because it is not able to choose which among all recipients/identities to use for unwrapping (only needs to happen for one of them).

Using rage, this seems to work differently, i.e. there's one plugin process that can index all identities/recipients:

-> add-identity AGE-PLUGIN-MY-PLUGIN<identity 1 data>

-> add-identity AGE-PLUGIN-MY-PLUGIN<identity 2 data>

-> wrap-file-key
[...]
-> done

Although for rage I also opened a similar issue for the decryption phase: https://github.com/str4d/rage/issues/414

olastor commented 5 months ago

It seems this is intentional: https://github.com/str4d/rage/issues/414#issuecomment-1925463164