GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/pkcs7/pk7_lib.c Lines: 142 325 43.7 %
Date: 2016-12-06 Branches: 68 189 36.0 %

Line Branch Exec Source
1
/* $OpenBSD: pk7_lib.c,v 1.18 2015/09/30 18:41:06 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
12
{
70
	int nid;
71
	long ret;
72
73
12
	nid = OBJ_obj2nid(p7->type);
74
75
12
	switch (cmd) {
76
	case PKCS7_OP_SET_DETACHED_SIGNATURE:
77
1
		if (nid == NID_pkcs7_signed) {
78
1
			ret = p7->detached = (int)larg;
79

1
			if (ret && PKCS7_type_is_data(p7->d.sign->contents)) {
80
				ASN1_OCTET_STRING *os;
81
1
				os = p7->d.sign->contents->d.data;
82
1
				ASN1_OCTET_STRING_free(os);
83
1
				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
11
		if (nid == NID_pkcs7_signed) {
93

16
			if (!p7->d.sign  || !p7->d.sign->contents->d.ptr)
94
5
				ret = 1;
95
			else
96
6
				ret = 0;
97
98
11
			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
12
	return (ret);
111
}
112
113
int
114
PKCS7_content_new(PKCS7 *p7, int type)
115
2
{
116
2
	PKCS7 *ret = NULL;
117
118
2
	if ((ret = PKCS7_new()) == NULL)
119
		goto err;
120
2
	if (!PKCS7_set_type(ret, type))
121
		goto err;
122
2
	if (!PKCS7_set_content(p7, ret))
123
		goto err;
124
125
2
	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
2
{
135
	int i;
136
137
2
	i = OBJ_obj2nid(p7->type);
138
2
	switch (i) {
139
	case NID_pkcs7_signed:
140
2
		if (p7->d.sign->contents != NULL)
141
2
			PKCS7_free(p7->d.sign->contents);
142
2
		p7->d.sign->contents = p7_data;
143
2
		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
2
	return (1);
159
err:
160
	return (0);
161
}
162
163
int
164
PKCS7_set_type(PKCS7 *p7, int type)
165
5
{
166
	ASN1_OBJECT *obj;
167
168
	/*PKCS7_content_free(p7);*/
169
5
	obj=OBJ_nid2obj(type); /* will not fail */
170
171

5
	switch (type) {
172
	case NID_pkcs7_signed:
173
2
		p7->type = obj;
174
2
		if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
175
			goto err;
176
2
		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
2
		p7->type = obj;
184
2
		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
1
		p7->type = obj;
200
1
		if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) == NULL)
201
			goto err;
202
1
		if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
203
			goto err;
204
1
		p7->d.enveloped->enc_data->content_type =
205
		    OBJ_nid2obj(NID_pkcs7_data);
206
1
		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
5
	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
