summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2022-01-05 16:50:00 +0100
committerTomas Mraz <tomas@openssl.org>2022-01-10 17:37:09 +0100
commit617203e64f17371b95fc8d64fc7fde9f8bc6e9db (patch)
tree6d5a538243f547e922f3a149f254287cea175240 /crypto
parent7e1ec537a91d1f33c50e8f70dff82a4ed6668e9a (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) (cherry picked from commit 64a8f6008acce93d0bf184559c63e66c0cc0e23d)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/evp/exchange.c24
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