From 2814906df029aea2130c7065d12be85634229861 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Sat, 27 Jun 2015 14:50:39 -0700 Subject: [PATCH] =?utf8?q?crypto/rsa:=20check=20for=20primes=20=E2=89=A4?= =?utf8?q?=201=20in=20Validate?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change 7c7126cfeb82894229b9c3d5109e4b04e6cfde0c removed the primality checking in Validate to save CPU time. That check happened to be filtering out private keys with primes that were zero or one. Without that filtering, such primes cause a panic when trying to use such a private key. This change specifically checks for and rejects primes ≤ 1 in Validate. Fixes #11233. Change-Id: Ie6537edb8250c07a45aaf50dab43227002ee7386 Reviewed-on: https://go-review.googlesource.com/11611 Reviewed-by: Brad Fitzpatrick Reviewed-by: Russ Cox --- src/crypto/rsa/rsa.go | 4 ++++ src/crypto/x509/x509_test.go | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go index 8a6014a5dc..1293b78367 100644 --- a/src/crypto/rsa/rsa.go +++ b/src/crypto/rsa/rsa.go @@ -146,6 +146,10 @@ func (priv *PrivateKey) Validate() error { // Check that Πprimes == n. modulus := new(big.Int).Set(bigOne) for _, prime := range priv.Primes { + // Any primes ≤ 1 will cause divide-by-zero panics later. + if prime.Cmp(bigOne) <= 0 { + return errors.New("crypto/rsa: invalid prime value") + } modulus.Mul(modulus, prime) } if modulus.Cmp(priv.N) != 0 { diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go index d83147bb29..f4f9fa2f7f 100644 --- a/src/crypto/x509/x509_test.go +++ b/src/crypto/x509/x509_test.go @@ -41,6 +41,13 @@ func TestParsePKCS1PrivateKey(t *testing.T) { priv.Primes[1].Cmp(rsaPrivateKey.Primes[1]) != 0 { t.Errorf("got:%+v want:%+v", priv, rsaPrivateKey) } + + // This private key includes an invalid prime that + // rsa.PrivateKey.Validate should reject. + data := []byte("0\x16\x02\x00\x02\x02\u007f\x00\x02\x0200\x02\x0200\x02\x02\x00\x01\x02\x02\u007f\x00") + if _, err := ParsePKCS1PrivateKey(data); err == nil { + t.Errorf("parsing invalid private key did not result in an error") + } } func TestParsePKIXPublicKey(t *testing.T) { -- 2.50.0