GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/pkcs7/pk7_lib.c Lines: 152 299 50.8 %
Date: 2017-11-13 Branches: 74 192 38.5 %

Line Branch Exec Source
1
/* $OpenBSD: pk7_lib.c,v 1.19 2017/01/29 17:49:23 beck 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
116
	nid = OBJ_obj2nid(p7->type);
74
75
58
	switch (cmd) {
76
	case PKCS7_OP_SET_DETACHED_SIGNATURE:
77
5
		if (nid == NID_pkcs7_signed) {
78
5
			ret = p7->detached = (int)larg;
79

10
			if (ret && PKCS7_type_is_data(p7->d.sign->contents)) {
80
				ASN1_OCTET_STRING *os;
81
5
				os = p7->d.sign->contents->d.data;
82
5
				ASN1_OCTET_STRING_free(os);
83
5
				p7->d.sign->contents->d.data = NULL;
84
5
			}
85
		} else {
86
			PKCS7error(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
87
			ret = 0;
88
		}
89
		break;
90
	case PKCS7_OP_GET_DETACHED_SIGNATURE:
91
53
		if (nid == NID_pkcs7_signed) {
92

106
			if (!p7->d.sign  || !p7->d.sign->contents->d.ptr)
93
23
				ret = 1;
94
			else
95
				ret = 0;
96
97
53
			p7->detached = ret;
98
53
		} else {
99
			PKCS7error(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
100
			ret = 0;
101
		}
102
103
		break;
104
	default:
105
		PKCS7error(PKCS7_R_UNKNOWN_OPERATION);
106
		ret = 0;
107
	}
108
58
	return (ret);
109
}
110
111
int
112
PKCS7_content_new(PKCS7 *p7, int type)
113
{
114
	PKCS7 *ret = NULL;
115
116
16
	if ((ret = PKCS7_new()) == NULL)
117
		goto err;
118
8
	if (!PKCS7_set_type(ret, type))
119
		goto err;
120
8
	if (!PKCS7_set_content(p7, ret))
121
		goto err;
122
123
8
	return (1);
124
err:
125
	if (ret != NULL)
126
		PKCS7_free(ret);
127
	return (0);
128
8
}
129
130
int
131
PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
132
{
133
	int i;
134
135
20
	i = OBJ_obj2nid(p7->type);
136
10
	switch (i) {
137
	case NID_pkcs7_signed:
138
10
		if (p7->d.sign->contents != NULL)
139
10
			PKCS7_free(p7->d.sign->contents);
140
10
		p7->d.sign->contents = p7_data;
141
10
		break;
142
	case NID_pkcs7_digest:
143
		if (p7->d.digest->contents != NULL)
144
			PKCS7_free(p7->d.digest->contents);
145
		p7->d.digest->contents = p7_data;
146
		break;
147
	case NID_pkcs7_data:
148
	case NID_pkcs7_enveloped:
149
	case NID_pkcs7_signedAndEnveloped:
150
	case NID_pkcs7_encrypted:
151
	default:
152
		PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
153
		goto err;
154
	}
155
10
	return (1);
156
err:
157
	return (0);
158
10
}
159
160
int
161
PKCS7_set_type(PKCS7 *p7, int type)
162
{
163
	ASN1_OBJECT *obj;
164
165
	/*PKCS7_content_free(p7);*/
166
46
	obj=OBJ_nid2obj(type); /* will not fail */
167
168

23
	switch (type) {
169
	case NID_pkcs7_signed:
170
10
		p7->type = obj;
171
10
		if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
172
			goto err;
173
10
		if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
174
			PKCS7_SIGNED_free(p7->d.sign);
175
			p7->d.sign = NULL;
176
			goto err;
177
		}
178
		break;
179
	case NID_pkcs7_data:
180
8
		p7->type = obj;
181
8
		if ((p7->d.data = 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 =
187
		    PKCS7_SIGN_ENVELOPE_new()) == NULL)
188
			goto err;
189
		ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1);
190
		if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
191
			goto err;
192
		p7->d.signed_and_enveloped->enc_data->content_type =
193
		    OBJ_nid2obj(NID_pkcs7_data);
194
		break;
195
	case NID_pkcs7_enveloped:
196
3
		p7->type = obj;
197
3
		if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) == NULL)
198
			goto err;
199
3
		if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
200
			goto err;
201
3
		p7->d.enveloped->enc_data->content_type =
