cmd/age: recognize armored identity files after whitespace

Reported by Joe Doyle of Trail of Bits.
This commit is contained in:
Filippo Valsorda
2026-08-29 19:30:10 +02:00
parent 9cbe8d8c2a
commit cdb30a188b
2 changed files with 24 additions and 5 deletions
+8 -5
View File
@@ -6,6 +6,7 @@ package main
import (
"bufio"
"bytes"
"crypto/rsa"
"encoding/base64"
"fmt"
@@ -179,14 +180,16 @@ func parseIdentitiesFile(name string) ([]age.Identity, error) {
}
b := bufio.NewReader(f)
p, _ := b.Peek(14) // length of "age-encryption" and "-----BEGIN AGE"
peeked := string(p)
const maxWhitespace = 1024
p, _ := b.Peek(maxWhitespace + len(armor.Header))
trimmed := bytes.TrimSpace(p)
switch {
// An age encrypted file, plain or armored.
case peeked == "age-encryption" || peeked == "-----BEGIN AGE":
case bytes.HasPrefix(p, []byte("age-encryption")) ||
bytes.HasPrefix(trimmed, []byte(armor.Header)):
var r io.Reader = b
if peeked == "-----BEGIN AGE" {
if bytes.HasPrefix(trimmed, []byte(armor.Header)) {
r = armor.NewReader(r)
}
const privateKeySizeLimit = 1 << 24 // 16 MiB
@@ -212,7 +215,7 @@ func parseIdentitiesFile(name string) ([]age.Identity, error) {
}}, nil
// Another PEM file, possibly an SSH private key.
case strings.HasPrefix(peeked, "-----BEGIN"):
case bytes.HasPrefix(trimmed, []byte("-----BEGIN")):
const privateKeySizeLimit = 1 << 14 // 16 KiB
contents, err := io.ReadAll(io.LimitReader(b, privateKeySizeLimit))
if err != nil {
+16
View File
@@ -60,10 +60,26 @@ ttyout 'Enter passphrase'
! stderr .
cmp stdout input
# armored identity files accept leading whitespace
exec age-keygen -o key.txt
age -e -i key.txt -o test.age input
ttyin newpass
age -p -a -o key.age key.txt
exec cat blank key.age
cp stdout key-with-blank.age
ttyin terminal
age -d -i key-with-blank.age test.age
cmp stdout input
-- input --
test
-- terminal --
password
-- newpass --
password
password
-- blank --
-- key_ed25519 --
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABCuvb97i7