summaryrefslogtreecommitdiffstats
path: root/crypto/evp/m_sigver.c
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-01-14 14:11:47 +0100
committerRichard Levitte <levitte@openssl.org>2020-01-18 05:27:50 +0100
commitf6aa57741254723b0c32f0dfe1ed8ad886b43c80 (patch)
tree203488625e054b4f1624066a87d428c0a8568c7d /crypto/evp/m_sigver.c
parentCORE: renumber OSSL_FUNC_KEYMGMT macros (diff)
downloadopenssl-f6aa57741254723b0c32f0dfe1ed8ad886b43c80.tar.xz
openssl-f6aa57741254723b0c32f0dfe1ed8ad886b43c80.zip
EVP: Add evp_pkey_make_provided() and refactor around it
The code to ensure that an EVP_PKEY is exported to providers is repeated all over the place, enough that copying it again has the usual future hazards with code copying. Instead, we refactor that code into one function, evp_pkey_make_provided(), and make sure to use that everywhere. It relies on the creation of EVP_PKEY_CTX to figure out facts about the input key, should it need to. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/10850)
Diffstat (limited to 'crypto/evp/m_sigver.c')
-rw-r--r--crypto/evp/m_sigver.c61
1 files changed, 30 insertions, 31 deletions
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index dbfa01b3ed..20c0a1ad59 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -31,6 +31,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
{
EVP_PKEY_CTX *locpctx = NULL;
EVP_SIGNATURE *signature = NULL;
+ EVP_KEYMGMT *tmp_keymgmt = NULL;
+ const char *supported_sig = NULL;
void *provkey = NULL;
int ret;
@@ -71,33 +73,38 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
}
}
- if (locpctx->keymgmt == NULL)
- locpctx->keymgmt = EVP_KEYMGMT_fetch(locpctx->libctx, locpctx->keytype,
- locpctx->propquery);
- if (locpctx->keymgmt != NULL) {
- const char *supported_sig = NULL;
+ /* Ensure that the key is provided. If not, go legacy */
+ tmp_keymgmt = locpctx->keymgmt;
+ provkey = evp_pkey_make_provided(locpctx->pkey, locpctx->libctx,
+ &tmp_keymgmt, locpctx->propquery, 0);
+ if (provkey == NULL)
+ goto legacy;
+ if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
+ 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 (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;
+ /*
+ * 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
- * checking if signature is already there.
- */
- signature = EVP_SIGNATURE_fetch(locpctx->libctx, supported_sig,
- locpctx->propquery);
- }
+ /*
+ * Because we cleared out old ops, we shouldn't need to worry about
+ * checking if signature is already there.
+ */
+ signature = EVP_SIGNATURE_fetch(locpctx->libctx, supported_sig,
+ locpctx->propquery);
- if (locpctx->keymgmt == NULL
- || signature == NULL
+ if (signature == NULL
|| (EVP_KEYMGMT_provider(locpctx->keymgmt)
!= EVP_SIGNATURE_provider(signature))) {
/*
@@ -113,16 +120,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
/* No more legacy from here down to legacy: */
locpctx->op.sig.signature = signature;
-
- provkey =
- evp_keymgmt_export_to_provider(locpctx->pkey, locpctx->keymgmt, 0);
- /* If export failed, legacy may be able to pick it up */
- if (provkey == NULL)
- goto legacy;
-
locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX
: EVP_PKEY_OP_SIGNCTX;
-
locpctx->op.sig.sigprovctx
= signature->newctx(ossl_provider_ctx(signature->prov));
if (locpctx->op.sig.sigprovctx == NULL) {