int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
	  EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
	  const char *file)
	{
	int len;
	int i;

	for (;;)
		{
		i=BIO_read(bp,(char *)buf,BUFSIZE);
		if(i < 0)
			{
			BIO_printf(bio_err, "Read Error in %s\n",file);
			ERR_print_errors(bio_err);
			return 1;
			}
		if (i == 0) break;
		}
	if(sigin)
		{
		EVP_MD_CTX *ctx;
		BIO_get_md_ctx(bp, &ctx);
		i = EVP_VerifyFinal(ctx, sigin, (unsigned int)siglen, key); 
		if(i > 0)
			BIO_printf(out, "Verified OK\n");
		else if(i == 0)
			{
			BIO_printf(out, "Verification Failure\n");
			return 1;
			}
		else
			{
			BIO_printf(bio_err, "Error Verifying Data\n");
			ERR_print_errors(bio_err);
			return 1;
			}
		return 0;
		}
	if(key)
		{
		EVP_MD_CTX *ctx;
		BIO_get_md_ctx(bp, &ctx);
		if(!EVP_SignFinal(ctx, buf, (unsigned int *)&len, key)) 
			{
			BIO_printf(bio_err, "Error Signing Data\n");
			ERR_print_errors(bio_err);
			return 1;
			}
		}
	else
		len=BIO_gets(bp,(char *)buf,BUFSIZE);

	if(binout) BIO_write(out, buf, len);
	else 
		{
		BIO_write(out,title,strlen(title));
		for (i=0; i<len; i++)
			{
			if (sep && (i != 0))
				BIO_printf(out, ":");
			BIO_printf(out, "%02x",buf[i]);
			}
		BIO_printf(out, "\n");
		}
	return 0;
	}