evp_pkey_ctx_free_old_ops(ctx);
ctx->operation = EVP_PKEY_OP_DERIVE;
- if (ctx->engine != NULL || ctx->algorithm == NULL)
+ if (ctx->engine != NULL || ctx->keytype == NULL)
goto legacy;
- /*
- * Because we cleared out old ops, we shouldn't need to worry about
- * checking if exchange is already there. Keymgmt is a different
- * matter, as it isn't tied to a specific EVP_PKEY op.
- */
- exchange = EVP_KEYEXCH_fetch(ctx->libctx, ctx->algorithm, ctx->propquery);
- if (exchange != NULL && ctx->keymgmt == NULL) {
- int name_id = EVP_KEYEXCH_number(exchange);
-
+ if (ctx->keymgmt == NULL)
ctx->keymgmt =
- evp_keymgmt_fetch_by_number(ctx->libctx, name_id, ctx->propquery);
+ EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery);
+ if (ctx->keymgmt != NULL) {
+ const char *supported_exch = NULL;
+
+ if (ctx->keymgmt->query_operation_name != NULL)
+ supported_exch =
+ ctx->keymgmt->query_operation_name(OSSL_OP_KEYEXCH);
+
+ /*
+ * If we didn't get a supported exch, assume there is one with the
+ * same name as the key type.
+ */
+ if (supported_exch == NULL)
+ supported_exch = ctx->keytype;
+
+ /*
+ * Because we cleared out old ops, we shouldn't need to worry about
+ * checking if exchange is already there.
+ */
+ exchange =
+ EVP_KEYEXCH_fetch(ctx->libctx, supported_exch, ctx->propquery);
}
if (ctx->keymgmt == NULL