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