Openssl 3.0.0 creating ECC key from X and Y, PEM_write_PUBKEY fails

Matt Caswell matt at openssl.org
Mon Oct 25 14:05:14 UTC 2021



On 22/10/2021 21:02, Ken Goldman wrote:
> I have X and Y as bignums.  I create EVP_PKEY with this.
> 
> I suspect that I have to do another step to indicate that I supplied X 
> and Y and not a compressed
> public key.

Unfortunately supplying x and y separately is not supported for import. 
You have to instead use OSSL_PKEY_PARAM_PUB_KEY. You can supply the key 
as an uncompressed public key simply be concatenating the byte "04", the 
x co-ord (padded to the appropriate size if necessary) and the y co-cord 
(also padded as appropriate).

The OSSL_PKEY_PARAM_EC_PUB_X and OSSL_PKEY_PARAM_EC_PUB_Y parameters are 
defined as "getters" only. From the manual:


"qx" (OSSL_PKEY_PARAM_EC_PUB_X) <unsigned integer>
Used for getting the EC public key X component.

"qy" (OSSL_PKEY_PARAM_EC_PUB_Y) <unsigned integer>
Used for getting the EC public key Y component.

https://www.openssl.org/docs/man3.0/man7/EVP_PKEY-EC.html


>      param_bld = OSSL_PARAM_BLD_new();
>      rc = getEcCurveString(&curveString,        gets strings like 
> prime256v1
>      irc = OSSL_PARAM_BLD_push_utf8_string(param_bld, 
> OSSL_PKEY_PARAM_GROUP_NAME,
>                            curveString, 0);
>      irc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_EC_PUB_X, x);
>      irc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_EC_PUB_Y, y);
>      params = OSSL_PARAM_BLD_to_param(param_bld);
>      ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
>      irc = EVP_PKEY_fromdata_init(ctx);
>      irc = EVP_PKEY_fromdata(ctx, evpPubkey, EVP_PKEY_PUBLIC_KEY, params);

It's actually quite surprising that this call succeeds. IMO it should 
have failed:

https://github.com/openssl/openssl/issues/16912

What you've actually ended up with here is a parameters only EVP_PKEY value.

> 
> following that, this fails with
> 
>      irc = PEM_write_PUBKEY(pemFile, evpPubkey);
> 
> ==88032== Invalid read of size 8


This crash is a bug in OpenSSL. You should have got a failure because 
your EVP_PKEY doesn't have a public key in it:


https://github.com/openssl/openssl/pull/16911

Matt


More information about the openssl-users mailing list