511ae8cb176dadba7e6e12a76d5bce2efbf0a948
[openssl.git] / crypto / pkcs7 / pk7_lib.c
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     /* 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
111 int 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
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     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
158 int 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 = 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
230 int 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
237 int 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
290 int 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
322 int 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
355 int 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     ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
372     if (!(p7i->issuer_and_serial->serial =
373           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
401 PKCS7_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
430 int 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
446 STACK_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
458 void 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
469 void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
470 {
471     if (penc)
472         *penc = ri->key_enc_algor;
473 }
474
475 PKCS7_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
492 int 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
516 int 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     ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
527     if (!(p7i->issuer_and_serial->serial =
528           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
564 X509 *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
575 int 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
605 int 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 = 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 = 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 }