BIGNUM *serial, char *subj, char *startdate, char *enddate, int days, char *ext_sect, LHASH *lconf, int verbose, unsigned long certopt,
BIGNUM *serial, char *subj, char *startdate, char *enddate, long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,	     BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,	     char *ext_sect, LHASH *lconf, int verbose, unsigned long certopt,	     unsigned long nameopt, int default_op, int ext_copy)	{	STACK_OF(CONF_VALUE) *sk=NULL;	LHASH *parms=NULL;	X509_REQ *req=NULL;	CONF_VALUE *cv=NULL;	NETSCAPE_SPKI *spki = NULL;	X509_REQ_INFO *ri;	char *type,*buf;	EVP_PKEY *pktmp=NULL;	X509_NAME *n=NULL;	X509_NAME_ENTRY *ne=NULL;	int ok= -1,i,j;	long errline;	int nid;	/*	 * Load input file into a hash table.  (This is just an easy	 * way to read and parse the file, then put it into a convenient	 * STACK format).	 */	parms=CONF_load(NULL,infile,&errline);	if (parms == NULL)		{		BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);		ERR_print_errors(bio_err);		goto err;		}	sk=CONF_get_section(parms, "default");	if (sk_CONF_VALUE_num(sk) == 0)		{		BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);		CONF_free(parms);		goto err;		}	/*	 * Now create a dummy X509 request structure.  We don't actually	 * have an X509 request, but we have many of the components	 * (a public key, various DN components).  The idea is that we	 * put these components into the right X509 request structure	 * and we can use the same code as if you had a real X509 request.	 */	req=X509_REQ_new();	if (req == NULL)		{		ERR_print_errors(bio_err);		goto err;		}	/*	 * Build up the subject name set.	 */	ri=req->req_info;	n = ri->subject;	for (i = 0; ; i++)		{		if (sk_CONF_VALUE_num(sk) <= i) break;		cv=sk_CONF_VALUE_value(sk,i);		type=cv->name;		/* Skip past any leading X. X: X, etc to allow for		 * multiple instances		 */		for (buf = cv->name; *buf ; buf++)			if ((*buf == ':') || (*buf == ',') || (*buf == '.'))				{				buf++;				if (*buf) type = buf;				break;				}		buf=cv->value;		if ((nid=OBJ_txt2nid(type)) == NID_undef)			{			if (strcmp(type, "SPKAC") == 0)				{				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);				if (spki == NULL)					{					BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");					ERR_print_errors(bio_err);					goto err;					}				}			continue;			}		j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);		if (fix_data(nid, &j) == 0)			{			BIO_printf(bio_err,				"invalid characters in string %s\n",buf);			goto err;			}		if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,			(unsigned char *)buf,			strlen(buf))) == NULL)			goto err;		if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;		}	if (spki == NULL)		{		BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",			infile);		goto err;		}	/*	 * Now extract the key from the SPKI structure.	 */	BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");	if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)		{		BIO_printf(bio_err,"error unpacking SPKAC public key\n");		goto err;		}	j = NETSCAPE_SPKI_verify(spki, pktmp);	if (j <= 0)		{		BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");		goto err;		}	BIO_printf(bio_err,"Signature ok\n");	X509_REQ_set_pubkey(req,pktmp);	EVP_PKEY_free(pktmp);	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,		   days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,			ext_copy);err:	if (req != NULL) X509_REQ_free(req);	if (parms != NULL) CONF_free(parms);	if (spki != NULL) NETSCAPE_SPKI_free(spki);	if (ne != NULL) X509_NAME_ENTRY_free(ne);	return(ok);	}