Flag to disable automatic copying of contexts.
Some functions such as EVP_VerifyFinal only finalise a copy of the passed context in case an application wants to digest more data. Doing this when it is not needed is inefficient and many applications don't require it. For compatibility the default is to still finalise a copy unless the flag EVP_MD_CTX_FLAG_FINALISE is set in which case the passed context is finalised an *no* further data can be digested after finalisation.
This commit is contained in:
parent
629b640bbc
commit
afa23c46d9
@ -300,6 +300,12 @@ struct env_md_ctx_st
|
||||
#define EVP_MD_CTX_FLAG_PAD_PSS 0x20 /* PSS mode */
|
||||
|
||||
#define EVP_MD_CTX_FLAG_NO_INIT 0x0100 /* Don't initialize md_data */
|
||||
/* Some functions such as EVP_DigestSign only finalise copies of internal
|
||||
* contexts so additional data can be included after the finalisation call.
|
||||
* This is inefficient if this functionality is not required: it is disabled
|
||||
* if the following flag is set.
|
||||
*/
|
||||
#define EVP_MD_CTX_FLAG_FINALISE 0x0200
|
||||
|
||||
struct evp_cipher_st
|
||||
{
|
||||
|
@ -140,14 +140,18 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
|
||||
EVP_PKEY_CTX *pctx = ctx->pctx;
|
||||
if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
|
||||
{
|
||||
EVP_PKEY_CTX *dctx;
|
||||
if (!sigret)
|
||||
return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
|
||||
dctx = EVP_PKEY_CTX_dup(ctx->pctx);
|
||||
if (!dctx)
|
||||
return 0;
|
||||
r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
|
||||
EVP_PKEY_CTX_free(dctx);
|
||||
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
|
||||
r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
|
||||
else
|
||||
{
|
||||
EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(ctx->pctx);
|
||||
if (!dctx)
|
||||
return 0;
|
||||
r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
|
||||
EVP_PKEY_CTX_free(dctx);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
if (pctx->pmeth->signctx)
|
||||
@ -156,18 +160,29 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
|
||||
sctx = 0;
|
||||
if (sigret)
|
||||
{
|
||||
EVP_MD_CTX tmp_ctx;
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
unsigned int mdlen;
|
||||
EVP_MD_CTX_init(&tmp_ctx);
|
||||
if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
|
||||
return 0;
|
||||
if (sctx)
|
||||
r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
|
||||
sigret, siglen, &tmp_ctx);
|
||||
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
|
||||
{
|
||||
if (sctx)
|
||||
r = ctx->pctx->pmeth->signctx(ctx->pctx,
|
||||
sigret, siglen, ctx);
|
||||
else
|
||||
r = EVP_DigestFinal_ex(ctx, md, &mdlen);
|
||||
}
|
||||
else
|
||||
r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
|
||||
EVP_MD_CTX_cleanup(&tmp_ctx);
|
||||
{
|
||||
EVP_MD_CTX tmp_ctx;
|
||||
EVP_MD_CTX_init(&tmp_ctx);
|
||||
if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
|
||||
return 0;
|
||||
if (sctx)
|
||||
r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
|
||||
sigret, siglen, &tmp_ctx);
|
||||
else
|
||||
r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
|
||||
EVP_MD_CTX_cleanup(&tmp_ctx);
|
||||
}
|
||||
if (sctx || !r)
|
||||
return r;
|
||||
if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
|
||||
@ -192,7 +207,6 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
|
||||
|
||||
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen)
|
||||
{
|
||||
EVP_MD_CTX tmp_ctx;
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
int r;
|
||||
unsigned int mdlen;
|
||||
@ -202,17 +216,31 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen)
|
||||
vctx = 1;
|
||||
else
|
||||
vctx = 0;
|
||||
EVP_MD_CTX_init(&tmp_ctx);
|
||||
if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
|
||||
return -1;
|
||||
if (vctx)
|
||||
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
|
||||
{
|
||||
r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
|
||||
sig, siglen, &tmp_ctx);
|
||||
if (vctx)
|
||||
{
|
||||
r = ctx->pctx->pmeth->verifyctx(ctx->pctx,
|
||||
sig, siglen, ctx);
|
||||
}
|
||||
else
|
||||
r = EVP_DigestFinal_ex(ctx, md, &mdlen);
|
||||
}
|
||||
else
|
||||
r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
|
||||
EVP_MD_CTX_cleanup(&tmp_ctx);
|
||||
{
|
||||
EVP_MD_CTX tmp_ctx;
|
||||
EVP_MD_CTX_init(&tmp_ctx);
|
||||
if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
|
||||
return -1;
|
||||
if (vctx)
|
||||
{
|
||||
r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
|
||||
sig, siglen, &tmp_ctx);
|
||||
}
|
||||
else
|
||||
r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
|
||||
EVP_MD_CTX_cleanup(&tmp_ctx);
|
||||
}
|
||||
if (vctx || !r)
|
||||
return r;
|
||||
return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
|
||||
|
@ -81,16 +81,26 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
|
||||
unsigned char m[EVP_MAX_MD_SIZE];
|
||||
unsigned int m_len;
|
||||
int i = 0,ok = 0,v;
|
||||
EVP_MD_CTX tmp_ctx;
|
||||
EVP_PKEY_CTX *pkctx = NULL;
|
||||
|
||||
*siglen=0;
|
||||
EVP_MD_CTX_init(&tmp_ctx);
|
||||
if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
|
||||
goto err;
|
||||
if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len))
|
||||
goto err;
|
||||
EVP_MD_CTX_cleanup(&tmp_ctx);
|
||||
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
|
||||
{
|
||||
if (!EVP_DigestFinal_ex(ctx, m, &m_len))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
int rv;
|
||||
EVP_MD_CTX tmp_ctx;
|
||||
EVP_MD_CTX_init(&tmp_ctx);
|
||||
rv = EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
|
||||
if (rv)
|
||||
rv = EVP_DigestFinal_ex(&tmp_ctx, m, &m_len);
|
||||
EVP_MD_CTX_cleanup(&tmp_ctx);
|
||||
if (!rv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
|
||||
{
|
||||
@ -133,7 +143,7 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
|
||||
EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
|
||||
return(0);
|
||||
}
|
||||
return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
|
||||
pkey->pkey.ptr));
|
||||
return ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
|
||||
pkey->pkey.ptr);
|
||||
}
|
||||
|
||||
|
@ -68,15 +68,25 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
|
||||
unsigned char m[EVP_MAX_MD_SIZE];
|
||||
unsigned int m_len;
|
||||
int i = 0,ok = 0,v;
|
||||
EVP_MD_CTX tmp_ctx;
|
||||
EVP_PKEY_CTX *pkctx = NULL;
|
||||
|
||||
EVP_MD_CTX_init(&tmp_ctx);
|
||||
if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
|
||||
goto err;
|
||||
if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len))
|
||||
goto err;
|
||||
EVP_MD_CTX_cleanup(&tmp_ctx);
|
||||
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
|
||||
{
|
||||
if (!EVP_DigestFinal_ex(ctx, m, &m_len))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
int rv;
|
||||
EVP_MD_CTX tmp_ctx;
|
||||
EVP_MD_CTX_init(&tmp_ctx);
|
||||
rv = EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
|
||||
if (rv)
|
||||
rv = EVP_DigestFinal_ex(&tmp_ctx, m, &m_len);
|
||||
EVP_MD_CTX_cleanup(&tmp_ctx);
|
||||
if (!rv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user