Merge branch 'vendor/LIBRESSL'
[dragonfly.git] / crypto / libressl / crypto / pkcs7 / pk7_lib.c
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 }