upkey=X509_get_pubkey(x); if (!EVP_PKEY_missing_parameters(pkey) && (EVP_PKEY_cmp_parameters(pkey,upkey) == 0)) { EVP_PKEY_save_parameters(upkey,0);  X509_set_pubkey(x,upkey); } EVP_PKEY_free(upkey);
static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,	     X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,	     int days, LHASH *conf, char *section)	{	int ret=0;	BIO *io=NULL;	MS_STATIC char buf2[1024];	char *buf=NULL,*p;	BIGNUM *serial=NULL;	ASN1_INTEGER *bs=NULL,bs2;	X509_STORE_CTX xsc;	EVP_PKEY *upkey;	upkey = X509_get_pubkey(xca);	EVP_PKEY_copy_parameters(upkey,pkey);	EVP_PKEY_free(upkey);	X509_STORE_CTX_init(&xsc,ctx,x,NULL);	buf=(char *)Malloc(EVP_PKEY_size(pkey)*2+		((serialfile == NULL)			?(strlen(CAfile)+strlen(POSTFIX)+1)			:(strlen(serialfile)))+1);	if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; }	if (serialfile == NULL)		{		strcpy(buf,CAfile);		for (p=buf; *p; p++)			if (*p == '.')				{				*p='\0';				break;				}		strcat(buf,POSTFIX);		}	else		strcpy(buf,serialfile);	serial=BN_new();	bs=ASN1_INTEGER_new();	if ((serial == NULL) || (bs == NULL))		{		ERR_print_errors(bio_err);		goto end;		}	io=BIO_new(BIO_s_file());	if (io == NULL)		{		ERR_print_errors(bio_err);		goto end;		}		if (BIO_read_filename(io,buf) <= 0)		{		if (!create)			{			perror(buf);			goto end;			}		else			{			ASN1_INTEGER_set(bs,0);			BN_zero(serial);			}		}	else 		{		if (!a2i_ASN1_INTEGER(io,bs,buf2,1024))			{			BIO_printf(bio_err,"unable to load serial number from %s\n",buf);			ERR_print_errors(bio_err);			goto end;			}		else			{			serial=BN_bin2bn(bs->data,bs->length,serial);			if (serial == NULL)				{				BIO_printf(bio_err,"error converting bin 2 bn");				goto end;				}			}		}	if (!BN_add_word(serial,1))		{ BIO_printf(bio_err,"add_word failure\n"); goto end; }	bs2.data=(unsigned char *)buf2;	bs2.length=BN_bn2bin(serial,bs2.data);	if (BIO_write_filename(io,buf) <= 0)		{		BIO_printf(bio_err,"error attempting to write serial number file\n");		perror(buf);		goto end;		}	i2a_ASN1_INTEGER(io,&bs2);	BIO_puts(io,"\n");	BIO_free(io);	io=NULL;		if (!X509_STORE_add_cert(ctx,x)) goto end;	/* NOTE: this certificate can/should be self signed, unless it was	 * a certificate request in which case it is not. */	X509_STORE_CTX_set_cert(&xsc,x);	if (!reqfile && !X509_verify_cert(&xsc))		goto end;	if (!X509_check_private_key(xca,pkey))		{		BIO_printf(bio_err,"CA certificate and CA private key do not match\n");		goto end;		}	if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end;	if (!X509_set_serialNumber(x,bs)) goto end;	if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL)		goto end;	/* hardwired expired */	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)		goto end;	/* don't save DSA parameters in child if parent has them	 * and the parents and the childs are the same. */	upkey=X509_get_pubkey(x);	if (!EVP_PKEY_missing_parameters(pkey) &&		(EVP_PKEY_cmp_parameters(pkey,upkey) == 0))		{		EVP_PKEY_save_parameters(upkey,0);		/* Force a re-write */		X509_set_pubkey(x,upkey);		}	EVP_PKEY_free(upkey);	if(conf) {		X509V3_CTX ctx2;		X509_set_version(x,2); /* version 3 certificate */                X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);                X509V3_set_conf_lhash(&ctx2, conf);                if(!X509V3_EXT_add_conf(conf, &ctx2, section, x)) goto end;	}	if (!X509_sign(x,pkey,digest)) goto end;	ret=1;end:	X509_STORE_CTX_cleanup(&xsc);	if (!ret)		ERR_print_errors(bio_err);	if (buf != NULL) Free(buf);	if (bs != NULL) ASN1_INTEGER_free(bs);	if (io != NULL)	BIO_free(io);	if (serial != NULL) BN_free(serial);	return(ret);	}