summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2023-09-11 09:24:14 +0000
committertb <>2023-09-11 09:24:14 +0000
commita3c3d56261390274eb902ba01caebb923f44fbbe (patch)
tree714a91739e1cf51340d405cab21ac4c5fe377a86 /src
parent885b2bd31df10f79fe9e4ed2f239dcd4721ac23f (diff)
downloadopenbsd-a3c3d56261390274eb902ba01caebb923f44fbbe.tar.gz
openbsd-a3c3d56261390274eb902ba01caebb923f44fbbe.tar.bz2
openbsd-a3c3d56261390274eb902ba01caebb923f44fbbe.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/cms/cms_sd.c116
1 files changed, 55 insertions, 61 deletions
diff --git a/src/lib/libcrypto/cms/cms_sd.c b/src/lib/libcrypto/cms/cms_sd.c
index 89ba5bf01f..73f67ce4c3 100644
--- a/src/lib/libcrypto/cms/cms_sd.c
+++ b/src/lib/libcrypto/cms/cms_sd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cms_sd.c,v 1.26 2023/07/08 08:26:26 beck Exp $ */ 1/* $OpenBSD: cms_sd.c,v 1.27 2023/09/11 09:24:14 tb Exp $ */
2/* 2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 * project. 4 * project.
@@ -721,119 +721,113 @@ cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
721int 721int
722CMS_SignerInfo_sign(CMS_SignerInfo *si) 722CMS_SignerInfo_sign(CMS_SignerInfo *si)
723{ 723{
724 EVP_MD_CTX *mctx = si->mctx; 724 const EVP_MD *md;
725 EVP_PKEY_CTX *pctx = NULL; 725 unsigned char *buf = NULL, *sig = NULL;
726 unsigned char *abuf = NULL; 726 int buf_len = 0;
727 int alen; 727 size_t sig_len = 0;
728 size_t siglen; 728 int ret = 0;
729 const EVP_MD *md = NULL;
730 729
731 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 730 if ((md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm)) == NULL)
732 if (md == NULL) 731 goto err;
733 return 0;
734 732
735 if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { 733 if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
736 if (!cms_add1_signingTime(si, NULL)) 734 if (!cms_add1_signingTime(si, NULL))
737 goto err; 735 goto err;
738 } 736 }
739 737
740 if (si->pctx) 738 if (si->pctx == NULL) {
741 pctx = si->pctx; 739 EVP_MD_CTX_reset(si->mctx);
742 else { 740 if (!EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, si->pkey))
743 EVP_MD_CTX_reset(mctx);
744 if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
745 goto err; 741 goto err;
746 si->pctx = pctx;
747 } 742 }
748 743
749 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 744 if (EVP_PKEY_CTX_ctrl(si->pctx, -1, EVP_PKEY_OP_SIGN,
750 EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { 745 EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) {
751 CMSerror(CMS_R_CTRL_ERROR); 746 CMSerror(CMS_R_CTRL_ERROR);
752 goto err; 747 goto err;
753 } 748 }
754 749
755 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, 750 if ((buf_len = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &buf,
756 &CMS_Attributes_Sign_it); 751 &CMS_Attributes_Sign_it)) <= 0) {
757 if (!abuf) 752 buf_len = 0;
758 goto err;
759 if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
760 goto err; 753 goto err;
761 if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0) 754 }
755 if (!EVP_DigestSign(si->mctx, NULL, &sig_len, buf, buf_len))
762 goto err; 756 goto err;
763 free(abuf); 757 if ((sig = calloc(1, sig_len)) == NULL)
764 abuf = malloc(siglen);
765 if (abuf == NULL)
766 goto err; 758 goto err;
767 if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) 759 if (!EVP_DigestSign(si->mctx, sig, &sig_len, buf, buf_len))
768 goto err; 760 goto err;
769 761
770 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 762 if (EVP_PKEY_CTX_ctrl(si->pctx, -1, EVP_PKEY_OP_SIGN,
771 EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { 763 EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) {
772 CMSerror(CMS_R_CTRL_ERROR); 764 CMSerror(CMS_R_CTRL_ERROR);
773 goto err; 765 goto err;
774 } 766 }
775 767
776 EVP_MD_CTX_reset(mctx); 768 ASN1_STRING_set0(si->signature, sig, sig_len);
769 sig = NULL;
777 770
778 ASN1_STRING_set0(si->signature, abuf, siglen); 771 ret = 1;
779
780 return 1;
781 772
782 err: 773 err:
783 free(abuf); 774 if (si->mctx != NULL)
784 EVP_MD_CTX_reset(mctx); 775 EVP_MD_CTX_reset(si->mctx);
776 freezero(buf, buf_len);
777 freezero(sig, sig_len);
785 778
786 return 0; 779 return ret;
787} 780}
788LCRYPTO_ALIAS(CMS_SignerInfo_sign); 781LCRYPTO_ALIAS(CMS_SignerInfo_sign);
789 782
790int 783int
791CMS_SignerInfo_verify(CMS_SignerInfo *si) 784CMS_SignerInfo_verify(CMS_SignerInfo *si)
792{ 785{
793 EVP_MD_CTX *mctx = NULL; 786 const EVP_MD *md;
794 unsigned char *abuf = NULL; 787 unsigned char *buf = NULL;
795 int alen, r = -1; 788 int buf_len = 0;
796 const EVP_MD *md = NULL; 789 int ret = -1;
797 790
798 if (!si->pkey) { 791 if ((md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm)) == NULL)
792 goto err;
793
794 if (si->pkey == NULL) {
799 CMSerror(CMS_R_NO_PUBLIC_KEY); 795 CMSerror(CMS_R_NO_PUBLIC_KEY);
800 return -1; 796 goto err;
801 } 797 }
802 798
803 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 799 if (si->mctx == NULL)
804 if (md == NULL) 800 si->mctx = EVP_MD_CTX_new();
805 return -1; 801 if (si->mctx == NULL) {
806 if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) {
807 CMSerror(ERR_R_MALLOC_FAILURE); 802 CMSerror(ERR_R_MALLOC_FAILURE);
808 return -1; 803 goto err;
809 } 804 }
810 mctx = si->mctx; 805
811 if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0) 806 if (EVP_DigestVerifyInit(si->mctx, &si->pctx, md, NULL, si->pkey) <= 0)
812 goto err; 807 goto err;
813 808
814 if (!cms_sd_asn1_ctrl(si, 1)) 809 if (!cms_sd_asn1_ctrl(si, 1))
815 goto err; 810 goto err;
816 811
817 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, 812 if ((buf_len = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &buf,
818 &CMS_Attributes_Verify_it); 813 &CMS_Attributes_Verify_it)) <= 0) {
819 if (!abuf) 814 buf_len = 0;
820 goto err;
821 r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
822 free(abuf);
823 if (r <= 0) {
824 r = -1;
825 goto err; 815 goto err;
826 } 816 }
827 817
828 r = EVP_DigestVerifyFinal(mctx, si->signature->data, 818 ret = EVP_DigestVerify(si->mctx, si->signature->data, si->signature->length,
829 si->signature->length); 819 buf, buf_len);
830 if (r <= 0) 820 if (ret <= 0) {
831 CMSerror(CMS_R_VERIFICATION_FAILURE); 821 CMSerror(CMS_R_VERIFICATION_FAILURE);
822 goto err;
823 }
832 824
833 err: 825 err:
834 EVP_MD_CTX_reset(mctx); 826 if (si->mctx != NULL)
827 EVP_MD_CTX_reset(si->mctx);
828 freezero(buf, buf_len);
835 829
836 return r; 830 return ret;
837} 831}
838LCRYPTO_ALIAS(CMS_SignerInfo_verify); 832LCRYPTO_ALIAS(CMS_SignerInfo_verify);
839 833