1 /* $OpenBSD: cms_lib.c,v 1.26 2024/11/01 18:53:35 tb Exp $ */ 2 /* 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4 * project. 5 */ 6 /* ==================================================================== 7 * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * licensing@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 */ 54 55 #include <stddef.h> 56 57 #include <openssl/asn1.h> 58 #include <openssl/bio.h> 59 #include <openssl/cms.h> 60 #include <openssl/err.h> 61 #include <openssl/evp.h> 62 #include <openssl/objects.h> 63 #include <openssl/x509.h> 64 #include <openssl/x509v3.h> 65 66 #include "cms_local.h" 67 #include "x509_local.h" 68 69 CMS_ContentInfo * 70 d2i_CMS_ContentInfo(CMS_ContentInfo **a, const unsigned char **in, long len) 71 { 72 return (CMS_ContentInfo *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 73 &CMS_ContentInfo_it); 74 } 75 LCRYPTO_ALIAS(d2i_CMS_ContentInfo); 76 77 int 78 i2d_CMS_ContentInfo(CMS_ContentInfo *a, unsigned char **out) 79 { 80 return ASN1_item_i2d((ASN1_VALUE *)a, out, &CMS_ContentInfo_it); 81 } 82 LCRYPTO_ALIAS(i2d_CMS_ContentInfo); 83 84 CMS_ContentInfo * 85 CMS_ContentInfo_new(void) 86 { 87 return (CMS_ContentInfo *)ASN1_item_new(&CMS_ContentInfo_it); 88 } 89 LCRYPTO_ALIAS(CMS_ContentInfo_new); 90 91 void 92 CMS_ContentInfo_free(CMS_ContentInfo *a) 93 { 94 ASN1_item_free((ASN1_VALUE *)a, &CMS_ContentInfo_it); 95 } 96 LCRYPTO_ALIAS(CMS_ContentInfo_free); 97 98 int 99 CMS_ContentInfo_print_ctx(BIO *out, CMS_ContentInfo *x, int indent, const ASN1_PCTX *pctx) 100 { 101 return ASN1_item_print(out, (ASN1_VALUE *)x, indent, 102 &CMS_ContentInfo_it, pctx); 103 } 104 LCRYPTO_ALIAS(CMS_ContentInfo_print_ctx); 105 106 const ASN1_OBJECT * 107 CMS_get0_type(const CMS_ContentInfo *cms) 108 { 109 return cms->contentType; 110 } 111 LCRYPTO_ALIAS(CMS_get0_type); 112 113 CMS_ContentInfo * 114 cms_Data_create(void) 115 { 116 CMS_ContentInfo *cms; 117 118 cms = CMS_ContentInfo_new(); 119 if (cms != NULL) { 120 cms->contentType = OBJ_nid2obj(NID_pkcs7_data); 121 /* Never detached */ 122 CMS_set_detached(cms, 0); 123 } 124 return cms; 125 } 126 127 static BIO * 128 cms_content_bio(CMS_ContentInfo *cms) 129 { 130 ASN1_OCTET_STRING **pos; 131 132 if ((pos = CMS_get0_content(cms)) == NULL) 133 return NULL; 134 135 /* If content is detached, data goes nowhere: create null BIO. */ 136 if (*pos == NULL) 137 return BIO_new(BIO_s_null()); 138 139 /* If content is not detached and was created, return memory BIO. */ 140 if ((*pos)->flags == ASN1_STRING_FLAG_CONT) 141 return BIO_new(BIO_s_mem()); 142 143 /* Else content was read in: return read-only BIO for it. */ 144 return BIO_new_mem_buf((*pos)->data, (*pos)->length); 145 } 146 147 BIO * 148 CMS_dataInit(CMS_ContentInfo *cms, BIO *in_content_bio) 149 { 150 BIO *cms_bio = NULL, *content_bio = NULL; 151 152 if ((content_bio = in_content_bio) == NULL) 153 content_bio = cms_content_bio(cms); 154 if (content_bio == NULL) { 155 CMSerror(CMS_R_NO_CONTENT); 156 goto err; 157 } 158 159 switch (OBJ_obj2nid(cms->contentType)) { 160 case NID_pkcs7_data: 161 return content_bio; 162 case NID_pkcs7_signed: 163 if ((cms_bio = cms_SignedData_init_bio(cms)) == NULL) 164 goto err; 165 break; 166 case NID_pkcs7_digest: 167 if ((cms_bio = cms_DigestedData_init_bio(cms)) == NULL) 168 goto err; 169 break; 170 case NID_pkcs7_encrypted: 171 if ((cms_bio = cms_EncryptedData_init_bio(cms)) == NULL) 172 goto err; 173 break; 174 case NID_pkcs7_enveloped: 175 if ((cms_bio = cms_EnvelopedData_init_bio(cms)) == NULL) 176 goto err; 177 break; 178 default: 179 CMSerror(CMS_R_UNSUPPORTED_TYPE); 180 goto err; 181 } 182 183 return BIO_push(cms_bio, content_bio); 184 185 err: 186 if (content_bio != in_content_bio) 187 BIO_free(content_bio); 188 189 return NULL; 190 } 191 LCRYPTO_ALIAS(CMS_dataInit); 192 193 int 194 CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) 195 { 196 ASN1_OCTET_STRING **pos = CMS_get0_content(cms); 197 198 if (!pos) 199 return 0; 200 /* If embedded content find memory BIO and set content */ 201 if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) { 202 BIO *mbio; 203 unsigned char *cont; 204 long contlen; 205 mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); 206 if (!mbio) { 207 CMSerror(CMS_R_CONTENT_NOT_FOUND); 208 return 0; 209 } 210 contlen = BIO_get_mem_data(mbio, &cont); 211 /* Set bio as read only so its content can't be clobbered */ 212 BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); 213 BIO_set_mem_eof_return(mbio, 0); 214 ASN1_STRING_set0(*pos, cont, contlen); 215 (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; 216 } 217 218 switch (OBJ_obj2nid(cms->contentType)) { 219 220 case NID_pkcs7_data: 221 case NID_pkcs7_enveloped: 222 case NID_pkcs7_encrypted: 223 case NID_id_smime_ct_compressedData: 224 /* Nothing to do */ 225 return 1; 226 227 case NID_pkcs7_signed: 228 return cms_SignedData_final(cms, cmsbio); 229 230 case NID_pkcs7_digest: 231 return cms_DigestedData_do_final(cms, cmsbio, 0); 232 233 default: 234 CMSerror(CMS_R_UNSUPPORTED_TYPE); 235 return 0; 236 } 237 } 238 LCRYPTO_ALIAS(CMS_dataFinal); 239 240 int 241 CMS_get_version(const CMS_ContentInfo *cms, long *version) 242 { 243 switch (OBJ_obj2nid(cms->contentType)) { 244 case NID_pkcs7_signed: 245 *version = cms->d.signedData->version; 246 return 1; 247 248 case NID_pkcs7_enveloped: 249 *version = cms->d.envelopedData->version; 250 return 1; 251 252 case NID_pkcs7_digest: 253 *version = cms->d.digestedData->version; 254 return 1; 255 256 case NID_pkcs7_encrypted: 257 *version = cms->d.encryptedData->version; 258 return 1; 259 260 case NID_id_smime_ct_authData: 261 *version = cms->d.authenticatedData->version; 262 return 1; 263 264 case NID_id_smime_ct_compressedData: 265 *version = cms->d.compressedData->version; 266 return 1; 267 268 default: 269 CMSerror(CMS_R_UNSUPPORTED_TYPE); 270 return 0; 271 } 272 } 273 LCRYPTO_ALIAS(CMS_get_version); 274 275 int 276 CMS_SignerInfo_get_version(const CMS_SignerInfo *si, long *version) 277 { 278 *version = si->version; 279 return 1; 280 } 281 LCRYPTO_ALIAS(CMS_SignerInfo_get_version); 282 283 /* 284 * Return an OCTET STRING pointer to content. This allows it to be accessed 285 * or set later. 286 */ 287 288 ASN1_OCTET_STRING ** 289 CMS_get0_content(CMS_ContentInfo *cms) 290 { 291 switch (OBJ_obj2nid(cms->contentType)) { 292 case NID_pkcs7_data: 293 return &cms->d.data; 294 295 case NID_pkcs7_signed: 296 return &cms->d.signedData->encapContentInfo->eContent; 297 298 case NID_pkcs7_enveloped: 299 return &cms->d.envelopedData->encryptedContentInfo->encryptedContent; 300 301 case NID_pkcs7_digest: 302 return &cms->d.digestedData->encapContentInfo->eContent; 303 304 case NID_pkcs7_encrypted: 305 return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; 306 307 case NID_id_smime_ct_authData: 308 return &cms->d.authenticatedData->encapContentInfo->eContent; 309 310 case NID_id_smime_ct_compressedData: 311 return &cms->d.compressedData->encapContentInfo->eContent; 312 313 default: 314 if (cms->d.other->type == V_ASN1_OCTET_STRING) 315 return &cms->d.other->value.octet_string; 316 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); 317 return NULL; 318 } 319 } 320 LCRYPTO_ALIAS(CMS_get0_content); 321 322 /* 323 * Return an ASN1_OBJECT pointer to content type. This allows it to be 324 * accessed or set later. 325 */ 326 327 static ASN1_OBJECT ** 328 cms_get0_econtent_type(CMS_ContentInfo *cms) 329 { 330 switch (OBJ_obj2nid(cms->contentType)) { 331 case NID_pkcs7_signed: 332 return &cms->d.signedData->encapContentInfo->eContentType; 333 334 case NID_pkcs7_enveloped: 335 return &cms->d.envelopedData->encryptedContentInfo->contentType; 336 337 case NID_pkcs7_digest: 338 return &cms->d.digestedData->encapContentInfo->eContentType; 339 340 case NID_pkcs7_encrypted: 341 return &cms->d.encryptedData->encryptedContentInfo->contentType; 342 343 case NID_id_smime_ct_authData: 344 return &cms->d.authenticatedData->encapContentInfo->eContentType; 345 346 case NID_id_smime_ct_compressedData: 347 return &cms->d.compressedData->encapContentInfo->eContentType; 348 349 default: 350 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); 351 return NULL; 352 } 353 } 354 355 const ASN1_OBJECT * 356 CMS_get0_eContentType(CMS_ContentInfo *cms) 357 { 358 ASN1_OBJECT **petype; 359 360 petype = cms_get0_econtent_type(cms); 361 if (petype) 362 return *petype; 363 364 return NULL; 365 } 366 LCRYPTO_ALIAS(CMS_get0_eContentType); 367 368 int 369 CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) 370 { 371 ASN1_OBJECT **petype, *etype; 372 373 petype = cms_get0_econtent_type(cms); 374 if (!petype) 375 return 0; 376 if (!oid) 377 return 1; 378 etype = OBJ_dup(oid); 379 if (!etype) 380 return 0; 381 ASN1_OBJECT_free(*petype); 382 *petype = etype; 383 384 return 1; 385 } 386 LCRYPTO_ALIAS(CMS_set1_eContentType); 387 388 int 389 CMS_is_detached(CMS_ContentInfo *cms) 390 { 391 ASN1_OCTET_STRING **pos; 392 393 pos = CMS_get0_content(cms); 394 if (!pos) 395 return -1; 396 if (*pos) 397 return 0; 398 399 return 1; 400 } 401 LCRYPTO_ALIAS(CMS_is_detached); 402 403 int 404 CMS_set_detached(CMS_ContentInfo *cms, int detached) 405 { 406 ASN1_OCTET_STRING **pos; 407 408 pos = CMS_get0_content(cms); 409 if (!pos) 410 return 0; 411 if (detached) { 412 ASN1_OCTET_STRING_free(*pos); 413 *pos = NULL; 414 return 1; 415 } 416 if (*pos == NULL) 417 *pos = ASN1_OCTET_STRING_new(); 418 if (*pos != NULL) { 419 /* 420 * NB: special flag to show content is created and not read in. 421 */ 422 (*pos)->flags |= ASN1_STRING_FLAG_CONT; 423 return 1; 424 } 425 CMSerror(ERR_R_MALLOC_FAILURE); 426 427 return 0; 428 } 429 LCRYPTO_ALIAS(CMS_set_detached); 430 431 /* Create a digest BIO from an X509_ALGOR structure */ 432 433 BIO * 434 cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) 435 { 436 BIO *mdbio = NULL; 437 const ASN1_OBJECT *digestoid; 438 const EVP_MD *digest; 439 440 X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); 441 digest = EVP_get_digestbyobj(digestoid); 442 if (!digest) { 443 CMSerror(CMS_R_UNKNOWN_DIGEST_ALGORITHM); 444 goto err; 445 } 446 mdbio = BIO_new(BIO_f_md()); 447 if (mdbio == NULL || !BIO_set_md(mdbio, digest)) { 448 CMSerror(CMS_R_MD_BIO_INIT_ERROR); 449 goto err; 450 } 451 return mdbio; 452 453 err: 454 BIO_free(mdbio); 455 456 return NULL; 457 } 458 459 /* Locate a message digest content from a BIO chain based on SignerInfo */ 460 461 int 462 cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, X509_ALGOR *mdalg) 463 { 464 int nid; 465 const ASN1_OBJECT *mdoid; 466 467 X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); 468 nid = OBJ_obj2nid(mdoid); 469 /* Look for digest type to match signature */ 470 for (;;) { 471 EVP_MD_CTX *mtmp; 472 chain = BIO_find_type(chain, BIO_TYPE_MD); 473 if (chain == NULL) { 474 CMSerror(CMS_R_NO_MATCHING_DIGEST); 475 return 0; 476 } 477 BIO_get_md_ctx(chain, &mtmp); 478 if (EVP_MD_CTX_type(mtmp) == nid 479 /* 480 * Workaround for broken implementations that use signature 481 * algorithm OID instead of digest. 482 */ 483 || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) 484 return EVP_MD_CTX_copy_ex(mctx, mtmp); 485 chain = BIO_next(chain); 486 } 487 } 488 489 static STACK_OF(CMS_CertificateChoices) ** 490 cms_get0_certificate_choices(CMS_ContentInfo *cms) 491 { 492 switch (OBJ_obj2nid(cms->contentType)) { 493 case NID_pkcs7_signed: 494 return &cms->d.signedData->certificates; 495 496 case NID_pkcs7_enveloped: 497 if (cms->d.envelopedData->originatorInfo == NULL) 498 return NULL; 499 return &cms->d.envelopedData->originatorInfo->certificates; 500 501 default: 502 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); 503 return NULL; 504 } 505 } 506 507 CMS_CertificateChoices * 508 CMS_add0_CertificateChoices(CMS_ContentInfo *cms) 509 { 510 STACK_OF(CMS_CertificateChoices) **pcerts; 511 CMS_CertificateChoices *cch; 512 513 pcerts = cms_get0_certificate_choices(cms); 514 if (!pcerts) 515 return NULL; 516 if (!*pcerts) 517 *pcerts = sk_CMS_CertificateChoices_new_null(); 518 if (!*pcerts) 519 return NULL; 520 cch = (CMS_CertificateChoices *)ASN1_item_new(&CMS_CertificateChoices_it); 521 if (!cch) 522 return NULL; 523 if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) { 524 ASN1_item_free((ASN1_VALUE *)cch, &CMS_CertificateChoices_it); 525 return NULL; 526 } 527 528 return cch; 529 } 530 LCRYPTO_ALIAS(CMS_add0_CertificateChoices); 531 532 int 533 CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) 534 { 535 CMS_CertificateChoices *cch; 536 STACK_OF(CMS_CertificateChoices) **pcerts; 537 int i; 538 539 pcerts = cms_get0_certificate_choices(cms); 540 if (!pcerts) 541 return 0; 542 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { 543 cch = sk_CMS_CertificateChoices_value(*pcerts, i); 544 if (cch->type == CMS_CERTCHOICE_CERT) { 545 if (!X509_cmp(cch->d.certificate, cert)) { 546 CMSerror(CMS_R_CERTIFICATE_ALREADY_PRESENT); 547 return 0; 548 } 549 } 550 } 551 cch = CMS_add0_CertificateChoices(cms); 552 if (!cch) 553 return 0; 554 cch->type = CMS_CERTCHOICE_CERT; 555 cch->d.certificate = cert; 556 557 return 1; 558 } 559 LCRYPTO_ALIAS(CMS_add0_cert); 560 561 int 562 CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) 563 { 564 int r; 565 566 r = CMS_add0_cert(cms, cert); 567 if (r > 0) 568 X509_up_ref(cert); 569 570 return r; 571 } 572 LCRYPTO_ALIAS(CMS_add1_cert); 573 574 static STACK_OF(CMS_RevocationInfoChoice) ** 575 cms_get0_revocation_choices(CMS_ContentInfo *cms) 576 { 577 switch (OBJ_obj2nid(cms->contentType)) { 578 case NID_pkcs7_signed: 579 return &cms->d.signedData->crls; 580 581 case NID_pkcs7_enveloped: 582 if (cms->d.envelopedData->originatorInfo == NULL) 583 return NULL; 584 return &cms->d.envelopedData->originatorInfo->crls; 585 586 default: 587 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); 588 return NULL; 589 } 590 } 591 592 CMS_RevocationInfoChoice * 593 CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) 594 { 595 STACK_OF(CMS_RevocationInfoChoice) **pcrls; 596 CMS_RevocationInfoChoice *rch; 597 598 pcrls = cms_get0_revocation_choices(cms); 599 if (!pcrls) 600 return NULL; 601 if (!*pcrls) 602 *pcrls = sk_CMS_RevocationInfoChoice_new_null(); 603 if (!*pcrls) 604 return NULL; 605 rch = (CMS_RevocationInfoChoice *)ASN1_item_new(&CMS_RevocationInfoChoice_it); 606 if (!rch) 607 return NULL; 608 if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) { 609 ASN1_item_free((ASN1_VALUE *)rch, &CMS_RevocationInfoChoice_it); 610 return NULL; 611 } 612 613 return rch; 614 } 615 LCRYPTO_ALIAS(CMS_add0_RevocationInfoChoice); 616 617 int 618 CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) 619 { 620 CMS_RevocationInfoChoice *rch; 621 622 rch = CMS_add0_RevocationInfoChoice(cms); 623 if (!rch) 624 return 0; 625 rch->type = CMS_REVCHOICE_CRL; 626 rch->d.crl = crl; 627 628 return 1; 629 } 630 LCRYPTO_ALIAS(CMS_add0_crl); 631 632 int 633 CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) 634 { 635 int r; 636 637 r = CMS_add0_crl(cms, crl); 638 if (r > 0) 639 X509_CRL_up_ref(crl); 640 641 return r; 642 } 643 LCRYPTO_ALIAS(CMS_add1_crl); 644 645 STACK_OF(X509) * 646 CMS_get1_certs(CMS_ContentInfo *cms) 647 { 648 STACK_OF(X509) *certs = NULL; 649 CMS_CertificateChoices *cch; 650 STACK_OF(CMS_CertificateChoices) **pcerts; 651 int i; 652 653 pcerts = cms_get0_certificate_choices(cms); 654 if (!pcerts) 655 return NULL; 656 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { 657 cch = sk_CMS_CertificateChoices_value(*pcerts, i); 658 if (cch->type == 0) { 659 if (!certs) { 660 certs = sk_X509_new_null(); 661 if (!certs) 662 return NULL; 663 } 664 if (!sk_X509_push(certs, cch->d.certificate)) { 665 sk_X509_pop_free(certs, X509_free); 666 return NULL; 667 } 668 X509_up_ref(cch->d.certificate); 669 } 670 } 671 return certs; 672 } 673 LCRYPTO_ALIAS(CMS_get1_certs); 674 675 STACK_OF(X509_CRL) * 676 CMS_get1_crls(CMS_ContentInfo *cms) 677 { 678 STACK_OF(X509_CRL) *crls = NULL; 679 STACK_OF(CMS_RevocationInfoChoice) **pcrls; 680 CMS_RevocationInfoChoice *rch; 681 int i; 682 683 pcrls = cms_get0_revocation_choices(cms); 684 if (!pcrls) 685 return NULL; 686 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) { 687 rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); 688 if (rch->type == 0) { 689 if (!crls) { 690 crls = sk_X509_CRL_new_null(); 691 if (!crls) 692 return NULL; 693 } 694 if (!sk_X509_CRL_push(crls, rch->d.crl)) { 695 sk_X509_CRL_pop_free(crls, X509_CRL_free); 696 return NULL; 697 } 698 X509_CRL_up_ref(rch->d.crl); 699 } 700 } 701 return crls; 702 } 703 LCRYPTO_ALIAS(CMS_get1_crls); 704 705 static const ASN1_OCTET_STRING * 706 cms_X509_get0_subject_key_id(X509 *x) 707 { 708 /* Call for side-effect of computing hash and caching extensions */ 709 X509_check_purpose(x, -1, -1); 710 return x->skid; 711 } 712 713 int 714 cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert) 715 { 716 int ret; 717 718 ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert)); 719 if (ret) 720 return ret; 721 722 return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert)); 723 } 724 725 int 726 cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert) 727 { 728 const ASN1_OCTET_STRING *cert_keyid = cms_X509_get0_subject_key_id(cert); 729 730 if (cert_keyid == NULL) 731 return -1; 732 733 return ASN1_OCTET_STRING_cmp(keyid, cert_keyid); 734 } 735 736 int 737 cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert) 738 { 739 CMS_IssuerAndSerialNumber *ias; 740 741 ias = (CMS_IssuerAndSerialNumber *)ASN1_item_new(&CMS_IssuerAndSerialNumber_it); 742 if (!ias) 743 goto err; 744 if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert))) 745 goto err; 746 if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert))) 747 goto err; 748 ASN1_item_free((ASN1_VALUE *)*pias, &CMS_IssuerAndSerialNumber_it); 749 *pias = ias; 750 751 return 1; 752 753 err: 754 ASN1_item_free((ASN1_VALUE *)ias, &CMS_IssuerAndSerialNumber_it); 755 CMSerror(ERR_R_MALLOC_FAILURE); 756 757 return 0; 758 } 759 760 int 761 cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert) 762 { 763 ASN1_OCTET_STRING *keyid = NULL; 764 const ASN1_OCTET_STRING *cert_keyid; 765 766 cert_keyid = cms_X509_get0_subject_key_id(cert); 767 if (cert_keyid == NULL) { 768 CMSerror(CMS_R_CERTIFICATE_HAS_NO_KEYID); 769 return 0; 770 } 771 keyid = ASN1_STRING_dup(cert_keyid); 772 if (!keyid) { 773 CMSerror(ERR_R_MALLOC_FAILURE); 774 return 0; 775 } 776 ASN1_OCTET_STRING_free(*pkeyid); 777 *pkeyid = keyid; 778 779 return 1; 780 } 781