ssh/agent: prevent panic on pathological ed25519 inputs
parseEd25519Key and parseEd25519Cert cast wire bytes to ed25519.PrivateKey without checking length; a short payload panics at priv[32:] in Public(). Fixes CVE-2026-46598 Fixes golang/go#46598 Change-Id: I127bc6a22adff1c4beb4d54533062bebc388de47 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/781360 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Nicholas Husin <nsh@golang.org> Reviewed-by: Nicholas Husin <husin@google.com>
This commit is contained in:
@@ -270,6 +270,9 @@ func parseEd25519Key(req []byte) (*AddedKey, error) {
|
||||
if err := ssh.Unmarshal(req, &k); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(k.Priv) != ed25519.PrivateKeySize {
|
||||
return nil, fmt.Errorf("agent: bad ED25519 key size: %d", len(k.Priv))
|
||||
}
|
||||
priv := ed25519.PrivateKey(k.Priv)
|
||||
|
||||
addedKey := &AddedKey{PrivateKey: &priv, Comment: k.Comments}
|
||||
@@ -336,6 +339,9 @@ func parseEd25519Cert(req []byte) (*AddedKey, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(k.Priv) != ed25519.PrivateKeySize {
|
||||
return nil, fmt.Errorf("agent: bad ED25519 key size: %d", len(k.Priv))
|
||||
}
|
||||
priv := ed25519.PrivateKey(k.Priv)
|
||||
cert, ok := pubKey.(*ssh.Certificate)
|
||||
if !ok {
|
||||
|
||||
@@ -271,3 +271,35 @@ func TestParseConstraints(t *testing.T) {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseEd25519KeyShortPanic(t *testing.T) {
|
||||
msg := ssh.Marshal(ed25519KeyMsg{
|
||||
Type: ssh.KeyAlgoED25519,
|
||||
Pub: []byte{1, 2, 3},
|
||||
Priv: []byte{1, 2, 3, 4, 5},
|
||||
})
|
||||
|
||||
a, b, err := netPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer a.Close()
|
||||
defer b.Close()
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() { done <- ServeAgent(NewKeyring(), a) }()
|
||||
|
||||
c := NewClient(b)
|
||||
_, err = c.(*client).call(msg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
keys, err := c.List()
|
||||
if err != nil {
|
||||
t.Fatalf("agent died: %v", err)
|
||||
}
|
||||
if len(keys) != 0 {
|
||||
t.Error("short ed25519 key was accepted into keyring")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user