xref: /onnv-gate/usr/src/common/openssl/crypto/pkcs7/pk7_lib.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/pkcs7/pk7_lib.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include "cryptlib.h"
610Sstevel@tonic-gate #include <openssl/objects.h>
620Sstevel@tonic-gate #include <openssl/x509.h>
630Sstevel@tonic-gate 
PKCS7_ctrl(PKCS7 * p7,int cmd,long larg,char * parg)640Sstevel@tonic-gate long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
650Sstevel@tonic-gate 	{
660Sstevel@tonic-gate 	int nid;
670Sstevel@tonic-gate 	long ret;
680Sstevel@tonic-gate 
690Sstevel@tonic-gate 	nid=OBJ_obj2nid(p7->type);
700Sstevel@tonic-gate 
710Sstevel@tonic-gate 	switch (cmd)
720Sstevel@tonic-gate 		{
730Sstevel@tonic-gate 	case PKCS7_OP_SET_DETACHED_SIGNATURE:
740Sstevel@tonic-gate 		if (nid == NID_pkcs7_signed)
750Sstevel@tonic-gate 			{
760Sstevel@tonic-gate 			ret=p7->detached=(int)larg;
770Sstevel@tonic-gate 			if (ret && PKCS7_type_is_data(p7->d.sign->contents))
780Sstevel@tonic-gate 					{
790Sstevel@tonic-gate 					ASN1_OCTET_STRING *os;
800Sstevel@tonic-gate 					os=p7->d.sign->contents->d.data;
810Sstevel@tonic-gate 					ASN1_OCTET_STRING_free(os);
820Sstevel@tonic-gate 					p7->d.sign->contents->d.data = NULL;
830Sstevel@tonic-gate 					}
840Sstevel@tonic-gate 			}
850Sstevel@tonic-gate 		else
860Sstevel@tonic-gate 			{
870Sstevel@tonic-gate 			PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
880Sstevel@tonic-gate 			ret=0;
890Sstevel@tonic-gate 			}
900Sstevel@tonic-gate 		break;
910Sstevel@tonic-gate 	case PKCS7_OP_GET_DETACHED_SIGNATURE:
920Sstevel@tonic-gate 		if (nid == NID_pkcs7_signed)
930Sstevel@tonic-gate 			{
940Sstevel@tonic-gate 			if(!p7->d.sign  || !p7->d.sign->contents->d.ptr)
950Sstevel@tonic-gate 				ret = 1;
960Sstevel@tonic-gate 			else ret = 0;
970Sstevel@tonic-gate 
980Sstevel@tonic-gate 			p7->detached = ret;
990Sstevel@tonic-gate 			}
1000Sstevel@tonic-gate 		else
1010Sstevel@tonic-gate 			{
1020Sstevel@tonic-gate 			PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
1030Sstevel@tonic-gate 			ret=0;
1040Sstevel@tonic-gate 			}
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 		break;
1070Sstevel@tonic-gate 	default:
1080Sstevel@tonic-gate 		PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_UNKNOWN_OPERATION);
1090Sstevel@tonic-gate 		ret=0;
1100Sstevel@tonic-gate 		}
1110Sstevel@tonic-gate 	return(ret);
1120Sstevel@tonic-gate 	}
1130Sstevel@tonic-gate 
PKCS7_content_new(PKCS7 * p7,int type)1140Sstevel@tonic-gate int PKCS7_content_new(PKCS7 *p7, int type)
1150Sstevel@tonic-gate 	{
1160Sstevel@tonic-gate 	PKCS7 *ret=NULL;
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate 	if ((ret=PKCS7_new()) == NULL) goto err;
1190Sstevel@tonic-gate 	if (!PKCS7_set_type(ret,type)) goto err;
1200Sstevel@tonic-gate 	if (!PKCS7_set_content(p7,ret)) goto err;
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate 	return(1);
1230Sstevel@tonic-gate err:
1240Sstevel@tonic-gate 	if (ret != NULL) PKCS7_free(ret);
1250Sstevel@tonic-gate 	return(0);
1260Sstevel@tonic-gate 	}
1270Sstevel@tonic-gate 
PKCS7_set_content(PKCS7 * p7,PKCS7 * p7_data)1280Sstevel@tonic-gate int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
1290Sstevel@tonic-gate 	{
1300Sstevel@tonic-gate 	int i;
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	i=OBJ_obj2nid(p7->type);
1330Sstevel@tonic-gate 	switch (i)
1340Sstevel@tonic-gate 		{
1350Sstevel@tonic-gate 	case NID_pkcs7_signed:
1360Sstevel@tonic-gate 		if (p7->d.sign->contents != NULL)
1370Sstevel@tonic-gate 			PKCS7_free(p7->d.sign->contents);
1380Sstevel@tonic-gate 		p7->d.sign->contents=p7_data;
1390Sstevel@tonic-gate 		break;
1400Sstevel@tonic-gate 	case NID_pkcs7_digest:
141*2139Sjp161948 		if (p7->d.digest->contents != NULL)
142*2139Sjp161948 			PKCS7_free(p7->d.digest->contents);
143*2139Sjp161948 		p7->d.digest->contents=p7_data;
144*2139Sjp161948 		break;
1450Sstevel@tonic-gate 	case NID_pkcs7_data:
1460Sstevel@tonic-gate 	case NID_pkcs7_enveloped:
1470Sstevel@tonic-gate 	case NID_pkcs7_signedAndEnveloped:
1480Sstevel@tonic-gate 	case NID_pkcs7_encrypted:
1490Sstevel@tonic-gate 	default:
1500Sstevel@tonic-gate 		PKCS7err(PKCS7_F_PKCS7_SET_CONTENT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
1510Sstevel@tonic-gate 		goto err;
1520Sstevel@tonic-gate 		}
1530Sstevel@tonic-gate 	return(1);
1540Sstevel@tonic-gate err:
1550Sstevel@tonic-gate 	return(0);
1560Sstevel@tonic-gate 	}
1570Sstevel@tonic-gate 
PKCS7_set_type(PKCS7 * p7,int type)1580Sstevel@tonic-gate int PKCS7_set_type(PKCS7 *p7, int type)
1590Sstevel@tonic-gate 	{
1600Sstevel@tonic-gate 	ASN1_OBJECT *obj;
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 	/*PKCS7_content_free(p7);*/
1630Sstevel@tonic-gate 	obj=OBJ_nid2obj(type); /* will not fail */
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	switch (type)
1660Sstevel@tonic-gate 		{
1670Sstevel@tonic-gate 	case NID_pkcs7_signed:
1680Sstevel@tonic-gate 		p7->type=obj;
1690Sstevel@tonic-gate 		if ((p7->d.sign=PKCS7_SIGNED_new()) == NULL)
1700Sstevel@tonic-gate 			goto err;
171*2139Sjp161948 		if (!ASN1_INTEGER_set(p7->d.sign->version,1))
172*2139Sjp161948 			{
173*2139Sjp161948 			PKCS7_SIGNED_free(p7->d.sign);
174*2139Sjp161948 			p7->d.sign=NULL;
175*2139Sjp161948 			goto err;
176*2139Sjp161948 			}
1770Sstevel@tonic-gate 		break;
1780Sstevel@tonic-gate 	case NID_pkcs7_data:
1790Sstevel@tonic-gate 		p7->type=obj;
1800Sstevel@tonic-gate 		if ((p7->d.data=M_ASN1_OCTET_STRING_new()) == NULL)
1810Sstevel@tonic-gate 			goto err;
1820Sstevel@tonic-gate 		break;
1830Sstevel@tonic-gate 	case NID_pkcs7_signedAndEnveloped:
1840Sstevel@tonic-gate 		p7->type=obj;
1850Sstevel@tonic-gate 		if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new())
1860Sstevel@tonic-gate 			== NULL) goto err;
1870Sstevel@tonic-gate 		ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1);
188*2139Sjp161948 		if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1))
189*2139Sjp161948 			goto err;
1900Sstevel@tonic-gate 		p7->d.signed_and_enveloped->enc_data->content_type
1910Sstevel@tonic-gate 						= OBJ_nid2obj(NID_pkcs7_data);
1920Sstevel@tonic-gate 		break;
1930Sstevel@tonic-gate 	case NID_pkcs7_enveloped:
1940Sstevel@tonic-gate 		p7->type=obj;
1950Sstevel@tonic-gate 		if ((p7->d.enveloped=PKCS7_ENVELOPE_new())
1960Sstevel@tonic-gate 			== NULL) goto err;
197*2139Sjp161948 		if (!ASN1_INTEGER_set(p7->d.enveloped->version,0))
198*2139Sjp161948 			goto err;
1990Sstevel@tonic-gate 		p7->d.enveloped->enc_data->content_type
2000Sstevel@tonic-gate 						= OBJ_nid2obj(NID_pkcs7_data);
2010Sstevel@tonic-gate 		break;
2020Sstevel@tonic-gate 	case NID_pkcs7_encrypted:
2030Sstevel@tonic-gate 		p7->type=obj;
2040Sstevel@tonic-gate 		if ((p7->d.encrypted=PKCS7_ENCRYPT_new())
2050Sstevel@tonic-gate 			== NULL) goto err;
206*2139Sjp161948 		if (!ASN1_INTEGER_set(p7->d.encrypted->version,0))
207*2139Sjp161948 			goto err;
2080Sstevel@tonic-gate 		p7->d.encrypted->enc_data->content_type
2090Sstevel@tonic-gate 						= OBJ_nid2obj(NID_pkcs7_data);
2100Sstevel@tonic-gate 		break;
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 	case NID_pkcs7_digest:
213*2139Sjp161948 		p7->type=obj;
214*2139Sjp161948 		if ((p7->d.digest=PKCS7_DIGEST_new())
215*2139Sjp161948 			== NULL) goto err;
216*2139Sjp161948 		if (!ASN1_INTEGER_set(p7->d.digest->version,0))
217*2139Sjp161948 			goto err;
218*2139Sjp161948 		break;
2190Sstevel@tonic-gate 	default:
2200Sstevel@tonic-gate 		PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
2210Sstevel@tonic-gate 		goto err;
2220Sstevel@tonic-gate 		}
2230Sstevel@tonic-gate 	return(1);
2240Sstevel@tonic-gate err:
2250Sstevel@tonic-gate 	return(0);
2260Sstevel@tonic-gate 	}
2270Sstevel@tonic-gate 
PKCS7_set0_type_other(PKCS7 * p7,int type,ASN1_TYPE * other)228*2139Sjp161948 int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
229*2139Sjp161948 	{
230*2139Sjp161948 	p7->type = OBJ_nid2obj(type);
231*2139Sjp161948 	p7->d.other = other;
232*2139Sjp161948 	return 1;
233*2139Sjp161948 	}
234*2139Sjp161948 
PKCS7_add_signer(PKCS7 * p7,PKCS7_SIGNER_INFO * psi)2350Sstevel@tonic-gate int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
2360Sstevel@tonic-gate 	{
2370Sstevel@tonic-gate 	int i,j,nid;
2380Sstevel@tonic-gate 	X509_ALGOR *alg;
2390Sstevel@tonic-gate 	STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
2400Sstevel@tonic-gate 	STACK_OF(X509_ALGOR) *md_sk;
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 	i=OBJ_obj2nid(p7->type);
2430Sstevel@tonic-gate 	switch (i)
2440Sstevel@tonic-gate 		{
2450Sstevel@tonic-gate 	case NID_pkcs7_signed:
2460Sstevel@tonic-gate 		signer_sk=	p7->d.sign->signer_info;
2470Sstevel@tonic-gate 		md_sk=		p7->d.sign->md_algs;
2480Sstevel@tonic-gate 		break;
2490Sstevel@tonic-gate 	case NID_pkcs7_signedAndEnveloped:
2500Sstevel@tonic-gate 		signer_sk=	p7->d.signed_and_enveloped->signer_info;
2510Sstevel@tonic-gate 		md_sk=		p7->d.signed_and_enveloped->md_algs;
2520Sstevel@tonic-gate 		break;
2530Sstevel@tonic-gate 	default:
2540Sstevel@tonic-gate 		PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE);
2550Sstevel@tonic-gate 		return(0);
2560Sstevel@tonic-gate 		}
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate 	nid=OBJ_obj2nid(psi->digest_alg->algorithm);
2590Sstevel@tonic-gate 
2600Sstevel@tonic-gate 	/* If the digest is not currently listed, add it */
2610Sstevel@tonic-gate 	j=0;
2620Sstevel@tonic-gate 	for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
2630Sstevel@tonic-gate 		{
2640Sstevel@tonic-gate 		alg=sk_X509_ALGOR_value(md_sk,i);
2650Sstevel@tonic-gate 		if (OBJ_obj2nid(alg->algorithm) == nid)
2660Sstevel@tonic-gate 			{
2670Sstevel@tonic-gate 			j=1;
2680Sstevel@tonic-gate 			break;
2690Sstevel@tonic-gate 			}
2700Sstevel@tonic-gate 		}
2710Sstevel@tonic-gate 	if (!j) /* we need to add another algorithm */
2720Sstevel@tonic-gate 		{
2730Sstevel@tonic-gate 		if(!(alg=X509_ALGOR_new())
2740Sstevel@tonic-gate 			|| !(alg->parameter = ASN1_TYPE_new())) {
2750Sstevel@tonic-gate 			PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE);
2760Sstevel@tonic-gate 			return(0);
2770Sstevel@tonic-gate 		}
2780Sstevel@tonic-gate 		alg->algorithm=OBJ_nid2obj(nid);
2790Sstevel@tonic-gate 		alg->parameter->type = V_ASN1_NULL;
2800Sstevel@tonic-gate 		sk_X509_ALGOR_push(md_sk,alg);
2810Sstevel@tonic-gate 		}
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate 	sk_PKCS7_SIGNER_INFO_push(signer_sk,psi);
2840Sstevel@tonic-gate 	return(1);
2850Sstevel@tonic-gate 	}
2860Sstevel@tonic-gate 
PKCS7_add_certificate(PKCS7 * p7,X509 * x509)2870Sstevel@tonic-gate int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
2880Sstevel@tonic-gate 	{
2890Sstevel@tonic-gate 	int i;
2900Sstevel@tonic-gate 	STACK_OF(X509) **sk;
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate 	i=OBJ_obj2nid(p7->type);
2930Sstevel@tonic-gate 	switch (i)
2940Sstevel@tonic-gate 		{
2950Sstevel@tonic-gate 	case NID_pkcs7_signed:
2960Sstevel@tonic-gate 		sk= &(p7->d.sign->cert);
2970Sstevel@tonic-gate 		break;
2980Sstevel@tonic-gate 	case NID_pkcs7_signedAndEnveloped:
2990Sstevel@tonic-gate 		sk= &(p7->d.signed_and_enveloped->cert);
3000Sstevel@tonic-gate 		break;
3010Sstevel@tonic-gate 	default:
3020Sstevel@tonic-gate 		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,PKCS7_R_WRONG_CONTENT_TYPE);
3030Sstevel@tonic-gate 		return(0);
3040Sstevel@tonic-gate 		}
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate 	if (*sk == NULL)
3070Sstevel@tonic-gate 		*sk=sk_X509_new_null();
3080Sstevel@tonic-gate 	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
3090Sstevel@tonic-gate 	sk_X509_push(*sk,x509);
3100Sstevel@tonic-gate 	return(1);
3110Sstevel@tonic-gate 	}
3120Sstevel@tonic-gate 
PKCS7_add_crl(PKCS7 * p7,X509_CRL * crl)3130Sstevel@tonic-gate int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
3140Sstevel@tonic-gate 	{
3150Sstevel@tonic-gate 	int i;
3160Sstevel@tonic-gate 	STACK_OF(X509_CRL) **sk;
3170Sstevel@tonic-gate 
3180Sstevel@tonic-gate 	i=OBJ_obj2nid(p7->type);
3190Sstevel@tonic-gate 	switch (i)
3200Sstevel@tonic-gate 		{
3210Sstevel@tonic-gate 	case NID_pkcs7_signed:
3220Sstevel@tonic-gate 		sk= &(p7->d.sign->crl);
3230Sstevel@tonic-gate 		break;
3240Sstevel@tonic-gate 	case NID_pkcs7_signedAndEnveloped:
3250Sstevel@tonic-gate 		sk= &(p7->d.signed_and_enveloped->crl);
3260Sstevel@tonic-gate 		break;
3270Sstevel@tonic-gate 	default:
3280Sstevel@tonic-gate 		PKCS7err(PKCS7_F_PKCS7_ADD_CRL,PKCS7_R_WRONG_CONTENT_TYPE);
3290Sstevel@tonic-gate 		return(0);
3300Sstevel@tonic-gate 		}
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 	if (*sk == NULL)
3330Sstevel@tonic-gate 		*sk=sk_X509_CRL_new_null();
3340Sstevel@tonic-gate 
3350Sstevel@tonic-gate 	CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL);
3360Sstevel@tonic-gate 	sk_X509_CRL_push(*sk,crl);
3370Sstevel@tonic-gate 	return(1);
3380Sstevel@tonic-gate 	}
3390Sstevel@tonic-gate 
PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO * p7i,X509 * x509,EVP_PKEY * pkey,const EVP_MD * dgst)3400Sstevel@tonic-gate int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
3410Sstevel@tonic-gate 	     const EVP_MD *dgst)
3420Sstevel@tonic-gate 	{
343*2139Sjp161948 	int nid;
3440Sstevel@tonic-gate 	char is_dsa;
345*2139Sjp161948 
346*2139Sjp161948 	if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
347*2139Sjp161948 		is_dsa = 1;
348*2139Sjp161948 	else
349*2139Sjp161948 		is_dsa = 0;
3500Sstevel@tonic-gate 	/* We now need to add another PKCS7_SIGNER_INFO entry */
351*2139Sjp161948 	if (!ASN1_INTEGER_set(p7i->version,1))
352*2139Sjp161948 		goto err;
353*2139Sjp161948 	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
354*2139Sjp161948 			X509_get_issuer_name(x509)))
355*2139Sjp161948 		goto err;
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 	/* because ASN1_INTEGER_set is used to set a 'long' we will do
3580Sstevel@tonic-gate 	 * things the ugly way. */
3590Sstevel@tonic-gate 	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
360*2139Sjp161948 	if (!(p7i->issuer_and_serial->serial=
361*2139Sjp161948 			M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
362*2139Sjp161948 		goto err;
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 	/* lets keep the pkey around for a while */
3650Sstevel@tonic-gate 	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
3660Sstevel@tonic-gate 	p7i->pkey=pkey;
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate 	/* Set the algorithms */
3690Sstevel@tonic-gate 	if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
3700Sstevel@tonic-gate 	else
3710Sstevel@tonic-gate 		p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 	if (p7i->digest_alg->parameter != NULL)
3740Sstevel@tonic-gate 		ASN1_TYPE_free(p7i->digest_alg->parameter);
3750Sstevel@tonic-gate 	if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
3760Sstevel@tonic-gate 		goto err;
3770Sstevel@tonic-gate 	p7i->digest_alg->parameter->type=V_ASN1_NULL;
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate 	if (p7i->digest_enc_alg->parameter != NULL)
3800Sstevel@tonic-gate 		ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
381*2139Sjp161948 	nid = EVP_PKEY_type(pkey->type);
382*2139Sjp161948 	if (nid == EVP_PKEY_RSA)
383*2139Sjp161948 		{
384*2139Sjp161948 		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption);
3850Sstevel@tonic-gate 		if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
3860Sstevel@tonic-gate 			goto err;
3870Sstevel@tonic-gate 		p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
388*2139Sjp161948 		}
389*2139Sjp161948 	else if (nid == EVP_PKEY_DSA)
390*2139Sjp161948 		{
391*2139Sjp161948 #if 1
392*2139Sjp161948 		/* use 'dsaEncryption' OID for compatibility with other software
393*2139Sjp161948 		 * (PKCS #7 v1.5 does specify how to handle DSA) ... */
394*2139Sjp161948 		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa);
395*2139Sjp161948 #else
396*2139Sjp161948 		/* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS)
397*2139Sjp161948 		 * would make more sense. */
398*2139Sjp161948 		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1);
399*2139Sjp161948 #endif
400*2139Sjp161948 		p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */
401*2139Sjp161948 		}
402*2139Sjp161948 	else if (nid == EVP_PKEY_EC)
403*2139Sjp161948 		{
404*2139Sjp161948 		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1);
405*2139Sjp161948 		if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
406*2139Sjp161948 			goto err;
407*2139Sjp161948 		p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
408*2139Sjp161948 		}
409*2139Sjp161948 	else
410*2139Sjp161948 		return(0);
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate 	return(1);
4130Sstevel@tonic-gate err:
4140Sstevel@tonic-gate 	return(0);
4150Sstevel@tonic-gate 	}
4160Sstevel@tonic-gate 
PKCS7_add_signature(PKCS7 * p7,X509 * x509,EVP_PKEY * pkey,const EVP_MD * dgst)4170Sstevel@tonic-gate PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
4180Sstevel@tonic-gate 	     const EVP_MD *dgst)
4190Sstevel@tonic-gate 	{
4200Sstevel@tonic-gate 	PKCS7_SIGNER_INFO *si;
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 	if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
4230Sstevel@tonic-gate 	if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
4240Sstevel@tonic-gate 	if (!PKCS7_add_signer(p7,si)) goto err;
4250Sstevel@tonic-gate 	return(si);
4260Sstevel@tonic-gate err:
4270Sstevel@tonic-gate 	return(NULL);
4280Sstevel@tonic-gate 	}
4290Sstevel@tonic-gate 
PKCS7_set_digest(PKCS7 * p7,const EVP_MD * md)430*2139Sjp161948 int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
431*2139Sjp161948 	{
432*2139Sjp161948 	if (PKCS7_type_is_digest(p7))
433*2139Sjp161948 		{
434*2139Sjp161948 		if(!(p7->d.digest->md->parameter = ASN1_TYPE_new()))
435*2139Sjp161948 			{
436*2139Sjp161948 			PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,ERR_R_MALLOC_FAILURE);
437*2139Sjp161948 			return 0;
438*2139Sjp161948 			}
439*2139Sjp161948 		p7->d.digest->md->parameter->type = V_ASN1_NULL;
440*2139Sjp161948 		p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
441*2139Sjp161948 		return 1;
442*2139Sjp161948 		}
443*2139Sjp161948 
444*2139Sjp161948 	PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,PKCS7_R_WRONG_CONTENT_TYPE);
445*2139Sjp161948 	return 1;
446*2139Sjp161948 	}
447*2139Sjp161948 
STACK_OF(PKCS7_SIGNER_INFO)4480Sstevel@tonic-gate STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
4490Sstevel@tonic-gate 	{
4500Sstevel@tonic-gate 	if (PKCS7_type_is_signed(p7))
4510Sstevel@tonic-gate 		{
4520Sstevel@tonic-gate 		return(p7->d.sign->signer_info);
4530Sstevel@tonic-gate 		}
4540Sstevel@tonic-gate 	else if (PKCS7_type_is_signedAndEnveloped(p7))
4550Sstevel@tonic-gate 		{
4560Sstevel@tonic-gate 		return(p7->d.signed_and_enveloped->signer_info);
4570Sstevel@tonic-gate 		}
4580Sstevel@tonic-gate 	else
4590Sstevel@tonic-gate 		return(NULL);
4600Sstevel@tonic-gate 	}
4610Sstevel@tonic-gate 
PKCS7_add_recipient(PKCS7 * p7,X509 * x509)4620Sstevel@tonic-gate PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
4630Sstevel@tonic-gate 	{
4640Sstevel@tonic-gate 	PKCS7_RECIP_INFO *ri;
4650Sstevel@tonic-gate 
4660Sstevel@tonic-gate 	if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
4670Sstevel@tonic-gate 	if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
4680Sstevel@tonic-gate 	if (!PKCS7_add_recipient_info(p7,ri)) goto err;
4690Sstevel@tonic-gate 	return(ri);
4700Sstevel@tonic-gate err:
4710Sstevel@tonic-gate 	return(NULL);
4720Sstevel@tonic-gate 	}
4730Sstevel@tonic-gate 
PKCS7_add_recipient_info(PKCS7 * p7,PKCS7_RECIP_INFO * ri)4740Sstevel@tonic-gate int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
4750Sstevel@tonic-gate 	{
4760Sstevel@tonic-gate 	int i;
4770Sstevel@tonic-gate 	STACK_OF(PKCS7_RECIP_INFO) *sk;
4780Sstevel@tonic-gate 
4790Sstevel@tonic-gate 	i=OBJ_obj2nid(p7->type);
4800Sstevel@tonic-gate 	switch (i)
4810Sstevel@tonic-gate 		{
4820Sstevel@tonic-gate 	case NID_pkcs7_signedAndEnveloped:
4830Sstevel@tonic-gate 		sk=	p7->d.signed_and_enveloped->recipientinfo;
4840Sstevel@tonic-gate 		break;
4850Sstevel@tonic-gate 	case NID_pkcs7_enveloped:
4860Sstevel@tonic-gate 		sk=	p7->d.enveloped->recipientinfo;
4870Sstevel@tonic-gate 		break;
4880Sstevel@tonic-gate 	default:
4890Sstevel@tonic-gate 		PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,PKCS7_R_WRONG_CONTENT_TYPE);
4900Sstevel@tonic-gate 		return(0);
4910Sstevel@tonic-gate 		}
4920Sstevel@tonic-gate 
4930Sstevel@tonic-gate 	sk_PKCS7_RECIP_INFO_push(sk,ri);
4940Sstevel@tonic-gate 	return(1);
4950Sstevel@tonic-gate 	}
4960Sstevel@tonic-gate 
PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO * p7i,X509 * x509)4970Sstevel@tonic-gate int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
4980Sstevel@tonic-gate 	{
499*2139Sjp161948 	if (!ASN1_INTEGER_set(p7i->version,0))
500*2139Sjp161948 		return 0;
501*2139Sjp161948 	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
502*2139Sjp161948 		X509_get_issuer_name(x509)))
503*2139Sjp161948 		return 0;
5040Sstevel@tonic-gate 
5050Sstevel@tonic-gate 	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
506*2139Sjp161948 	if (!(p7i->issuer_and_serial->serial=
507*2139Sjp161948 		M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
508*2139Sjp161948 		return 0;
5090Sstevel@tonic-gate 
5100Sstevel@tonic-gate 	X509_ALGOR_free(p7i->key_enc_algor);
511*2139Sjp161948 	if (!(p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor)))
512*2139Sjp161948 		return 0;
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate 	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
5150Sstevel@tonic-gate 	p7i->cert=x509;
5160Sstevel@tonic-gate 
5170Sstevel@tonic-gate 	return(1);
5180Sstevel@tonic-gate 	}
5190Sstevel@tonic-gate 
PKCS7_cert_from_signer_info(PKCS7 * p7,PKCS7_SIGNER_INFO * si)5200Sstevel@tonic-gate X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
5210Sstevel@tonic-gate 	{
5220Sstevel@tonic-gate 	if (PKCS7_type_is_signed(p7))
5230Sstevel@tonic-gate 		return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
5240Sstevel@tonic-gate 			si->issuer_and_serial->issuer,
5250Sstevel@tonic-gate 			si->issuer_and_serial->serial));
5260Sstevel@tonic-gate 	else
5270Sstevel@tonic-gate 		return(NULL);
5280Sstevel@tonic-gate 	}
5290Sstevel@tonic-gate 
PKCS7_set_cipher(PKCS7 * p7,const EVP_CIPHER * cipher)5300Sstevel@tonic-gate int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
5310Sstevel@tonic-gate 	{
5320Sstevel@tonic-gate 	int i;
5330Sstevel@tonic-gate 	ASN1_OBJECT *objtmp;
5340Sstevel@tonic-gate 	PKCS7_ENC_CONTENT *ec;
5350Sstevel@tonic-gate 
5360Sstevel@tonic-gate 	i=OBJ_obj2nid(p7->type);
5370Sstevel@tonic-gate 	switch (i)
5380Sstevel@tonic-gate 		{
5390Sstevel@tonic-gate 	case NID_pkcs7_signedAndEnveloped:
5400Sstevel@tonic-gate 		ec=p7->d.signed_and_enveloped->enc_data;
5410Sstevel@tonic-gate 		break;
5420Sstevel@tonic-gate 	case NID_pkcs7_enveloped:
5430Sstevel@tonic-gate 		ec=p7->d.enveloped->enc_data;
5440Sstevel@tonic-gate 		break;
5450Sstevel@tonic-gate 	default:
5460Sstevel@tonic-gate 		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_WRONG_CONTENT_TYPE);
5470Sstevel@tonic-gate 		return(0);
5480Sstevel@tonic-gate 		}
5490Sstevel@tonic-gate 
5500Sstevel@tonic-gate 	/* Check cipher OID exists and has data in it*/
5510Sstevel@tonic-gate 	i = EVP_CIPHER_type(cipher);
5520Sstevel@tonic-gate 	if(i == NID_undef) {
5530Sstevel@tonic-gate 		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
5540Sstevel@tonic-gate 		return(0);
5550Sstevel@tonic-gate 	}
5560Sstevel@tonic-gate 	objtmp = OBJ_nid2obj(i);
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate 	ec->cipher = cipher;
5590Sstevel@tonic-gate 	return 1;
5600Sstevel@tonic-gate 	}
5610Sstevel@tonic-gate 
562