Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/crypto: restrict RSA keys to <= 8192 bits #2454

Merged
merged 5 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions core/crypto/rsa_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ const WeakRsaKeyEnv = "LIBP2P_ALLOW_WEAK_RSA_KEYS"

var MinRsaKeyBits = 2048

var maxRsaKeyBits = 8192

// ErrRsaKeyTooSmall is returned when trying to generate or parse an RSA key
// that's smaller than MinRsaKeyBits bits. In test
var ErrRsaKeyTooSmall error
var ErrRsaKeyTooBig error = fmt.Errorf("rsa keys must be <= %d bits", maxRsaKeyBits)

func init() {
if _, ok := os.LookupEnv(WeakRsaKeyEnv); ok {
Expand Down
9 changes: 9 additions & 0 deletions core/crypto/rsa_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) {
if bits < MinRsaKeyBits {
return nil, nil, ErrRsaKeyTooSmall
}
if bits > maxRsaKeyBits {
return nil, nil, ErrRsaKeyTooBig
}
priv, err := rsa.GenerateKey(src, bits)
if err != nil {
return nil, nil, err
Expand Down Expand Up @@ -124,6 +127,9 @@ func UnmarshalRsaPrivateKey(b []byte) (key PrivKey, err error) {
if sk.N.BitLen() < MinRsaKeyBits {
return nil, ErrRsaKeyTooSmall
}
if sk.N.BitLen() > maxRsaKeyBits {
return nil, ErrRsaKeyTooBig
}
return &RsaPrivateKey{sk: *sk}, nil
}

Expand All @@ -141,6 +147,9 @@ func UnmarshalRsaPublicKey(b []byte) (key PubKey, err error) {
if pk.N.BitLen() < MinRsaKeyBits {
return nil, ErrRsaKeyTooSmall
}
if pk.N.BitLen() > maxRsaKeyBits {
return nil, ErrRsaKeyTooBig
}

return &RsaPublicKey{k: *pk}, nil
}
38 changes: 38 additions & 0 deletions core/crypto/rsa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,44 @@ func TestRSASmallKey(t *testing.T) {
}
}

func TestRSABigKeyFailsToGenerate(t *testing.T) {
_, _, err := GenerateRSAKeyPair(maxRsaKeyBits*2, rand.Reader)
if err != ErrRsaKeyTooBig {
t.Fatal("should have refused to create too big RSA key")
}
}

func TestRSABigKey(t *testing.T) {
// Make the global limit smaller for this test to run faster.
// Note we also change the limit below, but this is different
origSize := maxRsaKeyBits
maxRsaKeyBits = 2048
defer func() { maxRsaKeyBits = origSize }() //

maxRsaKeyBits *= 2
badPriv, badPub, err := GenerateRSAKeyPair(maxRsaKeyBits, rand.Reader)
if err != nil {
t.Fatalf("should have succeeded, got: %s", err)
}
pubBytes, err := MarshalPublicKey(badPub)
if err != nil {
t.Fatal(err)
}
privBytes, err := MarshalPrivateKey(badPriv)
if err != nil {
t.Fatal(err)
}
maxRsaKeyBits /= 2
_, err = UnmarshalPublicKey(pubBytes)
if err != ErrRsaKeyTooBig {
t.Fatal("should have refused to unmarshal a too big key")
}
_, err = UnmarshalPrivateKey(privBytes)
if err != ErrRsaKeyTooBig {
t.Fatal("should have refused to unmarshal a too big key")
}
}

func TestRSASignZero(t *testing.T) {
priv, pub, err := GenerateRSAKeyPair(2048, rand.Reader)
if err != nil {
Expand Down