1 /* 2 * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <openssl/asn1t.h> 11 #include <openssl/x509v3.h> 12 #include <openssl/err.h> 13 #include <openssl/pem.h> 14 #include <openssl/bio.h> 15 #include <openssl/asn1.h> 16 #include <openssl/cms.h> 17 #include <openssl/cms.h> 18 #include "internal/sizes.h" 19 #include "crypto/x509.h" 20 #include "cms_local.h" 21 22 static STACK_OF(CMS_CertificateChoices) 23 **cms_get0_certificate_choices(CMS_ContentInfo *cms); 24 25 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(CMS_ContentInfo) IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)26 IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo) 27 28 CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a, 29 const unsigned char **in, long len) 30 { 31 CMS_ContentInfo *ci; 32 const CMS_CTX *ctx = ossl_cms_get0_cmsctx(a == NULL ? NULL : *a); 33 34 ci = (CMS_ContentInfo *)ASN1_item_d2i_ex((ASN1_VALUE **)a, in, len, 35 (CMS_ContentInfo_it()), 36 ossl_cms_ctx_get0_libctx(ctx), 37 ossl_cms_ctx_get0_propq(ctx)); 38 if (ci != NULL) { 39 ERR_set_mark(); 40 ossl_cms_resolve_libctx(ci); 41 ERR_pop_to_mark(); 42 } 43 return ci; 44 } 45 i2d_CMS_ContentInfo(const CMS_ContentInfo * a,unsigned char ** out)46 int i2d_CMS_ContentInfo(const CMS_ContentInfo *a, unsigned char **out) 47 { 48 return ASN1_item_i2d((const ASN1_VALUE *)a, out, (CMS_ContentInfo_it())); 49 } 50 CMS_ContentInfo_new_ex(OSSL_LIB_CTX * libctx,const char * propq)51 CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq) 52 { 53 CMS_ContentInfo *ci; 54 55 ci = (CMS_ContentInfo *)ASN1_item_new_ex(ASN1_ITEM_rptr(CMS_ContentInfo), 56 libctx, propq); 57 if (ci != NULL) { 58 ci->ctx.libctx = libctx; 59 ci->ctx.propq = NULL; 60 if (propq != NULL) { 61 ci->ctx.propq = OPENSSL_strdup(propq); 62 if (ci->ctx.propq == NULL) { 63 CMS_ContentInfo_free(ci); 64 ci = NULL; 65 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 66 } 67 } 68 } 69 return ci; 70 } 71 ossl_cms_get0_cmsctx(const CMS_ContentInfo * cms)72 const CMS_CTX *ossl_cms_get0_cmsctx(const CMS_ContentInfo *cms) 73 { 74 return cms != NULL ? &cms->ctx : NULL; 75 } 76 ossl_cms_ctx_get0_libctx(const CMS_CTX * ctx)77 OSSL_LIB_CTX *ossl_cms_ctx_get0_libctx(const CMS_CTX *ctx) 78 { 79 return ctx != NULL ? ctx->libctx : NULL; 80 } 81 ossl_cms_ctx_get0_propq(const CMS_CTX * ctx)82 const char *ossl_cms_ctx_get0_propq(const CMS_CTX *ctx) 83 { 84 return ctx != NULL ? ctx->propq : NULL; 85 } 86 ossl_cms_resolve_libctx(CMS_ContentInfo * ci)87 void ossl_cms_resolve_libctx(CMS_ContentInfo *ci) 88 { 89 int i; 90 CMS_CertificateChoices *cch; 91 STACK_OF(CMS_CertificateChoices) **pcerts; 92 const CMS_CTX *ctx = ossl_cms_get0_cmsctx(ci); 93 OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx); 94 const char *propq = ossl_cms_ctx_get0_propq(ctx); 95 96 ossl_cms_SignerInfos_set_cmsctx(ci); 97 ossl_cms_RecipientInfos_set_cmsctx(ci); 98 99 pcerts = cms_get0_certificate_choices(ci); 100 if (pcerts != NULL) { 101 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { 102 cch = sk_CMS_CertificateChoices_value(*pcerts, i); 103 if (cch->type == CMS_CERTCHOICE_CERT) 104 ossl_x509_set0_libctx(cch->d.certificate, libctx, propq); 105 } 106 } 107 } 108 CMS_get0_type(const CMS_ContentInfo * cms)109 const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms) 110 { 111 return cms->contentType; 112 } 113 ossl_cms_Data_create(OSSL_LIB_CTX * libctx,const char * propq)114 CMS_ContentInfo *ossl_cms_Data_create(OSSL_LIB_CTX *libctx, const char *propq) 115 { 116 CMS_ContentInfo *cms = CMS_ContentInfo_new_ex(libctx, propq); 117 118 if (cms != NULL) { 119 cms->contentType = OBJ_nid2obj(NID_pkcs7_data); 120 /* Never detached */ 121 CMS_set_detached(cms, 0); 122 } 123 return cms; 124 } 125 ossl_cms_content_bio(CMS_ContentInfo * cms)126 BIO *ossl_cms_content_bio(CMS_ContentInfo *cms) 127 { 128 ASN1_OCTET_STRING **pos = CMS_get0_content(cms); 129 130 if (pos == NULL) 131 return NULL; 132 /* If content detached data goes nowhere: create NULL BIO */ 133 if (*pos == NULL) 134 return BIO_new(BIO_s_null()); 135 /* 136 * If content not detached and created return memory BIO 137 */ 138 if (*pos == NULL || ((*pos)->flags == ASN1_STRING_FLAG_CONT)) 139 return BIO_new(BIO_s_mem()); 140 /* Else content was read in: return read only BIO for it */ 141 return BIO_new_mem_buf((*pos)->data, (*pos)->length); 142 } 143 CMS_dataInit(CMS_ContentInfo * cms,BIO * icont)144 BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) 145 { 146 BIO *cmsbio, *cont; 147 if (icont) 148 cont = icont; 149 else 150 cont = ossl_cms_content_bio(cms); 151 if (!cont) { 152 ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT); 153 return NULL; 154 } 155 switch (OBJ_obj2nid(cms->contentType)) { 156 157 case NID_pkcs7_data: 158 return cont; 159 160 case NID_pkcs7_signed: 161 cmsbio = ossl_cms_SignedData_init_bio(cms); 162 break; 163 164 case NID_pkcs7_digest: 165 cmsbio = ossl_cms_DigestedData_init_bio(cms); 166 break; 167 #ifdef ZLIB 168 case NID_id_smime_ct_compressedData: 169 cmsbio = ossl_cms_CompressedData_init_bio(cms); 170 break; 171 #endif 172 173 case NID_pkcs7_encrypted: 174 cmsbio = ossl_cms_EncryptedData_init_bio(cms); 175 break; 176 177 case NID_pkcs7_enveloped: 178 cmsbio = ossl_cms_EnvelopedData_init_bio(cms); 179 break; 180 181 case NID_id_smime_ct_authEnvelopedData: 182 cmsbio = ossl_cms_AuthEnvelopedData_init_bio(cms); 183 break; 184 185 default: 186 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_TYPE); 187 goto err; 188 } 189 190 if (cmsbio) 191 return BIO_push(cmsbio, cont); 192 err: 193 if (!icont) 194 BIO_free(cont); 195 return NULL; 196 197 } 198 199 /* unfortunately cannot constify SMIME_write_ASN1() due to this function */ CMS_dataFinal(CMS_ContentInfo * cms,BIO * cmsbio)200 int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) 201 { 202 ASN1_OCTET_STRING **pos = CMS_get0_content(cms); 203 204 if (pos == NULL) 205 return 0; 206 /* If embedded content find memory BIO and set content */ 207 if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) { 208 BIO *mbio; 209 unsigned char *cont; 210 long contlen; 211 mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); 212 if (!mbio) { 213 ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_NOT_FOUND); 214 return 0; 215 } 216 contlen = BIO_get_mem_data(mbio, &cont); 217 /* Set bio as read only so its content can't be clobbered */ 218 BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); 219 BIO_set_mem_eof_return(mbio, 0); 220 ASN1_STRING_set0(*pos, cont, contlen); 221 (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; 222 } 223 224 switch (OBJ_obj2nid(cms->contentType)) { 225 226 case NID_pkcs7_data: 227 case NID_pkcs7_encrypted: 228 case NID_id_smime_ct_compressedData: 229 /* Nothing to do */ 230 return 1; 231 232 case NID_pkcs7_enveloped: 233 return ossl_cms_EnvelopedData_final(cms, cmsbio); 234 235 case NID_id_smime_ct_authEnvelopedData: 236 return ossl_cms_AuthEnvelopedData_final(cms, cmsbio); 237 238 case NID_pkcs7_signed: 239 return ossl_cms_SignedData_final(cms, cmsbio); 240 241 case NID_pkcs7_digest: 242 return ossl_cms_DigestedData_do_final(cms, cmsbio, 0); 243 244 default: 245 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_TYPE); 246 return 0; 247 } 248 } 249 250 /* 251 * Return an OCTET STRING pointer to content. This allows it to be accessed 252 * or set later. 253 */ 254 CMS_get0_content(CMS_ContentInfo * cms)255 ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) 256 { 257 switch (OBJ_obj2nid(cms->contentType)) { 258 259 case NID_pkcs7_data: 260 return &cms->d.data; 261 262 case NID_pkcs7_signed: 263 return &cms->d.signedData->encapContentInfo->eContent; 264 265 case NID_pkcs7_enveloped: 266 return &cms->d.envelopedData->encryptedContentInfo->encryptedContent; 267 268 case NID_pkcs7_digest: 269 return &cms->d.digestedData->encapContentInfo->eContent; 270 271 case NID_pkcs7_encrypted: 272 return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; 273 274 case NID_id_smime_ct_authEnvelopedData: 275 return &cms->d.authEnvelopedData->authEncryptedContentInfo 276 ->encryptedContent; 277 278 case NID_id_smime_ct_authData: 279 return &cms->d.authenticatedData->encapContentInfo->eContent; 280 281 case NID_id_smime_ct_compressedData: 282 return &cms->d.compressedData->encapContentInfo->eContent; 283 284 default: 285 if (cms->d.other->type == V_ASN1_OCTET_STRING) 286 return &cms->d.other->value.octet_string; 287 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE); 288 return NULL; 289 290 } 291 } 292 293 /* 294 * Return an ASN1_OBJECT pointer to content type. This allows it to be 295 * accessed or set later. 296 */ 297 cms_get0_econtent_type(CMS_ContentInfo * cms)298 static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) 299 { 300 switch (OBJ_obj2nid(cms->contentType)) { 301 302 case NID_pkcs7_signed: 303 return &cms->d.signedData->encapContentInfo->eContentType; 304 305 case NID_pkcs7_enveloped: 306 return &cms->d.envelopedData->encryptedContentInfo->contentType; 307 308 case NID_pkcs7_digest: 309 return &cms->d.digestedData->encapContentInfo->eContentType; 310 311 case NID_pkcs7_encrypted: 312 return &cms->d.encryptedData->encryptedContentInfo->contentType; 313 314 case NID_id_smime_ct_authEnvelopedData: 315 return &cms->d.authEnvelopedData->authEncryptedContentInfo 316 ->contentType; 317 case NID_id_smime_ct_authData: 318 return &cms->d.authenticatedData->encapContentInfo->eContentType; 319 320 case NID_id_smime_ct_compressedData: 321 return &cms->d.compressedData->encapContentInfo->eContentType; 322 323 default: 324 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE); 325 return NULL; 326 327 } 328 } 329 CMS_get0_eContentType(CMS_ContentInfo * cms)330 const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms) 331 { 332 ASN1_OBJECT **petype; 333 petype = cms_get0_econtent_type(cms); 334 if (petype) 335 return *petype; 336 return NULL; 337 } 338 CMS_set1_eContentType(CMS_ContentInfo * cms,const ASN1_OBJECT * oid)339 int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) 340 { 341 ASN1_OBJECT **petype, *etype; 342 343 petype = cms_get0_econtent_type(cms); 344 if (petype == NULL) 345 return 0; 346 if (oid == NULL) 347 return 1; 348 etype = OBJ_dup(oid); 349 if (etype == NULL) 350 return 0; 351 ASN1_OBJECT_free(*petype); 352 *petype = etype; 353 return 1; 354 } 355 CMS_is_detached(CMS_ContentInfo * cms)356 int CMS_is_detached(CMS_ContentInfo *cms) 357 { 358 ASN1_OCTET_STRING **pos; 359 360 pos = CMS_get0_content(cms); 361 if (pos == NULL) 362 return -1; 363 if (*pos != NULL) 364 return 0; 365 return 1; 366 } 367 CMS_set_detached(CMS_ContentInfo * cms,int detached)368 int CMS_set_detached(CMS_ContentInfo *cms, int detached) 369 { 370 ASN1_OCTET_STRING **pos; 371 372 pos = CMS_get0_content(cms); 373 if (pos == NULL) 374 return 0; 375 if (detached) { 376 ASN1_OCTET_STRING_free(*pos); 377 *pos = NULL; 378 return 1; 379 } 380 if (*pos == NULL) 381 *pos = ASN1_OCTET_STRING_new(); 382 if (*pos != NULL) { 383 /* 384 * NB: special flag to show content is created and not read in. 385 */ 386 (*pos)->flags |= ASN1_STRING_FLAG_CONT; 387 return 1; 388 } 389 ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); 390 return 0; 391 } 392 393 /* Create a digest BIO from an X509_ALGOR structure */ 394 ossl_cms_DigestAlgorithm_init_bio(X509_ALGOR * digestAlgorithm,const CMS_CTX * ctx)395 BIO *ossl_cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm, 396 const CMS_CTX *ctx) 397 { 398 BIO *mdbio = NULL; 399 const ASN1_OBJECT *digestoid; 400 const EVP_MD *digest = NULL; 401 EVP_MD *fetched_digest = NULL; 402 char alg[OSSL_MAX_NAME_SIZE]; 403 404 X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); 405 OBJ_obj2txt(alg, sizeof(alg), digestoid, 0); 406 407 (void)ERR_set_mark(); 408 fetched_digest = EVP_MD_fetch(ossl_cms_ctx_get0_libctx(ctx), alg, 409 ossl_cms_ctx_get0_propq(ctx)); 410 411 if (fetched_digest != NULL) 412 digest = fetched_digest; 413 else 414 digest = EVP_get_digestbyobj(digestoid); 415 if (digest == NULL) { 416 (void)ERR_clear_last_mark(); 417 ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM); 418 goto err; 419 } 420 (void)ERR_pop_to_mark(); 421 422 mdbio = BIO_new(BIO_f_md()); 423 if (mdbio == NULL || BIO_set_md(mdbio, digest) <= 0) { 424 ERR_raise(ERR_LIB_CMS, CMS_R_MD_BIO_INIT_ERROR); 425 goto err; 426 } 427 EVP_MD_free(fetched_digest); 428 return mdbio; 429 err: 430 EVP_MD_free(fetched_digest); 431 BIO_free(mdbio); 432 return NULL; 433 } 434 435 /* Locate a message digest content from a BIO chain based on SignerInfo */ 436 ossl_cms_DigestAlgorithm_find_ctx(EVP_MD_CTX * mctx,BIO * chain,X509_ALGOR * mdalg)437 int ossl_cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, 438 X509_ALGOR *mdalg) 439 { 440 int nid; 441 const ASN1_OBJECT *mdoid; 442 X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); 443 nid = OBJ_obj2nid(mdoid); 444 /* Look for digest type to match signature */ 445 for (;;) { 446 EVP_MD_CTX *mtmp; 447 chain = BIO_find_type(chain, BIO_TYPE_MD); 448 if (chain == NULL) { 449 ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_DIGEST); 450 return 0; 451 } 452 BIO_get_md_ctx(chain, &mtmp); 453 if (EVP_MD_CTX_get_type(mtmp) == nid 454 /* 455 * Workaround for broken implementations that use signature 456 * algorithm OID instead of digest. 457 */ 458 || EVP_MD_get_pkey_type(EVP_MD_CTX_get0_md(mtmp)) == nid) 459 return EVP_MD_CTX_copy_ex(mctx, mtmp); 460 chain = BIO_next(chain); 461 } 462 } 463 STACK_OF(CMS_CertificateChoices)464 static STACK_OF(CMS_CertificateChoices) 465 **cms_get0_certificate_choices(CMS_ContentInfo *cms) 466 { 467 switch (OBJ_obj2nid(cms->contentType)) { 468 469 case NID_pkcs7_signed: 470 return &cms->d.signedData->certificates; 471 472 case NID_pkcs7_enveloped: 473 if (cms->d.envelopedData->originatorInfo == NULL) 474 return NULL; 475 return &cms->d.envelopedData->originatorInfo->certificates; 476 477 case NID_id_smime_ct_authEnvelopedData: 478 if (cms->d.authEnvelopedData->originatorInfo == NULL) 479 return NULL; 480 return &cms->d.authEnvelopedData->originatorInfo->certificates; 481 482 default: 483 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE); 484 return NULL; 485 486 } 487 } 488 CMS_add0_CertificateChoices(CMS_ContentInfo * cms)489 CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms) 490 { 491 STACK_OF(CMS_CertificateChoices) **pcerts; 492 CMS_CertificateChoices *cch; 493 494 pcerts = cms_get0_certificate_choices(cms); 495 if (pcerts == NULL) 496 return NULL; 497 if (*pcerts == NULL) 498 *pcerts = sk_CMS_CertificateChoices_new_null(); 499 if (*pcerts == NULL) 500 return NULL; 501 cch = M_ASN1_new_of(CMS_CertificateChoices); 502 if (!cch) 503 return NULL; 504 if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) { 505 M_ASN1_free_of(cch, CMS_CertificateChoices); 506 return NULL; 507 } 508 return cch; 509 } 510 CMS_add0_cert(CMS_ContentInfo * cms,X509 * cert)511 int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) 512 { 513 CMS_CertificateChoices *cch; 514 STACK_OF(CMS_CertificateChoices) **pcerts; 515 int i; 516 517 pcerts = cms_get0_certificate_choices(cms); 518 if (pcerts == NULL) 519 return 0; 520 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { 521 cch = sk_CMS_CertificateChoices_value(*pcerts, i); 522 if (cch->type == CMS_CERTCHOICE_CERT) { 523 if (!X509_cmp(cch->d.certificate, cert)) { 524 ERR_raise(ERR_LIB_CMS, CMS_R_CERTIFICATE_ALREADY_PRESENT); 525 return 0; 526 } 527 } 528 } 529 cch = CMS_add0_CertificateChoices(cms); 530 if (!cch) 531 return 0; 532 cch->type = CMS_CERTCHOICE_CERT; 533 cch->d.certificate = cert; 534 return 1; 535 } 536 CMS_add1_cert(CMS_ContentInfo * cms,X509 * cert)537 int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) 538 { 539 int r; 540 r = CMS_add0_cert(cms, cert); 541 if (r > 0) 542 X509_up_ref(cert); 543 return r; 544 } 545 STACK_OF(CMS_RevocationInfoChoice)546 static STACK_OF(CMS_RevocationInfoChoice) 547 **cms_get0_revocation_choices(CMS_ContentInfo *cms) 548 { 549 switch (OBJ_obj2nid(cms->contentType)) { 550 551 case NID_pkcs7_signed: 552 return &cms->d.signedData->crls; 553 554 case NID_pkcs7_enveloped: 555 if (cms->d.envelopedData->originatorInfo == NULL) 556 return NULL; 557 return &cms->d.envelopedData->originatorInfo->crls; 558 559 case NID_id_smime_ct_authEnvelopedData: 560 if (cms->d.authEnvelopedData->originatorInfo == NULL) 561 return NULL; 562 return &cms->d.authEnvelopedData->originatorInfo->crls; 563 564 default: 565 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE); 566 return NULL; 567 568 } 569 } 570 CMS_add0_RevocationInfoChoice(CMS_ContentInfo * cms)571 CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) 572 { 573 STACK_OF(CMS_RevocationInfoChoice) **pcrls; 574 CMS_RevocationInfoChoice *rch; 575 576 pcrls = cms_get0_revocation_choices(cms); 577 if (pcrls == NULL) 578 return NULL; 579 if (*pcrls == NULL) 580 *pcrls = sk_CMS_RevocationInfoChoice_new_null(); 581 if (*pcrls == NULL) 582 return NULL; 583 rch = M_ASN1_new_of(CMS_RevocationInfoChoice); 584 if (rch == NULL) 585 return NULL; 586 if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) { 587 M_ASN1_free_of(rch, CMS_RevocationInfoChoice); 588 return NULL; 589 } 590 return rch; 591 } 592 CMS_add0_crl(CMS_ContentInfo * cms,X509_CRL * crl)593 int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) 594 { 595 CMS_RevocationInfoChoice *rch; 596 rch = CMS_add0_RevocationInfoChoice(cms); 597 if (!rch) 598 return 0; 599 rch->type = CMS_REVCHOICE_CRL; 600 rch->d.crl = crl; 601 return 1; 602 } 603 CMS_add1_crl(CMS_ContentInfo * cms,X509_CRL * crl)604 int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) 605 { 606 if (!X509_CRL_up_ref(crl)) 607 return 0; 608 if (CMS_add0_crl(cms, crl)) 609 return 1; 610 X509_CRL_free(crl); 611 return 0; 612 } 613 STACK_OF(X509)614 STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) 615 { 616 STACK_OF(X509) *certs = NULL; 617 CMS_CertificateChoices *cch; 618 STACK_OF(CMS_CertificateChoices) **pcerts; 619 int i; 620 621 pcerts = cms_get0_certificate_choices(cms); 622 if (pcerts == NULL) 623 return NULL; 624 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { 625 cch = sk_CMS_CertificateChoices_value(*pcerts, i); 626 if (cch->type == 0) { 627 if (!ossl_x509_add_cert_new(&certs, cch->d.certificate, 628 X509_ADD_FLAG_UP_REF)) { 629 sk_X509_pop_free(certs, X509_free); 630 return NULL; 631 } 632 } 633 } 634 return certs; 635 636 } 637 STACK_OF(X509_CRL)638 STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) 639 { 640 STACK_OF(X509_CRL) *crls = NULL; 641 STACK_OF(CMS_RevocationInfoChoice) **pcrls; 642 CMS_RevocationInfoChoice *rch; 643 int i; 644 645 pcrls = cms_get0_revocation_choices(cms); 646 if (pcrls == NULL) 647 return NULL; 648 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) { 649 rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); 650 if (rch->type == 0) { 651 if (!crls) { 652 crls = sk_X509_CRL_new_null(); 653 if (!crls) 654 return NULL; 655 } 656 if (!sk_X509_CRL_push(crls, rch->d.crl)) { 657 sk_X509_CRL_pop_free(crls, X509_CRL_free); 658 return NULL; 659 } 660 X509_CRL_up_ref(rch->d.crl); 661 } 662 } 663 return crls; 664 } 665 ossl_cms_ias_cert_cmp(CMS_IssuerAndSerialNumber * ias,X509 * cert)666 int ossl_cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert) 667 { 668 int ret; 669 ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert)); 670 if (ret) 671 return ret; 672 return ASN1_INTEGER_cmp(ias->serialNumber, X509_get0_serialNumber(cert)); 673 } 674 ossl_cms_keyid_cert_cmp(ASN1_OCTET_STRING * keyid,X509 * cert)675 int ossl_cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert) 676 { 677 const ASN1_OCTET_STRING *cert_keyid = X509_get0_subject_key_id(cert); 678 679 if (cert_keyid == NULL) 680 return -1; 681 return ASN1_OCTET_STRING_cmp(keyid, cert_keyid); 682 } 683 ossl_cms_set1_ias(CMS_IssuerAndSerialNumber ** pias,X509 * cert)684 int ossl_cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert) 685 { 686 CMS_IssuerAndSerialNumber *ias; 687 ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber); 688 if (!ias) 689 goto err; 690 if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert))) 691 goto err; 692 if (!ASN1_STRING_copy(ias->serialNumber, X509_get0_serialNumber(cert))) 693 goto err; 694 M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber); 695 *pias = ias; 696 return 1; 697 err: 698 M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber); 699 ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); 700 return 0; 701 } 702 ossl_cms_set1_keyid(ASN1_OCTET_STRING ** pkeyid,X509 * cert)703 int ossl_cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert) 704 { 705 ASN1_OCTET_STRING *keyid = NULL; 706 const ASN1_OCTET_STRING *cert_keyid; 707 cert_keyid = X509_get0_subject_key_id(cert); 708 if (cert_keyid == NULL) { 709 ERR_raise(ERR_LIB_CMS, CMS_R_CERTIFICATE_HAS_NO_KEYID); 710 return 0; 711 } 712 keyid = ASN1_STRING_dup(cert_keyid); 713 if (!keyid) { 714 ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); 715 return 0; 716 } 717 ASN1_OCTET_STRING_free(*pkeyid); 718 *pkeyid = keyid; 719 return 1; 720 } 721