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