if(EVP_CIPHER_nid(evp_cipher) == NID_rc2_cbc) { #ifndef NO_RC2 is_rc2 = 1; #else PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; #endif }
BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)	{	int i,j;	BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;	unsigned char *tmp=NULL;	X509_ALGOR *xa;	ASN1_OCTET_STRING *data_body=NULL;	const EVP_MD *evp_md;	const EVP_CIPHER *evp_cipher=NULL;	EVP_CIPHER_CTX *evp_ctx=NULL;	X509_ALGOR *enc_alg=NULL;	STACK_OF(X509_ALGOR) *md_sk=NULL;	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;	X509_ALGOR *xalg=NULL;	PKCS7_RECIP_INFO *ri=NULL;#ifndef NO_RC2	char is_rc2 = 0;#endif/*	EVP_PKEY *pkey; */#if 0	X509_STORE_CTX s_ctx;#endif	i=OBJ_obj2nid(p7->type);	p7->state=PKCS7_S_HEADER;	switch (i)		{	case NID_pkcs7_signed:		data_body=p7->d.sign->contents->d.data;		md_sk=p7->d.sign->md_algs;		break;	case NID_pkcs7_signedAndEnveloped:		rsk=p7->d.signed_and_enveloped->recipientinfo;		md_sk=p7->d.signed_and_enveloped->md_algs;		data_body=p7->d.signed_and_enveloped->enc_data->enc_data;		enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;		evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));		if (evp_cipher == NULL)			{			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);			goto err;			}		xalg=p7->d.signed_and_enveloped->enc_data->algorithm;		break;	case NID_pkcs7_enveloped:		rsk=p7->d.enveloped->recipientinfo;		enc_alg=p7->d.enveloped->enc_data->algorithm;		data_body=p7->d.enveloped->enc_data->enc_data;		evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));		if (evp_cipher == NULL)			{			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);			goto err;			}		xalg=p7->d.enveloped->enc_data->algorithm;		break;	default:		PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);	        goto err;		}	if(EVP_CIPHER_nid(evp_cipher) == NID_rc2_cbc)		{#ifndef NO_RC2				is_rc2 = 1; #else		PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);		goto err;#endif		}	/* We will be checking the signature */	if (md_sk != NULL)		{		for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)			{			xa=sk_X509_ALGOR_value(md_sk,i);			if ((btmp=BIO_new(BIO_f_md())) == NULL)				{				PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);				goto err;				}			j=OBJ_obj2nid(xa->algorithm);			evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));			if (evp_md == NULL)				{				PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);				goto err;				}			BIO_set_md(btmp,evp_md);			if (out == NULL)				out=btmp;			else				BIO_push(out,btmp);			btmp=NULL;			}		}	if (evp_cipher != NULL)		{#if 0		unsigned char key[EVP_MAX_KEY_LENGTH];		unsigned char iv[EVP_MAX_IV_LENGTH];		unsigned char *p;		int keylen,ivlen;		int max;		X509_OBJECT ret;#endif		int jj;		if ((etmp=BIO_new(BIO_f_cipher())) == NULL)			{			PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);			goto err;			}		/* It was encrypted, we need to decrypt the secret key		 * with the private key */		/* Find the recipientInfo which matches the passed certificate		 * (if any)		 */		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);			if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,					pcert->cert_info->issuer) &&			     !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,					ri->issuer_and_serial->serial)) break;			ri=NULL;		}		if (ri == NULL) {			PKCS7err(PKCS7_F_PKCS7_DATADECODE,				 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);			return(NULL);		}		jj=EVP_PKEY_size(pkey);		tmp=(unsigned char *)Malloc(jj+10);		if (tmp == NULL)			{			PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);			goto err;			}		jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key),			M_ASN1_STRING_length(ri->enc_key), pkey);		if (jj <= 0)			{			PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB);			goto err;			}		evp_ctx=NULL;		BIO_get_cipher_ctx(etmp,&evp_ctx);		EVP_CipherInit(evp_ctx,evp_cipher,NULL,NULL,0);		if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)			return(NULL);		if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {			/* HACK: some S/MIME clients don't use the same key			 * and effective key length. The key length is			 * determined by the size of the decrypted RSA key.			 * So we hack things to manually set the RC2 key			 * because we currently can't do this with the EVP			 * interface.			 */#ifndef NO_RC2					if(is_rc2) RC2_set_key(&(evp_ctx->c.rc2_ks),jj, tmp,					EVP_CIPHER_CTX_key_length(evp_ctx)*8);			else#endif				{				PKCS7err(PKCS7_F_PKCS7_DATADECODE,					PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);				goto err;				}		} else EVP_CipherInit(evp_ctx,NULL,tmp,NULL,0);		memset(tmp,0,jj);		if (out == NULL)			out=etmp;		else			BIO_push(out,etmp);		etmp=NULL;		}#if 1	if (p7->detached || (in_bio != NULL))		{		bio=in_bio;		}	else 		{#if 0		bio=BIO_new(BIO_s_mem());		/* We need to set this so that when we have read all		 * the data, the encrypt BIO, if present, will read		 * EOF and encode the last few bytes */		BIO_set_mem_eof_return(bio,0);		if (data_body->length > 0)			BIO_write(bio,(char *)data_body->data,data_body->length);#else		if (data_body->length > 0)		      bio = BIO_new_mem_buf(data_body->data,data_body->length);		else {			bio=BIO_new(BIO_s_mem());			BIO_set_mem_eof_return(bio,0);		}#endif		}	BIO_push(out,bio);	bio=NULL;#endif	if (0)		{err:		if (out != NULL) BIO_free_all(out);		if (btmp != NULL) BIO_free_all(btmp);		if (etmp != NULL) BIO_free_all(etmp);		if (bio != NULL) BIO_free_all(bio);		out=NULL;		}	if (tmp != NULL)		Free(tmp);	return(out);	}