Skip to content

Commit

Permalink
crypto/x509: don't panic marshaling invalid ECDSA keys
Browse files Browse the repository at this point in the history
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 golang#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>
  • Loading branch information
FiloSottile authored and gopherbot committed Aug 25, 2022
1 parent b9bf824 commit f64f12f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/crypto/x509/sec1.go
Expand Up @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion src/crypto/x509/x509.go
Expand Up @@ -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)
Expand Down
14 changes: 14 additions & 0 deletions src/crypto/x509/x509_test.go
Expand Up @@ -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)
Expand Down

0 comments on commit f64f12f

Please sign in to comment.