diff options
author | Filippo Valsorda <filippo@golang.org> | 2022-08-09 13:02:57 -0700 |
---|---|---|
committer | Heschi Kreinick <heschi@google.com> | 2022-08-29 19:14:33 +0000 |
commit | 2553a09e31d1a87072c7a68e352cd404df95b23d (patch) | |
tree | 49eea807829cf23d9175c18bbe88f6fd3ab697ca | |
parent | 28335508913a46e05ef0c04a18e8a1a6beb775ec (diff) | |
download | go-2553a09e31d1a87072c7a68e352cd404df95b23d.tar.gz go-2553a09e31d1a87072c7a68e352cd404df95b23d.zip |
[release-branch.go1.19] crypto/x509: don't panic marshaling invalid ECDSA keys
MarshalPKIXPublicKey, CreateCertificate, CreateCertificateRequest,
MarshalECPrivateKey, and MarshalPKCS8PrivateKey started raising a panic
when encoding an invalid ECDSA key in Go 1.19. Since they have an error
return value, they should return an error instead.
Updates #54288
Fixes #54295
Change-Id: Iba132cd2f890ece36bb7d0396eb9a9a77bdb81df
Reviewed-on: https://go-review.googlesource.com/c/go/+/422298
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit f64f12f0b32eba7d49c259480e0fa0c79eb47600)
Reviewed-on: https://go-review.googlesource.com/c/go/+/425634
-rw-r--r-- | src/crypto/x509/sec1.go | 3 | ||||
-rw-r--r-- | src/crypto/x509/x509.go | 5 | ||||
-rw-r--r-- | src/crypto/x509/x509_test.go | 14 |
3 files changed, 21 insertions, 1 deletions
diff --git a/src/crypto/x509/sec1.go b/src/crypto/x509/sec1.go index 8053ff5cda..ff48e0cc9e 100644 --- a/src/crypto/x509/sec1.go +++ b/src/crypto/x509/sec1.go @@ -54,6 +54,9 @@ func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) { // marshalECPrivateKey marshals an EC private key into ASN.1, DER format and // sets the curve ID to the given OID, or omits it if OID is nil. func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) { + if !key.Curve.IsOnCurve(key.X, key.Y) { + return nil, errors.New("invalid elliptic key public key") + } privateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8) return asn1.Marshal(ecPrivateKey{ Version: 1, diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go index 950f6d08c8..7c64761bd7 100644 --- a/src/crypto/x509/x509.go +++ b/src/crypto/x509/x509.go @@ -84,11 +84,14 @@ func marshalPublicKey(pub any) (publicKeyBytes []byte, publicKeyAlgorithm pkix.A // RFC 3279, Section 2.3.1. publicKeyAlgorithm.Parameters = asn1.NullRawValue case *ecdsa.PublicKey: - publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) oid, ok := oidFromNamedCurve(pub.Curve) if !ok { return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve") } + if !pub.Curve.IsOnCurve(pub.X, pub.Y) { + return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: invalid elliptic curve public key") + } + publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA var paramBytes []byte paramBytes, err = asn1.Marshal(oid) diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go index cba44f6f8c..b1cdabba28 100644 --- a/src/crypto/x509/x509_test.go +++ b/src/crypto/x509/x509_test.go @@ -68,6 +68,20 @@ func TestPKCS1MismatchPublicKeyFormat(t *testing.T) { } } +func TestMarshalInvalidPublicKey(t *testing.T) { + _, err := MarshalPKIXPublicKey(&ecdsa.PublicKey{}) + if err == nil { + t.Errorf("expected error, got MarshalPKIXPublicKey success") + } + _, err = MarshalPKIXPublicKey(&ecdsa.PublicKey{ + Curve: elliptic.P256(), + X: big.NewInt(1), Y: big.NewInt(2), + }) + if err == nil { + t.Errorf("expected error, got MarshalPKIXPublicKey success") + } +} + func testParsePKIXPublicKey(t *testing.T, pemBytes string) (pub any) { block, _ := pem.Decode([]byte(pemBytes)) pub, err := ParsePKIXPublicKey(block.Bytes) |