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