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