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