2
{
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
2
	i = OBJ_obj2nid(p7->type);
251
2
	switch (i) {
252
	case NID_pkcs7_signed:
253
2
		signer_sk = p7->d.sign->signer_info;
254
2
		md_sk = p7->d.sign->md_algs;
255
2
		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
2
	nid = OBJ_obj2nid(psi->digest_alg->algorithm);
266
267
	/* If the digest is not currently listed, add it */
268
2
	j = 0;
269
2
	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
2
	if (!j) /* we need to add another algorithm */
277
	{
278

2
		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
2
		alg->algorithm = OBJ_nid2obj(nid);
286
2
		alg->parameter->type = V_ASN1_NULL;
287
2
		if (!sk_X509_ALGOR_push(md_sk, alg)) {
288
			X509_ALGOR_free(alg);
289
			return 0;
290
		}
291
	}
292
293
2
	if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
294
		return 0;
295
2
	return (1);
296
}
297
298
int
299
PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
300
3
{
301
	int i;
302
	STACK_OF(X509) **sk;
303
304
3
	i = OBJ_obj2nid(p7->type);
305
3
	switch (i) {
306
	case NID_pkcs7_signed:
307
3
		sk = &(p7->d.sign->cert);
308
3
		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
3
	if (*sk == NULL)
319
2
		*sk = sk_X509_new_null();
320
3
	if (*sk == NULL) {
321
		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
322
		return 0;
323
	}
324
3
	CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
325
3
	if (!sk_X509_push(*sk, x509)) {
326
		X509_free(x509);
327
		return 0;
328
	}
329
3
	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
2
{
370
	int ret;
371
372
	/* We now need to add another PKCS7_SIGNER_INFO entry */
373
2
	if (!ASN1_INTEGER_set(p7i->version, 1))
374
		goto err;
375
2
	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
2
	ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
382
2
	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
2
	CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
388
2
	p7i->pkey = pkey;
389
390
	/* Set the algorithms */
391
392
2
	X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
393
	    V_ASN1_NULL, NULL);
394
395

2
	if (pkey->ameth && pkey->ameth->pkey_ctrl) {
396
2
		ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
397
		    0, p7i);
398
2
		if (ret > 0)
399
2
			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
2
{
415
2
	PKCS7_SIGNER_INFO *si = NULL;
416
417
2
	if (dgst == NULL) {
418
		int def_nid;
419
2
		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
420
			goto err;
421
2
		dgst = EVP_get_digestbynid(def_nid);
422
2
		if (dgst == NULL) {
423
			PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE,
424
			    PKCS7_R_NO_DEFAULT_DIGEST);
425
			goto err;
426
		}
427
	}
428
429
2
	if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
430
		goto err;
431
2
	if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst))
432
		goto err;
433
2
	if (!PKCS7_add_signer(p7, si))
434
		goto err;
435
2
	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
4
{
463

4
	if (p7 == NULL || p7->d.ptr == NULL)
464
		return (NULL);
465
4
	if (PKCS7_type_is_signed(p7)) {
466
4
		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
2
{
477
2
	if (pk)
478
		*pk = si->pkey;
479
2
	if (pdig)
480
		*pdig = si->digest_alg;
481
2
	if (psig)
482
2
		*psig = si->digest_enc_alg;
483
2
}
484
485
void
486
PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
487
1
{
488
1
	if (penc)
489
1
		*penc = ri->key_enc_algor;
490
1
}
491
492
PKCS7_RECIP_INFO *
493
PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
494
1
{
495
	PKCS7_RECIP_INFO *ri;
496
497
1
	if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
498
		goto err;
499
1
	if (!PKCS7_RECIP_INFO_set(ri, x509))
500
		goto err;
501
1
	if (!PKCS7_add_recipient_info(p7, ri))
502
		goto err;
503
1
	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
1
{
513
	int i;
514
	STACK_OF(PKCS7_RECIP_INFO) *sk;
515
516
1
	i = OBJ_obj2nid(p7->type);
517
1
	switch (i) {
518
	case NID_pkcs7_signedAndEnveloped:
519
		sk = p7->d.signed_and_enveloped->recipientinfo;
520
		break;
521
	case NID_pkcs7_enveloped:
522
1
		sk = p7->d.enveloped->recipientinfo;
523
1
		break;
524
	default:
525
		PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,
526
		    PKCS7_R_WRONG_CONTENT_TYPE);
527
		return (0);
528
	}
529
530
1
	if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
531
		return 0;
532
1
	return (1);
533
}
534
535
int
536
PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
537
1
{
538
	int ret;
539
1
	EVP_PKEY *pkey = NULL;
540
1
	if (!ASN1_INTEGER_set(p7i->version, 0))
541
		return 0;
542
1
	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
543
	    X509_get_issuer_name(x509)))
544
		return 0;
545
546
1
	ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
547
1
	if (!(p7i->issuer_and_serial->serial =
548
	    ASN1_STRING_dup(X509_get_serialNumber(x509))))
549
		return 0;
550
551
1
	pkey = X509_get_pubkey(x509);
552
553

1
	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
1
	ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
560
	    0, p7i);
561
1
	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
1
	if (ret <= 0) {
567
		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
568
		    PKCS7_R_ENCRYPTION_CTRL_FAILURE);
569
		goto err;
570
	}
571
572
1
	EVP_PKEY_free(pkey);
573
574
1
	CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
575
1
	p7i->cert = x509;
576
577
1
	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
1
{
598
	int i;
599
	PKCS7_ENC_CONTENT *ec;
600
601
1
	i = OBJ_obj2nid(p7->type);
602
1
	switch (i) {
603
	case NID_pkcs7_signedAndEnveloped:
604
		ec = p7->d.signed_and_enveloped->enc_data;
605
		break;
606
	case NID_pkcs7_enveloped:
607
1
		ec = p7->d.enveloped->enc_data;
608
1
		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
1
	i = EVP_CIPHER_type(cipher);
616
1
	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
1
	ec->cipher = cipher;
623
1
	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
}