1 /* crypto/cms/cms_sd.c */
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
6 /* ====================================================================
7 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
35 * 6. Redistributions of any form whatsoever must retain the following
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
56 #include <openssl/asn1t.h>
57 #include <openssl/pem.h>
58 #include <openssl/x509v3.h>
59 #include <openssl/err.h>
60 #include <openssl/cms.h>
63 /* CMS SignedData Utilities */
65 DECLARE_ASN1_ITEM(CMS_SignedData)
67 static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
69 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) {
70 CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
73 return cms->d.signedData;
76 static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
78 if (cms->d.other == NULL) {
79 cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
80 if (!cms->d.signedData) {
81 CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
84 cms->d.signedData->version = 1;
85 cms->d.signedData->encapContentInfo->eContentType =
86 OBJ_nid2obj(NID_pkcs7_data);
87 cms->d.signedData->encapContentInfo->partial = 1;
88 ASN1_OBJECT_free(cms->contentType);
89 cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
90 return cms->d.signedData;
92 return cms_get0_signed(cms);
95 /* Just initialize SignedData e.g. for certs only structure */
97 int CMS_SignedData_init(CMS_ContentInfo *cms)
99 if (cms_signed_data_init(cms))
105 /* Check structures and fixup version numbers (if necessary) */
107 static void cms_sd_set_version(CMS_SignedData *sd)
110 CMS_CertificateChoices *cch;
111 CMS_RevocationInfoChoice *rch;
114 for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) {
115 cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
116 if (cch->type == CMS_CERTCHOICE_OTHER) {
119 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
122 } else if (cch->type == CMS_CERTCHOICE_V1ACERT) {
128 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) {
129 rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
130 if (rch->type == CMS_REVCHOICE_OTHER) {
136 if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
137 && (sd->version < 3))
140 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
141 si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
142 if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
147 } else if (si->version < 1)
156 /* Copy an existing messageDigest value */
158 static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
160 STACK_OF(CMS_SignerInfo) *sinfos;
161 CMS_SignerInfo *sitmp;
163 sinfos = CMS_get0_SignerInfos(cms);
164 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
165 ASN1_OCTET_STRING *messageDigest;
166 sitmp = sk_CMS_SignerInfo_value(sinfos, i);
169 if (CMS_signed_get_attr_count(sitmp) < 0)
171 if (OBJ_cmp(si->digestAlgorithm->algorithm,
172 sitmp->digestAlgorithm->algorithm))
174 messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
176 (NID_pkcs9_messageDigest),
177 -3, V_ASN1_OCTET_STRING);
178 if (!messageDigest) {
179 CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
180 CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
184 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
191 CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
195 int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
198 case CMS_SIGNERINFO_ISSUER_SERIAL:
199 sid->d.issuerAndSerialNumber =
200 M_ASN1_new_of(CMS_IssuerAndSerialNumber);
201 if (!sid->d.issuerAndSerialNumber)
203 if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer,
204 X509_get_issuer_name(cert)))
206 ASN1_STRING_free(sid->d.issuerAndSerialNumber->serialNumber);
207 sid->d.issuerAndSerialNumber->serialNumber =
208 ASN1_STRING_dup(X509_get_serialNumber(cert));
209 if (!sid->d.issuerAndSerialNumber->serialNumber)
213 case CMS_SIGNERINFO_KEYIDENTIFIER:
215 CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER,
216 CMS_R_CERTIFICATE_HAS_NO_KEYID);
219 sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid);
220 if (!sid->d.subjectKeyIdentifier)
225 CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
234 CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE);
239 int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
240 ASN1_OCTET_STRING **keyid,
244 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
246 *issuer = sid->d.issuerAndSerialNumber->issuer;
248 *sno = sid->d.issuerAndSerialNumber->serialNumber;
249 } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
251 *keyid = sid->d.subjectKeyIdentifier;
257 int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
260 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
261 ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer,
262 X509_get_issuer_name(cert));
265 return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber,
266 X509_get_serialNumber(cert));
267 } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
268 X509_check_purpose(cert, -1, -1);
271 return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier, cert->skid);
276 CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
277 X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
281 CMS_SignerInfo *si = NULL;
284 if (!X509_check_private_key(signer, pk)) {
285 CMSerr(CMS_F_CMS_ADD1_SIGNER,
286 CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
289 sd = cms_signed_data_init(cms);
292 si = M_ASN1_new_of(CMS_SignerInfo);
295 X509_check_purpose(signer, -1, -1);
297 CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
298 CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
303 if (flags & CMS_USE_KEYID) {
307 type = CMS_SIGNERINFO_KEYIDENTIFIER;
309 type = CMS_SIGNERINFO_ISSUER_SERIAL;
313 if (!cms_set1_SignerIdentifier(si->sid, signer, type))
316 /* Since no EVP_PKEY_METHOD in 0.9.8 hard code SHA1 as default */
320 /* OpenSSL 0.9.8 only supports SHA1 with non-RSA keys */
322 if ((pk->type != EVP_PKEY_RSA) && (EVP_MD_type(md) != NID_sha1)) {
323 CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
327 cms_DigestAlgorithm_set(si->digestAlgorithm, md);
329 /* See if digest is present in digestAlgorithms */
330 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
332 alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
333 X509_ALGOR_get0(&aoid, NULL, NULL, alg);
334 if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
338 if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
339 alg = X509_ALGOR_new();
342 cms_DigestAlgorithm_set(alg, md);
343 if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) {
344 X509_ALGOR_free(alg);
350 * Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, hard code
351 * algorithm parameters.
357 X509_ALGOR_set0(si->signatureAlgorithm,
358 OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
362 X509_ALGOR_set0(si->signatureAlgorithm,
363 OBJ_nid2obj(NID_dsaWithSHA1), V_ASN1_UNDEF, 0);
367 X509_ALGOR_set0(si->signatureAlgorithm,
368 OBJ_nid2obj(NID_ecdsa_with_SHA1), V_ASN1_UNDEF, 0);
372 CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
377 if (!(flags & CMS_NOATTR)) {
379 * Initialialize signed attributes strutucture so other attributes
380 * such as signing time etc are added later even if we add none here.
382 if (!si->signedAttrs) {
383 si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
384 if (!si->signedAttrs)
388 if (!(flags & CMS_NOSMIMECAP)) {
389 STACK_OF(X509_ALGOR) *smcap = NULL;
390 i = CMS_add_standard_smimecap(&smcap);
392 i = CMS_add_smimecap(si, smcap);
393 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
397 if (flags & CMS_REUSE_DIGEST) {
398 if (!cms_copy_messageDigest(cms, si))
400 if (!(flags & CMS_PARTIAL) && !CMS_SignerInfo_sign(si))
405 if (!(flags & CMS_NOCERTS)) {
406 /* NB ignore -1 return for duplicate cert */
407 if (!CMS_add1_cert(cms, signer))
411 if (!sd->signerInfos)
412 sd->signerInfos = sk_CMS_SignerInfo_new_null();
413 if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si))
419 CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
422 M_ASN1_free_of(si, CMS_SignerInfo);
427 static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
434 tt = X509_gmtime_adj(NULL, 0);
439 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
440 tt->type, tt, -1) <= 0)
451 CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
457 STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
460 sd = cms_get0_signed(cms);
463 return sd->signerInfos;
466 STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
468 STACK_OF(X509) *signers = NULL;
469 STACK_OF(CMS_SignerInfo) *sinfos;
472 sinfos = CMS_get0_SignerInfos(cms);
473 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
474 si = sk_CMS_SignerInfo_value(sinfos, i);
477 signers = sk_X509_new_null();
481 if (!sk_X509_push(signers, si->signer)) {
482 sk_X509_free(signers);
490 void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
493 CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
495 EVP_PKEY_free(si->pkey);
496 si->pkey = X509_get_pubkey(signer);
499 X509_free(si->signer);
503 int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
504 ASN1_OCTET_STRING **keyid,
505 X509_NAME **issuer, ASN1_INTEGER **sno)
507 return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
510 int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
512 return cms_SignerIdentifier_cert_cmp(si->sid, cert);
515 int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
520 CMS_CertificateChoices *cch;
521 STACK_OF(CMS_CertificateChoices) *certs;
525 sd = cms_get0_signed(cms);
528 certs = sd->certificates;
529 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
530 si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
534 for (j = 0; j < sk_X509_num(scerts); j++) {
535 x = sk_X509_value(scerts, j);
536 if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
537 CMS_SignerInfo_set1_signer_cert(si, x);
543 if (si->signer || (flags & CMS_NOINTERN))
546 for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
547 cch = sk_CMS_CertificateChoices_value(certs, j);
550 x = cch->d.certificate;
551 if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
552 CMS_SignerInfo_set1_signer_cert(si, x);
561 void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
562 X509 **signer, X509_ALGOR **pdig,
568 *signer = si->signer;
570 *pdig = si->digestAlgorithm;
572 *psig = si->signatureAlgorithm;
576 * In OpenSSL 0.9.8 we have the link between digest types and public key
577 * types so we need to fixup the digest type if the public key type is not
581 static void cms_fixup_mctx(EVP_MD_CTX *mctx, EVP_PKEY *pkey)
583 if (EVP_MD_CTX_type(mctx) != NID_sha1)
585 #ifndef OPENSSL_NO_DSA
586 if (pkey->type == EVP_PKEY_DSA)
587 mctx->digest = EVP_dss1();
589 #ifndef OPENSSL_NO_ECDSA
590 if (pkey->type == EVP_PKEY_EC)
591 mctx->digest = EVP_ecdsa();
595 static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
596 CMS_SignerInfo *si, BIO *chain)
600 EVP_MD_CTX_init(&mctx);
603 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
607 if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
611 * If any signed attributes calculate and add messageDigest attribute
614 if (CMS_signed_get_attr_count(si) >= 0) {
616 cms->d.signedData->encapContentInfo->eContentType;
617 unsigned char md[EVP_MAX_MD_SIZE];
619 EVP_DigestFinal_ex(&mctx, md, &mdlen);
620 if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
621 V_ASN1_OCTET_STRING, md, mdlen))
623 /* Copy content type across */
624 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
625 V_ASN1_OBJECT, ctype, -1) <= 0)
627 if (!CMS_SignerInfo_sign(si))
632 sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
634 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
637 cms_fixup_mctx(&mctx, si->pkey);
638 if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) {
639 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR);
643 ASN1_STRING_set0(si->signature, sig, siglen);
649 EVP_MD_CTX_cleanup(&mctx);
654 int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
656 STACK_OF(CMS_SignerInfo) *sinfos;
659 sinfos = CMS_get0_SignerInfos(cms);
660 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
661 si = sk_CMS_SignerInfo_value(sinfos, i);
662 if (!cms_SignerInfo_content_sign(cms, si, chain))
665 cms->d.signedData->encapContentInfo->partial = 0;
669 int CMS_SignerInfo_sign(CMS_SignerInfo *si)
672 unsigned char *abuf = NULL;
675 const EVP_MD *md = NULL;
677 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
681 EVP_MD_CTX_init(&mctx);
683 if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
684 if (!cms_add1_signingTime(si, NULL))
688 if (EVP_SignInit_ex(&mctx, md, NULL) <= 0)
692 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
693 EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) {
694 CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
699 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
700 ASN1_ITEM_rptr(CMS_Attributes_Sign));
703 if (EVP_SignUpdate(&mctx, abuf, alen) <= 0)
705 siglen = EVP_PKEY_size(si->pkey);
707 abuf = OPENSSL_malloc(siglen);
710 cms_fixup_mctx(&mctx, si->pkey);
711 if (EVP_SignFinal(&mctx, abuf, &siglen, si->pkey) <= 0)
714 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
715 EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) {
716 CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
720 EVP_MD_CTX_cleanup(&mctx);
722 ASN1_STRING_set0(si->signature, abuf, siglen);
729 EVP_MD_CTX_cleanup(&mctx);
734 int CMS_SignerInfo_verify(CMS_SignerInfo *si)
737 unsigned char *abuf = NULL;
739 const EVP_MD *md = NULL;
742 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
746 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
749 EVP_MD_CTX_init(&mctx);
750 if (EVP_VerifyInit_ex(&mctx, md, NULL) <= 0)
753 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
754 ASN1_ITEM_rptr(CMS_Attributes_Verify));
757 r = EVP_VerifyUpdate(&mctx, abuf, alen);
763 cms_fixup_mctx(&mctx, si->pkey);
764 r = EVP_VerifyFinal(&mctx,
765 si->signature->data, si->signature->length, si->pkey);
767 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
769 EVP_MD_CTX_cleanup(&mctx);
773 /* Create a chain of digest BIOs from a CMS ContentInfo */
775 BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
780 sd = cms_get0_signed(cms);
783 if (cms->d.signedData->encapContentInfo->partial)
784 cms_sd_set_version(sd);
785 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
786 X509_ALGOR *digestAlgorithm;
788 digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
789 mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
793 BIO_push(chain, mdbio);
804 int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
806 ASN1_OCTET_STRING *os = NULL;
809 EVP_MD_CTX_init(&mctx);
810 /* If we have any signed attributes look for messageDigest value */
811 if (CMS_signed_get_attr_count(si) >= 0) {
812 os = CMS_signed_get0_data_by_OBJ(si,
813 OBJ_nid2obj(NID_pkcs9_messageDigest),
814 -3, V_ASN1_OCTET_STRING);
816 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
817 CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
822 if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
825 /* If messageDigest found compare it */
828 unsigned char mval[EVP_MAX_MD_SIZE];
830 if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) {
831 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
832 CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
835 if (mlen != (unsigned int)os->length) {
836 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
837 CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
841 if (memcmp(mval, os->data, mlen)) {
842 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
843 CMS_R_VERIFICATION_FAILURE);
848 cms_fixup_mctx(&mctx, si->pkey);
849 r = EVP_VerifyFinal(&mctx, si->signature->data,
850 si->signature->length, si->pkey);
852 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
853 CMS_R_VERIFICATION_FAILURE);
859 EVP_MD_CTX_cleanup(&mctx);
864 int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
866 unsigned char *smder = NULL;
868 smderlen = i2d_X509_ALGORS(algs, &smder);
871 r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
872 V_ASN1_SEQUENCE, smder, smderlen);
877 int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
878 int algnid, int keysize)
881 ASN1_INTEGER *key = NULL;
883 key = ASN1_INTEGER_new();
884 if (!key || !ASN1_INTEGER_set(key, keysize))
887 alg = X509_ALGOR_new();
890 ASN1_INTEGER_free(key);
894 X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
895 key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
897 *algs = sk_X509_ALGOR_new_null();
898 if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) {
899 X509_ALGOR_free(alg);
905 /* Check to see if a cipher exists and if so add S/MIME capabilities */
907 static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
909 if (EVP_get_cipherbynid(nid))
910 return CMS_add_simple_smimecap(sk, nid, arg);
915 static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
917 if (EVP_get_digestbynid(nid))
918 return CMS_add_simple_smimecap(sk, nid, arg);
922 int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
924 if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
925 || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
926 || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
927 || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
928 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
929 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
930 || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
931 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))