202
3
		    OBJ_nid2obj(NID_pkcs7_data);
203
3
		break;
204
	case NID_pkcs7_encrypted:
205
2
		p7->type = obj;
206
2
		if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) == NULL)
207
			goto err;
208
2
		if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
209
			goto err;
210
2
		p7->d.encrypted->enc_data->content_type =
211
2
		    OBJ_nid2obj(NID_pkcs7_data);
212
2
		break;
213
214
	case NID_pkcs7_digest:
215
		p7->type = obj;
216
		if ((p7->d.digest = PKCS7_DIGEST_new()) == NULL)
217
			goto err;
218
		if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
219
			goto err;
220
		break;
221
	default:
222
		PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
223
		goto err;
224
	}
225
23
	return (1);
226
err:
227
	return (0);
228
23
}
229
230
int
231
PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
232
{
233
	p7->type = OBJ_nid2obj(type);
234
	p7->d.other = other;
235
	return 1;
236
}
237
238
int
239
PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
240
{
241
	int i, j, nid;
242
	X509_ALGOR *alg;
243
	STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
244
	STACK_OF(X509_ALGOR) *md_sk;
245
246
20
	i = OBJ_obj2nid(p7->type);
247
10
	switch (i) {
248
	case NID_pkcs7_signed:
249
10
		signer_sk = p7->d.sign->signer_info;
250
10
		md_sk = p7->d.sign->md_algs;
251
10
		break;
252
	case NID_pkcs7_signedAndEnveloped:
253
		signer_sk = p7->d.signed_and_enveloped->signer_info;
254
		md_sk = p7->d.signed_and_enveloped->md_algs;
255
		break;
256
	default:
257
		PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
258
		return (0);
259
	}
260
261
10
	nid = OBJ_obj2nid(psi->digest_alg->algorithm);
262
263
	/* If the digest is not currently listed, add it */
264
	j = 0;
265
20
	for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
266
		alg = sk_X509_ALGOR_value(md_sk, i);
267
		if (OBJ_obj2nid(alg->algorithm) == nid) {
268
			j = 1;
269
			break;
270
		}
271
	}
272
10
	if (!j) /* we need to add another algorithm */
273
	{
274

20
		if (!(alg = X509_ALGOR_new()) ||
275
10
		    !(alg->parameter = ASN1_TYPE_new())) {
276
			X509_ALGOR_free(alg);
277
			PKCS7error(ERR_R_MALLOC_FAILURE);
278
			return (0);
279
		}
280
10
		alg->algorithm = OBJ_nid2obj(nid);
281
10
		alg->parameter->type = V_ASN1_NULL;
282
10
		if (!sk_X509_ALGOR_push(md_sk, alg)) {
283
			X509_ALGOR_free(alg);
284
			return 0;
285
		}
286
	}
287
288
10
	if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
289
		return 0;
290
10
	return (1);
291
10
}
292
293
int
294
PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
295
{
296
	int i;
297
	STACK_OF(X509) **sk;
298
299
22
	i = OBJ_obj2nid(p7->type);
300
11
	switch (i) {
301
	case NID_pkcs7_signed:
302
11
		sk = &(p7->d.sign->cert);
303
11
		break;
304
	case NID_pkcs7_signedAndEnveloped:
305
		sk = &(p7->d.signed_and_enveloped->cert);
306
		break;
307
	default:
308
		PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
309
		return (0);
310
	}
311
312
11
	if (*sk == NULL)
313
8
		*sk = sk_X509_new_null();
314
11
	if (*sk == NULL) {
315
		PKCS7error(ERR_R_MALLOC_FAILURE);
316
		return 0;
317
	}
318
11
	CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
319
11
	if (!sk_X509_push(*sk, x509)) {
320
		X509_free(x509);
321
		return 0;
322
	}
323
11
	return (1);
324
11
}
325
326
int
327
PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
328
{
329
	int i;
330
	STACK_OF(X509_CRL) **sk;
331
332
	i = OBJ_obj2nid(p7->type);
333
	switch (i) {
334
	case NID_pkcs7_signed:
335
		sk = &(p7->d.sign->crl);
336
		break;
337
	case NID_pkcs7_signedAndEnveloped:
338
		sk = &(p7->d.signed_and_enveloped->crl);
339
		break;
340
	default:
341
		PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
342
		return (0);
343
	}
344
345
	if (*sk == NULL)
346
		*sk = sk_X509_CRL_new_null();
347
	if (*sk == NULL) {
348
		PKCS7error(ERR_R_MALLOC_FAILURE);
349
		return 0;
350
	}
351
352
	CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
353
	if (!sk_X509_CRL_push(*sk, crl)) {
354
		X509_CRL_free(crl);
355
		return 0;
356
	}
357
	return (1);
358
}
359
360
int
361
PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
362
    const EVP_MD *dgst)
