summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/evp/m_sigver.c37
-rw-r--r--crypto/evp/p_sign.c2
-rw-r--r--crypto/evp/p_verify.c2
-rw-r--r--doc/man3/EVP_DigestSignInit.pod7
-rw-r--r--doc/man3/EVP_DigestVerifyInit.pod9
-rw-r--r--doc/man3/EVP_SignInit.pod9
-rw-r--r--doc/man3/EVP_VerifyInit.pod9
7 files changed, 52 insertions, 23 deletions
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 630d339c35..68ae957058 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -462,7 +462,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
size_t *siglen)
{
int sctx = 0, r = 0;
- EVP_PKEY_CTX *dctx, *pctx = ctx->pctx;
+ EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
if (pctx == NULL
|| pctx->operation != EVP_PKEY_OP_SIGNCTX
@@ -470,17 +470,15 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
|| pctx->op.sig.signature == NULL)
goto legacy;
- if (sigret == NULL || (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0)
- return pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx,
- sigret, siglen,
- sigret == NULL ? 0 : *siglen);
- dctx = EVP_PKEY_CTX_dup(pctx);
- if (dctx == NULL)
- return 0;
-
- r = dctx->op.sig.signature->digest_sign_final(dctx->op.sig.algctx,
+ if (sigret != NULL && (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) {
+ /* try dup */
+ dctx = EVP_PKEY_CTX_dup(pctx);
+ if (dctx != NULL)
+ pctx = dctx;
+ }
+ r = pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx,
sigret, siglen,
- *siglen);
+ sigret == NULL ? 0 : *siglen);
EVP_PKEY_CTX_free(dctx);
return r;
@@ -589,7 +587,7 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
int r = 0;
unsigned int mdlen = 0;
int vctx = 0;
- EVP_PKEY_CTX *dctx, *pctx = ctx->pctx;
+ EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
if (pctx == NULL
|| pctx->operation != EVP_PKEY_OP_VERIFYCTX
@@ -597,14 +595,13 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
|| pctx->op.sig.signature == NULL)
goto legacy;
- if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0)
- return pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx,
- sig, siglen);
- dctx = EVP_PKEY_CTX_dup(pctx);
- if (dctx == NULL)
- return 0;
-
- r = dctx->op.sig.signature->digest_verify_final(dctx->op.sig.algctx,
+ if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) {
+ /* try dup */
+ dctx = EVP_PKEY_CTX_dup(pctx);
+ if (dctx != NULL)
+ pctx = dctx;
+ }
+ r = pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx,
sig, siglen);
EVP_PKEY_CTX_free(dctx);
return r;
diff --git a/crypto/evp/p_sign.c b/crypto/evp/p_sign.c
index 4eb34db267..ae0de57202 100644
--- a/crypto/evp/p_sign.c
+++ b/crypto/evp/p_sign.c
@@ -39,6 +39,8 @@ int EVP_SignFinal_ex(EVP_MD_CTX *ctx, unsigned char *sigret,
rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
if (rv)
rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
+ else
+ rv = EVP_DigestFinal_ex(ctx, m, &m_len);
EVP_MD_CTX_free(tmp_ctx);
if (!rv)
return 0;
diff --git a/crypto/evp/p_verify.c b/crypto/evp/p_verify.c
index eb5084f839..8478e643dd 100644
--- a/crypto/evp/p_verify.c
+++ b/crypto/evp/p_verify.c
@@ -37,6 +37,8 @@ int EVP_VerifyFinal_ex(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
if (rv)
rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
+ else
+ rv = EVP_DigestFinal_ex(ctx, m, &m_len);
EVP_MD_CTX_free(tmp_ctx);
if (!rv)
return 0;
diff --git a/doc/man3/EVP_DigestSignInit.pod b/doc/man3/EVP_DigestSignInit.pod
index fe4a686184..f38eefcbbf 100644
--- a/doc/man3/EVP_DigestSignInit.pod
+++ b/doc/man3/EVP_DigestSignInit.pod
@@ -166,6 +166,13 @@ external circumstances (see L<RAND(7)>), the operation will fail.
The call to EVP_DigestSignFinal() internally finalizes a copy of the digest
context. This means that calls to EVP_DigestSignUpdate() and
EVP_DigestSignFinal() can be called later to digest and sign additional data.
+Applications may disable this behavior by setting the EVP_MD_CTX_FLAG_FINALISE
+context flag via L<EVP_MD_CTX_set_flags(3)>.
+
+Note that not all providers support continuation, in case the selected
+provider does not allow to duplicate contexts EVP_DigestSignFinal() will
+finalize the digest context and attempting to process additional data via
+EVP_DigestSignUpdate() will result in an error.
EVP_DigestSignInit() and EVP_DigestSignInit_ex() functions can be called
multiple times on a context and the parameters set by previous calls should be
diff --git a/doc/man3/EVP_DigestVerifyInit.pod b/doc/man3/EVP_DigestVerifyInit.pod
index d4bb8163d1..0dc8151a90 100644
--- a/doc/man3/EVP_DigestVerifyInit.pod
+++ b/doc/man3/EVP_DigestVerifyInit.pod
@@ -154,7 +154,14 @@ external circumstances (see L<RAND(7)>), the operation will fail.
The call to EVP_DigestVerifyFinal() internally finalizes a copy of the digest
context. This means that EVP_VerifyUpdate() and EVP_VerifyFinal() can
-be called later to digest and verify additional data.
+be called later to digest and verify additional data. Applications may disable
+this behavior by setting the EVP_MD_CTX_FLAG_FINALISE context flag via
+L<EVP_MD_CTX_set_flags(3)>.
+
+Note that not all providers support continuation, in case the selected
+provider does not allow to duplicate contexts EVP_DigestVerifyFinal() will
+finalize the digest context and attempting to process additional data via
+EVP_DigestVerifyUpdate() will result in an error.
EVP_DigestVerifyInit() and EVP_DigestVerifyInit_ex() functions can be called
multiple times on a context and the parameters set by previous calls should be
diff --git a/doc/man3/EVP_SignInit.pod b/doc/man3/EVP_SignInit.pod
index 11832ff761..c274ad9917 100644
--- a/doc/man3/EVP_SignInit.pod
+++ b/doc/man3/EVP_SignInit.pod
@@ -66,12 +66,19 @@ due to external circumstances (see L<RAND(7)>), the operation will fail.
The call to EVP_SignFinal() internally finalizes a copy of the digest context.
This means that calls to EVP_SignUpdate() and EVP_SignFinal() can be called
-later to digest and sign additional data.
+later to digest and sign additional data.cApplications may disable this
+behavior by setting the EVP_MD_CTX_FLAG_FINALISE context flag via
+L<EVP_MD_CTX_set_flags(3)>.
Since only a copy of the digest context is ever finalized the context must
be cleaned up after use by calling EVP_MD_CTX_free() or a memory leak
will occur.
+Note that not all providers support continuation, in case the selected
+provider does not allow to duplicate contexts EVP_SignFinal() will
+finalize the digest context and attempting to process additional data via
+EVP_SignUpdate() will result in an error.
+
=head1 BUGS
Older versions of this documentation wrongly stated that calls to
diff --git a/doc/man3/EVP_VerifyInit.pod b/doc/man3/EVP_VerifyInit.pod
index a6d5772c3b..f05b9135bf 100644
--- a/doc/man3/EVP_VerifyInit.pod
+++ b/doc/man3/EVP_VerifyInit.pod
@@ -62,12 +62,19 @@ transparent to the algorithm used and much more flexible.
The call to EVP_VerifyFinal() internally finalizes a copy of the digest context.
This means that calls to EVP_VerifyUpdate() and EVP_VerifyFinal() can be called
-later to digest and verify additional data.
+later to digest and verify additional data. Applications may disable this
+behavior by setting the EVP_MD_CTX_FLAG_FINALISE context flag via
+L<EVP_MD_CTX_set_flags(3)>.
Since only a copy of the digest context is ever finalized the context must
be cleaned up after use by calling EVP_MD_CTX_free() or a memory leak
will occur.
+Note that not all providers support continuation, in case the selected
+provider does not allow to duplicate contexts EVP_VerifyFinal() will
+finalize the digest context and attempting to process additional data via
+EVP_VerifyUpdate() will result in an error.
+
=head1 BUGS
Older versions of this documentation wrongly stated that calls to