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