363
{
364
	int ret;
365
366
	/* We now need to add another PKCS7_SIGNER_INFO entry */
367
20
	if (!ASN1_INTEGER_set(p7i->version, 1))
368
		goto err;
369
20
	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
370
10
	    X509_get_issuer_name(x509)))
371
		goto err;
372
373
	/* because ASN1_INTEGER_set is used to set a 'long' we will do
374
	 * things the ugly way. */
375
10
	ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
376
10
	if (!(p7i->issuer_and_serial->serial =
377
10
	    ASN1_STRING_dup(X509_get_serialNumber(x509))))
378
		goto err;
379
380
	/* lets keep the pkey around for a while */
381
10
	CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
382
10
	p7i->pkey = pkey;
383
384
	/* Set the algorithms */
385
386
10
	X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
387
	    V_ASN1_NULL, NULL);
388
389

20
	if (pkey->ameth && pkey->ameth->pkey_ctrl) {
390
10
		ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
391
10
		    0, p7i);
392
10
		if (ret > 0)
393
10
			return 1;
394
		if (ret != -2) {
395
			PKCS7error(PKCS7_R_SIGNING_CTRL_FAILURE);
396
			return 0;
397
		}
398
	}
399
	PKCS7error(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
400
err:
401
	return 0;
402
10
}
403
404
PKCS7_SIGNER_INFO *
405
PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst)
406
{
407
	PKCS7_SIGNER_INFO *si = NULL;
408
409
20
	if (dgst == NULL) {
410
8
		int def_nid;
411
8
		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
412
			goto err;
413
8
		dgst = EVP_get_digestbynid(def_nid);
414
8
		if (dgst == NULL) {
415
			PKCS7error(PKCS7_R_NO_DEFAULT_DIGEST);
416
			goto err;
417
		}
418
24
	}
419
420
10
	if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
421
		goto err;
422
10
	if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst))
423
		goto err;
424
10
	if (!PKCS7_add_signer(p7, si))
425
		goto err;
426
10
	return (si);
427
err:
428
	if (si)
429
		PKCS7_SIGNER_INFO_free(si);
430
	return (NULL);
431
10
}
432
433
int
434
PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
435
{
436
	if (PKCS7_type_is_digest(p7)) {
437
		if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) {
438
			PKCS7error(ERR_R_MALLOC_FAILURE);
439
			return 0;
440
		}
441
		p7->d.digest->md->parameter->type = V_ASN1_NULL;
442
		p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
443
		return 1;
444
	}
445
446
	PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
447
	return 1;
448
}
449
450
STACK_OF(PKCS7_SIGNER_INFO) *
451
PKCS7_get_signer_info(PKCS7 *p7)
452
{
453

66
	if (p7 == NULL || p7->d.ptr == NULL)
454
		return (NULL);
455
22
	if (PKCS7_type_is_signed(p7)) {
456
22
		return (p7->d.sign->signer_info);
457
	} else if (PKCS7_type_is_signedAndEnveloped(p7)) {
458
		return (p7->d.signed_and_enveloped->signer_info);
459
	} else
460
		return (NULL);
461
22
}
462
463
void
464
PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
465
    X509_ALGOR **pdig, X509_ALGOR **psig)
