os/ossrv/ssl/libcrypto/src/crypto/pkcs7/pk7_lib.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /* crypto/pkcs7/pk7_lib.c */
     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 #include "cryptlib.h"
    61 #include <openssl/objects.h>
    62 #include <openssl/x509.h>
    63 
    64 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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