char *(*func)(), void (*free_func)(), int ex_tag, int ex_class)
char *(*func)(), void (*free_func)(void *), int ex_tag, int ex_class)
STACK *d2i_ASN1_SET(STACK **a, unsigned char **pp, long length,	     char *(*func)(), void (*free_func)(), int ex_tag, int ex_class)	{	ASN1_CTX c;	STACK *ret=NULL;	if ((a == NULL) || ((*a) == NULL))		{ if ((ret=sk_new(NULL)) == NULL) goto err; }	else		ret=(*a);	c.p= *pp;	c.max=(length == 0)?0:(c.p+length);	c.inf=ASN1_get_object(&c.p,&c.slen,&c.tag,&c.xclass,c.max-c.p);	if (c.inf & 0x80) goto err;	if (ex_class != c.xclass)		{		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_CLASS);		goto err;		}	if (ex_tag != c.tag)		{		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_TAG);		goto err;		}	if ((c.slen+c.p) > c.max)		{		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_LENGTH_ERROR);		goto err;		}	/* check for infinite constructed - it can be as long	 * as the amount of data passed to us */	if (c.inf == (V_ASN1_CONSTRUCTED+1))		c.slen=length+ *pp-c.p;	c.max=c.p+c.slen;	while (c.p < c.max)		{		char *s;		if (M_ASN1_D2I_end_sequence()) break;		if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL)			{			ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT);			asn1_add_error(*pp,(int)(c.q- *pp));			goto err;			}		if (!sk_push(ret,s)) goto err;		}	if (a != NULL) (*a)=ret;	*pp=c.p;	return(ret);err:	if ((ret != NULL) && ((a == NULL) || (*a != ret)))		{		if (free_func != NULL)			sk_pop_free(ret,free_func);		else			sk_free(ret);		}	return(NULL);	}