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 
     64 long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
     65 	{
     66 	int nid;
     67 	long ret;
     68 
     69 	nid=OBJ_obj2nid(p7->type);
     70 
     71 	switch (cmd)
     72 		{
     73 	case PKCS7_OP_SET_DETACHED_SIGNATURE:
     74 		if (nid == NID_pkcs7_signed)
     75 			{
     76 			ret=p7->detached=(int)larg;
     77 			if (ret && PKCS7_type_is_data(p7->d.sign->contents))
     78 					{
     79 					ASN1_OCTET_STRING *os;
     80 					os=p7->d.sign->contents->d.data;
     81 					ASN1_OCTET_STRING_free(os);
     82 					p7->d.sign->contents->d.data = NULL;
     83 					}
     84 			}
     85 		else
     86 			{
     87 			PKCS7err(PKCS7_F_PKCS7_CTRL,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 			{
     94 			if(!p7->d.sign  || !p7->d.sign->contents->d.ptr)
     95 				ret = 1;
     96 			else ret = 0;
     97 
     98 			p7->detached = ret;
     99 			}
    100 		else
    101 			{
    102 			PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
    103 			ret=0;
    104 			}
    105 
    106 		break;
    107 	default:
    108 		PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_UNKNOWN_OPERATION);
    109 		ret=0;
    110 		}
    111 	return(ret);
    112 	}
    113 
    114 int PKCS7_content_new(PKCS7 *p7, int type)
    115 	{
    116 	PKCS7 *ret=NULL;
    117 
    118 	if ((ret=PKCS7_new()) == NULL) goto err;
    119 	if (!PKCS7_set_type(ret,type)) goto err;
    120 	if (!PKCS7_set_content(p7,ret)) goto err;
    121 
    122 	return(1);
    123 err:
    124 	if (ret != NULL) PKCS7_free(ret);
    125 	return(0);
    126 	}
    127 
    128 int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
    129 	{
    130 	int i;
    131 
    132 	i=OBJ_obj2nid(p7->type);
    133 	switch (i)
    134 		{
    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 	/*PKCS7_content_free(p7);*/
    163 	obj=OBJ_nid2obj(type); /* will not fail */
    164 
    165 	switch (type)
    166 		{
    167 	case NID_pkcs7_signed:
    168 		p7->type=obj;
    169 		if ((p7->d.sign=PKCS7_SIGNED_new()) == NULL)
    170 			goto err;
    171 		if (!ASN1_INTEGER_set(p7->d.sign->version,1))
    172 			{
    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=M_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) goto err;
    187 		ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1);
    188 		if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1))
    189 			goto err;
    190 		p7->d.signed_and_enveloped->enc_data->content_type
    191 						= OBJ_nid2obj(NID_pkcs7_data);
    192 		break;
    193 	case NID_pkcs7_enveloped:
    194 		p7->type=obj;
    195 		if ((p7->d.enveloped=PKCS7_ENVELOPE_new())
    196 			== NULL) goto err;
    197 		if (!ASN1_INTEGER_set(p7->d.enveloped->version,0))
    198 			goto err;
    199 		p7->d.enveloped->enc_data->content_type
    200 						= OBJ_nid2obj(NID_pkcs7_data);
    201 		break;
    202 	case NID_pkcs7_encrypted:
    203 		p7->type=obj;
    204 		if ((p7->d.encrypted=PKCS7_ENCRYPT_new())
    205 			== NULL) goto err;
    206 		if (!ASN1_INTEGER_set(p7->d.encrypted->version,0))
    207 			goto err;
    208 		p7->d.encrypted->enc_data->content_type
    209 						= OBJ_nid2obj(NID_pkcs7_data);
    210 		break;
    211 
    212 	case NID_pkcs7_digest:
    213 		p7->type=obj;
    214 		if ((p7->d.digest=PKCS7_DIGEST_new())
    215 			== NULL) goto err;
    216 		if (!ASN1_INTEGER_set(p7->d.digest->version,0))
    217 			goto err;
    218 		break;
    219 	default:
    220 		PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
    221 		goto err;
    222 		}
    223 	return(1);
    224 err:
    225 	return(0);
    226 	}
    227 
    228 int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
    229 	{
    230 	p7->type = OBJ_nid2obj(type);
    231 	p7->d.other = other;
    232 	return 1;
    233 	}
    234 
    235 int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
    236 	{
    237 	int i,j,nid;
    238 	X509_ALGOR *alg;
    239 	STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
    240 	STACK_OF(X509_ALGOR) *md_sk;
    241 
    242 	i=OBJ_obj2nid(p7->type);
    243 	switch (i)
    244 		{
    245 	case NID_pkcs7_signed:
    246 		signer_sk=	p7->d.sign->signer_info;
    247 		md_sk=		p7->d.sign->md_algs;
    248 		break;
    249 	case NID_pkcs7_signedAndEnveloped:
    250 		signer_sk=	p7->d.signed_and_enveloped->signer_info;
    251 		md_sk=		p7->d.signed_and_enveloped->md_algs;
    252 		break;
    253 	default:
    254 		PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE);
    255 		return(0);
    256 		}
    257 
    258 	nid=OBJ_obj2nid(psi->digest_alg->algorithm);
    259 
    260 	/* If the digest is not currently listed, add it */
    261 	j=0;
    262 	for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
    263 		{
    264 		alg=sk_X509_ALGOR_value(md_sk,i);
    265 		if (OBJ_obj2nid(alg->algorithm) == nid)
    266 			{
    267 			j=1;
    268 			break;
    269 			}
    270 		}
    271 	if (!j) /* we need to add another algorithm */
    272 		{
    273 		if(!(alg=X509_ALGOR_new())
    274 			|| !(alg->parameter = ASN1_TYPE_new()))
    275 			{
    276 			X509_ALGOR_free(alg);
    277 			PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE);
    278 			return(0);
    279 			}
    280 		alg->algorithm=OBJ_nid2obj(nid);
    281 		alg->parameter->type = V_ASN1_NULL;
    282 		if (!sk_X509_ALGOR_push(md_sk,alg))
    283 			{
    284 			X509_ALGOR_free(alg);
    285 			return 0;
    286 			}
    287 		}
    288 
    289 	if (!sk_PKCS7_SIGNER_INFO_push(signer_sk,psi))
    290 		return 0;
    291 	return(1);
    292 	}
    293 
    294 int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
    295 	{
    296 	int i;
    297 	STACK_OF(X509) **sk;
    298 
    299 	i=OBJ_obj2nid(p7->type);
    300 	switch (i)
    301 		{
    302 	case NID_pkcs7_signed:
    303 		sk= &(p7->d.sign->cert);
    304 		break;
    305 	case NID_pkcs7_signedAndEnveloped:
    306 		sk= &(p7->d.signed_and_enveloped->cert);
    307 		break;
    308 	default:
    309 		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,PKCS7_R_WRONG_CONTENT_TYPE);
    310 		return(0);
    311 		}
    312 
    313 	if (*sk == NULL)
    314 		*sk=sk_X509_new_null();
    315 	if (*sk == NULL)
    316 		{
    317 		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,ERR_R_MALLOC_FAILURE);
    318 		return 0;
    319 		}
    320 	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
    321 	if (!sk_X509_push(*sk,x509))
    322 		{
    323 		X509_free(x509);
    324 		return 0;
    325 		}
    326 	return(1);
    327 	}
    328 
    329 int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
    330 	{
    331 	int i;
    332 	STACK_OF(X509_CRL) **sk;
    333 
    334 	i=OBJ_obj2nid(p7->type);
    335 	switch (i)
    336 		{
    337 	case NID_pkcs7_signed:
    338 		sk= &(p7->d.sign->crl);
    339 		break;
    340 	case NID_pkcs7_signedAndEnveloped:
    341 		sk= &(p7->d.signed_and_enveloped->crl);
    342 		break;
    343 	default:
    344 		PKCS7err(PKCS7_F_PKCS7_ADD_CRL,PKCS7_R_WRONG_CONTENT_TYPE);
    345 		return(0);
    346 		}
    347 
    348 	if (*sk == NULL)
    349 		*sk=sk_X509_CRL_new_null();
    350 	if (*sk == NULL)
    351 		{
    352 		PKCS7err(PKCS7_F_PKCS7_ADD_CRL,ERR_R_MALLOC_FAILURE);
    353 		return 0;
    354 		}
    355 
    356 	CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL);
    357 	if (!sk_X509_CRL_push(*sk,crl))
    358 		{
    359 		X509_CRL_free(crl);
    360 		return 0;
    361 		}
    362 	return(1);
    363 	}
    364 
    365 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
    366 	     const EVP_MD *dgst)
    367 	{
    368 	int nid;
    369 	char is_dsa;
    370 
    371 	if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
    372 		is_dsa = 1;
    373 	else
    374 		is_dsa = 0;
    375 	/* We now need to add another PKCS7_SIGNER_INFO entry */
    376 	if (!ASN1_INTEGER_set(p7i->version,1))
    377 		goto err;
    378 	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
    379 			X509_get_issuer_name(x509)))
    380 		goto err;
    381 
    382 	/* because ASN1_INTEGER_set is used to set a 'long' we will do
    383 	 * things the ugly way. */
    384 	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
    385 	if (!(p7i->issuer_and_serial->serial=
    386 			M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
    387 		goto err;
    388 
    389 	/* lets keep the pkey around for a while */
    390 	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
    391 	p7i->pkey=pkey;
    392 
    393 	/* Set the algorithms */
    394 	if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
    395 	else
    396 		p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
    397 
    398 	if (p7i->digest_alg->parameter != NULL)
    399 		ASN1_TYPE_free(p7i->digest_alg->parameter);
    400 	if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
    401 		goto err;
    402 	p7i->digest_alg->parameter->type=V_ASN1_NULL;
    403 
    404 	if (p7i->digest_enc_alg->parameter != NULL)
    405 		ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
    406 	nid = EVP_PKEY_type(pkey->type);
    407 	if (nid == EVP_PKEY_RSA)
    408 		{
    409 		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption);
    410 		if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
    411 			goto err;
    412 		p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
    413 		}
    414 	else if (nid == EVP_PKEY_DSA)
    415 		{
    416 #if 1
    417 		/* use 'dsaEncryption' OID for compatibility with other software
    418 		 * (PKCS #7 v1.5 does specify how to handle DSA) ... */
    419 		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa);
    420 #else
    421 		/* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS)
    422 		 * would make more sense. */
    423 		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1);
    424 #endif
    425 		p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */
    426 		}
    427 	else if (nid == EVP_PKEY_EC)
    428 		{
    429 		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1);
    430 		if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
    431 			goto err;
    432 		p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
    433 		}
    434 	else
    435 		return(0);
    436 
    437 	return(1);
    438 err:
    439 	return(0);
    440 	}
    441 
    442 PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
    443 	     const EVP_MD *dgst)
    444 	{
    445 	PKCS7_SIGNER_INFO *si;
    446 
    447 	if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
    448 	if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
    449 	if (!PKCS7_add_signer(p7,si)) goto err;
    450 	return(si);
    451 err:
    452 	PKCS7_SIGNER_INFO_free(si);
    453 	return(NULL);
    454 	}
    455 
    456 int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
    457 	{
    458 	if (PKCS7_type_is_digest(p7))
    459 		{
    460 		if(!(p7->d.digest->md->parameter = ASN1_TYPE_new()))
    461 			{
    462 			PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,ERR_R_MALLOC_FAILURE);
    463 			return 0;
    464 			}
    465 		p7->d.digest->md->parameter->type = V_ASN1_NULL;
    466 		p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
    467 		return 1;
    468 		}
    469 
    470 	PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,PKCS7_R_WRONG_CONTENT_TYPE);
    471 	return 1;
    472 	}
    473 
    474 STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
    475 	{
    476 	if (PKCS7_type_is_signed(p7))
    477 		{
    478 		return(p7->d.sign->signer_info);
    479 		}
    480 	else if (PKCS7_type_is_signedAndEnveloped(p7))
    481 		{
    482 		return(p7->d.signed_and_enveloped->signer_info);
    483 		}
    484 	else
    485 		return(NULL);
    486 	}
    487 
    488 PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
    489 	{
    490 	PKCS7_RECIP_INFO *ri;
    491 
    492 	if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
    493 	if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
    494 	if (!PKCS7_add_recipient_info(p7,ri)) goto err;
    495 	return(ri);
    496 err:
    497 	PKCS7_RECIP_INFO_free(ri);
    498 	return(NULL);
    499 	}
    500 
    501 int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
    502 	{
    503 	int i;
    504 	STACK_OF(PKCS7_RECIP_INFO) *sk;
    505 
    506 	i=OBJ_obj2nid(p7->type);
    507 	switch (i)
    508 		{
    509 	case NID_pkcs7_signedAndEnveloped:
    510 		sk=	p7->d.signed_and_enveloped->recipientinfo;
    511 		break;
    512 	case NID_pkcs7_enveloped:
    513 		sk=	p7->d.enveloped->recipientinfo;
    514 		break;
    515 	default:
    516 		PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,PKCS7_R_WRONG_CONTENT_TYPE);
    517 		return(0);
    518 		}
    519 
    520 	if (!sk_PKCS7_RECIP_INFO_push(sk,ri))
    521 		return 0;
    522 	return(1);
    523 	}
    524 
    525 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
    526 	{
    527 	if (!ASN1_INTEGER_set(p7i->version,0))
    528 		return 0;
    529 	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
    530 		X509_get_issuer_name(x509)))
    531 		return 0;
    532 
    533 	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
    534 	if (!(p7i->issuer_and_serial->serial=
    535 		M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
    536 		return 0;
    537 
    538 	X509_ALGOR_free(p7i->key_enc_algor);
    539 	if (!(p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor)))
    540 		return 0;
    541 
    542 	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
    543 	p7i->cert=x509;
    544 
    545 	return(1);
    546 	}
    547 
    548 X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
    549 	{
    550 	if (PKCS7_type_is_signed(p7))
    551 		return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
    552 			si->issuer_and_serial->issuer,
    553 			si->issuer_and_serial->serial));
    554 	else
    555 		return(NULL);
    556 	}
    557 
    558 int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
    559 	{
    560 	int i;
    561 	ASN1_OBJECT *objtmp;
    562 	PKCS7_ENC_CONTENT *ec;
    563 
    564 	i=OBJ_obj2nid(p7->type);
    565 	switch (i)
    566 		{
    567 	case NID_pkcs7_signedAndEnveloped:
    568 		ec=p7->d.signed_and_enveloped->enc_data;
    569 		break;
    570 	case NID_pkcs7_enveloped:
    571 		ec=p7->d.enveloped->enc_data;
    572 		break;
    573 	default:
    574 		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_WRONG_CONTENT_TYPE);
    575 		return(0);
    576 		}
    577 
    578 	/* Check cipher OID exists and has data in it*/
    579 	i = EVP_CIPHER_type(cipher);
    580 	if(i == NID_undef) {
    581 		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
    582 		return(0);
    583 	}
    584 	objtmp = OBJ_nid2obj(i);
    585 
    586 	ec->cipher = cipher;
    587 	return 1;
    588 	}
    589 
    590