466
{
467
20
	if (pk)
468
		*pk = si->pkey;
469
10
	if (pdig)
470
		*pdig = si->digest_alg;
471
10
	if (psig)
472
10
		*psig = si->digest_enc_alg;
473
10
}
474
475
void
476
PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
477
{
478
6
	if (penc)
479
3
		*penc = ri->key_enc_algor;
480
3
}
481
482
PKCS7_RECIP_INFO *
483
PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
484
{
485
	PKCS7_RECIP_INFO *ri;
486
487
6
	if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
488
		goto err;
489
3
	if (!PKCS7_RECIP_INFO_set(ri, x509))
490
		goto err;
491
3
	if (!PKCS7_add_recipient_info(p7, ri))
492
		goto err;
493
3
	return ri;
494
err:
495
	if (ri)
496
		PKCS7_RECIP_INFO_free(ri);
497
	return NULL;
498
3
}
499
500
int
501
PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
502
{
503
	int i;
504
	STACK_OF(PKCS7_RECIP_INFO) *sk;
505
506
6
	i = OBJ_obj2nid(p7->type);
507
3
	switch (i) {
508
	case NID_pkcs7_signedAndEnveloped:
509
		sk = p7->d.signed_and_enveloped->recipientinfo;
510
		break;
511
	case NID_pkcs7_enveloped:
512
3
		sk = p7->d.enveloped->recipientinfo;
513
3
		break;
514
	default:
515
		PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
516
		return (0);
517
	}
518
519
3
	if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
520
		return 0;
521
3
	return (1);
522
3
}
523
524
int
525
PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
526
{
527
	int ret;
528
	EVP_PKEY *pkey = NULL;
529
6
	if (!ASN1_INTEGER_set(p7i->version, 0))
530
		return 0;
531
6
	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
532
3
	    X509_get_issuer_name(x509)))
533
		return 0;
534
535
3
	ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
536
3
	if (!(p7i->issuer_and_serial->serial =
537
3
	    ASN1_STRING_dup(X509_get_serialNumber(x509))))
538
		return 0;
539
540
3
	pkey = X509_get_pubkey(x509);
541
542

9
	if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) {
543
		PKCS7error(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
544
		goto err;
545
	}
546
547
3
	ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
548
3
	    0, p7i);
549
3
	if (ret == -2) {
550
		PKCS7error(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
551
		goto err;
552
	}
553
3
	if (ret <= 0) {
554
		PKCS7error(PKCS7_R_ENCRYPTION_CTRL_FAILURE);
555
		goto err;
556
	}
557
558
3
	EVP_PKEY_free(pkey);
559
560
3
	CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
561
3
	p7i->cert = x509;
562
563
3
	return 1;
564
565
err:
566
	EVP_PKEY_free(pkey);
567
	return 0;
568
3
}
569
570
X509 *
571
PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
572
{
573
	if (PKCS7_type_is_signed(p7))
574
		return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
575
		    si->issuer_and_serial->issuer,
576
		    si->issuer_and_serial->serial));
577
	else
578
		return (NULL);
579
}
580
581
int
582
PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
583
{
584
	int i;
585
	PKCS7_ENC_CONTENT *ec;
586
587
6
	i = OBJ_obj2nid(p7->type);
588
3
	switch (i) {
589
	case NID_pkcs7_signedAndEnveloped:
590
		ec = p7->d.signed_and_enveloped->enc_data;
591
		break;
592
	case NID_pkcs7_enveloped:
593
3
		ec = p7->d.enveloped->enc_data;
594
3
		break;
595
	default:
596
		PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
597
		return (0);
598
	}
599
600
	/* Check cipher OID exists and has data in it*/
601
3
	i = EVP_CIPHER_type(cipher);
602
3
	if (i == NID_undef) {
603
		PKCS7error(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
604
		return (0);
605
	}
606
607
3
	ec->cipher = cipher;
608
3
	return 1;
609
3
}
610
611
int
612
PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
613
{
614
	ASN1_OCTET_STRING *os = NULL;
615
616
	switch (OBJ_obj2nid(p7->type)) {
617
	case NID_pkcs7_data:
618
		os = p7->d.data;
619
		break;
620
621
	case NID_pkcs7_signedAndEnveloped:
622
		os = p7->d.signed_and_enveloped->enc_data->enc_data;
623
		if (os == NULL) {
624
			os = ASN1_OCTET_STRING_new();
625
			p7->d.signed_and_enveloped->enc_data->enc_data = os;
626
		}
627
		break;
628
629
	case NID_pkcs7_enveloped:
630
		os = p7->d.enveloped->enc_data->enc_data;
631
		if (os == NULL) {
632
			os = ASN1_OCTET_STRING_new();
633
			p7->d.enveloped->enc_data->enc_data = os;
634
		}
635
		break;
636
637
	case NID_pkcs7_signed:
638
		os = p7->d.sign->contents->d.data;
639
		break;
640
641
	default:
642
		os = NULL;
643
		break;
644
	}
645
646
	if (os == NULL)
647
		return 0;
648
649
	os->flags |= ASN1_STRING_FLAG_NDEF;
650
	*boundary = &os->data;
651
652
	return 1;
653
}