diff --git a/agessh/agessh.go b/agessh/agessh.go index dc3a2a3..27be67d 100644 --- a/agessh/agessh.go +++ b/agessh/agessh.go @@ -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)}, diff --git a/agessh/agessh_test.go b/agessh/agessh_test.go index fe1b23e..eef82d0 100644 --- a/agessh/agessh_test.go +++ b/agessh/agessh_test.go @@ -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 {