From 86e5d9e5b215ca99895f2e3f13c0999de9d42c07 Mon Sep 17 00:00:00 2001 From: tb Date: Mon, 11 Sep 2023 09:24:14 +0000 Subject: [PATCH] Rewrite CMS_SignerInfo_{sign,verify}() Convert to using one-shot signing and verification. This is simpler than doing Init/Update/Final and necessary for Ed25519 support (RFC 8419). Use a single exit idiom, don't reuse the same buffer for decoding and signing and simplify a few other things. ok jsing --- lib/libcrypto/cms/cms_sd.c | 116 ++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 61 deletions(-) diff --git a/lib/libcrypto/cms/cms_sd.c b/lib/libcrypto/cms/cms_sd.c index 89ba5bf01f0..73f67ce4c32 100644 --- a/lib/libcrypto/cms/cms_sd.c +++ b/lib/libcrypto/cms/cms_sd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cms_sd.c,v 1.26 2023/07/08 08:26:26 beck Exp $ */ +/* $OpenBSD: cms_sd.c,v 1.27 2023/09/11 09:24:14 tb Exp $ */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -721,119 +721,113 @@ cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) int CMS_SignerInfo_sign(CMS_SignerInfo *si) { - EVP_MD_CTX *mctx = si->mctx; - EVP_PKEY_CTX *pctx = NULL; - unsigned char *abuf = NULL; - int alen; - size_t siglen; - const EVP_MD *md = NULL; + const EVP_MD *md; + unsigned char *buf = NULL, *sig = NULL; + int buf_len = 0; + size_t sig_len = 0; + int ret = 0; - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); - if (md == NULL) - return 0; + if ((md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm)) == NULL) + goto err; if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { if (!cms_add1_signingTime(si, NULL)) goto err; } - if (si->pctx) - pctx = si->pctx; - else { - EVP_MD_CTX_reset(mctx); - if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) + if (si->pctx == NULL) { + EVP_MD_CTX_reset(si->mctx); + if (!EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, si->pkey)) goto err; - si->pctx = pctx; } - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + if (EVP_PKEY_CTX_ctrl(si->pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { CMSerror(CMS_R_CTRL_ERROR); goto err; } - alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, - &CMS_Attributes_Sign_it); - if (!abuf) - goto err; - if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0) + if ((buf_len = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &buf, + &CMS_Attributes_Sign_it)) <= 0) { + buf_len = 0; goto err; - if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0) + } + if (!EVP_DigestSign(si->mctx, NULL, &sig_len, buf, buf_len)) goto err; - free(abuf); - abuf = malloc(siglen); - if (abuf == NULL) + if ((sig = calloc(1, sig_len)) == NULL) goto err; - if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) + if (!EVP_DigestSign(si->mctx, sig, &sig_len, buf, buf_len)) goto err; - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + if (EVP_PKEY_CTX_ctrl(si->pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { CMSerror(CMS_R_CTRL_ERROR); goto err; } - EVP_MD_CTX_reset(mctx); + ASN1_STRING_set0(si->signature, sig, sig_len); + sig = NULL; - ASN1_STRING_set0(si->signature, abuf, siglen); - - return 1; + ret = 1; err: - free(abuf); - EVP_MD_CTX_reset(mctx); + if (si->mctx != NULL) + EVP_MD_CTX_reset(si->mctx); + freezero(buf, buf_len); + freezero(sig, sig_len); - return 0; + return ret; } LCRYPTO_ALIAS(CMS_SignerInfo_sign); int CMS_SignerInfo_verify(CMS_SignerInfo *si) { - EVP_MD_CTX *mctx = NULL; - unsigned char *abuf = NULL; - int alen, r = -1; - const EVP_MD *md = NULL; + const EVP_MD *md; + unsigned char *buf = NULL; + int buf_len = 0; + int ret = -1; - if (!si->pkey) { + if ((md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm)) == NULL) + goto err; + + if (si->pkey == NULL) { CMSerror(CMS_R_NO_PUBLIC_KEY); - return -1; + goto err; } - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); - if (md == NULL) - return -1; - if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) { + if (si->mctx == NULL) + si->mctx = EVP_MD_CTX_new(); + if (si->mctx == NULL) { CMSerror(ERR_R_MALLOC_FAILURE); - return -1; + goto err; } - mctx = si->mctx; - if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0) + + if (EVP_DigestVerifyInit(si->mctx, &si->pctx, md, NULL, si->pkey) <= 0) goto err; if (!cms_sd_asn1_ctrl(si, 1)) goto err; - alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, - &CMS_Attributes_Verify_it); - if (!abuf) - goto err; - r = EVP_DigestVerifyUpdate(mctx, abuf, alen); - free(abuf); - if (r <= 0) { - r = -1; + if ((buf_len = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &buf, + &CMS_Attributes_Verify_it)) <= 0) { + buf_len = 0; goto err; } - r = EVP_DigestVerifyFinal(mctx, si->signature->data, - si->signature->length); - if (r <= 0) + ret = EVP_DigestVerify(si->mctx, si->signature->data, si->signature->length, + buf, buf_len); + if (ret <= 0) { CMSerror(CMS_R_VERIFICATION_FAILURE); + goto err; + } err: - EVP_MD_CTX_reset(mctx); + if (si->mctx != NULL) + EVP_MD_CTX_reset(si->mctx); + freezero(buf, buf_len); - return r; + return ret; } LCRYPTO_ALIAS(CMS_SignerInfo_verify); -- 2.20.1