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 <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/11353)
This commit is contained in:
Matt Caswell 2020-03-12 14:39:47 +00:00
parent 0996cff91f
commit a45694a356
5 changed files with 38 additions and 30 deletions

View File

@ -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 */

View File

@ -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<ctx> 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<OPENSSL_CTX> specified
in I<libctx> and the property query string specified in I<props>.
The digest I<mdname> may be NULL if the signing algorithm supports it. The
I<props> argument can always be NULL.

View File

@ -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<ctx> to use a digest
with the name B<mdname> and public key B<pkey>. The signature algorithm
B<signature> 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<props> argument for the properties to
be used during the fetch.
with the name B<mdname> and public key B<pkey>. 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<props> argument
for the properties to be used during the fetch.
The B<signature> 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<provider(7)> for further information about providers and fetching
algorithms.
The I<pkey> algorithm is used to fetch a B<EVP_SIGNATURE> method implicitly, to
be used for the actual signing. See L<provider(7)/Implicit fetch> 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<ctx> 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<OPENSSL_CTX>
specified in I<libctx> and the property query string specified in I<props>.
No B<EVP_PKEY_CTX> will be created by EVP_DigestSignInit_ex() if the passed
B<ctx> has already been assigned one via L<EVP_MD_CTX_set_pkey_ctx(3)>. See also

View File

@ -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);

View File

@ -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;
/*