mirror of
https://github.com/FiloSottile/age.git
synced 2026-09-04 15:17:04 +00:00
cmd/age-inspect: classify unknown recipient stanzas
Reported by Joe Doyle of Trail of Bits.
This commit is contained in:
@@ -33,7 +33,7 @@ type Metadata struct {
|
||||
func Inspect(r io.Reader, fileSize int64) (*Metadata, error) {
|
||||
data := &Metadata{
|
||||
Version: "age-encryption.org/v1",
|
||||
Postquantum: "unknown",
|
||||
Postquantum: "yes",
|
||||
}
|
||||
|
||||
tr := &trackReader{r: r}
|
||||
@@ -64,8 +64,10 @@ func Inspect(r io.Reader, fileSize int64) (*Metadata, error) {
|
||||
case "X25519", "ssh-rsa", "ssh-ed25519", "p256tag", "piv-p256":
|
||||
data.Postquantum = "no"
|
||||
case "mlkem768x25519", "scrypt", "mlkem768p256tag":
|
||||
// Keep "yes".
|
||||
default:
|
||||
if data.Postquantum != "no" {
|
||||
data.Postquantum = "yes"
|
||||
data.Postquantum = "unknown"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ import (
|
||||
"filippo.io/age/internal/stream"
|
||||
)
|
||||
|
||||
// buildFile serializes a header with a single stanza of the given type,
|
||||
// buildFile serializes a header with the given stanza types,
|
||||
// followed by the minimal valid encrypted payload (a 16-byte stream nonce
|
||||
// and a single empty ChaCha20-Poly1305 chunk).
|
||||
func buildFile(t *testing.T, stanzaType string) []byte {
|
||||
func buildFile(t *testing.T, stanzaTypes ...string) []byte {
|
||||
t.Helper()
|
||||
hdr := &format.Header{
|
||||
Recipients: []*format.Stanza{{Type: stanzaType}},
|
||||
MAC: make([]byte, 32),
|
||||
hdr := &format.Header{MAC: make([]byte, 32)}
|
||||
for _, stanzaType := range stanzaTypes {
|
||||
hdr.Recipients = append(hdr.Recipients, &format.Stanza{Type: stanzaType})
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
if err := hdr.Marshal(buf); err != nil {
|
||||
@@ -53,6 +53,35 @@ func TestInspectTagStanzas(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspectPostquantum(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
stanzaTypes []string
|
||||
want string
|
||||
}{
|
||||
{"postquantum", []string{"mlkem768x25519"}, "yes"},
|
||||
{"classical", []string{"X25519"}, "no"},
|
||||
{"both", []string{"mlkem768x25519", "X25519"}, "no"},
|
||||
{"unrecognized", []string{"tpm-ecc"}, "unknown"},
|
||||
{"postquantum and unrecognized", []string{"mlkem768x25519", "tpm-ecc"}, "unknown"},
|
||||
{"unrecognized and postquantum", []string{"tpm-ecc", "mlkem768x25519"}, "unknown"},
|
||||
{"classical and unrecognized", []string{"X25519", "tpm-ecc"}, "no"},
|
||||
{"unrecognized and classical", []string{"tpm-ecc", "X25519"}, "no"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
f := buildFile(t, tt.stanzaTypes...)
|
||||
md, err := Inspect(bytes.NewReader(f), int64(len(f)))
|
||||
if err != nil {
|
||||
t.Fatalf("Inspect: %v", err)
|
||||
}
|
||||
if md.Postquantum != tt.want {
|
||||
t.Errorf("Postquantum = %q, want %q", md.Postquantum, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// readAfterEOFReader returns io.EOF along with the last of its data, and then
|
||||
// more data from subsequent Reads, like a terminal that received Ctrl-D
|
||||
// followed by more input.
|
||||
|
||||
Reference in New Issue
Block a user