diff options
author | Tomas Mraz <tomas@openssl.org> | 2022-01-05 16:50:00 +0100 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2022-01-10 17:31:57 +0100 |
commit | 64a8f6008acce93d0bf184559c63e66c0cc0e23d (patch) | |
tree | e0c48468bc64b145fecdf5305d4b93fa02e237c7 /crypto | |
parent | 328bf5adf9e23da523d4195db309083aa02403c4 (diff) |
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 <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17425)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/evp/exchange.c | 24 |
1 files 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 |