1 /* $OpenBSD: cms_lib.c,v 1.25 2024/03/30 01:53:05 joshua 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 LCRYPTO_ALIAS(CMS_get0_content); 318 319 /* 320 * Return an ASN1_OBJECT pointer to content type. This allows it to be 321 * accessed or set later. 322 */ 323 324 static ASN1_OBJECT ** 325 cms_get0_econtent_type(CMS_ContentInfo *cms) 326 { 327 switch (OBJ_obj2nid(cms->contentType)) { 328 case NID_pkcs7_signed: 329 return &cms->d.signedData->encapContentInfo->eContentType; 330 331 case NID_pkcs7_enveloped: 332 return &cms->d.envelopedData->encryptedContentInfo->contentType; 333 334 case NID_pkcs7_digest: 335 return &cms->d.digestedData->encapContentInfo->eContentType; 336 337 case NID_pkcs7_encrypted: 338 return &cms->d.encryptedData->encryptedContentInfo->contentType; 339 340 case NID_id_smime_ct_authData: 341 return &cms->d.authenticatedData->encapContentInfo->eContentType; 342 343 case NID_id_smime_ct_compressedData: 344 return &cms->d.compressedData->encapContentInfo->eContentType; 345 346 default: 347 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); 348 return NULL; 349 } 350 } 351 352 const ASN1_OBJECT * 353 CMS_get0_eContentType(CMS_ContentInfo *cms) 354 { 355 ASN1_OBJECT **petype; 356 357 petype = cms_get0_econtent_type(cms); 358 if (petype) 359 return *petype; 360 361 return NULL; 362 } 363 LCRYPTO_ALIAS(CMS_get0_eContentType); 364 365 int 366 CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) 367 { 368 ASN1_OBJECT **petype, *etype; 369 370 petype = cms_get0_econtent_type(cms); 371 if (!petype) 372 return 0; 373 if (!oid) 374 return 1; 375 etype = OBJ_dup(oid); 376 if (!etype) 377 return 0; 378 ASN1_OBJECT_free(*petype); 379 *petype = etype; 380 381 return 1; 382 } 383 LCRYPTO_ALIAS(CMS_set1_eContentType); 384 385 int 386 CMS_is_detached(CMS_ContentInfo *cms) 387 { 388 ASN1_OCTET_STRING **pos; 389 390 pos = CMS_get0_content(cms); 391 if (!pos) 392 return -1; 393 if (*pos) 394 return 0; 395 396 return 1; 397 } 398 LCRYPTO_ALIAS(CMS_is_detached); 399 400 int 401 CMS_set_detached(CMS_ContentInfo *cms, int detached) 402 { 403 ASN1_OCTET_STRING **pos; 404 405 pos = CMS_get0_content(cms); 406 if (!pos) 407 return 0; 408 if (detached) { 409 ASN1_OCTET_STRING_free(*pos); 410 *pos = NULL; 411 return 1; 412 } 413 if (*pos == NULL) 414 *pos = ASN1_OCTET_STRING_new(); 415 if (*pos != NULL) { 416 /* 417 * NB: special flag to show content is created and not read in. 418 */ 419 (*pos)->flags |= ASN1_STRING_FLAG_CONT; 420 return 1; 421 } 422 CMSerror(ERR_R_MALLOC_FAILURE); 423 424 return 0; 425 } 426 LCRYPTO_ALIAS(CMS_set_detached); 427 428 /* Create a digest BIO from an X509_ALGOR structure */ 429 430 BIO * 431 cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) 432 { 433 BIO *mdbio = NULL; 434 const ASN1_OBJECT *digestoid; 435 const EVP_MD *digest; 436 437 X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); 438 digest = EVP_get_digestbyobj(digestoid); 439 if (!digest) { 440 CMSerror(CMS_R_UNKNOWN_DIGEST_ALGORITHM); 441 goto err; 442 } 443 mdbio = BIO_new(BIO_f_md()); 444 if (mdbio == NULL || !BIO_set_md(mdbio, digest)) { 445 CMSerror(CMS_R_MD_BIO_INIT_ERROR); 446 goto err; 447 } 448 return mdbio; 449 450 err: 451 BIO_free(mdbio); 452 453 return NULL; 454 } 455 456 /* Locate a message digest content from a BIO chain based on SignerInfo */ 457 458 int 459 cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, X509_ALGOR *mdalg) 460 { 461 int nid; 462 const ASN1_OBJECT *mdoid; 463 464 X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); 465 nid = OBJ_obj2nid(mdoid); 466 /* Look for digest type to match signature */ 467 for (;;) { 468 EVP_MD_CTX *mtmp; 469 chain = BIO_find_type(chain, BIO_TYPE_MD); 470 if (chain == NULL) { 471 CMSerror(CMS_R_NO_MATCHING_DIGEST); 472 return 0; 473 } 474 BIO_get_md_ctx(chain, &mtmp); 475 if (EVP_MD_CTX_type(mtmp) == nid 476 /* 477 * Workaround for broken implementations that use signature 478 * algorithm OID instead of digest. 479 */ 480 || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) 481 return EVP_MD_CTX_copy_ex(mctx, mtmp); 482 chain = BIO_next(chain); 483 } 484 } 485 486 static STACK_OF(CMS_CertificateChoices) ** 487 cms_get0_certificate_choices(CMS_ContentInfo *cms) 488 { 489 switch (OBJ_obj2nid(cms->contentType)) { 490 case NID_pkcs7_signed: 491 return &cms->d.signedData->certificates; 492 493 case NID_pkcs7_enveloped: 494 if (cms->d.envelopedData->originatorInfo == NULL) 495 return NULL; 496 return &cms->d.envelopedData->originatorInfo->certificates; 497 498 default: 499 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); 500 return NULL; 501 } 502 } 503 504 CMS_CertificateChoices * 505 CMS_add0_CertificateChoices(CMS_ContentInfo *cms) 506 { 507 STACK_OF(CMS_CertificateChoices) **pcerts; 508 CMS_CertificateChoices *cch; 509 510 pcerts = cms_get0_certificate_choices(cms); 511 if (!pcerts) 512 return NULL; 513 if (!*pcerts) 514 *pcerts = sk_CMS_CertificateChoices_new_null(); 515 if (!*pcerts) 516 return NULL; 517 cch = (CMS_CertificateChoices *)ASN1_item_new(&CMS_CertificateChoices_it); 518 if (!cch) 519 return NULL; 520 if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) { 521 ASN1_item_free((ASN1_VALUE *)cch, &CMS_CertificateChoices_it); 522 return NULL; 523 } 524 525 return cch; 526 } 527 LCRYPTO_ALIAS(CMS_add0_CertificateChoices); 528 529 int 530 CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) 531 { 532 CMS_CertificateChoices *cch; 533 STACK_OF(CMS_CertificateChoices) **pcerts; 534 int i; 535 536 pcerts = cms_get0_certificate_choices(cms); 537 if (!pcerts) 538 return 0; 539 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { 540 cch = sk_CMS_CertificateChoices_value(*pcerts, i); 541 if (cch->type == CMS_CERTCHOICE_CERT) { 542 if (!X509_cmp(cch->d.certificate, cert)) { 543 CMSerror(CMS_R_CERTIFICATE_ALREADY_PRESENT); 544 return 0; 545 } 546 } 547 } 548 cch = CMS_add0_CertificateChoices(cms); 549 if (!cch) 550 return 0; 551 cch->type = CMS_CERTCHOICE_CERT; 552 cch->d.certificate = cert; 553 554 return 1; 555 } 556 LCRYPTO_ALIAS(CMS_add0_cert); 557 558 int 559 CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) 560 { 561 int r; 562 563 r = CMS_add0_cert(cms, cert); 564 if (r > 0) 565 X509_up_ref(cert); 566 567 return r; 568 } 569 LCRYPTO_ALIAS(CMS_add1_cert); 570 571 static STACK_OF(CMS_RevocationInfoChoice) ** 572 cms_get0_revocation_choices(CMS_ContentInfo *cms) 573 { 574 switch (OBJ_obj2nid(cms->contentType)) { 575 case NID_pkcs7_signed: 576 return &cms->d.signedData->crls; 577 578 case NID_pkcs7_enveloped: 579 if (cms->d.envelopedData->originatorInfo == NULL) 580 return NULL; 581 return &cms->d.envelopedData->originatorInfo->crls; 582 583 default: 584 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE); 585 return NULL; 586 } 587 } 588 589 CMS_RevocationInfoChoice * 590 CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) 591 { 592 STACK_OF(CMS_RevocationInfoChoice) **pcrls; 593 CMS_RevocationInfoChoice *rch; 594 595 pcrls = cms_get0_revocation_choices(cms); 596 if (!pcrls) 597 return NULL; 598 if (!*pcrls) 599 *pcrls = sk_CMS_RevocationInfoChoice_new_null(); 600 if (!*pcrls) 601 return NULL; 602 rch = (CMS_RevocationInfoChoice *)ASN1_item_new(&CMS_RevocationInfoChoice_it); 603 if (!rch) 604 return NULL; 605 if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) { 606 ASN1_item_free((ASN1_VALUE *)rch, &CMS_RevocationInfoChoice_it); 607 return NULL; 608 } 609 610 return rch; 611 } 612 LCRYPTO_ALIAS(CMS_add0_RevocationInfoChoice); 613 614 int 615 CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) 616 { 617 CMS_RevocationInfoChoice *rch; 618 619 rch = CMS_add0_RevocationInfoChoice(cms); 620 if (!rch) 621 return 0; 622 rch->type = CMS_REVCHOICE_CRL; 623 rch->d.crl = crl; 624 625 return 1; 626 } 627 LCRYPTO_ALIAS(CMS_add0_crl); 628 629 int 630 CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) 631 { 632 int r; 633 634 r = CMS_add0_crl(cms, crl); 635 if (r > 0) 636 X509_CRL_up_ref(crl); 637 638 return r; 639 } 640 LCRYPTO_ALIAS(CMS_add1_crl); 641 642 STACK_OF(X509) * 643 CMS_get1_certs(CMS_ContentInfo *cms) 644 { 645 STACK_OF(X509) *certs = NULL; 646 CMS_CertificateChoices *cch; 647 STACK_OF(CMS_CertificateChoices) **pcerts; 648 int i; 649 650 pcerts = cms_get0_certificate_choices(cms); 651 if (!pcerts) 652 return NULL; 653 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { 654 cch = sk_CMS_CertificateChoices_value(*pcerts, i); 655 if (cch->type == 0) { 656 if (!certs) { 657 certs = sk_X509_new_null(); 658 if (!certs) 659 return NULL; 660 } 661 if (!sk_X509_push(certs, cch->d.certificate)) { 662 sk_X509_pop_free(certs, X509_free); 663 return NULL; 664 } 665 X509_up_ref(cch->d.certificate); 666 } 667 } 668 return certs; 669 } 670 LCRYPTO_ALIAS(CMS_get1_certs); 671 672 STACK_OF(X509_CRL) * 673 CMS_get1_crls(CMS_ContentInfo *cms) 674 { 675 STACK_OF(X509_CRL) *crls = NULL; 676 STACK_OF(CMS_RevocationInfoChoice) **pcrls; 677 CMS_RevocationInfoChoice *rch; 678 int i; 679 680 pcrls = cms_get0_revocation_choices(cms); 681 if (!pcrls) 682 return NULL; 683 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) { 684 rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); 685 if (rch->type == 0) { 686 if (!crls) { 687 crls = sk_X509_CRL_new_null(); 688 if (!crls) 689 return NULL; 690 } 691 if (!sk_X509_CRL_push(crls, rch->d.crl)) { 692 sk_X509_CRL_pop_free(crls, X509_CRL_free); 693 return NULL; 694 } 695 X509_CRL_up_ref(rch->d.crl); 696 } 697 } 698 return crls; 699 } 700 LCRYPTO_ALIAS(CMS_get1_crls); 701 702 static const ASN1_OCTET_STRING * 703 cms_X509_get0_subject_key_id(X509 *x) 704 { 705 /* Call for side-effect of computing hash and caching extensions */ 706 X509_check_purpose(x, -1, -1); 707 return x->skid; 708 } 709 710 int 711 cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert) 712 { 713 int ret; 714 715 ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert)); 716 if (ret) 717 return ret; 718 719 return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert)); 720 } 721 722 int 723 cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert) 724 { 725 const ASN1_OCTET_STRING *cert_keyid = cms_X509_get0_subject_key_id(cert); 726 727 if (cert_keyid == NULL) 728 return -1; 729 730 return ASN1_OCTET_STRING_cmp(keyid, cert_keyid); 731 } 732 733 int 734 cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert) 735 { 736 CMS_IssuerAndSerialNumber *ias; 737 738 ias = (CMS_IssuerAndSerialNumber *)ASN1_item_new(&CMS_IssuerAndSerialNumber_it); 739 if (!ias) 740 goto err; 741 if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert))) 742 goto err; 743 if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert))) 744 goto err; 745 ASN1_item_free((ASN1_VALUE *)*pias, &CMS_IssuerAndSerialNumber_it); 746 *pias = ias; 747 748 return 1; 749 750 err: 751 ASN1_item_free((ASN1_VALUE *)ias, &CMS_IssuerAndSerialNumber_it); 752 CMSerror(ERR_R_MALLOC_FAILURE); 753 754 return 0; 755 } 756 757 int 758 cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert) 759 { 760 ASN1_OCTET_STRING *keyid = NULL; 761 const ASN1_OCTET_STRING *cert_keyid; 762 763 cert_keyid = cms_X509_get0_subject_key_id(cert); 764 if (cert_keyid == NULL) { 765 CMSerror(CMS_R_CERTIFICATE_HAS_NO_KEYID); 766 return 0; 767 } 768 keyid = ASN1_STRING_dup(cert_keyid); 769 if (!keyid) { 770 CMSerror(ERR_R_MALLOC_FAILURE); 771 return 0; 772 } 773 ASN1_OCTET_STRING_free(*pkeyid); 774 *pkeyid = keyid; 775 776 return 1; 777 } 778