diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index c380dca0b581c14f4148fc792c8755f8f663b024..8a2d162df186cbcfeb4be1fbffa748e3ddabb0e1 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -32,7 +32,12 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size); } - EVP_PKEY_CTX_free(ctx->pctx); + /* + * pctx should be freed by the user of EVP_MD_CTX + * if EVP_MD_CTX_FLAG_NEGLECT_PCTX is set + */ + if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_NEGLECT_PCTX)) + EVP_PKEY_CTX_free(ctx->pctx); #ifndef OPENSSL_NO_ENGINE ENGINE_finish(ctx->engine); #endif diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 6c48199f835cec55dd7f38c7a6351289c8fdcd72..4faaf694b4e6f8b85c25501f1778076fcf9abc5b 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -460,6 +460,13 @@ EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) return ctx->pctx; } +void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_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_NEGLECT_PCTX); +} + void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx) { return ctx->md_data; diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 185cc29b88e51b978848710f1240de8d73f32aed..d72c2104bc16b0efb84e65475253c531a5ac591d 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -181,6 +181,9 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd, */ # define EVP_MD_CTX_FLAG_FINALISE 0x0200 +/* Don't free up ctx->pctx in EVP_MD_CTX_reset */ +# define EVP_MD_CTX_FLAG_NEGLECT_PCTX 0x0400 + EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len); EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher); void EVP_CIPHER_meth_free(EVP_CIPHER *cipher); @@ -453,6 +456,7 @@ void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx, # define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) # define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) 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); void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx); int EVP_CIPHER_nid(const EVP_CIPHER *cipher); diff --git a/util/libcrypto.num b/util/libcrypto.num index 81171fe2dcc2de0061e1fa875198a89371b50c3d..c6c881f4c2eb26ae2bf67370a81851dcd8ba97b9 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4574,3 +4574,4 @@ EC_GROUP_set_curve 4527 1_1_1 EXIST::FUNCTION:EC EC_GROUP_get_curve 4528 1_1_1 EXIST::FUNCTION:EC OCSP_resp_get0_tbs_sigalg 4529 1_1_0j EXIST::FUNCTION:OCSP OCSP_resp_get0_respdata 4530 1_1_0j EXIST::FUNCTION:OCSP +EVP_MD_CTX_set_pkey_ctx 4531 1_1_1 EXIST::FUNCTION: