diff options
author | tb <> | 2023-09-11 09:24:14 +0000 |
---|---|---|
committer | tb <> | 2023-09-11 09:24:14 +0000 |
commit | a3c3d56261390274eb902ba01caebb923f44fbbe (patch) | |
tree | 714a91739e1cf51340d405cab21ac4c5fe377a86 /src | |
parent | 885b2bd31df10f79fe9e4ed2f239dcd4721ac23f (diff) | |
download | openbsd-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.c | 116 |
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) | |||
721 | int | 721 | int |
722 | CMS_SignerInfo_sign(CMS_SignerInfo *si) | 722 | CMS_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 | } |
788 | LCRYPTO_ALIAS(CMS_SignerInfo_sign); | 781 | LCRYPTO_ALIAS(CMS_SignerInfo_sign); |
789 | 782 | ||
790 | int | 783 | int |
791 | CMS_SignerInfo_verify(CMS_SignerInfo *si) | 784 | CMS_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 | } |
838 | LCRYPTO_ALIAS(CMS_SignerInfo_verify); | 832 | LCRYPTO_ALIAS(CMS_SignerInfo_verify); |
839 | 833 | ||