summaryrefslogtreecommitdiffstats
path: root/crypto/evp/m_sigver.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/evp/m_sigver.c')
-rw-r--r--crypto/evp/m_sigver.c64
1 files changed, 33 insertions, 31 deletions
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 70669c3e6d..55675c36e1 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -81,34 +81,21 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
goto legacy;
/*
- * Ensure that the key is provided, either natively, or as a cached export.
+ * Try to derive the supported signature from |locpctx->keymgmt|.
*/
- tmp_keymgmt = locpctx->keymgmt;
- provkey = evp_pkey_export_to_provider(locpctx->pkey, locpctx->libctx,
- &tmp_keymgmt, locpctx->propquery);
- if (provkey == NULL) {
+ if (!ossl_assert(locpctx->pkey->keymgmt == NULL
+ || locpctx->pkey->keymgmt == locpctx->keymgmt)) {
ERR_clear_last_mark();
- ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+ ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
goto err;
}
- if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
+ supported_sig = evp_keymgmt_util_query_operation_name(locpctx->keymgmt,
+ OSSL_OP_SIGNATURE);
+ if (supported_sig == NULL) {
ERR_clear_last_mark();
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
goto err;
}
- EVP_KEYMGMT_free(locpctx->keymgmt);
- locpctx->keymgmt = tmp_keymgmt;
-
- if (locpctx->keymgmt->query_operation_name != NULL)
- supported_sig =
- locpctx->keymgmt->query_operation_name(OSSL_OP_SIGNATURE);
-
- /*
- * If we didn't get a supported sig, assume there is one with the
- * same name as the key type.
- */
- if (supported_sig == NULL)
- supported_sig = locpctx->keytype;
/*
* Because we cleared out old ops, we shouldn't need to worry about
@@ -117,21 +104,32 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
signature = EVP_SIGNATURE_fetch(locpctx->libctx, supported_sig,
locpctx->propquery);
- if (signature == NULL
- || (EVP_KEYMGMT_get0_provider(locpctx->keymgmt)
- != EVP_SIGNATURE_get0_provider(signature))) {
- /*
- * We don't need to free ctx->keymgmt here, as it's not necessarily
- * tied to this operation. It will be freed by EVP_PKEY_CTX_free().
- */
- EVP_SIGNATURE_free(signature);
+ if (signature == NULL)
goto legacy;
- }
/*
- * If we don't have the full support we need with provided methods,
- * let's go see if legacy does.
+ * Ensure that the key is provided, either natively, or as a cached export.
+ * We start by fetching the keymgmt with the same name as |locpctx->pkey|,
+ * but from the provider of the signature method, using the same property
+ * query as when fetching the signature method.
+ * With the keymgmt we found (if we did), we try to export |locpctx->pkey|
+ * to it (evp_pkey_export_to_provider() is smart enough to only actually
+
+ * export it if |tmp_keymgmt| is different from |locpctx->pkey|'s keymgmt)
*/
+ tmp_keymgmt
+ = evp_keymgmt_fetch_from_prov(EVP_SIGNATURE_get0_provider(signature),
+ EVP_KEYMGMT_get0_name(locpctx->keymgmt),
+ locpctx->propquery);
+ if (tmp_keymgmt != NULL)
+ provkey = evp_pkey_export_to_provider(locpctx->pkey, locpctx->libctx,
+ &tmp_keymgmt, locpctx->propquery);
+ if (provkey == NULL) {
+ ERR_clear_last_mark();
+ ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+ goto err;
+ }
+
ERR_pop_to_mark();
/* No more legacy from here down to legacy: */
@@ -221,6 +219,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
err:
evp_pkey_ctx_free_old_ops(locpctx);
locpctx->operation = EVP_PKEY_OP_UNDEFINED;
+ EVP_KEYMGMT_free(tmp_keymgmt);
return 0;
legacy:
@@ -229,6 +228,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
* let's go see if legacy does.
*/
ERR_pop_to_mark();
+ EVP_KEYMGMT_free(tmp_keymgmt);
+ tmp_keymgmt = NULL;
if (type == NULL && mdname != NULL)
type = evp_get_digestbyname_ex(locpctx->libctx, mdname);
@@ -299,6 +300,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
ret = evp_pkey_ctx_use_cached_data(locpctx);
#endif
+ EVP_KEYMGMT_free(tmp_keymgmt);
return ret > 0 ? 1 : 0;
}