From b7c913c820a80f8534ead1dc49b569280fcb1f9a Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 29 Mar 2019 16:28:07 +0000 Subject: [PATCH] Ensure EVP_MD_CTX_md returns the EVP_MD originally used Fixes #8613 Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/8614) --- crypto/evp/digest.c | 4 ++++ crypto/evp/evp_lib.c | 4 ++-- crypto/evp/evp_locl.h | 1 + doc/man3/EVP_DigestInit.pod | 7 ++++++- doc/man3/EVP_MD_fetch.pod | 22 +++++++++++++++++----- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 7b4972553b..89f8e54a91 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -83,6 +83,7 @@ void EVP_MD_CTX_free(EVP_MD_CTX *ctx) EVP_MD_meth_free(ctx->fetched_digest); ctx->fetched_digest = NULL; ctx->digest = NULL; + ctx->reqdigest = NULL; OPENSSL_free(ctx); return; @@ -106,6 +107,9 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); + if (type != NULL) + ctx->reqdigest = type; + /* TODO(3.0): Legacy work around code below. Remove this */ #ifndef OPENSSL_NO_ENGINE /* diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 219ae532d1..f99e905e42 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -479,9 +479,9 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd, const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) { - if (!ctx) + if (ctx == NULL) return NULL; - return ctx->digest; + return ctx->reqdigest; } EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index 936824a851..2453effe1d 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -10,6 +10,7 @@ /* EVP_MD_CTX related stuff */ struct evp_md_ctx_st { + const EVP_MD *reqdigest; /* The original requested digest */ const EVP_MD *digest; ENGINE *engine; /* functional reference if 'digest' is * ENGINE-provided */ diff --git a/doc/man3/EVP_DigestInit.pod b/doc/man3/EVP_DigestInit.pod index 37cdb274c2..4f5e38c3a4 100644 --- a/doc/man3/EVP_DigestInit.pod +++ b/doc/man3/EVP_DigestInit.pod @@ -182,7 +182,12 @@ EVP_MD_meth_set_app_datasize(). =item EVP_MD_CTX_md() -Returns the B structure corresponding to the passed B. +Returns the B structure corresponding to the passed B. This +will be the same B object originally passed to EVP_DigestInit_ex() (or +other similar function) when the EVP_MD_CTX was first initialised. Note that +where explicit fetch is in use (see L) the value returned from +this function will not have its reference count incremented and therefore it +should not be used after the EVP_MD_CTX is freed. =item EVP_MD_CTX_set_update_fn() diff --git a/doc/man3/EVP_MD_fetch.pod b/doc/man3/EVP_MD_fetch.pod index 17481089f0..96536048bc 100644 --- a/doc/man3/EVP_MD_fetch.pod +++ b/doc/man3/EVP_MD_fetch.pod @@ -21,13 +21,13 @@ calculate the digest of input data using functions such as L, L and L. Digest implementations may be obtained in one of three ways, i.e. implicit -lookup, explicit lookup or user defined. +fetch, explicit fetch or user defined. =over 4 -=item Implicit Lookup +=item Implicit Fetch -With implicit lookup an application can use functions such as L, +With implicit fetch an application can use functions such as L, L or L to obtain an B object. When used in a function like L the actual implementation to be used will be fetched implicitly using default search criteria. Typically, @@ -35,9 +35,9 @@ be used will be fetched implicitly using default search criteria. Typically, have been loaded), this will return an implementation of the appropriate algorithm from the default provider. -=item Explicit Lookup +=item Explicit Fetch -With explicit lookup an application uses the EVP_MD_fetch() function to obtain +With explicit fetch an application uses the EVP_MD_fetch() function to obtain an algorithm implementation. An implementation with the given name and satisfying the search criteria specified in the B parameter will be looked for within the available providers and returned. See L @@ -83,6 +83,18 @@ The return value from a call to EVP_MD_fetch() must be freed by the caller using L. Note that EVP_MD objects are reference counted. See L. +=head1 NOTES + +Where an application that previously used implicit fetch is converted to use +explicit fetch care should be taken with the L function. +Specifically, this function returns the EVP_MD object orginally passed to +EVP_DigestInit_ex() (or other similar function). With implicit fetch the +returned EVP_MD object is guaranteed to be available throughout the application +lifetime. However, with explicit fetch EVP_MD objects are reference counted. +EVP_MD_CTX_md does not increment the reference count and so the returned EVP_MD +object may not be accessible beyond the lifetime of the EVP_MD_CTX it is +associated with. + =head1 RETURN VALUES EVP_MD_fetch() returns a pointer to the algorithm implementation represented by -- 2.39.2