aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippo Valsorda <filippo@golang.org>2022-08-09 13:02:57 -0700
committerHeschi Kreinick <heschi@google.com>2022-08-29 19:14:33 +0000
commit2553a09e31d1a87072c7a68e352cd404df95b23d (patch)
tree49eea807829cf23d9175c18bbe88f6fd3ab697ca
parent28335508913a46e05ef0c04a18e8a1a6beb775ec (diff)
downloadgo-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.go3
-rw-r--r--src/crypto/x509/x509.go5
-rw-r--r--src/crypto/x509/x509_test.go14
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)