agessh: enforce the RSA key size when wrapping

Reported by Joe Doyle of Trail of Bits.
This commit is contained in:
Filippo Valsorda
2026-08-29 19:30:10 +02:00
parent b030f04671
commit 572b47c3e7
2 changed files with 32 additions and 1 deletions
+4 -1
View File
@@ -63,13 +63,16 @@ func NewRSARecipient(pk ssh.PublicKey) (*RSARecipient, error) {
} else {
return nil, errors.New("pk does not implement ssh.CryptoPublicKey")
}
if r.pubKey.Size() < 2048/8 {
if r.pubKey.N.BitLen() < 2048 {
return nil, errors.New("RSA key size is too small")
}
return r, nil
}
func (r *RSARecipient) Wrap(fileKey []byte) ([]*age.Stanza, error) {
if r.pubKey.N.BitLen() < 2048 {
return nil, errors.New("RSA key size is too small")
}
l := &age.Stanza{
Type: "ssh-rsa",
Args: []string{sshFingerprint(r.sshKey)},
+28
View File
@@ -10,6 +10,7 @@ import (
"crypto/rand"
"crypto/rsa"
"encoding/pem"
"math/big"
"reflect"
"testing"
@@ -17,6 +18,33 @@ import (
"golang.org/x/crypto/ssh"
)
func TestSSHRSAKeySize(t *testing.T) {
for _, bits := range []int{2041, 2047, 2048} {
n := new(big.Int).Lsh(big.NewInt(1), uint(bits-1))
n.SetBit(n, 0, 1)
pub, err := ssh.NewPublicKey(&rsa.PublicKey{N: n, E: 65537})
if err != nil {
t.Fatal(err)
}
_, err = agessh.NewRSARecipient(pub)
if rejected, want := err != nil, bits < 2048; rejected != want {
t.Errorf("%d-bit key: rejected = %v, want %v", bits, rejected, want)
}
}
key, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
t.Fatal(err)
}
id, err := agessh.NewRSAIdentity(key)
if err != nil {
t.Fatal(err)
}
if _, err := id.Recipient().Wrap(make([]byte, 16)); err == nil {
t.Error("RSAIdentity.Recipient accepted a 1024-bit key")
}
}
func TestSSHRSARoundTrip(t *testing.T) {
pk, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {