1 /* $OpenBSD: pk7_lib.c,v 1.30 2024/12/06 07:10:20 tb Exp $ */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59 #include <stdio.h> 60 61 #include <openssl/err.h> 62 #include <openssl/objects.h> 63 #include <openssl/x509.h> 64 65 #include "asn1_local.h" 66 #include "evp_local.h" 67 #include "x509_local.h" 68 69 long 70 PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) 71 { 72 int nid; 73 long ret = 0; 74 75 nid = OBJ_obj2nid(p7->type); 76 77 switch (cmd) { 78 case PKCS7_OP_SET_DETACHED_SIGNATURE: 79 if (nid == NID_pkcs7_signed) { 80 if (p7->d.sign == NULL) { 81 PKCS7error(PKCS7_R_NO_CONTENT); 82 break; 83 } 84 ret = p7->detached = (int)larg; 85 if (ret && PKCS7_type_is_data(p7->d.sign->contents)) { 86 ASN1_OCTET_STRING *os; 87 os = p7->d.sign->contents->d.data; 88 ASN1_OCTET_STRING_free(os); 89 p7->d.sign->contents->d.data = NULL; 90 } 91 } else { 92 PKCS7error(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); 93 ret = 0; 94 } 95 break; 96 case PKCS7_OP_GET_DETACHED_SIGNATURE: 97 if (nid == NID_pkcs7_signed) { 98 if (p7->d.sign == NULL || 99 p7->d.sign->contents->d.ptr == NULL) 100 ret = 1; 101 else 102 ret = 0; 103 104 p7->detached = ret; 105 } else { 106 PKCS7error(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); 107 ret = 0; 108 } 109 110 break; 111 default: 112 PKCS7error(PKCS7_R_UNKNOWN_OPERATION); 113 ret = 0; 114 } 115 return (ret); 116 } 117 LCRYPTO_ALIAS(PKCS7_ctrl); 118 119 int 120 PKCS7_content_new(PKCS7 *p7, int type) 121 { 122 PKCS7 *ret = NULL; 123 124 if ((ret = PKCS7_new()) == NULL) 125 goto err; 126 if (!PKCS7_set_type(ret, type)) 127 goto err; 128 if (!PKCS7_set_content(p7, ret)) 129 goto err; 130 131 return (1); 132 err: 133 if (ret != NULL) 134 PKCS7_free(ret); 135 return (0); 136 } 137 LCRYPTO_ALIAS(PKCS7_content_new); 138 139 int 140 PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) 141 { 142 int i; 143 144 i = OBJ_obj2nid(p7->type); 145 switch (i) { 146 case NID_pkcs7_signed: 147 if (p7->d.sign->contents != NULL) 148 PKCS7_free(p7->d.sign->contents); 149 p7->d.sign->contents = p7_data; 150 break; 151 case NID_pkcs7_digest: 152 if (p7->d.digest->contents != NULL) 153 PKCS7_free(p7->d.digest->contents); 154 p7->d.digest->contents = p7_data; 155 break; 156 case NID_pkcs7_data: 157 case NID_pkcs7_enveloped: 158 case NID_pkcs7_signedAndEnveloped: 159 case NID_pkcs7_encrypted: 160 default: 161 PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 162 goto err; 163 } 164 return (1); 165 err: 166 return (0); 167 } 168 LCRYPTO_ALIAS(PKCS7_set_content); 169 170 int 171 PKCS7_set_type(PKCS7 *p7, int type) 172 { 173 ASN1_OBJECT *obj; 174 175 /*PKCS7_content_free(p7);*/ 176 obj=OBJ_nid2obj(type); /* will not fail */ 177 178 switch (type) { 179 case NID_pkcs7_signed: 180 p7->type = obj; 181 if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL) 182 goto err; 183 if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) { 184 PKCS7_SIGNED_free(p7->d.sign); 185 p7->d.sign = NULL; 186 goto err; 187 } 188 break; 189 case NID_pkcs7_data: 190 p7->type = obj; 191 if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL) 192 goto err; 193 break; 194 case NID_pkcs7_signedAndEnveloped: 195 p7->type = obj; 196 if ((p7->d.signed_and_enveloped = 197 PKCS7_SIGN_ENVELOPE_new()) == NULL) 198 goto err; 199 if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1)) 200 goto err; 201 p7->d.signed_and_enveloped->enc_data->content_type = 202 OBJ_nid2obj(NID_pkcs7_data); 203 break; 204 case NID_pkcs7_enveloped: 205 p7->type = obj; 206 if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) == NULL) 207 goto err; 208 if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0)) 209 goto err; 210 p7->d.enveloped->enc_data->content_type = 211 OBJ_nid2obj(NID_pkcs7_data); 212 break; 213 case NID_pkcs7_encrypted: 214 p7->type = obj; 215 if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) == NULL) 216 goto err; 217 if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0)) 218 goto err; 219 p7->d.encrypted->enc_data->content_type = 220 OBJ_nid2obj(NID_pkcs7_data); 221 break; 222 223 case NID_pkcs7_digest: 224 p7->type = obj; 225 if ((p7->d.digest = PKCS7_DIGEST_new()) == NULL) 226 goto err; 227 if (!ASN1_INTEGER_set(p7->d.digest->version, 0)) 228 goto err; 229 break; 230 default: 231 PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 232 goto err; 233 } 234 return (1); 235 err: 236 return (0); 237 } 238 LCRYPTO_ALIAS(PKCS7_set_type); 239 240 int 241 PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other) 242 { 243 p7->type = OBJ_nid2obj(type); 244 p7->d.other = other; 245 return 1; 246 } 247 LCRYPTO_ALIAS(PKCS7_set0_type_other); 248 249 int 250 PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) 251 { 252 int i, j, nid; 253 X509_ALGOR *alg; 254 STACK_OF(PKCS7_SIGNER_INFO) *signer_sk; 255 STACK_OF(X509_ALGOR) *md_sk; 256 257 i = OBJ_obj2nid(p7->type); 258 switch (i) { 259 case NID_pkcs7_signed: 260 signer_sk = p7->d.sign->signer_info; 261 md_sk = p7->d.sign->md_algs; 262 break; 263 case NID_pkcs7_signedAndEnveloped: 264 signer_sk = p7->d.signed_and_enveloped->signer_info; 265 md_sk = p7->d.signed_and_enveloped->md_algs; 266 break; 267 default: 268 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); 269 return (0); 270 } 271 272 nid = OBJ_obj2nid(psi->digest_alg->algorithm); 273 274 /* If the digest is not currently listed, add it */ 275 j = 0; 276 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { 277 alg = sk_X509_ALGOR_value(md_sk, i); 278 if (OBJ_obj2nid(alg->algorithm) == nid) { 279 j = 1; 280 break; 281 } 282 } 283 if (!j) /* we need to add another algorithm */ 284 { 285 if (!(alg = X509_ALGOR_new()) || 286 !(alg->parameter = ASN1_TYPE_new())) { 287 X509_ALGOR_free(alg); 288 PKCS7error(ERR_R_MALLOC_FAILURE); 289 return (0); 290 } 291 alg->algorithm = OBJ_nid2obj(nid); 292 alg->parameter->type = V_ASN1_NULL; 293 if (!sk_X509_ALGOR_push(md_sk, alg)) { 294 X509_ALGOR_free(alg); 295 return 0; 296 } 297 } 298 299 if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi)) 300 return 0; 301 return (1); 302 } 303 LCRYPTO_ALIAS(PKCS7_add_signer); 304 305 int 306 PKCS7_add_certificate(PKCS7 *p7, X509 *x509) 307 { 308 int i; 309 STACK_OF(X509) **sk; 310 311 i = OBJ_obj2nid(p7->type); 312 switch (i) { 313 case NID_pkcs7_signed: 314 sk = &(p7->d.sign->cert); 315 break; 316 case NID_pkcs7_signedAndEnveloped: 317 sk = &(p7->d.signed_and_enveloped->cert); 318 break; 319 default: 320 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); 321 return (0); 322 } 323 324 if (*sk == NULL) 325 *sk = sk_X509_new_null(); 326 if (*sk == NULL) { 327 PKCS7error(ERR_R_MALLOC_FAILURE); 328 return 0; 329 } 330 CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); 331 if (!sk_X509_push(*sk, x509)) { 332 X509_free(x509); 333 return 0; 334 } 335 return (1); 336 } 337 LCRYPTO_ALIAS(PKCS7_add_certificate); 338 339 int 340 PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) 341 { 342 int i; 343 STACK_OF(X509_CRL) **sk; 344 345 i = OBJ_obj2nid(p7->type); 346 switch (i) { 347 case NID_pkcs7_signed: 348 sk = &(p7->d.sign->crl); 349 break; 350 case NID_pkcs7_signedAndEnveloped: 351 sk = &(p7->d.signed_and_enveloped->crl); 352 break; 353 default: 354 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); 355 return (0); 356 } 357 358 if (*sk == NULL) 359 *sk = sk_X509_CRL_new_null(); 360 if (*sk == NULL) { 361 PKCS7error(ERR_R_MALLOC_FAILURE); 362 return 0; 363 } 364 365 CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); 366 if (!sk_X509_CRL_push(*sk, crl)) { 367 X509_CRL_free(crl); 368 return 0; 369 } 370 return (1); 371 } 372 LCRYPTO_ALIAS(PKCS7_add_crl); 373 374 int 375 PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, 376 const EVP_MD *dgst) 377 { 378 int nid; 379 int ret; 380 381 /* We now need to add another PKCS7_SIGNER_INFO entry */ 382 if (!ASN1_INTEGER_set(p7i->version, 1)) 383 goto err; 384 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, 385 X509_get_issuer_name(x509))) 386 goto err; 387 388 /* because ASN1_INTEGER_set is used to set a 'long' we will do 389 * things the ugly way. */ 390 ASN1_INTEGER_free(p7i->issuer_and_serial->serial); 391 if (!(p7i->issuer_and_serial->serial = 392 ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) 393 goto err; 394 395 /* lets keep the pkey around for a while */ 396 CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 397 p7i->pkey = pkey; 398 399 /* 400 * Do not use X509_ALGOR_set_evp_md() to match historical behavior. 401 * A mistranslation of the ASN.1 from 1988 to 1997 syntax lost the 402 * OPTIONAL field, cf. the NOTE above RFC 5754, 2.1. 403 * Using X509_ALGOR_set_evp_md() would change encoding of the SHAs. 404 */ 405 nid = EVP_MD_type(dgst); 406 if (!X509_ALGOR_set0_by_nid(p7i->digest_alg, nid, V_ASN1_NULL, NULL)) 407 return 0; 408 409 if (pkey->ameth && pkey->ameth->pkey_ctrl) { 410 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 411 0, p7i); 412 if (ret > 0) 413 return 1; 414 if (ret != -2) { 415 PKCS7error(PKCS7_R_SIGNING_CTRL_FAILURE); 416 return 0; 417 } 418 } 419 PKCS7error(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 420 err: 421 return 0; 422 } 423 LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_set); 424 425 PKCS7_SIGNER_INFO * 426 PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst) 427 { 428 PKCS7_SIGNER_INFO *si = NULL; 429 430 if (dgst == NULL) { 431 int def_nid; 432 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) 433 goto err; 434 dgst = EVP_get_digestbynid(def_nid); 435 if (dgst == NULL) { 436 PKCS7error(PKCS7_R_NO_DEFAULT_DIGEST); 437 goto err; 438 } 439 } 440 441 if ((si = PKCS7_SIGNER_INFO_new()) == NULL) 442 goto err; 443 if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst)) 444 goto err; 445 if (!PKCS7_add_signer(p7, si)) 446 goto err; 447 return (si); 448 err: 449 if (si) 450 PKCS7_SIGNER_INFO_free(si); 451 return (NULL); 452 } 453 LCRYPTO_ALIAS(PKCS7_add_signature); 454 455 int 456 PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) 457 { 458 if (PKCS7_type_is_digest(p7)) { 459 if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) { 460 PKCS7error(ERR_R_MALLOC_FAILURE); 461 return 0; 462 } 463 p7->d.digest->md->parameter->type = V_ASN1_NULL; 464 p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md)); 465 return 1; 466 } 467 468 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); 469 return 1; 470 } 471 LCRYPTO_ALIAS(PKCS7_set_digest); 472 473 STACK_OF(PKCS7_SIGNER_INFO) * 474 PKCS7_get_signer_info(PKCS7 *p7) 475 { 476 if (p7 == NULL || p7->d.ptr == NULL) 477 return (NULL); 478 if (PKCS7_type_is_signed(p7)) { 479 return (p7->d.sign->signer_info); 480 } else if (PKCS7_type_is_signedAndEnveloped(p7)) { 481 return (p7->d.signed_and_enveloped->signer_info); 482 } else 483 return (NULL); 484 } 485 LCRYPTO_ALIAS(PKCS7_get_signer_info); 486 487 void 488 PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, 489 X509_ALGOR **pdig, X509_ALGOR **psig) 490 { 491 if (pk) 492 *pk = si->pkey; 493 if (pdig) 494 *pdig = si->digest_alg; 495 if (psig) 496 *psig = si->digest_enc_alg; 497 } 498 LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_get0_algs); 499 500 void 501 PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc) 502 { 503 if (penc) 504 *penc = ri->key_enc_algor; 505 } 506 LCRYPTO_ALIAS(PKCS7_RECIP_INFO_get0_alg); 507 508 PKCS7_RECIP_INFO * 509 PKCS7_add_recipient(PKCS7 *p7, X509 *x509) 510 { 511 PKCS7_RECIP_INFO *ri; 512 513 if ((ri = PKCS7_RECIP_INFO_new()) == NULL) 514 goto err; 515 if (!PKCS7_RECIP_INFO_set(ri, x509)) 516 goto err; 517 if (!PKCS7_add_recipient_info(p7, ri)) 518 goto err; 519 return ri; 520 err: 521 if (ri) 522 PKCS7_RECIP_INFO_free(ri); 523 return NULL; 524 } 525 LCRYPTO_ALIAS(PKCS7_add_recipient); 526 527 int 528 PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) 529 { 530 int i; 531 STACK_OF(PKCS7_RECIP_INFO) *sk; 532 533 i = OBJ_obj2nid(p7->type); 534 switch (i) { 535 case NID_pkcs7_signedAndEnveloped: 536 sk = p7->d.signed_and_enveloped->recipientinfo; 537 break; 538 case NID_pkcs7_enveloped: 539 sk = p7->d.enveloped->recipientinfo; 540 break; 541 default: 542 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); 543 return (0); 544 } 545 546 if (!sk_PKCS7_RECIP_INFO_push(sk, ri)) 547 return 0; 548 return (1); 549 } 550 LCRYPTO_ALIAS(PKCS7_add_recipient_info); 551 552 int 553 PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) 554 { 555 int ret; 556 EVP_PKEY *pkey = NULL; 557 if (!ASN1_INTEGER_set(p7i->version, 0)) 558 return 0; 559 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, 560 X509_get_issuer_name(x509))) 561 return 0; 562 563 ASN1_INTEGER_free(p7i->issuer_and_serial->serial); 564 if (!(p7i->issuer_and_serial->serial = 565 ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) 566 return 0; 567 568 pkey = X509_get_pubkey(x509); 569 570 if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) { 571 PKCS7error(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 572 goto err; 573 } 574 575 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 576 0, p7i); 577 if (ret == -2) { 578 PKCS7error(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 579 goto err; 580 } 581 if (ret <= 0) { 582 PKCS7error(PKCS7_R_ENCRYPTION_CTRL_FAILURE); 583 goto err; 584 } 585 586 EVP_PKEY_free(pkey); 587 588 CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); 589 p7i->cert = x509; 590 591 return 1; 592 593 err: 594 EVP_PKEY_free(pkey); 595 return 0; 596 } 597 LCRYPTO_ALIAS(PKCS7_RECIP_INFO_set); 598 599 X509 * 600 PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) 601 { 602 if (PKCS7_type_is_signed(p7)) 603 return(X509_find_by_issuer_and_serial(p7->d.sign->cert, 604 si->issuer_and_serial->issuer, 605 si->issuer_and_serial->serial)); 606 else 607 return (NULL); 608 } 609 LCRYPTO_ALIAS(PKCS7_cert_from_signer_info); 610 611 int 612 PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) 613 { 614 int i; 615 PKCS7_ENC_CONTENT *ec; 616 617 i = OBJ_obj2nid(p7->type); 618 switch (i) { 619 case NID_pkcs7_signedAndEnveloped: 620 ec = p7->d.signed_and_enveloped->enc_data; 621 break; 622 case NID_pkcs7_enveloped: 623 ec = p7->d.enveloped->enc_data; 624 break; 625 default: 626 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); 627 return (0); 628 } 629 630 /* Check cipher OID exists and has data in it*/ 631 i = EVP_CIPHER_type(cipher); 632 if (i == NID_undef) { 633 PKCS7error(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); 634 return (0); 635 } 636 637 ec->cipher = cipher; 638 return 1; 639 } 640 LCRYPTO_ALIAS(PKCS7_set_cipher); 641 642 int 643 PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) 644 { 645 ASN1_OCTET_STRING *os = NULL; 646 647 switch (OBJ_obj2nid(p7->type)) { 648 case NID_pkcs7_data: 649 os = p7->d.data; 650 break; 651 652 case NID_pkcs7_signedAndEnveloped: 653 os = p7->d.signed_and_enveloped->enc_data->enc_data; 654 if (os == NULL) { 655 os = ASN1_OCTET_STRING_new(); 656 p7->d.signed_and_enveloped->enc_data->enc_data = os; 657 } 658 break; 659 660 case NID_pkcs7_enveloped: 661 os = p7->d.enveloped->enc_data->enc_data; 662 if (os == NULL) { 663 os = ASN1_OCTET_STRING_new(); 664 p7->d.enveloped->enc_data->enc_data = os; 665 } 666 break; 667 668 case NID_pkcs7_signed: 669 os = p7->d.sign->contents->d.data; 670 break; 671 672 default: 673 os = NULL; 674 break; 675 } 676 677 if (os == NULL) 678 return 0; 679 680 os->flags |= ASN1_STRING_FLAG_NDEF; 681 *boundary = &os->data; 682 683 return 1; 684 } 685 LCRYPTO_ALIAS(PKCS7_stream); 686