1183234Ssimon/* crypto/cms/cms_sd.c */ 2183234Ssimon/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3183234Ssimon * project. 4183234Ssimon */ 5183234Ssimon/* ==================================================================== 6183234Ssimon * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 7183234Ssimon * 8183234Ssimon * Redistribution and use in source and binary forms, with or without 9183234Ssimon * modification, are permitted provided that the following conditions 10183234Ssimon * are met: 11183234Ssimon * 12183234Ssimon * 1. Redistributions of source code must retain the above copyright 13183234Ssimon * notice, this list of conditions and the following disclaimer. 14183234Ssimon * 15183234Ssimon * 2. Redistributions in binary form must reproduce the above copyright 16183234Ssimon * notice, this list of conditions and the following disclaimer in 17183234Ssimon * the documentation and/or other materials provided with the 18183234Ssimon * distribution. 19183234Ssimon * 20183234Ssimon * 3. All advertising materials mentioning features or use of this 21183234Ssimon * software must display the following acknowledgment: 22183234Ssimon * "This product includes software developed by the OpenSSL Project 23183234Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24183234Ssimon * 25183234Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26183234Ssimon * endorse or promote products derived from this software without 27183234Ssimon * prior written permission. For written permission, please contact 28183234Ssimon * licensing@OpenSSL.org. 29183234Ssimon * 30183234Ssimon * 5. Products derived from this software may not be called "OpenSSL" 31183234Ssimon * nor may "OpenSSL" appear in their names without prior written 32183234Ssimon * permission of the OpenSSL Project. 33183234Ssimon * 34183234Ssimon * 6. Redistributions of any form whatsoever must retain the following 35183234Ssimon * acknowledgment: 36183234Ssimon * "This product includes software developed by the OpenSSL Project 37183234Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38183234Ssimon * 39183234Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40183234Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41183234Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42183234Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43183234Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44183234Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45183234Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46183234Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47183234Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48183234Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49183234Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50183234Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 51183234Ssimon * ==================================================================== 52183234Ssimon */ 53183234Ssimon 54183234Ssimon#include "cryptlib.h" 55183234Ssimon#include <openssl/asn1t.h> 56183234Ssimon#include <openssl/pem.h> 57183234Ssimon#include <openssl/x509v3.h> 58183234Ssimon#include <openssl/err.h> 59183234Ssimon#include <openssl/cms.h> 60183234Ssimon#include "cms_lcl.h" 61238405Sjkim#include "asn1_locl.h" 62183234Ssimon 63183234Ssimon/* CMS SignedData Utilities */ 64183234Ssimon 65183234SsimonDECLARE_ASN1_ITEM(CMS_SignedData) 66183234Ssimon 67183234Ssimonstatic CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms) 68183234Ssimon { 69183234Ssimon if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) 70183234Ssimon { 71183234Ssimon CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); 72183234Ssimon return NULL; 73183234Ssimon } 74183234Ssimon return cms->d.signedData; 75183234Ssimon } 76183234Ssimon 77183234Ssimonstatic CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) 78183234Ssimon { 79183234Ssimon if (cms->d.other == NULL) 80183234Ssimon { 81183234Ssimon cms->d.signedData = M_ASN1_new_of(CMS_SignedData); 82183234Ssimon if (!cms->d.signedData) 83183234Ssimon { 84183234Ssimon CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE); 85183234Ssimon return NULL; 86183234Ssimon } 87183234Ssimon cms->d.signedData->version = 1; 88183234Ssimon cms->d.signedData->encapContentInfo->eContentType = 89183234Ssimon OBJ_nid2obj(NID_pkcs7_data); 90183234Ssimon cms->d.signedData->encapContentInfo->partial = 1; 91183234Ssimon ASN1_OBJECT_free(cms->contentType); 92183234Ssimon cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); 93183234Ssimon return cms->d.signedData; 94183234Ssimon } 95183234Ssimon return cms_get0_signed(cms); 96183234Ssimon } 97183234Ssimon 98183234Ssimon/* Just initialize SignedData e.g. for certs only structure */ 99183234Ssimon 100183234Ssimonint CMS_SignedData_init(CMS_ContentInfo *cms) 101183234Ssimon { 102183234Ssimon if (cms_signed_data_init(cms)) 103183234Ssimon return 1; 104183234Ssimon else 105183234Ssimon return 0; 106183234Ssimon } 107183234Ssimon 108183234Ssimon/* Check structures and fixup version numbers (if necessary) */ 109183234Ssimon 110183234Ssimonstatic void cms_sd_set_version(CMS_SignedData *sd) 111183234Ssimon { 112183234Ssimon int i; 113183234Ssimon CMS_CertificateChoices *cch; 114183234Ssimon CMS_RevocationInfoChoice *rch; 115183234Ssimon CMS_SignerInfo *si; 116183234Ssimon 117183234Ssimon for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) 118183234Ssimon { 119183234Ssimon cch = sk_CMS_CertificateChoices_value(sd->certificates, i); 120183234Ssimon if (cch->type == CMS_CERTCHOICE_OTHER) 121183234Ssimon { 122183234Ssimon if (sd->version < 5) 123183234Ssimon sd->version = 5; 124183234Ssimon } 125183234Ssimon else if (cch->type == CMS_CERTCHOICE_V2ACERT) 126183234Ssimon { 127183234Ssimon if (sd->version < 4) 128183234Ssimon sd->version = 4; 129183234Ssimon } 130183234Ssimon else if (cch->type == CMS_CERTCHOICE_V1ACERT) 131183234Ssimon { 132183234Ssimon if (sd->version < 3) 133183234Ssimon sd->version = 3; 134183234Ssimon } 135183234Ssimon } 136183234Ssimon 137183234Ssimon for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) 138183234Ssimon { 139183234Ssimon rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i); 140183234Ssimon if (rch->type == CMS_REVCHOICE_OTHER) 141183234Ssimon { 142183234Ssimon if (sd->version < 5) 143183234Ssimon sd->version = 5; 144183234Ssimon } 145183234Ssimon } 146183234Ssimon 147183234Ssimon if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data) 148183234Ssimon && (sd->version < 3)) 149183234Ssimon sd->version = 3; 150183234Ssimon 151183234Ssimon for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) 152183234Ssimon { 153183234Ssimon si = sk_CMS_SignerInfo_value(sd->signerInfos, i); 154183234Ssimon if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) 155183234Ssimon { 156183234Ssimon if (si->version < 3) 157183234Ssimon si->version = 3; 158183234Ssimon if (sd->version < 3) 159183234Ssimon sd->version = 3; 160183234Ssimon } 161279264Sdelphij else if (si->version < 1) 162279264Sdelphij si->version = 1; 163183234Ssimon } 164183234Ssimon 165183234Ssimon if (sd->version < 1) 166183234Ssimon sd->version = 1; 167183234Ssimon 168183234Ssimon } 169183234Ssimon 170183234Ssimon/* Copy an existing messageDigest value */ 171183234Ssimon 172183234Ssimonstatic int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) 173183234Ssimon { 174183234Ssimon STACK_OF(CMS_SignerInfo) *sinfos; 175183234Ssimon CMS_SignerInfo *sitmp; 176183234Ssimon int i; 177183234Ssimon sinfos = CMS_get0_SignerInfos(cms); 178183234Ssimon for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) 179183234Ssimon { 180183234Ssimon ASN1_OCTET_STRING *messageDigest; 181183234Ssimon sitmp = sk_CMS_SignerInfo_value(sinfos, i); 182183234Ssimon if (sitmp == si) 183183234Ssimon continue; 184183234Ssimon if (CMS_signed_get_attr_count(sitmp) < 0) 185183234Ssimon continue; 186183234Ssimon if (OBJ_cmp(si->digestAlgorithm->algorithm, 187183234Ssimon sitmp->digestAlgorithm->algorithm)) 188183234Ssimon continue; 189183234Ssimon messageDigest = CMS_signed_get0_data_by_OBJ(sitmp, 190183234Ssimon OBJ_nid2obj(NID_pkcs9_messageDigest), 191183234Ssimon -3, V_ASN1_OCTET_STRING); 192183234Ssimon if (!messageDigest) 193183234Ssimon { 194183234Ssimon CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, 195183234Ssimon CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); 196183234Ssimon return 0; 197183234Ssimon } 198183234Ssimon 199183234Ssimon if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, 200183234Ssimon V_ASN1_OCTET_STRING, 201183234Ssimon messageDigest, -1)) 202183234Ssimon return 1; 203183234Ssimon else 204183234Ssimon return 0; 205183234Ssimon } 206183234Ssimon CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST); 207183234Ssimon return 0; 208183234Ssimon } 209183234Ssimon 210183234Ssimonint cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) 211183234Ssimon { 212183234Ssimon switch(type) 213183234Ssimon { 214183234Ssimon case CMS_SIGNERINFO_ISSUER_SERIAL: 215183234Ssimon sid->d.issuerAndSerialNumber = 216183234Ssimon M_ASN1_new_of(CMS_IssuerAndSerialNumber); 217183234Ssimon if (!sid->d.issuerAndSerialNumber) 218183234Ssimon goto merr; 219183234Ssimon if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer, 220183234Ssimon X509_get_issuer_name(cert))) 221183234Ssimon goto merr; 222238405Sjkim if (!ASN1_STRING_copy( 223238405Sjkim sid->d.issuerAndSerialNumber->serialNumber, 224238405Sjkim X509_get_serialNumber(cert))) 225183234Ssimon goto merr; 226183234Ssimon break; 227183234Ssimon 228183234Ssimon case CMS_SIGNERINFO_KEYIDENTIFIER: 229183234Ssimon if (!cert->skid) 230183234Ssimon { 231183234Ssimon CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, 232183234Ssimon CMS_R_CERTIFICATE_HAS_NO_KEYID); 233183234Ssimon return 0; 234183234Ssimon } 235183234Ssimon sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid); 236183234Ssimon if (!sid->d.subjectKeyIdentifier) 237183234Ssimon goto merr; 238183234Ssimon break; 239183234Ssimon 240183234Ssimon default: 241183234Ssimon CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID); 242183234Ssimon return 0; 243183234Ssimon } 244183234Ssimon 245183234Ssimon sid->type = type; 246183234Ssimon 247183234Ssimon return 1; 248183234Ssimon 249183234Ssimon merr: 250183234Ssimon CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE); 251183234Ssimon return 0; 252183234Ssimon 253183234Ssimon } 254183234Ssimon 255183234Ssimonint cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, 256183234Ssimon ASN1_OCTET_STRING **keyid, 257183234Ssimon X509_NAME **issuer, ASN1_INTEGER **sno) 258183234Ssimon { 259183234Ssimon if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) 260183234Ssimon { 261183234Ssimon if (issuer) 262183234Ssimon *issuer = sid->d.issuerAndSerialNumber->issuer; 263183234Ssimon if (sno) 264183234Ssimon *sno = sid->d.issuerAndSerialNumber->serialNumber; 265183234Ssimon } 266183234Ssimon else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) 267183234Ssimon { 268183234Ssimon if (keyid) 269183234Ssimon *keyid = sid->d.subjectKeyIdentifier; 270183234Ssimon } 271183234Ssimon else 272183234Ssimon return 0; 273183234Ssimon return 1; 274183234Ssimon } 275183234Ssimon 276183234Ssimonint cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) 277183234Ssimon { 278183234Ssimon int ret; 279183234Ssimon if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) 280183234Ssimon { 281183234Ssimon ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer, 282183234Ssimon X509_get_issuer_name(cert)); 283183234Ssimon if (ret) 284183234Ssimon return ret; 285183234Ssimon return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber, 286183234Ssimon X509_get_serialNumber(cert)); 287183234Ssimon } 288183234Ssimon else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) 289183234Ssimon { 290183234Ssimon X509_check_purpose(cert, -1, -1); 291183234Ssimon if (!cert->skid) 292183234Ssimon return -1; 293183234Ssimon return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier, 294183234Ssimon cert->skid); 295183234Ssimon } 296183234Ssimon else 297183234Ssimon return -1; 298183234Ssimon } 299183234Ssimon 300183234SsimonCMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, 301183234Ssimon X509 *signer, EVP_PKEY *pk, const EVP_MD *md, 302183234Ssimon unsigned int flags) 303183234Ssimon { 304183234Ssimon CMS_SignedData *sd; 305183234Ssimon CMS_SignerInfo *si = NULL; 306183234Ssimon X509_ALGOR *alg; 307183234Ssimon int i, type; 308183234Ssimon if(!X509_check_private_key(signer, pk)) 309183234Ssimon { 310183234Ssimon CMSerr(CMS_F_CMS_ADD1_SIGNER, 311183234Ssimon CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 312183234Ssimon return NULL; 313183234Ssimon } 314183234Ssimon sd = cms_signed_data_init(cms); 315183234Ssimon if (!sd) 316183234Ssimon goto err; 317183234Ssimon si = M_ASN1_new_of(CMS_SignerInfo); 318183234Ssimon if (!si) 319183234Ssimon goto merr; 320183234Ssimon X509_check_purpose(signer, -1, -1); 321183234Ssimon 322183234Ssimon CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); 323183234Ssimon CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); 324183234Ssimon 325183234Ssimon si->pkey = pk; 326183234Ssimon si->signer = signer; 327183234Ssimon 328183234Ssimon if (flags & CMS_USE_KEYID) 329183234Ssimon { 330183234Ssimon si->version = 3; 331183234Ssimon if (sd->version < 3) 332183234Ssimon sd->version = 3; 333183234Ssimon type = CMS_SIGNERINFO_KEYIDENTIFIER; 334183234Ssimon } 335183234Ssimon else 336183234Ssimon { 337183234Ssimon type = CMS_SIGNERINFO_ISSUER_SERIAL; 338183234Ssimon si->version = 1; 339183234Ssimon } 340183234Ssimon 341183234Ssimon if (!cms_set1_SignerIdentifier(si->sid, signer, type)) 342183234Ssimon goto err; 343183234Ssimon 344183234Ssimon if (md == NULL) 345238405Sjkim { 346238405Sjkim int def_nid; 347238405Sjkim if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) 348238405Sjkim goto err; 349238405Sjkim md = EVP_get_digestbynid(def_nid); 350238405Sjkim if (md == NULL) 351238405Sjkim { 352238405Sjkim CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); 353238405Sjkim goto err; 354238405Sjkim } 355238405Sjkim } 356183234Ssimon 357238405Sjkim if (!md) 358183234Ssimon { 359238405Sjkim CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); 360183234Ssimon goto err; 361183234Ssimon } 362183234Ssimon 363183234Ssimon cms_DigestAlgorithm_set(si->digestAlgorithm, md); 364183234Ssimon 365183234Ssimon /* See if digest is present in digestAlgorithms */ 366183234Ssimon for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) 367183234Ssimon { 368183234Ssimon ASN1_OBJECT *aoid; 369183234Ssimon alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); 370183234Ssimon X509_ALGOR_get0(&aoid, NULL, NULL, alg); 371183234Ssimon if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) 372183234Ssimon break; 373183234Ssimon } 374183234Ssimon 375183234Ssimon if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) 376183234Ssimon { 377183234Ssimon alg = X509_ALGOR_new(); 378183234Ssimon if (!alg) 379183234Ssimon goto merr; 380183234Ssimon cms_DigestAlgorithm_set(alg, md); 381183234Ssimon if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) 382183234Ssimon { 383183234Ssimon X509_ALGOR_free(alg); 384183234Ssimon goto merr; 385183234Ssimon } 386183234Ssimon } 387183234Ssimon 388238405Sjkim if (pk->ameth && pk->ameth->pkey_ctrl) 389183234Ssimon { 390238405Sjkim i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN, 391238405Sjkim 0, si); 392238405Sjkim if (i == -2) 393238405Sjkim { 394238405Sjkim CMSerr(CMS_F_CMS_ADD1_SIGNER, 395183234Ssimon CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 396238405Sjkim goto err; 397238405Sjkim } 398238405Sjkim if (i <= 0) 399238405Sjkim { 400238405Sjkim CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE); 401238405Sjkim goto err; 402238405Sjkim } 403183234Ssimon } 404183234Ssimon 405183234Ssimon if (!(flags & CMS_NOATTR)) 406183234Ssimon { 407183234Ssimon /* Initialialize signed attributes strutucture so other 408183234Ssimon * attributes such as signing time etc are added later 409183234Ssimon * even if we add none here. 410183234Ssimon */ 411183234Ssimon if (!si->signedAttrs) 412183234Ssimon { 413183234Ssimon si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); 414183234Ssimon if (!si->signedAttrs) 415183234Ssimon goto merr; 416183234Ssimon } 417183234Ssimon 418183234Ssimon if (!(flags & CMS_NOSMIMECAP)) 419183234Ssimon { 420183234Ssimon STACK_OF(X509_ALGOR) *smcap = NULL; 421183234Ssimon i = CMS_add_standard_smimecap(&smcap); 422183234Ssimon if (i) 423183234Ssimon i = CMS_add_smimecap(si, smcap); 424183234Ssimon sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 425183234Ssimon if (!i) 426183234Ssimon goto merr; 427183234Ssimon } 428183234Ssimon if (flags & CMS_REUSE_DIGEST) 429183234Ssimon { 430183234Ssimon if (!cms_copy_messageDigest(cms, si)) 431183234Ssimon goto err; 432183234Ssimon if (!(flags & CMS_PARTIAL) && 433183234Ssimon !CMS_SignerInfo_sign(si)) 434183234Ssimon goto err; 435183234Ssimon } 436183234Ssimon } 437183234Ssimon 438183234Ssimon if (!(flags & CMS_NOCERTS)) 439183234Ssimon { 440183234Ssimon /* NB ignore -1 return for duplicate cert */ 441183234Ssimon if (!CMS_add1_cert(cms, signer)) 442183234Ssimon goto merr; 443183234Ssimon } 444183234Ssimon 445183234Ssimon if (!sd->signerInfos) 446183234Ssimon sd->signerInfos = sk_CMS_SignerInfo_new_null(); 447183234Ssimon if (!sd->signerInfos || 448183234Ssimon !sk_CMS_SignerInfo_push(sd->signerInfos, si)) 449183234Ssimon goto merr; 450183234Ssimon 451183234Ssimon return si; 452183234Ssimon 453183234Ssimon merr: 454183234Ssimon CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); 455183234Ssimon err: 456183234Ssimon if (si) 457183234Ssimon M_ASN1_free_of(si, CMS_SignerInfo); 458183234Ssimon return NULL; 459183234Ssimon 460183234Ssimon } 461183234Ssimon 462183234Ssimonstatic int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) 463183234Ssimon { 464183234Ssimon ASN1_TIME *tt; 465183234Ssimon int r = 0; 466183234Ssimon if (t) 467183234Ssimon tt = t; 468183234Ssimon else 469183234Ssimon tt = X509_gmtime_adj(NULL, 0); 470183234Ssimon 471183234Ssimon if (!tt) 472183234Ssimon goto merr; 473183234Ssimon 474183234Ssimon if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, 475183234Ssimon tt->type, tt, -1) <= 0) 476183234Ssimon goto merr; 477183234Ssimon 478183234Ssimon r = 1; 479183234Ssimon 480183234Ssimon merr: 481183234Ssimon 482183234Ssimon if (!t) 483183234Ssimon ASN1_TIME_free(tt); 484183234Ssimon 485183234Ssimon if (!r) 486183234Ssimon CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE); 487183234Ssimon 488183234Ssimon return r; 489183234Ssimon 490183234Ssimon } 491183234Ssimon 492183234SsimonSTACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms) 493183234Ssimon { 494183234Ssimon CMS_SignedData *sd; 495183234Ssimon sd = cms_get0_signed(cms); 496183234Ssimon if (!sd) 497183234Ssimon return NULL; 498183234Ssimon return sd->signerInfos; 499183234Ssimon } 500183234Ssimon 501183234SsimonSTACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) 502183234Ssimon { 503183234Ssimon STACK_OF(X509) *signers = NULL; 504183234Ssimon STACK_OF(CMS_SignerInfo) *sinfos; 505183234Ssimon CMS_SignerInfo *si; 506183234Ssimon int i; 507183234Ssimon sinfos = CMS_get0_SignerInfos(cms); 508183234Ssimon for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) 509183234Ssimon { 510183234Ssimon si = sk_CMS_SignerInfo_value(sinfos, i); 511183234Ssimon if (si->signer) 512183234Ssimon { 513183234Ssimon if (!signers) 514183234Ssimon { 515183234Ssimon signers = sk_X509_new_null(); 516183234Ssimon if (!signers) 517183234Ssimon return NULL; 518183234Ssimon } 519183234Ssimon if (!sk_X509_push(signers, si->signer)) 520183234Ssimon { 521183234Ssimon sk_X509_free(signers); 522183234Ssimon return NULL; 523183234Ssimon } 524183234Ssimon } 525183234Ssimon } 526183234Ssimon return signers; 527183234Ssimon } 528183234Ssimon 529183234Ssimonvoid CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) 530183234Ssimon { 531183234Ssimon if (signer) 532183234Ssimon { 533183234Ssimon CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); 534183234Ssimon if (si->pkey) 535183234Ssimon EVP_PKEY_free(si->pkey); 536183234Ssimon si->pkey = X509_get_pubkey(signer); 537183234Ssimon } 538183234Ssimon if (si->signer) 539183234Ssimon X509_free(si->signer); 540183234Ssimon si->signer = signer; 541183234Ssimon } 542183234Ssimon 543183234Ssimonint CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, 544183234Ssimon ASN1_OCTET_STRING **keyid, 545183234Ssimon X509_NAME **issuer, ASN1_INTEGER **sno) 546183234Ssimon { 547183234Ssimon return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); 548183234Ssimon } 549183234Ssimon 550183234Ssimonint CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) 551183234Ssimon { 552183234Ssimon return cms_SignerIdentifier_cert_cmp(si->sid, cert); 553183234Ssimon } 554183234Ssimon 555183234Ssimonint CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, 556183234Ssimon unsigned int flags) 557183234Ssimon { 558183234Ssimon CMS_SignedData *sd; 559183234Ssimon CMS_SignerInfo *si; 560183234Ssimon CMS_CertificateChoices *cch; 561183234Ssimon STACK_OF(CMS_CertificateChoices) *certs; 562183234Ssimon X509 *x; 563183234Ssimon int i, j; 564183234Ssimon int ret = 0; 565183234Ssimon sd = cms_get0_signed(cms); 566183234Ssimon if (!sd) 567183234Ssimon return -1; 568183234Ssimon certs = sd->certificates; 569183234Ssimon for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) 570183234Ssimon { 571183234Ssimon si = sk_CMS_SignerInfo_value(sd->signerInfos, i); 572183234Ssimon if (si->signer) 573183234Ssimon continue; 574183234Ssimon 575183234Ssimon for (j = 0; j < sk_X509_num(scerts); j++) 576183234Ssimon { 577183234Ssimon x = sk_X509_value(scerts, j); 578183234Ssimon if (CMS_SignerInfo_cert_cmp(si, x) == 0) 579183234Ssimon { 580183234Ssimon CMS_SignerInfo_set1_signer_cert(si, x); 581183234Ssimon ret++; 582183234Ssimon break; 583183234Ssimon } 584183234Ssimon } 585183234Ssimon 586183234Ssimon if (si->signer || (flags & CMS_NOINTERN)) 587183234Ssimon continue; 588183234Ssimon 589183234Ssimon for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) 590183234Ssimon { 591183234Ssimon cch = sk_CMS_CertificateChoices_value(certs, j); 592183234Ssimon if (cch->type != 0) 593183234Ssimon continue; 594183234Ssimon x = cch->d.certificate; 595183234Ssimon if (CMS_SignerInfo_cert_cmp(si, x) == 0) 596183234Ssimon { 597183234Ssimon CMS_SignerInfo_set1_signer_cert(si, x); 598183234Ssimon ret++; 599183234Ssimon break; 600183234Ssimon } 601183234Ssimon } 602183234Ssimon } 603183234Ssimon return ret; 604183234Ssimon } 605183234Ssimon 606183234Ssimonvoid CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, 607183234Ssimon X509_ALGOR **pdig, X509_ALGOR **psig) 608183234Ssimon { 609183234Ssimon if (pk) 610183234Ssimon *pk = si->pkey; 611183234Ssimon if (signer) 612183234Ssimon *signer = si->signer; 613183234Ssimon if (pdig) 614183234Ssimon *pdig = si->digestAlgorithm; 615183234Ssimon if (psig) 616183234Ssimon *psig = si->signatureAlgorithm; 617183234Ssimon } 618183234Ssimon 619183234Ssimonstatic int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, 620183234Ssimon CMS_SignerInfo *si, BIO *chain) 621183234Ssimon { 622183234Ssimon EVP_MD_CTX mctx; 623183234Ssimon int r = 0; 624183234Ssimon EVP_MD_CTX_init(&mctx); 625183234Ssimon 626183234Ssimon 627183234Ssimon if (!si->pkey) 628183234Ssimon { 629183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY); 630183234Ssimon return 0; 631183234Ssimon } 632183234Ssimon 633183234Ssimon if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) 634183234Ssimon goto err; 635183234Ssimon 636183234Ssimon /* If any signed attributes calculate and add messageDigest attribute */ 637183234Ssimon 638183234Ssimon if (CMS_signed_get_attr_count(si) >= 0) 639183234Ssimon { 640183234Ssimon ASN1_OBJECT *ctype = 641183234Ssimon cms->d.signedData->encapContentInfo->eContentType; 642183234Ssimon unsigned char md[EVP_MAX_MD_SIZE]; 643183234Ssimon unsigned int mdlen; 644238405Sjkim if (!EVP_DigestFinal_ex(&mctx, md, &mdlen)) 645238405Sjkim goto err; 646183234Ssimon if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, 647183234Ssimon V_ASN1_OCTET_STRING, 648183234Ssimon md, mdlen)) 649183234Ssimon goto err; 650183234Ssimon /* Copy content type across */ 651183234Ssimon if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType, 652183234Ssimon V_ASN1_OBJECT, ctype, -1) <= 0) 653183234Ssimon goto err; 654183234Ssimon if (!CMS_SignerInfo_sign(si)) 655183234Ssimon goto err; 656183234Ssimon } 657183234Ssimon else 658183234Ssimon { 659183234Ssimon unsigned char *sig; 660183234Ssimon unsigned int siglen; 661183234Ssimon sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey)); 662183234Ssimon if (!sig) 663183234Ssimon { 664183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, 665183234Ssimon ERR_R_MALLOC_FAILURE); 666183234Ssimon goto err; 667183234Ssimon } 668183234Ssimon if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) 669183234Ssimon { 670183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, 671183234Ssimon CMS_R_SIGNFINAL_ERROR); 672183234Ssimon OPENSSL_free(sig); 673183234Ssimon goto err; 674183234Ssimon } 675183234Ssimon ASN1_STRING_set0(si->signature, sig, siglen); 676183234Ssimon } 677183234Ssimon 678183234Ssimon r = 1; 679183234Ssimon 680183234Ssimon err: 681183234Ssimon EVP_MD_CTX_cleanup(&mctx); 682183234Ssimon return r; 683183234Ssimon 684183234Ssimon } 685183234Ssimon 686183234Ssimonint cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) 687183234Ssimon { 688183234Ssimon STACK_OF(CMS_SignerInfo) *sinfos; 689183234Ssimon CMS_SignerInfo *si; 690183234Ssimon int i; 691183234Ssimon sinfos = CMS_get0_SignerInfos(cms); 692183234Ssimon for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) 693183234Ssimon { 694183234Ssimon si = sk_CMS_SignerInfo_value(sinfos, i); 695183234Ssimon if (!cms_SignerInfo_content_sign(cms, si, chain)) 696183234Ssimon return 0; 697183234Ssimon } 698183234Ssimon cms->d.signedData->encapContentInfo->partial = 0; 699183234Ssimon return 1; 700183234Ssimon } 701183234Ssimon 702183234Ssimonint CMS_SignerInfo_sign(CMS_SignerInfo *si) 703183234Ssimon { 704183234Ssimon EVP_MD_CTX mctx; 705238405Sjkim EVP_PKEY_CTX *pctx; 706183234Ssimon unsigned char *abuf = NULL; 707183234Ssimon int alen; 708238405Sjkim size_t siglen; 709183234Ssimon const EVP_MD *md = NULL; 710183234Ssimon 711183234Ssimon md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 712183234Ssimon if (md == NULL) 713183234Ssimon return 0; 714183234Ssimon 715183234Ssimon EVP_MD_CTX_init(&mctx); 716183234Ssimon 717183234Ssimon if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) 718183234Ssimon { 719183234Ssimon if (!cms_add1_signingTime(si, NULL)) 720183234Ssimon goto err; 721183234Ssimon } 722183234Ssimon 723238405Sjkim if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) 724183234Ssimon goto err; 725183234Ssimon 726183234Ssimon if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 727183234Ssimon EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) 728183234Ssimon { 729183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); 730183234Ssimon goto err; 731183234Ssimon } 732183234Ssimon 733183234Ssimon alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, 734183234Ssimon ASN1_ITEM_rptr(CMS_Attributes_Sign)); 735183234Ssimon if(!abuf) 736183234Ssimon goto err; 737238405Sjkim if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) 738183234Ssimon goto err; 739238405Sjkim if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) 740238405Sjkim goto err; 741183234Ssimon OPENSSL_free(abuf); 742183234Ssimon abuf = OPENSSL_malloc(siglen); 743183234Ssimon if(!abuf) 744183234Ssimon goto err; 745238405Sjkim if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) 746183234Ssimon goto err; 747238405Sjkim 748183234Ssimon if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 749183234Ssimon EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) 750183234Ssimon { 751183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); 752183234Ssimon goto err; 753183234Ssimon } 754238405Sjkim 755183234Ssimon EVP_MD_CTX_cleanup(&mctx); 756183234Ssimon 757183234Ssimon ASN1_STRING_set0(si->signature, abuf, siglen); 758183234Ssimon 759183234Ssimon return 1; 760183234Ssimon 761183234Ssimon err: 762183234Ssimon if (abuf) 763183234Ssimon OPENSSL_free(abuf); 764183234Ssimon EVP_MD_CTX_cleanup(&mctx); 765183234Ssimon return 0; 766183234Ssimon 767183234Ssimon } 768183234Ssimon 769183234Ssimonint CMS_SignerInfo_verify(CMS_SignerInfo *si) 770183234Ssimon { 771183234Ssimon EVP_MD_CTX mctx; 772238405Sjkim EVP_PKEY_CTX *pctx; 773183234Ssimon unsigned char *abuf = NULL; 774183234Ssimon int alen, r = -1; 775183234Ssimon const EVP_MD *md = NULL; 776183234Ssimon 777183234Ssimon if (!si->pkey) 778183234Ssimon { 779183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY); 780183234Ssimon return -1; 781183234Ssimon } 782183234Ssimon 783183234Ssimon md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 784183234Ssimon if (md == NULL) 785183234Ssimon return -1; 786183234Ssimon EVP_MD_CTX_init(&mctx); 787238405Sjkim if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) 788183234Ssimon goto err; 789183234Ssimon 790183234Ssimon alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, 791183234Ssimon ASN1_ITEM_rptr(CMS_Attributes_Verify)); 792183234Ssimon if(!abuf) 793183234Ssimon goto err; 794238405Sjkim r = EVP_DigestVerifyUpdate(&mctx, abuf, alen); 795183234Ssimon OPENSSL_free(abuf); 796183234Ssimon if (r <= 0) 797183234Ssimon { 798183234Ssimon r = -1; 799183234Ssimon goto err; 800183234Ssimon } 801238405Sjkim r = EVP_DigestVerifyFinal(&mctx, 802238405Sjkim si->signature->data, si->signature->length); 803193645Ssimon if (r <= 0) 804183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); 805183234Ssimon err: 806183234Ssimon EVP_MD_CTX_cleanup(&mctx); 807183234Ssimon return r; 808183234Ssimon } 809183234Ssimon 810183234Ssimon/* Create a chain of digest BIOs from a CMS ContentInfo */ 811183234Ssimon 812183234SsimonBIO *cms_SignedData_init_bio(CMS_ContentInfo *cms) 813183234Ssimon { 814183234Ssimon int i; 815183234Ssimon CMS_SignedData *sd; 816183234Ssimon BIO *chain = NULL; 817183234Ssimon sd = cms_get0_signed(cms); 818183234Ssimon if (!sd) 819183234Ssimon return NULL; 820183234Ssimon if (cms->d.signedData->encapContentInfo->partial) 821183234Ssimon cms_sd_set_version(sd); 822183234Ssimon for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) 823183234Ssimon { 824183234Ssimon X509_ALGOR *digestAlgorithm; 825183234Ssimon BIO *mdbio; 826183234Ssimon digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); 827183234Ssimon mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); 828183234Ssimon if (!mdbio) 829183234Ssimon goto err; 830183234Ssimon if (chain) 831183234Ssimon BIO_push(chain, mdbio); 832183234Ssimon else 833183234Ssimon chain = mdbio; 834183234Ssimon } 835183234Ssimon return chain; 836183234Ssimon err: 837183234Ssimon if (chain) 838183234Ssimon BIO_free_all(chain); 839183234Ssimon return NULL; 840183234Ssimon } 841183234Ssimon 842183234Ssimonint CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) 843183234Ssimon { 844183234Ssimon ASN1_OCTET_STRING *os = NULL; 845183234Ssimon EVP_MD_CTX mctx; 846183234Ssimon int r = -1; 847183234Ssimon EVP_MD_CTX_init(&mctx); 848183234Ssimon /* If we have any signed attributes look for messageDigest value */ 849183234Ssimon if (CMS_signed_get_attr_count(si) >= 0) 850183234Ssimon { 851183234Ssimon os = CMS_signed_get0_data_by_OBJ(si, 852183234Ssimon OBJ_nid2obj(NID_pkcs9_messageDigest), 853183234Ssimon -3, V_ASN1_OCTET_STRING); 854183234Ssimon if (!os) 855183234Ssimon { 856183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 857183234Ssimon CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); 858183234Ssimon goto err; 859183234Ssimon } 860183234Ssimon } 861183234Ssimon 862183234Ssimon if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) 863183234Ssimon goto err; 864183234Ssimon 865183234Ssimon /* If messageDigest found compare it */ 866183234Ssimon 867183234Ssimon if (os) 868183234Ssimon { 869183234Ssimon unsigned char mval[EVP_MAX_MD_SIZE]; 870183234Ssimon unsigned int mlen; 871183234Ssimon if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) 872183234Ssimon { 873183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 874183234Ssimon CMS_R_UNABLE_TO_FINALIZE_CONTEXT); 875183234Ssimon goto err; 876183234Ssimon } 877183234Ssimon if (mlen != (unsigned int)os->length) 878183234Ssimon { 879183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 880183234Ssimon CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); 881183234Ssimon goto err; 882183234Ssimon } 883183234Ssimon 884183234Ssimon if (memcmp(mval, os->data, mlen)) 885183234Ssimon { 886183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 887183234Ssimon CMS_R_VERIFICATION_FAILURE); 888183234Ssimon r = 0; 889183234Ssimon } 890183234Ssimon else 891183234Ssimon r = 1; 892183234Ssimon } 893183234Ssimon else 894183234Ssimon { 895183234Ssimon r = EVP_VerifyFinal(&mctx, si->signature->data, 896183234Ssimon si->signature->length, si->pkey); 897183234Ssimon if (r <= 0) 898183234Ssimon { 899183234Ssimon CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 900183234Ssimon CMS_R_VERIFICATION_FAILURE); 901183234Ssimon r = 0; 902183234Ssimon } 903183234Ssimon } 904183234Ssimon 905183234Ssimon err: 906183234Ssimon EVP_MD_CTX_cleanup(&mctx); 907183234Ssimon return r; 908183234Ssimon 909183234Ssimon } 910183234Ssimon 911183234Ssimonint CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) 912183234Ssimon { 913183234Ssimon unsigned char *smder = NULL; 914183234Ssimon int smderlen, r; 915183234Ssimon smderlen = i2d_X509_ALGORS(algs, &smder); 916183234Ssimon if (smderlen <= 0) 917183234Ssimon return 0; 918183234Ssimon r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities, 919183234Ssimon V_ASN1_SEQUENCE, smder, smderlen); 920183234Ssimon OPENSSL_free(smder); 921183234Ssimon return r; 922183234Ssimon } 923183234Ssimon 924183234Ssimonint CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, 925183234Ssimon int algnid, int keysize) 926183234Ssimon { 927183234Ssimon X509_ALGOR *alg; 928183234Ssimon ASN1_INTEGER *key = NULL; 929183234Ssimon if (keysize > 0) 930183234Ssimon { 931183234Ssimon key = ASN1_INTEGER_new(); 932183234Ssimon if (!key || !ASN1_INTEGER_set(key, keysize)) 933183234Ssimon return 0; 934183234Ssimon } 935183234Ssimon alg = X509_ALGOR_new(); 936183234Ssimon if (!alg) 937183234Ssimon { 938183234Ssimon if (key) 939183234Ssimon ASN1_INTEGER_free(key); 940183234Ssimon return 0; 941183234Ssimon } 942183234Ssimon 943183234Ssimon X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), 944183234Ssimon key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); 945183234Ssimon if (!*algs) 946183234Ssimon *algs = sk_X509_ALGOR_new_null(); 947183234Ssimon if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) 948183234Ssimon { 949183234Ssimon X509_ALGOR_free(alg); 950183234Ssimon return 0; 951183234Ssimon } 952183234Ssimon return 1; 953183234Ssimon } 954183234Ssimon 955183234Ssimon/* Check to see if a cipher exists and if so add S/MIME capabilities */ 956183234Ssimon 957183234Ssimonstatic int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 958183234Ssimon { 959183234Ssimon if (EVP_get_cipherbynid(nid)) 960183234Ssimon return CMS_add_simple_smimecap(sk, nid, arg); 961183234Ssimon return 1; 962183234Ssimon } 963238405Sjkim 964183234Ssimonstatic int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 965183234Ssimon { 966183234Ssimon if (EVP_get_digestbynid(nid)) 967183234Ssimon return CMS_add_simple_smimecap(sk, nid, arg); 968183234Ssimon return 1; 969183234Ssimon } 970238405Sjkim 971183234Ssimonint CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) 972183234Ssimon { 973183234Ssimon if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) 974238405Sjkim || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) 975238405Sjkim || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) 976183234Ssimon || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) 977183234Ssimon || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) 978183234Ssimon || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) 979183234Ssimon || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) 980183234Ssimon || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) 981183234Ssimon || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) 982183234Ssimon || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) 983183234Ssimon return 0; 984183234Ssimon return 1; 985183234Ssimon } 986