Skip to content

crypto/ecdsa: add NewPublicKey and PublicKey.Bytes #63963

Closed
@mrwonko

Description

@mrwonko

I'm working with the JS Web Push API to send push messages, which uses an ECDH Key in base64-encoded X9.62 uncompressed form, like BJ932huv68tUDxifpf6qlzuRa_JBF-2E9J47alSQRuxpmt3QFtiCnhqXlPgZuGWKZzcp5jAzQYeHpMUB990JiHM. I can easily parse that using ecdh.P256().NewPublicKey(base64DecodedBytes), but that yields an *ecdh.PublicKey, while all the cryptography functions need an *ecdsa.PublicKey.

There appears to be no straightforward conversion from *ecdh.PublicKey to *ecdsa.PublicKey, the best thing I've found is an x509 PKIX roundtrip:

func ecdhPublicKeyToECDSA(key *ecdh.PublicKey) (*ecdsa.PublicKey, error) {
	b, err := x509.MarshalPKIXPublicKey(key)
	if err != nil {
		return nil, fmt.Errorf("marshaling ecdh public key: %w", err)
	}
	parsedKey, err := x509.ParsePKIXPublicKey(b)
	if err != nil {
		return nil, fmt.Errorf("parsing marshaled ecdh public key: %w", err)
	}
	res, ok := parsedKey.(*ecdsa.PublicKey)
	if !ok {
		return nil, fmt.Errorf("x509.ParsePKIXPublicKey returned %T instead of *ecdsa.PublicKey", parsedKey)
	}
	return res, nil
}

That feels clunky, inefficient, and I lose type safety / need a type assertion. For the inverse conversion, there's already an ecdsa.PublicKey.ECDH() function. I propose adding something similar for ecdh to ecdsa conversion, both for public and private keys. I imagine it will have to be added to the ecdsa package to avoid cyclic imports.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Accepted

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions