startdate,days,ext_sect,conf,verbose)
startdate,days,ext_sect,lconf,verbose)
static int certify_spkac(xret,infile,pkey,x509,dgst,policy,db,serial,	startdate,days,ext_sect,conf,verbose)X509 **xret;char *infile;EVP_PKEY *pkey;X509 *x509;EVP_MD *dgst;STACK *policy;TXT_DB *db;BIGNUM *serial;char *startdate;int days;char *ext_sect;LHASH *conf;int verbose;	{	STACK *sk=NULL;	LHASH *parms=NULL;	X509_REQ *req=NULL;	CONF_VALUE *cv=NULL;	NETSCAPE_SPKI *spki = NULL;	unsigned char *spki_der = NULL,*p;	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_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 ((int)sk_num(sk) <= i) break;		cv=(CONF_VALUE *)sk_value(sk,i);		type=cv->name;		buf=cv->value;		if ((nid=OBJ_txt2nid(type)) == NID_undef)			{			if (strcmp(type, "SPKAC") == 0)				{				spki_der=(unsigned char *)Malloc(					strlen(cv->value)+1);				if (spki_der == NULL)					{					BIO_printf(bio_err,"Malloc failure\n");					goto err;					}				j = EVP_DecodeBlock(spki_der, (unsigned char *)cv->value,					strlen(cv->value));				if (j <= 0)					{					BIO_printf(bio_err, "Can't b64 decode SPKAC structure\n");					goto err;					}				p=spki_der;				spki = d2i_NETSCAPE_SPKI(&spki, &p, j);				Free(spki_der);				spki_der = NULL;				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,X509_NAME_entry_count(n),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=X509_PUBKEY_get(spki->spkac->pubkey)) == 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,startdate,		days,1,verbose,req,ext_sect,conf);err:	if (req != NULL) X509_REQ_free(req);	if (parms != NULL) CONF_free(parms);	if (spki_der != NULL) Free(spki_der);	if (spki != NULL) NETSCAPE_SPKI_free(spki);	if (ne != NULL) X509_NAME_ENTRY_free(ne);	return(ok);	}