1 /* $OpenBSD: pk7_lib.c,v 1.17 2015/09/30 17:30:15 jsing 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_locl.h" 66 67 long 68 PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) 69 { 70 int nid; 71 long ret; 72 73 nid = OBJ_obj2nid(p7->type); 74 75 switch (cmd) { 76 case PKCS7_OP_SET_DETACHED_SIGNATURE: 77 if (nid == NID_pkcs7_signed) { 78 ret = p7->detached = (int)larg; 79 if (ret && PKCS7_type_is_data(p7->d.sign->contents)) { 80 ASN1_OCTET_STRING *os; 81 os = p7->d.sign->contents->d.data; 82 ASN1_OCTET_STRING_free(os); 83 p7->d.sign->contents->d.data = NULL; 84 } 85 } else { 86 PKCS7err(PKCS7_F_PKCS7_CTRL, 87 PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); 88 ret = 0; 89 } 90 break; 91 case PKCS7_OP_GET_DETACHED_SIGNATURE: 92 if (nid == NID_pkcs7_signed) { 93 if (!p7->d.sign || !p7->d.sign->contents->d.ptr) 94 ret = 1; 95 else 96 ret = 0; 97 98 p7->detached = ret; 99 } else { 100 PKCS7err(PKCS7_F_PKCS7_CTRL, 101 PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); 102 ret = 0; 103 } 104 105 break; 106 default: 107 PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION); 108 ret = 0; 109 } 110 return (ret); 111 } 112 113 int 114 PKCS7_content_new(PKCS7 *p7, int type) 115 { 116 PKCS7 *ret = NULL; 117 118 if ((ret = PKCS7_new()) == NULL) 119 goto err; 120 if (!PKCS7_set_type(ret, type)) 121 goto err; 122 if (!PKCS7_set_content(p7, ret)) 123 goto err; 124 125 return (1); 126 err: 127 if (ret != NULL) 128 PKCS7_free(ret); 129 return (0); 130 } 131 132 int 133 PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) 134 { 135 int i; 136 137 i = OBJ_obj2nid(p7->type); 138 switch (i) { 139 case NID_pkcs7_signed: 140 if (p7->d.sign->contents != NULL) 141 PKCS7_free(p7->d.sign->contents); 142 p7->d.sign->contents = p7_data; 143 break; 144 case NID_pkcs7_digest: 145 if (p7->d.digest->contents != NULL) 146 PKCS7_free(p7->d.digest->contents); 147 p7->d.digest->contents = p7_data; 148 break; 149 case NID_pkcs7_data: 150 case NID_pkcs7_enveloped: 151 case NID_pkcs7_signedAndEnveloped: 152 case NID_pkcs7_encrypted: 153 default: 154 PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, 155 PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 156 goto err; 157 } 158 return (1); 159 err: 160 return (0); 161 } 162 163 int 164 PKCS7_set_type(PKCS7 *p7, int type) 165 { 166 ASN1_OBJECT *obj; 167 168 /*PKCS7_content_free(p7);*/ 169 obj=OBJ_nid2obj(type); /* will not fail */ 170 171 switch (type) { 172 case NID_pkcs7_signed: 173 p7->type = obj; 174 if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL) 175 goto err; 176 if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) { 177 PKCS7_SIGNED_free(p7->d.sign); 178 p7->d.sign = NULL; 179 goto err; 180 } 181 break; 182 case NID_pkcs7_data: 183 p7->type = obj; 184 if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL) 185 goto err; 186 break; 187 case NID_pkcs7_signedAndEnveloped: 188 p7->type = obj; 189 if ((p7->d.signed_and_enveloped = 190 PKCS7_SIGN_ENVELOPE_new()) == NULL) 191 goto err; 192 ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1); 193 if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1)) 194 goto err; 195 p7->d.signed_and_enveloped->enc_data->content_type = 196 OBJ_nid2obj(NID_pkcs7_data); 197 break; 198 case NID_pkcs7_enveloped: 199 p7->type = obj; 200 if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) == NULL) 201 goto err; 202 if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0)) 203 goto err; 204 p7->d.enveloped->enc_data->content_type = 205 OBJ_nid2obj(NID_pkcs7_data); 206 break; 207 case NID_pkcs7_encrypted: 208 p7->type = obj; 209 if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) == NULL) 210 goto err; 211 if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0)) 212 goto err; 213 p7->d.encrypted->enc_data->content_type = 214 OBJ_nid2obj(NID_pkcs7_data); 215 break; 216 217 case NID_pkcs7_digest: 218 p7->type = obj; 219 if ((p7->d.digest = PKCS7_DIGEST_new()) == NULL) 220 goto err; 221 if (!ASN1_INTEGER_set(p7->d.digest->version, 0)) 222 goto err; 223 break; 224 default: 225 PKCS7err(PKCS7_F_PKCS7_SET_TYPE, 226 PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 227 goto err; 228 } 229 return (1); 230 err: 231 return (0); 232 } 233 234 int 235 PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other) 236 { 237 p7->type = OBJ_nid2obj(type); 238 p7->d.other = other; 239 return 1; 240 } 241 242 int 243 PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) 244 { 245 int i, j, nid; 246 X509_ALGOR *alg; 247 STACK_OF(PKCS7_SIGNER_INFO) *signer_sk; 248 STACK_OF(X509_ALGOR) *md_sk; 249 250 i = OBJ_obj2nid(p7->type); 251 switch (i) { 252 case NID_pkcs7_signed: 253 signer_sk = p7->d.sign->signer_info; 254 md_sk = p7->d.sign->md_algs; 255 break; 256 case NID_pkcs7_signedAndEnveloped: 257 signer_sk = p7->d.signed_and_enveloped->signer_info; 258 md_sk = p7->d.signed_and_enveloped->md_algs; 259 break; 260 default: 261 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE); 262 return (0); 263 } 264 265 nid = OBJ_obj2nid(psi->digest_alg->algorithm); 266 267 /* If the digest is not currently listed, add it */ 268 j = 0; 269 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { 270 alg = sk_X509_ALGOR_value(md_sk, i); 271 if (OBJ_obj2nid(alg->algorithm) == nid) { 272 j = 1; 273 break; 274 } 275 } 276 if (!j) /* we need to add another algorithm */ 277 { 278 if (!(alg = X509_ALGOR_new()) || 279 !(alg->parameter = ASN1_TYPE_new())) { 280 X509_ALGOR_free(alg); 281 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, 282 ERR_R_MALLOC_FAILURE); 283 return (0); 284 } 285 alg->algorithm = OBJ_nid2obj(nid); 286 alg->parameter->type = V_ASN1_NULL; 287 if (!sk_X509_ALGOR_push(md_sk, alg)) { 288 X509_ALGOR_free(alg); 289 return 0; 290 } 291 } 292 293 if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi)) 294 return 0; 295 return (1); 296 } 297 298 int 299 PKCS7_add_certificate(PKCS7 *p7, X509 *x509) 300 { 301 int i; 302 STACK_OF(X509) **sk; 303 304 i = OBJ_obj2nid(p7->type); 305 switch (i) { 306 case NID_pkcs7_signed: 307 sk = &(p7->d.sign->cert); 308 break; 309 case NID_pkcs7_signedAndEnveloped: 310 sk = &(p7->d.signed_and_enveloped->cert); 311 break; 312 default: 313 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, 314 PKCS7_R_WRONG_CONTENT_TYPE); 315 return (0); 316 } 317 318 if (*sk == NULL) 319 *sk = sk_X509_new_null(); 320 if (*sk == NULL) { 321 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE); 322 return 0; 323 } 324 CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); 325 if (!sk_X509_push(*sk, x509)) { 326 X509_free(x509); 327 return 0; 328 } 329 return (1); 330 } 331 332 int 333 PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) 334 { 335 int i; 336 STACK_OF(X509_CRL) **sk; 337 338 i = OBJ_obj2nid(p7->type); 339 switch (i) { 340 case NID_pkcs7_signed: 341 sk = &(p7->d.sign->crl); 342 break; 343 case NID_pkcs7_signedAndEnveloped: 344 sk = &(p7->d.signed_and_enveloped->crl); 345 break; 346 default: 347 PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE); 348 return (0); 349 } 350 351 if (*sk == NULL) 352 *sk = sk_X509_CRL_new_null(); 353 if (*sk == NULL) { 354 PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE); 355 return 0; 356 } 357 358 CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); 359 if (!sk_X509_CRL_push(*sk, crl)) { 360 X509_CRL_free(crl); 361 return 0; 362 } 363 return (1); 364 } 365 366 int 367 PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, 368 const EVP_MD *dgst) 369 { 370 int ret; 371 372 /* We now need to add another PKCS7_SIGNER_INFO entry */ 373 if (!ASN1_INTEGER_set(p7i->version, 1)) 374 goto err; 375 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, 376 X509_get_issuer_name(x509))) 377 goto err; 378 379 /* because ASN1_INTEGER_set is used to set a 'long' we will do 380 * things the ugly way. */ 381 ASN1_INTEGER_free(p7i->issuer_and_serial->serial); 382 if (!(p7i->issuer_and_serial->serial = 383 ASN1_STRING_dup(X509_get_serialNumber(x509)))) 384 goto err; 385 386 /* lets keep the pkey around for a while */ 387 CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 388 p7i->pkey = pkey; 389 390 /* Set the algorithms */ 391 392 X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)), 393 V_ASN1_NULL, NULL); 394 395 if (pkey->ameth && pkey->ameth->pkey_ctrl) { 396 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 397 0, p7i); 398 if (ret > 0) 399 return 1; 400 if (ret != -2) { 401 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, 402 PKCS7_R_SIGNING_CTRL_FAILURE); 403 return 0; 404 } 405 } 406 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, 407 PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 408 err: 409 return 0; 410 } 411 412 PKCS7_SIGNER_INFO * 413 PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst) 414 { 415 PKCS7_SIGNER_INFO *si = NULL; 416 417 if (dgst == NULL) { 418 int def_nid; 419 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) 420 goto err; 421 dgst = EVP_get_digestbynid(def_nid); 422 if (dgst == NULL) { 423 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, 424 PKCS7_R_NO_DEFAULT_DIGEST); 425 goto err; 426 } 427 } 428 429 if ((si = PKCS7_SIGNER_INFO_new()) == NULL) 430 goto err; 431 if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst)) 432 goto err; 433 if (!PKCS7_add_signer(p7, si)) 434 goto err; 435 return (si); 436 err: 437 if (si) 438 PKCS7_SIGNER_INFO_free(si); 439 return (NULL); 440 } 441 442 int 443 PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) 444 { 445 if (PKCS7_type_is_digest(p7)) { 446 if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) { 447 PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, 448 ERR_R_MALLOC_FAILURE); 449 return 0; 450 } 451 p7->d.digest->md->parameter->type = V_ASN1_NULL; 452 p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md)); 453 return 1; 454 } 455 456 PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE); 457 return 1; 458 } 459 460 STACK_OF(PKCS7_SIGNER_INFO) * 461 PKCS7_get_signer_info(PKCS7 *p7) 462 { 463 if (p7 == NULL || p7->d.ptr == NULL) 464 return (NULL); 465 if (PKCS7_type_is_signed(p7)) { 466 return (p7->d.sign->signer_info); 467 } else if (PKCS7_type_is_signedAndEnveloped(p7)) { 468 return (p7->d.signed_and_enveloped->signer_info); 469 } else 470 return (NULL); 471 } 472 473 void 474 PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, 475 X509_ALGOR **pdig, X509_ALGOR **psig) 476 { 477 if (pk) 478 *pk = si->pkey; 479 if (pdig) 480 *pdig = si->digest_alg; 481 if (psig) 482 *psig = si->digest_enc_alg; 483 } 484 485 void 486 PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc) 487 { 488 if (penc) 489 *penc = ri->key_enc_algor; 490 } 491 492 PKCS7_RECIP_INFO * 493 PKCS7_add_recipient(PKCS7 *p7, X509 *x509) 494 { 495 PKCS7_RECIP_INFO *ri; 496 497 if ((ri = PKCS7_RECIP_INFO_new()) == NULL) 498 goto err; 499 if (!PKCS7_RECIP_INFO_set(ri, x509)) 500 goto err; 501 if (!PKCS7_add_recipient_info(p7, ri)) 502 goto err; 503 return ri; 504 err: 505 if (ri) 506 PKCS7_RECIP_INFO_free(ri); 507 return NULL; 508 } 509 510 int 511 PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) 512 { 513 int i; 514 STACK_OF(PKCS7_RECIP_INFO) *sk; 515 516 i = OBJ_obj2nid(p7->type); 517 switch (i) { 518 case NID_pkcs7_signedAndEnveloped: 519 sk = p7->d.signed_and_enveloped->recipientinfo; 520 break; 521 case NID_pkcs7_enveloped: 522 sk = p7->d.enveloped->recipientinfo; 523 break; 524 default: 525 PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO, 526 PKCS7_R_WRONG_CONTENT_TYPE); 527 return (0); 528 } 529 530 if (!sk_PKCS7_RECIP_INFO_push(sk, ri)) 531 return 0; 532 return (1); 533 } 534 535 int 536 PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) 537 { 538 int ret; 539 EVP_PKEY *pkey = NULL; 540 if (!ASN1_INTEGER_set(p7i->version, 0)) 541 return 0; 542 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, 543 X509_get_issuer_name(x509))) 544 return 0; 545 546 ASN1_INTEGER_free(p7i->issuer_and_serial->serial); 547 if (!(p7i->issuer_and_serial->serial = 548 ASN1_STRING_dup(X509_get_serialNumber(x509)))) 549 return 0; 550 551 pkey = X509_get_pubkey(x509); 552 553 if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) { 554 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, 555 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 556 goto err; 557 } 558 559 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 560 0, p7i); 561 if (ret == -2) { 562 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, 563 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 564 goto err; 565 } 566 if (ret <= 0) { 567 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, 568 PKCS7_R_ENCRYPTION_CTRL_FAILURE); 569 goto err; 570 } 571 572 EVP_PKEY_free(pkey); 573 574 CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); 575 p7i->cert = x509; 576 577 return 1; 578 579 err: 580 EVP_PKEY_free(pkey); 581 return 0; 582 } 583 584 X509 * 585 PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) 586 { 587 if (PKCS7_type_is_signed(p7)) 588 return(X509_find_by_issuer_and_serial(p7->d.sign->cert, 589 si->issuer_and_serial->issuer, 590 si->issuer_and_serial->serial)); 591 else 592 return (NULL); 593 } 594 595 int 596 PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) 597 { 598 int i; 599 PKCS7_ENC_CONTENT *ec; 600 601 i = OBJ_obj2nid(p7->type); 602 switch (i) { 603 case NID_pkcs7_signedAndEnveloped: 604 ec = p7->d.signed_and_enveloped->enc_data; 605 break; 606 case NID_pkcs7_enveloped: 607 ec = p7->d.enveloped->enc_data; 608 break; 609 default: 610 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE); 611 return (0); 612 } 613 614 /* Check cipher OID exists and has data in it*/ 615 i = EVP_CIPHER_type(cipher); 616 if (i == NID_undef) { 617 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, 618 PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); 619 return (0); 620 } 621 622 ec->cipher = cipher; 623 return 1; 624 } 625 626 int 627 PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) 628 { 629 ASN1_OCTET_STRING *os = NULL; 630 631 switch (OBJ_obj2nid(p7->type)) { 632 case NID_pkcs7_data: 633 os = p7->d.data; 634 break; 635 636 case NID_pkcs7_signedAndEnveloped: 637 os = p7->d.signed_and_enveloped->enc_data->enc_data; 638 if (os == NULL) { 639 os = ASN1_OCTET_STRING_new(); 640 p7->d.signed_and_enveloped->enc_data->enc_data = os; 641 } 642 break; 643 644 case NID_pkcs7_enveloped: 645 os = p7->d.enveloped->enc_data->enc_data; 646 if (os == NULL) { 647 os = ASN1_OCTET_STRING_new(); 648 p7->d.enveloped->enc_data->enc_data = os; 649 } 650 break; 651 652 case NID_pkcs7_signed: 653 os = p7->d.sign->contents->d.data; 654 break; 655 656 default: 657 os = NULL; 658 break; 659 } 660 661 if (os == NULL) 662 return 0; 663 664 os->flags |= ASN1_STRING_FLAG_NDEF; 665 *boundary = &os->data; 666 667 return 1; 668 } 669