cms_lib.c revision 183234
1240116Smarcel/* crypto/cms/cms_lib.c */ 2240116Smarcel/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3240116Smarcel * project. 4240116Smarcel */ 5240116Smarcel/* ==================================================================== 6240116Smarcel * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 7240116Smarcel * 8240116Smarcel * Redistribution and use in source and binary forms, with or without 9240116Smarcel * modification, are permitted provided that the following conditions 10240116Smarcel * are met: 11240116Smarcel * 12240116Smarcel * 1. Redistributions of source code must retain the above copyright 13240116Smarcel * notice, this list of conditions and the following disclaimer. 14240116Smarcel * 15240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright 16240116Smarcel * notice, this list of conditions and the following disclaimer in 17240116Smarcel * the documentation and/or other materials provided with the 18240116Smarcel * distribution. 19240116Smarcel * 20240116Smarcel * 3. All advertising materials mentioning features or use of this 21240116Smarcel * software must display the following acknowledgment: 22240116Smarcel * "This product includes software developed by the OpenSSL Project 23240116Smarcel * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24240116Smarcel * 25240116Smarcel * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26273929Sjmmv * endorse or promote products derived from this software without 27273929Sjmmv * prior written permission. For written permission, please contact 28240116Smarcel * licensing@OpenSSL.org. 29240116Smarcel * 30240116Smarcel * 5. Products derived from this software may not be called "OpenSSL" 31240116Smarcel * nor may "OpenSSL" appear in their names without prior written 32240116Smarcel * permission of the OpenSSL Project. 33240116Smarcel * 34240116Smarcel * 6. Redistributions of any form whatsoever must retain the following 35240116Smarcel * acknowledgment: 36240116Smarcel * "This product includes software developed by the OpenSSL Project 37240116Smarcel * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38240116Smarcel * 39240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40240116Smarcel * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41273929Sjmmv * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42240116Smarcel * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43240116Smarcel * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44240116Smarcel * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45240116Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46240116Smarcel * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47240116Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48240116Smarcel * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49240116Smarcel * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50240116Smarcel * OF THE POSSIBILITY OF SUCH DAMAGE. 51240116Smarcel * ==================================================================== 52240116Smarcel */ 53240116Smarcel 54240116Smarcel#include <openssl/asn1t.h> 55240116Smarcel#include <openssl/x509.h> 56240116Smarcel#include <openssl/err.h> 57240116Smarcel#include <openssl/pem.h> 58240116Smarcel#include <openssl/bio.h> 59240116Smarcel#include <openssl/asn1.h> 60240116Smarcel#include "cms.h" 61240116Smarcel#include "cms_lcl.h" 62240116Smarcel 63240116SmarcelIMPLEMENT_ASN1_FUNCTIONS_const(CMS_ContentInfo) 64240116Smarcel 65240116SmarcelDECLARE_ASN1_ITEM(CMS_CertificateChoices) 66240116SmarcelDECLARE_ASN1_ITEM(CMS_RevocationInfoChoice) 67240116SmarcelDECLARE_STACK_OF(CMS_CertificateChoices) 68240116SmarcelDECLARE_STACK_OF(CMS_RevocationInfoChoice) 69240116Smarcel 70240116Smarcelconst ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms) 71240116Smarcel { 72240116Smarcel return cms->contentType; 73240116Smarcel } 74240116Smarcel 75240116SmarcelCMS_ContentInfo *cms_Data_create(void) 76240116Smarcel { 77240116Smarcel CMS_ContentInfo *cms; 78240116Smarcel cms = CMS_ContentInfo_new(); 79240116Smarcel if (cms) 80240116Smarcel { 81240116Smarcel cms->contentType = OBJ_nid2obj(NID_pkcs7_data); 82240116Smarcel /* Never detached */ 83240116Smarcel CMS_set_detached(cms, 0); 84240116Smarcel } 85240116Smarcel return cms; 86240116Smarcel } 87240116Smarcel 88240116SmarcelBIO *cms_content_bio(CMS_ContentInfo *cms) 89240116Smarcel { 90240116Smarcel ASN1_OCTET_STRING **pos = CMS_get0_content(cms); 91240116Smarcel if (!pos) 92240116Smarcel return NULL; 93240116Smarcel /* If content detached data goes nowhere: create NULL BIO */ 94240116Smarcel if (!*pos) 95240116Smarcel return BIO_new(BIO_s_null()); 96240116Smarcel /* If content not detached and created return memory BIO 97240116Smarcel */ 98240116Smarcel if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT)) 99240116Smarcel return BIO_new(BIO_s_mem()); 100240116Smarcel /* Else content was read in: return read only BIO for it */ 101240116Smarcel return BIO_new_mem_buf((*pos)->data, (*pos)->length); 102240116Smarcel } 103240116Smarcel 104240116SmarcelBIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) 105240116Smarcel { 106240116Smarcel BIO *cmsbio, *cont; 107240116Smarcel if (icont) 108240116Smarcel cont = icont; 109240116Smarcel else 110240116Smarcel cont = cms_content_bio(cms); 111240116Smarcel if (!cont) 112240116Smarcel { 113240116Smarcel CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT); 114240116Smarcel return NULL; 115240116Smarcel } 116240116Smarcel switch (OBJ_obj2nid(cms->contentType)) 117240116Smarcel { 118240116Smarcel 119240116Smarcel case NID_pkcs7_data: 120240116Smarcel return cont; 121240116Smarcel 122240116Smarcel case NID_pkcs7_signed: 123240116Smarcel cmsbio = cms_SignedData_init_bio(cms); 124240116Smarcel break; 125240116Smarcel 126240116Smarcel case NID_pkcs7_digest: 127240116Smarcel cmsbio = cms_DigestedData_init_bio(cms); 128240116Smarcel break; 129240116Smarcel#ifdef ZLIB 130240116Smarcel case NID_id_smime_ct_compressedData: 131240116Smarcel cmsbio = cms_CompressedData_init_bio(cms); 132240116Smarcel break; 133240116Smarcel#endif 134240116Smarcel 135240116Smarcel case NID_pkcs7_encrypted: 136240116Smarcel cmsbio = cms_EncryptedData_init_bio(cms); 137240116Smarcel break; 138240116Smarcel 139240116Smarcel case NID_pkcs7_enveloped: 140240116Smarcel cmsbio = cms_EnvelopedData_init_bio(cms); 141240116Smarcel break; 142240116Smarcel 143240116Smarcel default: 144240116Smarcel CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE); 145240116Smarcel return NULL; 146240116Smarcel } 147240116Smarcel 148240116Smarcel if (cmsbio) 149240116Smarcel return BIO_push(cmsbio, cont); 150240116Smarcel 151240116Smarcel if (!icont) 152240116Smarcel BIO_free(cont); 153240116Smarcel return NULL; 154240116Smarcel 155240116Smarcel } 156240116Smarcel 157240116Smarcelint CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) 158240116Smarcel { 159240116Smarcel ASN1_OCTET_STRING **pos = CMS_get0_content(cms); 160240116Smarcel if (!pos) 161240116Smarcel return 0; 162240116Smarcel /* If ebmedded content find memory BIO and set content */ 163240116Smarcel if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) 164240116Smarcel { 165240116Smarcel BIO *mbio; 166240116Smarcel unsigned char *cont; 167240116Smarcel long contlen; 168240116Smarcel mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); 169240116Smarcel if (!mbio) 170240116Smarcel { 171240116Smarcel CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND); 172240116Smarcel return 0; 173240116Smarcel } 174240116Smarcel contlen = BIO_get_mem_data(mbio, &cont); 175240116Smarcel /* Set bio as read only so its content can't be clobbered */ 176240116Smarcel BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); 177240116Smarcel BIO_set_mem_eof_return(mbio, 0); 178240116Smarcel ASN1_STRING_set0(*pos, cont, contlen); 179240116Smarcel (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; 180240116Smarcel } 181240116Smarcel 182240116Smarcel switch (OBJ_obj2nid(cms->contentType)) 183240116Smarcel { 184240116Smarcel 185240116Smarcel case NID_pkcs7_data: 186240116Smarcel case NID_pkcs7_enveloped: 187240116Smarcel case NID_pkcs7_encrypted: 188240116Smarcel case NID_id_smime_ct_compressedData: 189240116Smarcel /* Nothing to do */ 190240116Smarcel return 1; 191240116Smarcel 192240116Smarcel case NID_pkcs7_signed: 193240116Smarcel return cms_SignedData_final(cms, cmsbio); 194240116Smarcel 195240116Smarcel case NID_pkcs7_digest: 196240116Smarcel return cms_DigestedData_do_final(cms, cmsbio, 0); 197240116Smarcel 198240116Smarcel default: 199240116Smarcel CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE); 200240116Smarcel return 0; 201240116Smarcel } 202240116Smarcel } 203240116Smarcel 204240116Smarcel/* Return an OCTET STRING pointer to content. This allows it to 205240116Smarcel * be accessed or set later. 206240116Smarcel */ 207240116Smarcel 208240116SmarcelASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) 209240116Smarcel { 210240116Smarcel switch (OBJ_obj2nid(cms->contentType)) 211240116Smarcel { 212240116Smarcel 213240116Smarcel case NID_pkcs7_data: 214240116Smarcel return &cms->d.data; 215240116Smarcel 216240116Smarcel case NID_pkcs7_signed: 217240116Smarcel return &cms->d.signedData->encapContentInfo->eContent; 218240116Smarcel 219240116Smarcel case NID_pkcs7_enveloped: 220240116Smarcel return &cms->d.envelopedData->encryptedContentInfo->encryptedContent; 221240116Smarcel 222240116Smarcel case NID_pkcs7_digest: 223240116Smarcel return &cms->d.digestedData->encapContentInfo->eContent; 224240116Smarcel 225240116Smarcel case NID_pkcs7_encrypted: 226240116Smarcel return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; 227240116Smarcel 228240116Smarcel case NID_id_smime_ct_authData: 229240116Smarcel return &cms->d.authenticatedData->encapContentInfo->eContent; 230240116Smarcel 231240116Smarcel case NID_id_smime_ct_compressedData: 232240116Smarcel return &cms->d.compressedData->encapContentInfo->eContent; 233240116Smarcel 234240116Smarcel default: 235240116Smarcel if (cms->d.other->type == V_ASN1_OCTET_STRING) 236240116Smarcel return &cms->d.other->value.octet_string; 237240116Smarcel CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE); 238240116Smarcel return NULL; 239240116Smarcel 240240116Smarcel } 241240116Smarcel } 242240116Smarcel 243240116Smarcel/* Return an ASN1_OBJECT pointer to content type. This allows it to 244240116Smarcel * be accessed or set later. 245240116Smarcel */ 246240116Smarcel 247240116Smarcelstatic ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) 248240116Smarcel { 249240116Smarcel switch (OBJ_obj2nid(cms->contentType)) 250240116Smarcel { 251240116Smarcel 252240116Smarcel case NID_pkcs7_signed: 253240116Smarcel return &cms->d.signedData->encapContentInfo->eContentType; 254240116Smarcel 255240116Smarcel case NID_pkcs7_enveloped: 256240116Smarcel return &cms->d.envelopedData->encryptedContentInfo->contentType; 257240116Smarcel 258240116Smarcel case NID_pkcs7_digest: 259240116Smarcel return &cms->d.digestedData->encapContentInfo->eContentType; 260240116Smarcel 261240116Smarcel case NID_pkcs7_encrypted: 262240116Smarcel return &cms->d.encryptedData->encryptedContentInfo->contentType; 263240116Smarcel 264240116Smarcel case NID_id_smime_ct_authData: 265240116Smarcel return &cms->d.authenticatedData->encapContentInfo->eContentType; 266240116Smarcel 267240116Smarcel case NID_id_smime_ct_compressedData: 268240116Smarcel return &cms->d.compressedData->encapContentInfo->eContentType; 269240116Smarcel 270240116Smarcel default: 271240116Smarcel CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, 272240116Smarcel CMS_R_UNSUPPORTED_CONTENT_TYPE); 273240116Smarcel return NULL; 274240116Smarcel 275240116Smarcel } 276240116Smarcel } 277240116Smarcel 278240116Smarcelconst ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms) 279240116Smarcel { 280240116Smarcel ASN1_OBJECT **petype; 281240116Smarcel petype = cms_get0_econtent_type(cms); 282240116Smarcel if (petype) 283240116Smarcel return *petype; 284240116Smarcel return NULL; 285240116Smarcel } 286240116Smarcel 287240116Smarcelint CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) 288240116Smarcel { 289240116Smarcel ASN1_OBJECT **petype, *etype; 290240116Smarcel petype = cms_get0_econtent_type(cms); 291240116Smarcel if (!petype) 292240116Smarcel return 0; 293240116Smarcel if (!oid) 294240116Smarcel return 1; 295240116Smarcel etype = OBJ_dup(oid); 296240116Smarcel if (!etype) 297240116Smarcel return 0; 298240116Smarcel ASN1_OBJECT_free(*petype); 299240116Smarcel *petype = etype; 300240116Smarcel return 1; 301240116Smarcel } 302240116Smarcel 303240116Smarcelint CMS_is_detached(CMS_ContentInfo *cms) 304240116Smarcel { 305240116Smarcel ASN1_OCTET_STRING **pos; 306240116Smarcel pos = CMS_get0_content(cms); 307240116Smarcel if (!pos) 308240116Smarcel return -1; 309240116Smarcel if (*pos) 310240116Smarcel return 0; 311240116Smarcel return 1; 312240116Smarcel } 313240116Smarcel 314240116Smarcelint CMS_set_detached(CMS_ContentInfo *cms, int detached) 315240116Smarcel { 316240116Smarcel ASN1_OCTET_STRING **pos; 317240116Smarcel pos = CMS_get0_content(cms); 318240116Smarcel if (!pos) 319240116Smarcel return 0; 320240116Smarcel if (detached) 321240116Smarcel { 322240116Smarcel if (*pos) 323240116Smarcel { 324240116Smarcel ASN1_OCTET_STRING_free(*pos); 325240116Smarcel *pos = NULL; 326240116Smarcel } 327240116Smarcel return 1; 328240116Smarcel } 329240116Smarcel if (!*pos) 330240116Smarcel *pos = ASN1_OCTET_STRING_new(); 331240116Smarcel if (*pos) 332240116Smarcel { 333240116Smarcel /* NB: special flag to show content is created and not 334240116Smarcel * read in. 335240116Smarcel */ 336240116Smarcel (*pos)->flags |= ASN1_STRING_FLAG_CONT; 337240116Smarcel return 1; 338240116Smarcel } 339240116Smarcel CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE); 340240116Smarcel return 0; 341240116Smarcel } 342240116Smarcel 343240116Smarcel/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ 344240116Smarcel 345240116Smarcelvoid cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md) 346240116Smarcel { 347240116Smarcel int param_type; 348240116Smarcel 349240116Smarcel switch (EVP_MD_type(md)) 350240116Smarcel { 351240116Smarcel case NID_sha1: 352240116Smarcel case NID_sha224: 353240116Smarcel case NID_sha256: 354240116Smarcel case NID_sha384: 355240116Smarcel case NID_sha512: 356240116Smarcel param_type = V_ASN1_UNDEF; 357240116Smarcel break; 358240116Smarcel 359240116Smarcel default: 360240116Smarcel param_type = V_ASN1_NULL; 361240116Smarcel break; 362240116Smarcel } 363240116Smarcel 364240116Smarcel X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); 365240116Smarcel 366240116Smarcel } 367240116Smarcel 368240116Smarcel/* Create a digest BIO from an X509_ALGOR structure */ 369240116Smarcel 370240116SmarcelBIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) 371240116Smarcel { 372240116Smarcel BIO *mdbio = NULL; 373240116Smarcel ASN1_OBJECT *digestoid; 374240116Smarcel const EVP_MD *digest; 375240116Smarcel X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); 376240116Smarcel digest = EVP_get_digestbyobj(digestoid); 377240116Smarcel if (!digest) 378240116Smarcel { 379240116Smarcel CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, 380240116Smarcel CMS_R_UNKNOWN_DIGEST_ALGORIHM); 381240116Smarcel goto err; 382240116Smarcel } 383240116Smarcel mdbio = BIO_new(BIO_f_md()); 384240116Smarcel if (!mdbio || !BIO_set_md(mdbio, digest)) 385240116Smarcel { 386240116Smarcel CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, 387273929Sjmmv CMS_R_MD_BIO_INIT_ERROR); 388 goto err; 389 } 390 return mdbio; 391 err: 392 if (mdbio) 393 BIO_free(mdbio); 394 return NULL; 395 } 396 397/* Locate a message digest content from a BIO chain based on SignerInfo */ 398 399int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, 400 X509_ALGOR *mdalg) 401 { 402 int nid; 403 ASN1_OBJECT *mdoid; 404 X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); 405 nid = OBJ_obj2nid(mdoid); 406 /* Look for digest type to match signature */ 407 for (;;) 408 { 409 EVP_MD_CTX *mtmp; 410 chain = BIO_find_type(chain, BIO_TYPE_MD); 411 if (chain == NULL) 412 { 413 CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, 414 CMS_R_NO_MATCHING_DIGEST); 415 return 0; 416 } 417 BIO_get_md_ctx(chain, &mtmp); 418 if (EVP_MD_CTX_type(mtmp) == nid) 419 { 420 EVP_MD_CTX_copy_ex(mctx, mtmp); 421 return 1; 422 } 423 chain = BIO_next(chain); 424 } 425 } 426 427static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms) 428 { 429 switch (OBJ_obj2nid(cms->contentType)) 430 { 431 432 case NID_pkcs7_signed: 433 return &cms->d.signedData->certificates; 434 435 case NID_pkcs7_enveloped: 436 return &cms->d.envelopedData->originatorInfo->certificates; 437 438 default: 439 CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES, 440 CMS_R_UNSUPPORTED_CONTENT_TYPE); 441 return NULL; 442 443 } 444 } 445 446CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms) 447 { 448 STACK_OF(CMS_CertificateChoices) **pcerts; 449 CMS_CertificateChoices *cch; 450 pcerts = cms_get0_certificate_choices(cms); 451 if (!pcerts) 452 return NULL; 453 if (!*pcerts) 454 *pcerts = sk_CMS_CertificateChoices_new_null(); 455 if (!*pcerts) 456 return NULL; 457 cch = M_ASN1_new_of(CMS_CertificateChoices); 458 if (!cch) 459 return NULL; 460 if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) 461 { 462 M_ASN1_free_of(cch, CMS_CertificateChoices); 463 return NULL; 464 } 465 return cch; 466 } 467 468int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) 469 { 470 CMS_CertificateChoices *cch; 471 STACK_OF(CMS_CertificateChoices) **pcerts; 472 int i; 473 pcerts = cms_get0_certificate_choices(cms); 474 if (!pcerts) 475 return 0; 476 if (!pcerts) 477 return 0; 478 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) 479 { 480 cch = sk_CMS_CertificateChoices_value(*pcerts, i); 481 if (cch->type == CMS_CERTCHOICE_CERT) 482 { 483 if (!X509_cmp(cch->d.certificate, cert)) 484 { 485 CMSerr(CMS_F_CMS_ADD0_CERT, 486 CMS_R_CERTIFICATE_ALREADY_PRESENT); 487 return 0; 488 } 489 } 490 } 491 cch = CMS_add0_CertificateChoices(cms); 492 if (!cch) 493 return 0; 494 cch->type = CMS_CERTCHOICE_CERT; 495 cch->d.certificate = cert; 496 return 1; 497 } 498 499int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) 500 { 501 int r; 502 r = CMS_add0_cert(cms, cert); 503 if (r > 0) 504 CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); 505 return r; 506 } 507 508static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms) 509 { 510 switch (OBJ_obj2nid(cms->contentType)) 511 { 512 513 case NID_pkcs7_signed: 514 return &cms->d.signedData->crls; 515 516 case NID_pkcs7_enveloped: 517 return &cms->d.envelopedData->originatorInfo->crls; 518 519 default: 520 CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES, 521 CMS_R_UNSUPPORTED_CONTENT_TYPE); 522 return NULL; 523 524 } 525 } 526 527CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) 528 { 529 STACK_OF(CMS_RevocationInfoChoice) **pcrls; 530 CMS_RevocationInfoChoice *rch; 531 pcrls = cms_get0_revocation_choices(cms); 532 if (!pcrls) 533 return NULL; 534 if (!*pcrls) 535 *pcrls = sk_CMS_RevocationInfoChoice_new_null(); 536 if (!*pcrls) 537 return NULL; 538 rch = M_ASN1_new_of(CMS_RevocationInfoChoice); 539 if (!rch) 540 return NULL; 541 if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) 542 { 543 M_ASN1_free_of(rch, CMS_RevocationInfoChoice); 544 return NULL; 545 } 546 return rch; 547 } 548 549int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) 550 { 551 CMS_RevocationInfoChoice *rch; 552 rch = CMS_add0_RevocationInfoChoice(cms); 553 if (!rch) 554 return 0; 555 rch->type = CMS_REVCHOICE_CRL; 556 rch->d.crl = crl; 557 return 1; 558 } 559 560STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) 561 { 562 STACK_OF(X509) *certs = NULL; 563 CMS_CertificateChoices *cch; 564 STACK_OF(CMS_CertificateChoices) **pcerts; 565 int i; 566 pcerts = cms_get0_certificate_choices(cms); 567 if (!pcerts) 568 return NULL; 569 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) 570 { 571 cch = sk_CMS_CertificateChoices_value(*pcerts, i); 572 if (cch->type == 0) 573 { 574 if (!certs) 575 { 576 certs = sk_X509_new_null(); 577 if (!certs) 578 return NULL; 579 } 580 if (!sk_X509_push(certs, cch->d.certificate)) 581 { 582 sk_X509_pop_free(certs, X509_free); 583 return NULL; 584 } 585 CRYPTO_add(&cch->d.certificate->references, 586 1, CRYPTO_LOCK_X509); 587 } 588 } 589 return certs; 590 591 } 592 593STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) 594 { 595 STACK_OF(X509_CRL) *crls = NULL; 596 STACK_OF(CMS_RevocationInfoChoice) **pcrls; 597 CMS_RevocationInfoChoice *rch; 598 int i; 599 pcrls = cms_get0_revocation_choices(cms); 600 if (!pcrls) 601 return NULL; 602 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) 603 { 604 rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); 605 if (rch->type == 0) 606 { 607 if (!crls) 608 { 609 crls = sk_X509_CRL_new_null(); 610 if (!crls) 611 return NULL; 612 } 613 if (!sk_X509_CRL_push(crls, rch->d.crl)) 614 { 615 sk_X509_CRL_pop_free(crls, X509_CRL_free); 616 return NULL; 617 } 618 CRYPTO_add(&rch->d.crl->references, 619 1, CRYPTO_LOCK_X509_CRL); 620 } 621 } 622 return crls; 623 } 624