Allow EVP_MD_CTX_set_pkey_ctx to accept NULL pctx
authorPaul Yang <yang.yang@baishancloud.com>
Wed, 5 Sep 2018 14:01:33 +0000 (22:01 +0800)
committerPaul Yang <yang.yang@baishancloud.com>
Fri, 7 Sep 2018 10:12:26 +0000 (18:12 +0800)
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7113)

crypto/evp/evp_lib.c
doc/man3/EVP_DigestInit.pod

index 81a5bf0..1b3c984 100644 (file)
@@ -462,9 +462,21 @@ EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx)
 
 void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx)
 {
+    /*
+     * it's reasonable to set NULL pctx (a.k.a clear the ctx->pctx), so
+     * we have to deal with the cleanup job here.
+     */
+    if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX))
+        EVP_PKEY_CTX_free(ctx->pctx);
+
     ctx->pctx = pctx;
-    /* make sure pctx is not freed when destroying EVP_MD_CTX */
-    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
+
+    if (pctx != NULL) {
+        /* make sure pctx is not freed when destroying EVP_MD_CTX */
+        EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
+    } else {
+        EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
+    }
 }
 
 void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx)
index 02e7719..9b74e41 100644 (file)
@@ -186,8 +186,10 @@ B<ASN1_OBJECT> structure respectively.
 
 Assigns an B<EVP_PKEY_CTX> to B<EVP_MD_CTX>. This is usually used to provide
 a customzied B<EVP_PKEY_CTX> to L<EVP_DigestSignInit(3)> or
-L<EVP_DigestVerifyInit(3)>. The B<EVP_PKEY_CTX> passed to this function should
-be freed by the caller.
+L<EVP_DigestVerifyInit(3)>. The B<pctx> passed to this function should be freed
+by the caller. A null B<pctx> pointer is also allowed to clear the B<EVP_PKEY_CTX>
+assigned to B<ctx>. In such case, freeing the cleared B<EVP_PKEY_CTX> or not
+depends on how the B<EVP_PKEY_CTX> is created.
 
 =back
 
@@ -374,7 +376,7 @@ later, so now EVP_sha1() can be used with RSA and DSA.
 
 EVP_dss1() was removed in OpenSSL 1.1.0.
 
-EVP_MD_CTX_set_pkey_ctx() is added in 1.1.1.
+EVP_MD_CTX_set_pkey_ctx() was added in 1.1.1.
 
 =head1 COPYRIGHT