Ensure EVP_MD_CTX_md returns the EVP_MD originally used
authorMatt Caswell <matt@openssl.org>
Fri, 29 Mar 2019 16:28:07 +0000 (16:28 +0000)
committerMatt Caswell <matt@openssl.org>
Wed, 3 Apr 2019 14:44:36 +0000 (15:44 +0100)
Fixes #8613

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8614)

crypto/evp/digest.c
crypto/evp/evp_lib.c
crypto/evp/evp_locl.h
doc/man3/EVP_DigestInit.pod
doc/man3/EVP_MD_fetch.pod

index 7b4972553b92b618ce5b6727858759e2acbee766..89f8e54a91b232b40e278dac7dde71b4929c2fa6 100644 (file)
@@ -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
     /*
index 219ae532d1d4e4c3110cb0ea9f499af60f86a14e..f99e905e42af263f87428d41ddf37b63235df2da 100644 (file)
@@ -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)
index 936824a85132db2d1a6aaa2f182821e9e3f7150f..2453effe1d0f786314bd1d90872c617bebb9fe6f 100644 (file)
@@ -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 */
index 37cdb274c25a27d2aca5e2b703987035e3a9573b..4f5e38c3a433bc42729bd586c92abb0d2e743b4c 100644 (file)
@@ -182,7 +182,12 @@ EVP_MD_meth_set_app_datasize().
 
 =item EVP_MD_CTX_md()
 
-Returns the B<EVP_MD> structure corresponding to the passed B<EVP_MD_CTX>.
+Returns the B<EVP_MD> structure corresponding to the passed B<EVP_MD_CTX>. This
+will be the same B<EVP_MD> 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<EVP_MD_fetch(3)>) 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()
 
index 17481089f065db27a088f6c7f8f3e0a6b95ad06d..96536048bcd178863a7774905a808fe6b36287eb 100644 (file)
@@ -21,13 +21,13 @@ calculate the digest of input data using functions such as
 L<EVP_DigestInit_ex(3)>, L<EVP_DigestUpdate(3)> and L<EVP_DigestFinal_ex(3)>.
 
 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<EVP_sha256(3)>,
+With implicit fetch an application can use functions such as L<EVP_sha256(3)>,
 L<EVP_sha512(3)> or L<EVP_blake2b512(3)> to obtain an B<EVP_MD> object. When
 used in a function like L<EVP_DigestInit_ex(3)> 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<properties> parameter will be
 looked for within the available providers and returned. See L<OSSL_PROVIDER(3)>
@@ -83,6 +83,18 @@ The return value from a call to EVP_MD_fetch() must be freed by the caller using
 L<EVP_MD_meth_free(3)>. Note that EVP_MD objects are reference counted. See
 L<EVP_MD_upref(3)>.
 
+=head1 NOTES
+
+Where an application that previously used implicit fetch is converted to use
+explicit fetch care should be taken with the L<EVP_MD_CTX_md(3)> 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