if(!X509V3_EXT_add_conf(conf, NULL, ext_sect, ret)) goto err;
ctx.subject_cert = ret; ctx.issuer_cert = x509; ctx.subject_req = req; ctx.crl = NULL; ctx.flags = 0;  if(!X509V3_EXT_add_conf(conf, &ctx, ext_sect, ret)) goto err;
static int do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,days,	batch,verbose,req, ext_sect,conf)X509 **xret;EVP_PKEY *pkey;X509 *x509;EVP_MD *dgst;STACK *policy;TXT_DB *db;BIGNUM *serial;char *startdate;int days;int batch;int verbose;X509_REQ *req;char *ext_sect;LHASH *conf;	{	X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;	ASN1_UTCTIME *tm,*tmptm;	ASN1_STRING *str,*str2;	ASN1_OBJECT *obj;	X509 *ret=NULL;	X509_CINF *ci;	X509_NAME_ENTRY *ne;	X509_NAME_ENTRY *tne,*push;	EVP_PKEY *pktmp;	int ok= -1,i,j,last,nid;	char *p;	CONF_VALUE *cv;	char *row[DB_NUMBER],**rrow,**irow=NULL;	char buf[25],*pbuf;	tmptm=ASN1_UTCTIME_new();	if (tmptm == NULL)		{		BIO_printf(bio_err,"malloc error\n");		return(0);		}	for (i=0; i<DB_NUMBER; i++)		row[i]=NULL;	BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");	name=X509_REQ_get_subject_name(req);	for (i=0; i<X509_NAME_entry_count(name); i++)		{		ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);		obj=X509_NAME_ENTRY_get_object(ne);		j=i2a_ASN1_OBJECT(bio_err,obj);		str=X509_NAME_ENTRY_get_data(ne);		pbuf=buf;		for (j=22-j; j>0; j--)			*(pbuf++)=' ';		*(pbuf++)=':';		*(pbuf++)='\0';		BIO_puts(bio_err,buf);		if (msie_hack)			{			/* assume all type should be strings */			nid=OBJ_obj2nid(ne->object);			if (str->type == V_ASN1_UNIVERSALSTRING)				ASN1_UNIVERSALSTRING_to_string(str);			if ((str->type == V_ASN1_IA5STRING) &&				(nid != NID_pkcs9_emailAddress))				str->type=V_ASN1_T61STRING;			if ((nid == NID_pkcs9_emailAddress) &&				(str->type == V_ASN1_PRINTABLESTRING))				str->type=V_ASN1_IA5STRING;			}		if (str->type == V_ASN1_PRINTABLESTRING)			BIO_printf(bio_err,"PRINTABLE:'");		else if (str->type == V_ASN1_T61STRING)			BIO_printf(bio_err,"T61STRING:'");		else if (str->type == V_ASN1_IA5STRING)			BIO_printf(bio_err,"IA5STRING:'");		else if (str->type == V_ASN1_UNIVERSALSTRING)			BIO_printf(bio_err,"UNIVERSALSTRING:'");		else			BIO_printf(bio_err,"ASN.1 %2d:'",str->type);		/* check some things */		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&			(str->type != V_ASN1_IA5STRING))			{			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");			goto err;			}		j=ASN1_PRINTABLE_type(str->data,str->length);		if (	((j == V_ASN1_T61STRING) &&			 (str->type != V_ASN1_T61STRING)) ||			((j == V_ASN1_IA5STRING) &&			 (str->type == V_ASN1_PRINTABLESTRING)))			{			BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");			goto err;			}					p=(char *)str->data;		for (j=str->length; j>0; j--)			{			if ((*p >= ' ') && (*p <= '~'))				BIO_printf(bio_err,"%c",*p);			else if (*p & 0x80)				BIO_printf(bio_err,"\\0x%02X",*p);			else if ((unsigned char)*p == 0xf7)				BIO_printf(bio_err,"^?");			else	BIO_printf(bio_err,"^%c",*p+'@');			p++;			}		BIO_printf(bio_err,"'\n");		}	/* Ok, now we check the 'policy' stuff. */	if ((subject=X509_NAME_new()) == NULL)		{		BIO_printf(bio_err,"Malloc failure\n");		goto err;		}	/* take a copy of the issuer name before we mess with it. */	CAname=X509_NAME_dup(x509->cert_info->subject);	if (CAname == NULL) goto err;	str=str2=NULL;	for (i=0; i<sk_num(policy); i++)		{		cv=(CONF_VALUE *)sk_value(policy,i); /* get the object id */		if ((j=OBJ_txt2nid(cv->name)) == NID_undef)			{			BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);			goto err;			}		obj=OBJ_nid2obj(j);		last= -1;		for (;;)			{			/* lookup the object in the supplied name list */			j=X509_NAME_get_index_by_OBJ(name,obj,last);			if (j < 0)				{				if (last != -1) break;				tne=NULL;				}			else				{				tne=X509_NAME_get_entry(name,j);				}			last=j;			/* depending on the 'policy', decide what to do. */			push=NULL;			if (strcmp(cv->value,"optional") == 0)				{				if (tne != NULL)					push=tne;				}			else if (strcmp(cv->value,"supplied") == 0)				{				if (tne == NULL)					{					BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);					goto err;					}				else					push=tne;				}			else if (strcmp(cv->value,"match") == 0)				{				int last2;				if (tne == NULL)					{					BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);					goto err;					}				last2= -1;again2:				j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);				if ((j < 0) && (last2 == -1))					{					BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);					goto err;					}				if (j >= 0)					{					push=X509_NAME_get_entry(CAname,j);					str=X509_NAME_ENTRY_get_data(tne);					str2=X509_NAME_ENTRY_get_data(push);					last2=j;					if (ASN1_STRING_cmp(str,str2) != 0)						goto again2;					}				if (j < 0)					{					BIO_printf(bio_err,"The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",cv->name,((str == NULL)?"NULL":(char *)str->data),((str2 == NULL)?"NULL":(char *)str2->data));					goto err;					}				}			else				{				BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);				goto err;				}			if (push != NULL)				{				if (!X509_NAME_add_entry(subject,push,					X509_NAME_entry_count(subject),0))					{					if (push != NULL)						X509_NAME_ENTRY_free(push);					BIO_printf(bio_err,"Malloc failure\n");					goto err;					}				}			if (j < 0) break;			}		}	if (preserve)		{		X509_NAME_free(subject);		subject=X509_NAME_dup(X509_REQ_get_subject_name(req));		if (subject == NULL) goto err;		}	if (verbose)		BIO_printf(bio_err,"The subject name apears to be ok, checking data base for clashes\n");	row[DB_name]=X509_NAME_oneline(subject,NULL,0);	row[DB_serial]=BN_bn2hex(serial);	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))		{		BIO_printf(bio_err,"Malloc failure\n");		goto err;		}	rrow=TXT_DB_get_by_index(db,DB_name,row);	if (rrow != NULL)		{		BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",			row[DB_name]);		}	else		{		rrow=TXT_DB_get_by_index(db,DB_serial,row);		if (rrow != NULL)			{			BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",				row[DB_serial]);			BIO_printf(bio_err,"      check the database/serial_file for corruption\n");			}		}	if (rrow != NULL)		{		BIO_printf(bio_err,			"The matching entry has the following details\n");		if (rrow[DB_type][0] == 'E')			p="Expired";		else if (rrow[DB_type][0] == 'R')			p="Revoked";		else if (rrow[DB_type][0] == 'V')			p="Valid";		else			p="\ninvalid type, Data base error\n";		BIO_printf(bio_err,"Type          :%s\n",p);;		if (rrow[DB_type][0] == 'R')			{			p=rrow[DB_exp_date]; if (p == NULL) p="undef";			BIO_printf(bio_err,"Was revoked on:%s\n",p);			}		p=rrow[DB_exp_date]; if (p == NULL) p="undef";		BIO_printf(bio_err,"Expires on    :%s\n",p);		p=rrow[DB_serial]; if (p == NULL) p="undef";		BIO_printf(bio_err,"Serial Number :%s\n",p);		p=rrow[DB_file]; if (p == NULL) p="undef";		BIO_printf(bio_err,"File name     :%s\n",p);		p=rrow[DB_name]; if (p == NULL) p="undef";		BIO_printf(bio_err,"Subject Name  :%s\n",p);		ok= -1; /* This is now a 'bad' error. */		goto err;		}	/* We are now totaly happy, lets make and sign the certificate */	if (verbose)		BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");	if ((ret=X509_new()) == NULL) goto err;	ci=ret->cert_info;#ifdef X509_V3	/* Make it an X509 v3 certificate. */	if (!X509_set_version(x509,2)) goto err;#endif	if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)		goto err;	if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))		goto err;	BIO_printf(bio_err,"Certificate is to be certified until ");	if (strcmp(startdate,"today") == 0)		{		X509_gmtime_adj(X509_get_notBefore(ret),0);		X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);		}	else		{		/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/		ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);		}	ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));	BIO_printf(bio_err," (%d days)\n",days);	if (!X509_set_subject_name(ret,subject)) goto err;	pktmp=X509_REQ_get_pubkey(req);	i = X509_set_pubkey(ret,pktmp);	EVP_PKEY_free(pktmp);	if (!i) goto err;	/* Lets add the extensions, if there are any */	if (ext_sect)		{		if (ci->version == NULL)			if ((ci->version=ASN1_INTEGER_new()) == NULL)				goto err;		ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */		/* Free the current entries if any, there should not		 * be any I belive */		if (ci->extensions != NULL)			sk_pop_free(ci->extensions,X509_EXTENSION_free);		ci->extensions = NULL;		if(!X509V3_EXT_add_conf(conf, NULL, ext_sect, ret)) goto err;		}	if (!batch)		{		BIO_printf(bio_err,"Sign the certificate? [y/n]:");		BIO_flush(bio_err);		buf[0]='\0';		fgets(buf,sizeof(buf)-1,stdin);		if (!((buf[0] == 'y') || (buf[0] == 'Y')))			{			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");			ok=0;			goto err;			}		}#ifndef NO_DSA	if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();        pktmp=X509_get_pubkey(ret);        if (EVP_PKEY_missing_parameters(pktmp) &&		!EVP_PKEY_missing_parameters(pkey))		EVP_PKEY_copy_parameters(pktmp,pkey);	EVP_PKEY_free(pktmp);#endif	if (!X509_sign(ret,pkey,dgst))		goto err;	/* We now just add it to the database */	row[DB_type]=(char *)Malloc(2);	tm=X509_get_notAfter(ret);	row[DB_exp_date]=(char *)Malloc(tm->length+1);	memcpy(row[DB_exp_date],tm->data,tm->length);	row[DB_exp_date][tm->length]='\0';	row[DB_rev_date]=NULL;	/* row[DB_serial] done already */	row[DB_file]=(char *)Malloc(8);	/* row[DB_name] done already */	if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||		(row[DB_file] == NULL))		{		BIO_printf(bio_err,"Malloc failure\n");		goto err;		}	strcpy(row[DB_file],"unknown");	row[DB_type][0]='V';	row[DB_type][1]='\0';	if ((irow=(char **)Malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)		{		BIO_printf(bio_err,"Malloc failure\n");		goto err;		}	for (i=0; i<DB_NUMBER; i++)		{		irow[i]=row[i];		row[i]=NULL;		}	irow[DB_NUMBER]=NULL;	if (!TXT_DB_insert(db,irow))		{		BIO_printf(bio_err,"failed to update database\n");		BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);		goto err;		}	ok=1;err:	for (i=0; i<DB_NUMBER; i++)		if (row[i] != NULL) Free(row[i]);	if (CAname != NULL)		X509_NAME_free(CAname);	if (subject != NULL)		X509_NAME_free(subject);	if (ok <= 0)		{		if (ret != NULL) X509_free(ret);		ret=NULL;		}	else		*xret=ret;	return(ok);	}