From a45694a3567ce8de754cffa7b450c22578ebdd6c Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 12 Mar 2020 14:39:47 +0000 Subject: [PATCH] Make it possible to easily specify a libctx for EVP_DigestSign* EVP_DigestSignInit_ex and EVP_DigestVerifyInit_ex did not provide the capability to specify an explicit OPENSSL_CTX parameter. It is still possible by explicitly setting an EVP_PKEY_CTX - but in most cases it would be much simpler to just specify it in the Init call. We add the capability to do that. Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/11353) --- crypto/evp/m_sigver.c | 24 +++++++++++++++--------- doc/man3/EVP_DigestSignInit.pod | 6 ++++-- doc/man3/EVP_DigestVerifyInit.pod | 31 +++++++++++++++---------------- include/openssl/evp.h | 6 +++--- test/evp_extra_test.c | 3 ++- 5 files changed, 39 insertions(+), 31 deletions(-) diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index 1948f234ca..3d15a9fcbc 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -39,7 +39,7 @@ static const char *canon_mdname(const char *mdname) static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, const char *mdname, const char *props, ENGINE *e, EVP_PKEY *pkey, - int ver) + OPENSSL_CTX *libctx, int ver) { EVP_PKEY_CTX *locpctx = NULL; EVP_SIGNATURE *signature = NULL; @@ -59,8 +59,12 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, ctx->provctx = NULL; } - if (ctx->pctx == NULL) - ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + if (ctx->pctx == NULL) { + if (libctx != NULL) + ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props); + else + ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + } if (ctx->pctx == NULL) return 0; @@ -258,28 +262,30 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, } int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const char *mdname, const char *props, EVP_PKEY *pkey) + const char *mdname, const char *props, EVP_PKEY *pkey, + OPENSSL_CTX *libctx) { - return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, 0); + return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, libctx, + 0); } int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, 0); + return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 0); } int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const char *mdname, const char *props, - EVP_PKEY *pkey) + EVP_PKEY *pkey, OPENSSL_CTX *libctx) { - return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, 1); + return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, libctx, 1); } int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, 1); + return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 1); } #endif /* FIPS_MDOE */ diff --git a/doc/man3/EVP_DigestSignInit.pod b/doc/man3/EVP_DigestSignInit.pod index b5bd7bc3c7..d0c13bbc17 100644 --- a/doc/man3/EVP_DigestSignInit.pod +++ b/doc/man3/EVP_DigestSignInit.pod @@ -11,7 +11,7 @@ EVP_DigestSignFinal, EVP_DigestSign - EVP signing functions int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const char *mdname, const char *props, - EVP_PKEY *pkey); + EVP_PKEY *pkey, OPENSSL_CTX *libctx); int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); @@ -51,7 +51,9 @@ existing value in I<*pctx> is overwritten. The EVP_PKEY_CTX value returned must not be freed directly by the application if I is not assigned an EVP_PKEY_CTX value before being passed to EVP_DigestSignInit_ex() (which means the EVP_PKEY_CTX is created inside EVP_DigestSignInit_ex() and it will be freed -automatically when the EVP_MD_CTX is freed). +automatically when the EVP_MD_CTX is freed). If the EVP_PKEY_CTX to be used is +created by EVP_DigestSignInit_ex then it will use the B specified +in I and the property query string specified in I. The digest I may be NULL if the signing algorithm supports it. The I argument can always be NULL. diff --git a/doc/man3/EVP_DigestVerifyInit.pod b/doc/man3/EVP_DigestVerifyInit.pod index 5173abded0..9b5de646b0 100644 --- a/doc/man3/EVP_DigestVerifyInit.pod +++ b/doc/man3/EVP_DigestVerifyInit.pod @@ -11,7 +11,7 @@ EVP_DigestVerifyFinal, EVP_DigestVerify - EVP signature verification functions int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const char *mdname, const char *props, - EVP_PKEY *pkey, EVP_SIGNATURE *signature); + EVP_PKEY *pkey, OPENSSL_CTX *libctx); int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); @@ -26,20 +26,17 @@ The EVP signature routines are a high level interface to digital signatures. Input data is digested first before the signature verification takes place. EVP_DigestVerifyInit_ex() sets up verification context B to use a digest -with the name B and public key B. The signature algorithm -B will be used for the actual signature verification which must be -compatible with the public key. The name of the digest to be used is passed to -the provider of the signature algorithm in use. How that provider interprets the -digest name is provider specific. The provider may implement that digest -directly itself or it may (optionally) choose to fetch it (which could result in -a digest from a different provider being selected). If the provider supports -fetching the digest then it may use the B argument for the properties to -be used during the fetch. - -The B parameter may be NULL in which case a suitable signature -algorithm implementation will be implicitly fetched based on the type of key in -use. See L for further information about providers and fetching -algorithms. +with the name B and public key B. The name of the digest to be +used is passed to the provider of the signature algorithm in use. How that +provider interprets the digest name is provider specific. The provider may +implement that digest directly itself or it may (optionally) choose to fetch it +(which could result in a digest from a different provider being selected). If +the provider supports fetching the digest then it may use the B argument +for the properties to be used during the fetch. + +The I algorithm is used to fetch a B method implicitly, to +be used for the actual signing. See L for +more information about implict fetches. The OpenSSL default and legacy providers support fetching digests and can fetch those digests from any available provider. The OpenSSL fips provider also @@ -53,7 +50,9 @@ Note that any existing value in B<*pctx> is overwritten. The EVP_PKEY_CTX value returned must not be freed directly by the application if B is not assigned an EVP_PKEY_CTX value before being passed to EVP_DigestVerifyInit_ex() (which means the EVP_PKEY_CTX is created inside EVP_DigestVerifyInit_ex() and it will -be freed automatically when the EVP_MD_CTX is freed). +be freed automatically when the EVP_MD_CTX is freed). If the EVP_PKEY_CTX to be +used is created by EVP_DigestVerifyInit_ex then it will use the B +specified in I and the property query string specified in I. No B will be created by EVP_DigestSignInit_ex() if the passed B has already been assigned one via L. See also diff --git a/include/openssl/evp.h b/include/openssl/evp.h index a3e0581913..3487b27e0a 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -686,8 +686,8 @@ __owur int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t tbslen); int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const char *mdname, const char *props, - EVP_PKEY *pkey); + const char *mdname, const char *props, EVP_PKEY *pkey, + OPENSSL_CTX *libctx); /*__owur*/ int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); @@ -697,7 +697,7 @@ __owur int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const char *mdname, const char *props, - EVP_PKEY *pkey); + EVP_PKEY *pkey, OPENSSL_CTX *libctx); __owur int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index 68eb5ffdd3..07161ad8d8 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -1302,7 +1302,8 @@ static int test_EVP_PKEY_CTX_get_set_params(EVP_PKEY *pkey) */ mdctx = EVP_MD_CTX_new(); if (!TEST_ptr(mdctx) - || !TEST_true(EVP_DigestSignInit_ex(mdctx, NULL, "SHA1", NULL, pkey))) + || !TEST_true(EVP_DigestSignInit_ex(mdctx, NULL, "SHA1", NULL, pkey, + NULL))) goto err; /* -- 2.34.1