cmd/age-plugin-tag,cmd/age-plugin-tagpq: new backward compatibility plugins

This commit is contained in:
Filippo Valsorda
2025-12-07 20:32:06 +01:00
committed by Filippo Valsorda
parent 78947d862d
commit de158f906b
3 changed files with 79 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
package main
import (
"flag"
"fmt"
"log"
"os"
"filippo.io/age"
"filippo.io/age/plugin"
"filippo.io/age/tag"
)
const usage = `age-plugin-tag is an age plugin for P-256 tagged recipients. These are supported
natively by age v1.3.0 and later, but this plugin can be placed in $PATH to add
support to any version and implementation of age that supports plugins.
Usually, tagged recipients are the public side of private keys held in hardware,
where the identity side is handled by a different plugin.`
func main() {
flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n", usage) }
p, err := plugin.New("tag")
if err != nil {
log.Fatal(err)
}
p.HandleRecipient(func(b []byte) (age.Recipient, error) {
return tag.NewClassicRecipient(b)
})
os.Exit(p.Main())
}

View File

@@ -0,0 +1,33 @@
package main
import (
"flag"
"fmt"
"log"
"os"
"filippo.io/age"
"filippo.io/age/plugin"
"filippo.io/age/tag"
)
const usage = `age-plugin-tagpq is an age plugin for ML-KEM-768 + P-256 post-quantum hybrid
tagged recipients. These are supported natively by age v1.3.0 and later, but
this plugin can be placed in $PATH to add support to any version and
implementation of age that supports plugins.
Usually, tagged recipients are the public side of private keys held in hardware,
where the identity side is handled by a different plugin.`
func main() {
flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n", usage) }
p, err := plugin.New("tagpq")
if err != nil {
log.Fatal(err)
}
p.HandleRecipient(func(b []byte) (age.Recipient, error) {
return tag.NewHybridRecipient(b)
})
os.Exit(p.Main())
}

View File

@@ -237,6 +237,20 @@ instruct the user to perform encryption with the `-e`/`--encrypt` and
doesn't make sense (such as a password-encryption plugin) may instruct the user
to use the `-j` flag.
#### Tagged recipients
`age` can natively encrypt to recipients starting with `age1tag1` (using P-256
ECDH) or `age1tagpq1` (using the ML-KEM-768 + P-256 post-quantum hybrid). These
are intended to be the public side of private keys held in hardware.
They are directly supported to avoid the need to install the plugin, which may
be platform-specific, on the encrypting side.
The tag reduces privacy, by allowing an observer to correlate files with a
recipient (but not files amongst them without knowledge of the recipient),
but this is also a desirable property for hardware keys that require user
interaction for each decryption operation.
## EXIT STATUS
`age` will exit 0 if and only if encryption or decryption are successful for the