V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SET);
V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
int PKCS7_dataVerify(cert_store,ctx,bio,p7,si)X509_STORE *cert_store;X509_STORE_CTX *ctx;BIO *bio;PKCS7 *p7;PKCS7_SIGNER_INFO *si;	{/*	PKCS7_SIGNED *s; */	ASN1_OCTET_STRING *os;	EVP_MD_CTX mdc_tmp,*mdc;	unsigned char *pp,*p;	PKCS7_ISSUER_AND_SERIAL *ias;	int ret=0,i;	int md_type;	STACK *sk,*cert;	BIO *btmp;	X509 *x509;	if (PKCS7_type_is_signed(p7))		{		cert=p7->d.sign->cert;		}	else if (PKCS7_type_is_signedAndEnveloped(p7))		{		cert=p7->d.signed_and_enveloped->cert;		}	else		{		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE);		goto err;		}	/* XXXXXXXXXXXXXXXXXXXXXXX */	ias=si->issuer_and_serial;	x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial);	/* were we able to find the cert in passed to us */	if (x509 == NULL)		{		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);		goto err;		}	/* Lets verify */	X509_STORE_CTX_init(ctx,cert_store,x509,cert);	i=X509_verify_cert(ctx);	if (i <= 0) 		{		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);		goto err;		}	X509_STORE_CTX_cleanup(ctx);	/* So we like 'x509', lets check the signature. */	md_type=OBJ_obj2nid(si->digest_alg->algorithm);	btmp=bio;	for (;;)		{		if ((btmp == NULL) ||			((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))			{			PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);			goto err;			}		BIO_get_md_ctx(btmp,&mdc);		if (mdc == NULL)			{			PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_INTERNAL_ERROR);			goto err;			}		if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == md_type)			break;		btmp=btmp->next_bio;			}	/* mdc is the digest ctx that we want, unless there are attributes,	 * in which case the digest is the signed attributes */	memcpy(&mdc_tmp,mdc,sizeof(mdc_tmp));	sk=si->auth_attr;	if ((sk != NULL) && (sk_num(sk) != 0))		{		unsigned char md_dat[EVP_MAX_MD_SIZE];                int md_len;		ASN1_OCTET_STRING *message_digest;		EVP_DigestFinal(&mdc_tmp,md_dat,&md_len);		message_digest=PKCS7_digest_from_attributes(sk);		if (!message_digest)			{			PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);			goto err;			}		if ((message_digest->length != md_len) ||			(memcmp(message_digest->data,md_dat,md_len)))			{#if 0{int ii;for (ii=0; ii<message_digest->length; ii++)	printf("%02X",message_digest->data[ii]); printf(" sent\n");for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");}#endif			PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_DIGEST_FAILURE);			ret= -1;			goto err;			}		EVP_VerifyInit(&mdc_tmp,EVP_get_digestbynid(md_type));		i=i2d_ASN1_SET(sk,NULL,i2d_X509_ATTRIBUTE,			V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SET);		pp=(unsigned char *)Malloc(i);		p=pp;		i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE,			V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SET);		EVP_VerifyUpdate(&mdc_tmp,pp,i);		Free(pp);		}	os=si->enc_digest;	if (X509_get_pubkey(x509)->type == EVP_PKEY_DSA)		mdc_tmp.digest=EVP_dss1();	i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length,		X509_get_pubkey(x509));	if (i <= 0)		{		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_SIGNATURE_FAILURE);		ret= -1;		goto err;		}	else		ret=1;err:	return(ret);	}