The branch master has been updated via 64a8f6008acce93d0bf184559c63e66c0cc0e23d (commit) from 328bf5adf9e23da523d4195db309083aa02403c4 (commit)
- Log ----------------------------------------------------------------- commit 64a8f6008acce93d0bf184559c63e66c0cc0e23d Author: Tomas Mraz <to...@openssl.org> Date: Wed Jan 5 16:50:00 2022 +0100 EVP_PKEY_derive_set_peer_ex: Export the peer key to proper keymgmt The peer key has to be exported to the operation's keymgmt not the ctx->pkey's keymgmt. Fixes #17424 Reviewed-by: Paul Dale <pa...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/17425) ----------------------------------------------------------------------- Summary of changes: crypto/evp/exchange.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index e2ca30c94d..bd97a047c5 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -306,7 +306,7 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) /* * Ensure that the key is provided, either natively, or as a cached * export. We start by fetching the keymgmt with the same name as - * |ctx->pkey|, but from the provider of the exchange method, using + * |ctx->keymgmt|, but from the provider of the exchange method, using * the same property query as when fetching the exchange method. * With the keymgmt we found (if we did), we try to export |ctx->pkey| * to it (evp_pkey_export_to_provider() is smart enough to only actually @@ -380,6 +380,7 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer, int ret = 0, check; void *provkey = NULL; EVP_PKEY_CTX *check_ctx = NULL; + EVP_KEYMGMT *tmp_keymgmt = NULL, *tmp_keymgmt_tofree = NULL; if (ctx == NULL) { ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); @@ -404,8 +405,25 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer, return -1; } - provkey = evp_pkey_export_to_provider(peer, ctx->libctx, &ctx->keymgmt, - ctx->propquery); + /* + * Ensure that the |peer| is provided, either natively, or as a cached + * export. We start by fetching the keymgmt with the same name as + * |ctx->keymgmt|, but from the provider of the exchange method, using + * the same property query as when fetching the exchange method. + * With the keymgmt we found (if we did), we try to export |peer| + * to it (evp_pkey_export_to_provider() is smart enough to only actually + * export it if |tmp_keymgmt| is different from |peer|'s keymgmt) + */ + tmp_keymgmt_tofree = tmp_keymgmt = + evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *) + EVP_KEYEXCH_get0_provider(ctx->op.kex.exchange), + EVP_KEYMGMT_get0_name(ctx->keymgmt), + ctx->propquery); + if (tmp_keymgmt != NULL) + provkey = evp_pkey_export_to_provider(peer, ctx->libctx, + &tmp_keymgmt, ctx->propquery); + EVP_KEYMGMT_free(tmp_keymgmt_tofree); + /* * If making the key provided wasn't possible, legacy may be able to pick * it up