1183234Ssimon/* crypto/cms/cms_sd.c */ 2296341Sdelphij/* 3296341Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4183234Ssimon * project. 5183234Ssimon */ 6183234Ssimon/* ==================================================================== 7183234Ssimon * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 8183234Ssimon * 9183234Ssimon * Redistribution and use in source and binary forms, with or without 10183234Ssimon * modification, are permitted provided that the following conditions 11183234Ssimon * are met: 12183234Ssimon * 13183234Ssimon * 1. Redistributions of source code must retain the above copyright 14296341Sdelphij * notice, this list of conditions and the following disclaimer. 15183234Ssimon * 16183234Ssimon * 2. Redistributions in binary form must reproduce the above copyright 17183234Ssimon * notice, this list of conditions and the following disclaimer in 18183234Ssimon * the documentation and/or other materials provided with the 19183234Ssimon * distribution. 20183234Ssimon * 21183234Ssimon * 3. All advertising materials mentioning features or use of this 22183234Ssimon * software must display the following acknowledgment: 23183234Ssimon * "This product includes software developed by the OpenSSL Project 24183234Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25183234Ssimon * 26183234Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27183234Ssimon * endorse or promote products derived from this software without 28183234Ssimon * prior written permission. For written permission, please contact 29183234Ssimon * licensing@OpenSSL.org. 30183234Ssimon * 31183234Ssimon * 5. Products derived from this software may not be called "OpenSSL" 32183234Ssimon * nor may "OpenSSL" appear in their names without prior written 33183234Ssimon * permission of the OpenSSL Project. 34183234Ssimon * 35183234Ssimon * 6. Redistributions of any form whatsoever must retain the following 36183234Ssimon * acknowledgment: 37183234Ssimon * "This product includes software developed by the OpenSSL Project 38183234Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39183234Ssimon * 40183234Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41183234Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42183234Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43183234Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44183234Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45183234Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46183234Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47183234Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48183234Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49183234Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50183234Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51183234Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 52183234Ssimon * ==================================================================== 53183234Ssimon */ 54183234Ssimon 55183234Ssimon#include "cryptlib.h" 56183234Ssimon#include <openssl/asn1t.h> 57183234Ssimon#include <openssl/pem.h> 58183234Ssimon#include <openssl/x509v3.h> 59183234Ssimon#include <openssl/err.h> 60183234Ssimon#include <openssl/cms.h> 61183234Ssimon#include "cms_lcl.h" 62238405Sjkim#include "asn1_locl.h" 63183234Ssimon 64183234Ssimon/* CMS SignedData Utilities */ 65183234Ssimon 66183234SsimonDECLARE_ASN1_ITEM(CMS_SignedData) 67183234Ssimon 68183234Ssimonstatic CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms) 69296341Sdelphij{ 70296341Sdelphij if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) { 71296341Sdelphij CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); 72296341Sdelphij return NULL; 73296341Sdelphij } 74296341Sdelphij return cms->d.signedData; 75296341Sdelphij} 76183234Ssimon 77183234Ssimonstatic CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) 78296341Sdelphij{ 79296341Sdelphij if (cms->d.other == NULL) { 80296341Sdelphij cms->d.signedData = M_ASN1_new_of(CMS_SignedData); 81296341Sdelphij if (!cms->d.signedData) { 82296341Sdelphij CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE); 83296341Sdelphij return NULL; 84296341Sdelphij } 85296341Sdelphij cms->d.signedData->version = 1; 86296341Sdelphij cms->d.signedData->encapContentInfo->eContentType = 87296341Sdelphij OBJ_nid2obj(NID_pkcs7_data); 88296341Sdelphij cms->d.signedData->encapContentInfo->partial = 1; 89296341Sdelphij ASN1_OBJECT_free(cms->contentType); 90296341Sdelphij cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); 91296341Sdelphij return cms->d.signedData; 92296341Sdelphij } 93296341Sdelphij return cms_get0_signed(cms); 94296341Sdelphij} 95183234Ssimon 96183234Ssimon/* Just initialize SignedData e.g. for certs only structure */ 97183234Ssimon 98183234Ssimonint CMS_SignedData_init(CMS_ContentInfo *cms) 99296341Sdelphij{ 100296341Sdelphij if (cms_signed_data_init(cms)) 101296341Sdelphij return 1; 102296341Sdelphij else 103296341Sdelphij return 0; 104296341Sdelphij} 105183234Ssimon 106183234Ssimon/* Check structures and fixup version numbers (if necessary) */ 107183234Ssimon 108183234Ssimonstatic void cms_sd_set_version(CMS_SignedData *sd) 109296341Sdelphij{ 110296341Sdelphij int i; 111296341Sdelphij CMS_CertificateChoices *cch; 112296341Sdelphij CMS_RevocationInfoChoice *rch; 113296341Sdelphij CMS_SignerInfo *si; 114183234Ssimon 115296341Sdelphij for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) { 116296341Sdelphij cch = sk_CMS_CertificateChoices_value(sd->certificates, i); 117296341Sdelphij if (cch->type == CMS_CERTCHOICE_OTHER) { 118296341Sdelphij if (sd->version < 5) 119296341Sdelphij sd->version = 5; 120296341Sdelphij } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { 121296341Sdelphij if (sd->version < 4) 122296341Sdelphij sd->version = 4; 123296341Sdelphij } else if (cch->type == CMS_CERTCHOICE_V1ACERT) { 124296341Sdelphij if (sd->version < 3) 125296341Sdelphij sd->version = 3; 126296341Sdelphij } 127296341Sdelphij } 128183234Ssimon 129296341Sdelphij for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) { 130296341Sdelphij rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i); 131296341Sdelphij if (rch->type == CMS_REVCHOICE_OTHER) { 132296341Sdelphij if (sd->version < 5) 133296341Sdelphij sd->version = 5; 134296341Sdelphij } 135296341Sdelphij } 136183234Ssimon 137296341Sdelphij if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data) 138296341Sdelphij && (sd->version < 3)) 139296341Sdelphij sd->version = 3; 140183234Ssimon 141296341Sdelphij for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { 142296341Sdelphij si = sk_CMS_SignerInfo_value(sd->signerInfos, i); 143296341Sdelphij if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { 144296341Sdelphij if (si->version < 3) 145296341Sdelphij si->version = 3; 146296341Sdelphij if (sd->version < 3) 147296341Sdelphij sd->version = 3; 148296341Sdelphij } else if (si->version < 1) 149296341Sdelphij si->version = 1; 150296341Sdelphij } 151183234Ssimon 152296341Sdelphij if (sd->version < 1) 153296341Sdelphij sd->version = 1; 154183234Ssimon 155296341Sdelphij} 156296341Sdelphij 157183234Ssimon/* Copy an existing messageDigest value */ 158183234Ssimon 159183234Ssimonstatic int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) 160296341Sdelphij{ 161296341Sdelphij STACK_OF(CMS_SignerInfo) *sinfos; 162296341Sdelphij CMS_SignerInfo *sitmp; 163296341Sdelphij int i; 164296341Sdelphij sinfos = CMS_get0_SignerInfos(cms); 165296341Sdelphij for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 166296341Sdelphij ASN1_OCTET_STRING *messageDigest; 167296341Sdelphij sitmp = sk_CMS_SignerInfo_value(sinfos, i); 168296341Sdelphij if (sitmp == si) 169296341Sdelphij continue; 170296341Sdelphij if (CMS_signed_get_attr_count(sitmp) < 0) 171296341Sdelphij continue; 172296341Sdelphij if (OBJ_cmp(si->digestAlgorithm->algorithm, 173296341Sdelphij sitmp->digestAlgorithm->algorithm)) 174296341Sdelphij continue; 175296341Sdelphij messageDigest = CMS_signed_get0_data_by_OBJ(sitmp, 176296341Sdelphij OBJ_nid2obj 177296341Sdelphij (NID_pkcs9_messageDigest), 178296341Sdelphij -3, V_ASN1_OCTET_STRING); 179296341Sdelphij if (!messageDigest) { 180296341Sdelphij CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, 181296341Sdelphij CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); 182296341Sdelphij return 0; 183296341Sdelphij } 184183234Ssimon 185296341Sdelphij if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, 186296341Sdelphij V_ASN1_OCTET_STRING, 187296341Sdelphij messageDigest, -1)) 188296341Sdelphij return 1; 189296341Sdelphij else 190296341Sdelphij return 0; 191296341Sdelphij } 192296341Sdelphij CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST); 193296341Sdelphij return 0; 194296341Sdelphij} 195183234Ssimon 196183234Ssimonint cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) 197296341Sdelphij{ 198296341Sdelphij switch (type) { 199296341Sdelphij case CMS_SIGNERINFO_ISSUER_SERIAL: 200296341Sdelphij sid->d.issuerAndSerialNumber = 201296341Sdelphij M_ASN1_new_of(CMS_IssuerAndSerialNumber); 202296341Sdelphij if (!sid->d.issuerAndSerialNumber) 203296341Sdelphij goto merr; 204296341Sdelphij if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer, 205296341Sdelphij X509_get_issuer_name(cert))) 206296341Sdelphij goto merr; 207296341Sdelphij if (!ASN1_STRING_copy(sid->d.issuerAndSerialNumber->serialNumber, 208296341Sdelphij X509_get_serialNumber(cert))) 209296341Sdelphij goto merr; 210296341Sdelphij break; 211183234Ssimon 212296341Sdelphij case CMS_SIGNERINFO_KEYIDENTIFIER: 213296341Sdelphij if (!cert->skid) { 214296341Sdelphij CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, 215296341Sdelphij CMS_R_CERTIFICATE_HAS_NO_KEYID); 216296341Sdelphij return 0; 217296341Sdelphij } 218296341Sdelphij sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid); 219296341Sdelphij if (!sid->d.subjectKeyIdentifier) 220296341Sdelphij goto merr; 221296341Sdelphij break; 222183234Ssimon 223296341Sdelphij default: 224296341Sdelphij CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID); 225296341Sdelphij return 0; 226296341Sdelphij } 227183234Ssimon 228296341Sdelphij sid->type = type; 229183234Ssimon 230296341Sdelphij return 1; 231183234Ssimon 232296341Sdelphij merr: 233296341Sdelphij CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE); 234296341Sdelphij return 0; 235183234Ssimon 236296341Sdelphij} 237183234Ssimon 238183234Ssimonint cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, 239296341Sdelphij ASN1_OCTET_STRING **keyid, 240296341Sdelphij X509_NAME **issuer, 241296341Sdelphij ASN1_INTEGER **sno) 242296341Sdelphij{ 243296341Sdelphij if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { 244296341Sdelphij if (issuer) 245296341Sdelphij *issuer = sid->d.issuerAndSerialNumber->issuer; 246296341Sdelphij if (sno) 247296341Sdelphij *sno = sid->d.issuerAndSerialNumber->serialNumber; 248296341Sdelphij } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { 249296341Sdelphij if (keyid) 250296341Sdelphij *keyid = sid->d.subjectKeyIdentifier; 251296341Sdelphij } else 252296341Sdelphij return 0; 253296341Sdelphij return 1; 254296341Sdelphij} 255183234Ssimon 256183234Ssimonint cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) 257296341Sdelphij{ 258296341Sdelphij int ret; 259296341Sdelphij if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { 260296341Sdelphij ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer, 261296341Sdelphij X509_get_issuer_name(cert)); 262296341Sdelphij if (ret) 263296341Sdelphij return ret; 264296341Sdelphij return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber, 265296341Sdelphij X509_get_serialNumber(cert)); 266296341Sdelphij } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { 267296341Sdelphij X509_check_purpose(cert, -1, -1); 268296341Sdelphij if (!cert->skid) 269296341Sdelphij return -1; 270296341Sdelphij return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier, cert->skid); 271296341Sdelphij } else 272296341Sdelphij return -1; 273296341Sdelphij} 274183234Ssimon 275183234SsimonCMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, 276296341Sdelphij X509 *signer, EVP_PKEY *pk, const EVP_MD *md, 277296341Sdelphij unsigned int flags) 278296341Sdelphij{ 279296341Sdelphij CMS_SignedData *sd; 280296341Sdelphij CMS_SignerInfo *si = NULL; 281296341Sdelphij X509_ALGOR *alg; 282296341Sdelphij int i, type; 283296341Sdelphij if (!X509_check_private_key(signer, pk)) { 284296341Sdelphij CMSerr(CMS_F_CMS_ADD1_SIGNER, 285296341Sdelphij CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 286296341Sdelphij return NULL; 287296341Sdelphij } 288296341Sdelphij sd = cms_signed_data_init(cms); 289296341Sdelphij if (!sd) 290296341Sdelphij goto err; 291296341Sdelphij si = M_ASN1_new_of(CMS_SignerInfo); 292296341Sdelphij if (!si) 293296341Sdelphij goto merr; 294296341Sdelphij X509_check_purpose(signer, -1, -1); 295183234Ssimon 296296341Sdelphij CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); 297296341Sdelphij CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); 298183234Ssimon 299296341Sdelphij si->pkey = pk; 300296341Sdelphij si->signer = signer; 301183234Ssimon 302296341Sdelphij if (flags & CMS_USE_KEYID) { 303296341Sdelphij si->version = 3; 304296341Sdelphij if (sd->version < 3) 305296341Sdelphij sd->version = 3; 306296341Sdelphij type = CMS_SIGNERINFO_KEYIDENTIFIER; 307296341Sdelphij } else { 308296341Sdelphij type = CMS_SIGNERINFO_ISSUER_SERIAL; 309296341Sdelphij si->version = 1; 310296341Sdelphij } 311183234Ssimon 312296341Sdelphij if (!cms_set1_SignerIdentifier(si->sid, signer, type)) 313296341Sdelphij goto err; 314183234Ssimon 315296341Sdelphij if (md == NULL) { 316296341Sdelphij int def_nid; 317296341Sdelphij if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) 318296341Sdelphij goto err; 319296341Sdelphij md = EVP_get_digestbynid(def_nid); 320296341Sdelphij if (md == NULL) { 321296341Sdelphij CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); 322296341Sdelphij goto err; 323296341Sdelphij } 324296341Sdelphij } 325183234Ssimon 326296341Sdelphij if (!md) { 327296341Sdelphij CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); 328296341Sdelphij goto err; 329296341Sdelphij } 330183234Ssimon 331296341Sdelphij cms_DigestAlgorithm_set(si->digestAlgorithm, md); 332183234Ssimon 333296341Sdelphij /* See if digest is present in digestAlgorithms */ 334296341Sdelphij for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { 335296341Sdelphij ASN1_OBJECT *aoid; 336296341Sdelphij alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); 337296341Sdelphij X509_ALGOR_get0(&aoid, NULL, NULL, alg); 338296341Sdelphij if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) 339296341Sdelphij break; 340296341Sdelphij } 341183234Ssimon 342296341Sdelphij if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { 343296341Sdelphij alg = X509_ALGOR_new(); 344296341Sdelphij if (!alg) 345296341Sdelphij goto merr; 346296341Sdelphij cms_DigestAlgorithm_set(alg, md); 347296341Sdelphij if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { 348296341Sdelphij X509_ALGOR_free(alg); 349296341Sdelphij goto merr; 350296341Sdelphij } 351296341Sdelphij } 352183234Ssimon 353296341Sdelphij if (pk->ameth && pk->ameth->pkey_ctrl) { 354296341Sdelphij i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN, 0, si); 355296341Sdelphij if (i == -2) { 356296341Sdelphij CMSerr(CMS_F_CMS_ADD1_SIGNER, 357296341Sdelphij CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 358296341Sdelphij goto err; 359296341Sdelphij } 360296341Sdelphij if (i <= 0) { 361296341Sdelphij CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE); 362296341Sdelphij goto err; 363296341Sdelphij } 364296341Sdelphij } 365183234Ssimon 366296341Sdelphij if (!(flags & CMS_NOATTR)) { 367296341Sdelphij /* 368296341Sdelphij * Initialialize signed attributes strutucture so other attributes 369296341Sdelphij * such as signing time etc are added later even if we add none here. 370296341Sdelphij */ 371296341Sdelphij if (!si->signedAttrs) { 372296341Sdelphij si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); 373296341Sdelphij if (!si->signedAttrs) 374296341Sdelphij goto merr; 375296341Sdelphij } 376183234Ssimon 377296341Sdelphij if (!(flags & CMS_NOSMIMECAP)) { 378296341Sdelphij STACK_OF(X509_ALGOR) *smcap = NULL; 379296341Sdelphij i = CMS_add_standard_smimecap(&smcap); 380296341Sdelphij if (i) 381296341Sdelphij i = CMS_add_smimecap(si, smcap); 382296341Sdelphij sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 383296341Sdelphij if (!i) 384296341Sdelphij goto merr; 385296341Sdelphij } 386296341Sdelphij if (flags & CMS_REUSE_DIGEST) { 387296341Sdelphij if (!cms_copy_messageDigest(cms, si)) 388296341Sdelphij goto err; 389296341Sdelphij if (!(flags & CMS_PARTIAL) && !CMS_SignerInfo_sign(si)) 390296341Sdelphij goto err; 391296341Sdelphij } 392296341Sdelphij } 393183234Ssimon 394296341Sdelphij if (!(flags & CMS_NOCERTS)) { 395296341Sdelphij /* NB ignore -1 return for duplicate cert */ 396296341Sdelphij if (!CMS_add1_cert(cms, signer)) 397296341Sdelphij goto merr; 398296341Sdelphij } 399183234Ssimon 400296341Sdelphij if (!sd->signerInfos) 401296341Sdelphij sd->signerInfos = sk_CMS_SignerInfo_new_null(); 402296341Sdelphij if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) 403296341Sdelphij goto merr; 404183234Ssimon 405296341Sdelphij return si; 406183234Ssimon 407296341Sdelphij merr: 408296341Sdelphij CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); 409296341Sdelphij err: 410296341Sdelphij if (si) 411296341Sdelphij M_ASN1_free_of(si, CMS_SignerInfo); 412296341Sdelphij return NULL; 413183234Ssimon 414296341Sdelphij} 415183234Ssimon 416183234Ssimonstatic int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) 417296341Sdelphij{ 418296341Sdelphij ASN1_TIME *tt; 419296341Sdelphij int r = 0; 420296341Sdelphij if (t) 421296341Sdelphij tt = t; 422296341Sdelphij else 423296341Sdelphij tt = X509_gmtime_adj(NULL, 0); 424183234Ssimon 425296341Sdelphij if (!tt) 426296341Sdelphij goto merr; 427183234Ssimon 428296341Sdelphij if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, 429296341Sdelphij tt->type, tt, -1) <= 0) 430296341Sdelphij goto merr; 431183234Ssimon 432296341Sdelphij r = 1; 433183234Ssimon 434296341Sdelphij merr: 435183234Ssimon 436296341Sdelphij if (!t) 437296341Sdelphij ASN1_TIME_free(tt); 438183234Ssimon 439296341Sdelphij if (!r) 440296341Sdelphij CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE); 441183234Ssimon 442296341Sdelphij return r; 443183234Ssimon 444296341Sdelphij} 445183234Ssimon 446183234SsimonSTACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms) 447296341Sdelphij{ 448296341Sdelphij CMS_SignedData *sd; 449296341Sdelphij sd = cms_get0_signed(cms); 450296341Sdelphij if (!sd) 451296341Sdelphij return NULL; 452296341Sdelphij return sd->signerInfos; 453296341Sdelphij} 454183234Ssimon 455183234SsimonSTACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) 456296341Sdelphij{ 457296341Sdelphij STACK_OF(X509) *signers = NULL; 458296341Sdelphij STACK_OF(CMS_SignerInfo) *sinfos; 459296341Sdelphij CMS_SignerInfo *si; 460296341Sdelphij int i; 461296341Sdelphij sinfos = CMS_get0_SignerInfos(cms); 462296341Sdelphij for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 463296341Sdelphij si = sk_CMS_SignerInfo_value(sinfos, i); 464296341Sdelphij if (si->signer) { 465296341Sdelphij if (!signers) { 466296341Sdelphij signers = sk_X509_new_null(); 467296341Sdelphij if (!signers) 468296341Sdelphij return NULL; 469296341Sdelphij } 470296341Sdelphij if (!sk_X509_push(signers, si->signer)) { 471296341Sdelphij sk_X509_free(signers); 472296341Sdelphij return NULL; 473296341Sdelphij } 474296341Sdelphij } 475296341Sdelphij } 476296341Sdelphij return signers; 477296341Sdelphij} 478183234Ssimon 479183234Ssimonvoid CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) 480296341Sdelphij{ 481296341Sdelphij if (signer) { 482296341Sdelphij CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); 483296341Sdelphij if (si->pkey) 484296341Sdelphij EVP_PKEY_free(si->pkey); 485296341Sdelphij si->pkey = X509_get_pubkey(signer); 486296341Sdelphij } 487296341Sdelphij if (si->signer) 488296341Sdelphij X509_free(si->signer); 489296341Sdelphij si->signer = signer; 490296341Sdelphij} 491183234Ssimon 492183234Ssimonint CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, 493296341Sdelphij ASN1_OCTET_STRING **keyid, 494296341Sdelphij X509_NAME **issuer, ASN1_INTEGER **sno) 495296341Sdelphij{ 496296341Sdelphij return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); 497296341Sdelphij} 498183234Ssimon 499183234Ssimonint CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) 500296341Sdelphij{ 501296341Sdelphij return cms_SignerIdentifier_cert_cmp(si->sid, cert); 502296341Sdelphij} 503183234Ssimon 504183234Ssimonint CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, 505296341Sdelphij unsigned int flags) 506296341Sdelphij{ 507296341Sdelphij CMS_SignedData *sd; 508296341Sdelphij CMS_SignerInfo *si; 509296341Sdelphij CMS_CertificateChoices *cch; 510296341Sdelphij STACK_OF(CMS_CertificateChoices) *certs; 511296341Sdelphij X509 *x; 512296341Sdelphij int i, j; 513296341Sdelphij int ret = 0; 514296341Sdelphij sd = cms_get0_signed(cms); 515296341Sdelphij if (!sd) 516296341Sdelphij return -1; 517296341Sdelphij certs = sd->certificates; 518296341Sdelphij for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { 519296341Sdelphij si = sk_CMS_SignerInfo_value(sd->signerInfos, i); 520296341Sdelphij if (si->signer) 521296341Sdelphij continue; 522183234Ssimon 523296341Sdelphij for (j = 0; j < sk_X509_num(scerts); j++) { 524296341Sdelphij x = sk_X509_value(scerts, j); 525296341Sdelphij if (CMS_SignerInfo_cert_cmp(si, x) == 0) { 526296341Sdelphij CMS_SignerInfo_set1_signer_cert(si, x); 527296341Sdelphij ret++; 528296341Sdelphij break; 529296341Sdelphij } 530296341Sdelphij } 531183234Ssimon 532296341Sdelphij if (si->signer || (flags & CMS_NOINTERN)) 533296341Sdelphij continue; 534183234Ssimon 535296341Sdelphij for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { 536296341Sdelphij cch = sk_CMS_CertificateChoices_value(certs, j); 537296341Sdelphij if (cch->type != 0) 538296341Sdelphij continue; 539296341Sdelphij x = cch->d.certificate; 540296341Sdelphij if (CMS_SignerInfo_cert_cmp(si, x) == 0) { 541296341Sdelphij CMS_SignerInfo_set1_signer_cert(si, x); 542296341Sdelphij ret++; 543296341Sdelphij break; 544296341Sdelphij } 545296341Sdelphij } 546296341Sdelphij } 547296341Sdelphij return ret; 548296341Sdelphij} 549183234Ssimon 550296341Sdelphijvoid CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, 551296341Sdelphij X509 **signer, X509_ALGOR **pdig, 552296341Sdelphij X509_ALGOR **psig) 553296341Sdelphij{ 554296341Sdelphij if (pk) 555296341Sdelphij *pk = si->pkey; 556296341Sdelphij if (signer) 557296341Sdelphij *signer = si->signer; 558296341Sdelphij if (pdig) 559296341Sdelphij *pdig = si->digestAlgorithm; 560296341Sdelphij if (psig) 561296341Sdelphij *psig = si->signatureAlgorithm; 562296341Sdelphij} 563183234Ssimon 564183234Ssimonstatic int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, 565296341Sdelphij CMS_SignerInfo *si, BIO *chain) 566296341Sdelphij{ 567296341Sdelphij EVP_MD_CTX mctx; 568296341Sdelphij int r = 0; 569296341Sdelphij EVP_MD_CTX_init(&mctx); 570183234Ssimon 571296341Sdelphij if (!si->pkey) { 572296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY); 573296341Sdelphij return 0; 574296341Sdelphij } 575183234Ssimon 576296341Sdelphij if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) 577296341Sdelphij goto err; 578183234Ssimon 579296341Sdelphij /* 580296341Sdelphij * If any signed attributes calculate and add messageDigest attribute 581296341Sdelphij */ 582183234Ssimon 583296341Sdelphij if (CMS_signed_get_attr_count(si) >= 0) { 584296341Sdelphij ASN1_OBJECT *ctype = 585296341Sdelphij cms->d.signedData->encapContentInfo->eContentType; 586296341Sdelphij unsigned char md[EVP_MAX_MD_SIZE]; 587296341Sdelphij unsigned int mdlen; 588296341Sdelphij if (!EVP_DigestFinal_ex(&mctx, md, &mdlen)) 589296341Sdelphij goto err; 590296341Sdelphij if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, 591296341Sdelphij V_ASN1_OCTET_STRING, md, mdlen)) 592296341Sdelphij goto err; 593296341Sdelphij /* Copy content type across */ 594296341Sdelphij if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType, 595296341Sdelphij V_ASN1_OBJECT, ctype, -1) <= 0) 596296341Sdelphij goto err; 597296341Sdelphij if (!CMS_SignerInfo_sign(si)) 598296341Sdelphij goto err; 599296341Sdelphij } else { 600296341Sdelphij unsigned char *sig; 601296341Sdelphij unsigned int siglen; 602296341Sdelphij sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey)); 603296341Sdelphij if (!sig) { 604296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); 605296341Sdelphij goto err; 606296341Sdelphij } 607296341Sdelphij if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) { 608296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR); 609296341Sdelphij OPENSSL_free(sig); 610296341Sdelphij goto err; 611296341Sdelphij } 612296341Sdelphij ASN1_STRING_set0(si->signature, sig, siglen); 613296341Sdelphij } 614183234Ssimon 615296341Sdelphij r = 1; 616183234Ssimon 617296341Sdelphij err: 618296341Sdelphij EVP_MD_CTX_cleanup(&mctx); 619296341Sdelphij return r; 620183234Ssimon 621296341Sdelphij} 622183234Ssimon 623183234Ssimonint cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) 624296341Sdelphij{ 625296341Sdelphij STACK_OF(CMS_SignerInfo) *sinfos; 626296341Sdelphij CMS_SignerInfo *si; 627296341Sdelphij int i; 628296341Sdelphij sinfos = CMS_get0_SignerInfos(cms); 629296341Sdelphij for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 630296341Sdelphij si = sk_CMS_SignerInfo_value(sinfos, i); 631296341Sdelphij if (!cms_SignerInfo_content_sign(cms, si, chain)) 632296341Sdelphij return 0; 633296341Sdelphij } 634296341Sdelphij cms->d.signedData->encapContentInfo->partial = 0; 635296341Sdelphij return 1; 636296341Sdelphij} 637183234Ssimon 638183234Ssimonint CMS_SignerInfo_sign(CMS_SignerInfo *si) 639296341Sdelphij{ 640296341Sdelphij EVP_MD_CTX mctx; 641296341Sdelphij EVP_PKEY_CTX *pctx; 642296341Sdelphij unsigned char *abuf = NULL; 643296341Sdelphij int alen; 644296341Sdelphij size_t siglen; 645296341Sdelphij const EVP_MD *md = NULL; 646183234Ssimon 647296341Sdelphij md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 648296341Sdelphij if (md == NULL) 649296341Sdelphij return 0; 650183234Ssimon 651296341Sdelphij EVP_MD_CTX_init(&mctx); 652183234Ssimon 653296341Sdelphij if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { 654296341Sdelphij if (!cms_add1_signingTime(si, NULL)) 655296341Sdelphij goto err; 656296341Sdelphij } 657183234Ssimon 658296341Sdelphij if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) 659296341Sdelphij goto err; 660183234Ssimon 661296341Sdelphij if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 662296341Sdelphij EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { 663296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); 664296341Sdelphij goto err; 665296341Sdelphij } 666183234Ssimon 667296341Sdelphij alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, 668296341Sdelphij ASN1_ITEM_rptr(CMS_Attributes_Sign)); 669296341Sdelphij if (!abuf) 670296341Sdelphij goto err; 671296341Sdelphij if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) 672296341Sdelphij goto err; 673296341Sdelphij if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) 674296341Sdelphij goto err; 675296341Sdelphij OPENSSL_free(abuf); 676296341Sdelphij abuf = OPENSSL_malloc(siglen); 677296341Sdelphij if (!abuf) 678296341Sdelphij goto err; 679296341Sdelphij if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) 680296341Sdelphij goto err; 681238405Sjkim 682296341Sdelphij if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 683296341Sdelphij EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { 684296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); 685296341Sdelphij goto err; 686296341Sdelphij } 687238405Sjkim 688296341Sdelphij EVP_MD_CTX_cleanup(&mctx); 689183234Ssimon 690296341Sdelphij ASN1_STRING_set0(si->signature, abuf, siglen); 691183234Ssimon 692296341Sdelphij return 1; 693183234Ssimon 694296341Sdelphij err: 695296341Sdelphij if (abuf) 696296341Sdelphij OPENSSL_free(abuf); 697296341Sdelphij EVP_MD_CTX_cleanup(&mctx); 698296341Sdelphij return 0; 699183234Ssimon 700296341Sdelphij} 701183234Ssimon 702183234Ssimonint CMS_SignerInfo_verify(CMS_SignerInfo *si) 703296341Sdelphij{ 704296341Sdelphij EVP_MD_CTX mctx; 705296341Sdelphij EVP_PKEY_CTX *pctx; 706296341Sdelphij unsigned char *abuf = NULL; 707296341Sdelphij int alen, r = -1; 708296341Sdelphij const EVP_MD *md = NULL; 709183234Ssimon 710296341Sdelphij if (!si->pkey) { 711296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY); 712296341Sdelphij return -1; 713296341Sdelphij } 714183234Ssimon 715296341Sdelphij md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 716296341Sdelphij if (md == NULL) 717296341Sdelphij return -1; 718296341Sdelphij EVP_MD_CTX_init(&mctx); 719296341Sdelphij if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) 720296341Sdelphij goto err; 721183234Ssimon 722296341Sdelphij alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, 723296341Sdelphij ASN1_ITEM_rptr(CMS_Attributes_Verify)); 724296341Sdelphij if (!abuf) 725296341Sdelphij goto err; 726296341Sdelphij r = EVP_DigestVerifyUpdate(&mctx, abuf, alen); 727296341Sdelphij OPENSSL_free(abuf); 728296341Sdelphij if (r <= 0) { 729296341Sdelphij r = -1; 730296341Sdelphij goto err; 731296341Sdelphij } 732296341Sdelphij r = EVP_DigestVerifyFinal(&mctx, 733296341Sdelphij si->signature->data, si->signature->length); 734296341Sdelphij if (r <= 0) 735296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); 736296341Sdelphij err: 737296341Sdelphij EVP_MD_CTX_cleanup(&mctx); 738296341Sdelphij return r; 739296341Sdelphij} 740183234Ssimon 741183234Ssimon/* Create a chain of digest BIOs from a CMS ContentInfo */ 742183234Ssimon 743183234SsimonBIO *cms_SignedData_init_bio(CMS_ContentInfo *cms) 744296341Sdelphij{ 745296341Sdelphij int i; 746296341Sdelphij CMS_SignedData *sd; 747296341Sdelphij BIO *chain = NULL; 748296341Sdelphij sd = cms_get0_signed(cms); 749296341Sdelphij if (!sd) 750296341Sdelphij return NULL; 751296341Sdelphij if (cms->d.signedData->encapContentInfo->partial) 752296341Sdelphij cms_sd_set_version(sd); 753296341Sdelphij for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { 754296341Sdelphij X509_ALGOR *digestAlgorithm; 755296341Sdelphij BIO *mdbio; 756296341Sdelphij digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); 757296341Sdelphij mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); 758296341Sdelphij if (!mdbio) 759296341Sdelphij goto err; 760296341Sdelphij if (chain) 761296341Sdelphij BIO_push(chain, mdbio); 762296341Sdelphij else 763296341Sdelphij chain = mdbio; 764296341Sdelphij } 765296341Sdelphij return chain; 766296341Sdelphij err: 767296341Sdelphij if (chain) 768296341Sdelphij BIO_free_all(chain); 769296341Sdelphij return NULL; 770296341Sdelphij} 771183234Ssimon 772183234Ssimonint CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) 773296341Sdelphij{ 774296341Sdelphij ASN1_OCTET_STRING *os = NULL; 775296341Sdelphij EVP_MD_CTX mctx; 776296341Sdelphij int r = -1; 777296341Sdelphij EVP_MD_CTX_init(&mctx); 778296341Sdelphij /* If we have any signed attributes look for messageDigest value */ 779296341Sdelphij if (CMS_signed_get_attr_count(si) >= 0) { 780296341Sdelphij os = CMS_signed_get0_data_by_OBJ(si, 781296341Sdelphij OBJ_nid2obj(NID_pkcs9_messageDigest), 782296341Sdelphij -3, V_ASN1_OCTET_STRING); 783296341Sdelphij if (!os) { 784296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 785296341Sdelphij CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); 786296341Sdelphij goto err; 787296341Sdelphij } 788296341Sdelphij } 789183234Ssimon 790296341Sdelphij if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) 791296341Sdelphij goto err; 792183234Ssimon 793296341Sdelphij /* If messageDigest found compare it */ 794183234Ssimon 795296341Sdelphij if (os) { 796296341Sdelphij unsigned char mval[EVP_MAX_MD_SIZE]; 797296341Sdelphij unsigned int mlen; 798296341Sdelphij if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) { 799296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 800296341Sdelphij CMS_R_UNABLE_TO_FINALIZE_CONTEXT); 801296341Sdelphij goto err; 802296341Sdelphij } 803296341Sdelphij if (mlen != (unsigned int)os->length) { 804296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 805296341Sdelphij CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); 806296341Sdelphij goto err; 807296341Sdelphij } 808183234Ssimon 809296341Sdelphij if (memcmp(mval, os->data, mlen)) { 810296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 811296341Sdelphij CMS_R_VERIFICATION_FAILURE); 812296341Sdelphij r = 0; 813296341Sdelphij } else 814296341Sdelphij r = 1; 815296341Sdelphij } else { 816296341Sdelphij r = EVP_VerifyFinal(&mctx, si->signature->data, 817296341Sdelphij si->signature->length, si->pkey); 818296341Sdelphij if (r <= 0) { 819296341Sdelphij CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 820296341Sdelphij CMS_R_VERIFICATION_FAILURE); 821296341Sdelphij r = 0; 822296341Sdelphij } 823296341Sdelphij } 824183234Ssimon 825296341Sdelphij err: 826296341Sdelphij EVP_MD_CTX_cleanup(&mctx); 827296341Sdelphij return r; 828183234Ssimon 829296341Sdelphij} 830183234Ssimon 831183234Ssimonint CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) 832296341Sdelphij{ 833296341Sdelphij unsigned char *smder = NULL; 834296341Sdelphij int smderlen, r; 835296341Sdelphij smderlen = i2d_X509_ALGORS(algs, &smder); 836296341Sdelphij if (smderlen <= 0) 837296341Sdelphij return 0; 838296341Sdelphij r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities, 839296341Sdelphij V_ASN1_SEQUENCE, smder, smderlen); 840296341Sdelphij OPENSSL_free(smder); 841296341Sdelphij return r; 842296341Sdelphij} 843183234Ssimon 844183234Ssimonint CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, 845296341Sdelphij int algnid, int keysize) 846296341Sdelphij{ 847296341Sdelphij X509_ALGOR *alg; 848296341Sdelphij ASN1_INTEGER *key = NULL; 849296341Sdelphij if (keysize > 0) { 850296341Sdelphij key = ASN1_INTEGER_new(); 851296341Sdelphij if (!key || !ASN1_INTEGER_set(key, keysize)) 852296341Sdelphij return 0; 853296341Sdelphij } 854296341Sdelphij alg = X509_ALGOR_new(); 855296341Sdelphij if (!alg) { 856296341Sdelphij if (key) 857296341Sdelphij ASN1_INTEGER_free(key); 858296341Sdelphij return 0; 859296341Sdelphij } 860183234Ssimon 861296341Sdelphij X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), 862296341Sdelphij key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); 863296341Sdelphij if (!*algs) 864296341Sdelphij *algs = sk_X509_ALGOR_new_null(); 865296341Sdelphij if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) { 866296341Sdelphij X509_ALGOR_free(alg); 867296341Sdelphij return 0; 868296341Sdelphij } 869296341Sdelphij return 1; 870296341Sdelphij} 871296341Sdelphij 872183234Ssimon/* Check to see if a cipher exists and if so add S/MIME capabilities */ 873183234Ssimon 874183234Ssimonstatic int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 875296341Sdelphij{ 876296341Sdelphij if (EVP_get_cipherbynid(nid)) 877296341Sdelphij return CMS_add_simple_smimecap(sk, nid, arg); 878296341Sdelphij return 1; 879296341Sdelphij} 880238405Sjkim 881183234Ssimonstatic int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 882296341Sdelphij{ 883296341Sdelphij if (EVP_get_digestbynid(nid)) 884296341Sdelphij return CMS_add_simple_smimecap(sk, nid, arg); 885296341Sdelphij return 1; 886296341Sdelphij} 887238405Sjkim 888183234Ssimonint CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) 889296341Sdelphij{ 890296341Sdelphij if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) 891296341Sdelphij || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) 892296341Sdelphij || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) 893296341Sdelphij || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) 894296341Sdelphij || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) 895296341Sdelphij || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) 896296341Sdelphij || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) 897296341Sdelphij || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) 898296341Sdelphij || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) 899296341Sdelphij || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) 900296341Sdelphij return 0; 901296341Sdelphij return 1; 902296341Sdelphij} 903