]> Cypherpunks.ru repositories - gostls13.git/commitdiff
crypto/x509: don't panic marshaling invalid ECDSA keys
authorFilippo Valsorda <filippo@golang.org>
Tue, 9 Aug 2022 20:02:57 +0000 (13:02 -0700)
committerGopher Robot <gobot@golang.org>
Thu, 25 Aug 2022 19:17:14 +0000 (19:17 +0000)
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.

Fixes #54288

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>
src/crypto/x509/sec1.go
src/crypto/x509/x509.go
src/crypto/x509/x509_test.go

index 8053ff5cda3e35a379f887f531dbfc0b5ab5a464..ff48e0cc9e51d1b4f24e807988481e245e9cba06 100644 (file)
@@ -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,
index 950f6d08c8fff9ac70be105b70b3eb5d3f7efd83..7c64761bd7603b11b68cb5a4536fd5265a6a98e3 100644 (file)
@@ -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)
index cba44f6f8c0f50168db9016329b9be2d68ebea3a..b1cdabba283066f3e047b21b95ccf1df0fa8f9ac 100644 (file)
@@ -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)