Hi
I build two functions for pkcs7 ,like below;
I have two question,
One,If I use the code, The function PKCS7_signatrueVerify return 0,it is
verify failed.

two: if I use the code


BIO *databio=NULL;

databio=BIO_new(BIO_s_mem());
if(databio==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"Out of memory\n");
goto end;
}

ret=BIO_write(databio,buf->v,buf->l);
BIO_flush(databio); x
BIO_push(p7bio,databio);

replace

ret=BIO_write(p7bio,buf->v,buf->l);
BIO_flush(p7bio);

in pkcs7_encode .

the function PKCS7_signatureVerify return 1,it't ok.but When
BIO_read the p7bio .it's return NULL.

please help me !!sorry for my poor englist.



vchar_t *pkcs7_encode(vchar_t *buf,struct pkcs7_sess *sess)
{
vchar_t *p7der=NULL;
vchar_t *p7der_b64=NULL;
PKCS7 *p7=NULL;
const EVP_CIPHER *evp_cipher=NULL;
PKCS7_RECIP_INFO *p7recipinfo=NULL;
PKCS7_SIGNER_INFO *info=NULL;
BIO *p7bio=NULL;
int ret=0;
int derlen=0;

assert(buf!=NULL&&sess!=NULL);

if(sess->x509_RecCert==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"peer reccert is NULL\n");
return NULL;
}

p7=PKCS7_new();
if(p7==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"Out of memory\n");
return NULL;
}

PKCS7_set_type(p7,NID_pkcs7_signedAndEnveloped);

evp_cipher=EVP_bf_cbc();
if(evp_cipher==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"Can't get des cbc algorithm\n");
goto end;
}

PKCS7_set_cipher(p7,evp_cipher);

p7recipinfo=PKCS7_add_recipient(p7,sess->x509_RecCert);
if(p7recipinfo==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"Set peer certificate failed\n");
goto end;
}

info=PKCS7_add_signature(p7,sess->cert,sess->evp_pkey,EVP_sha1());

PKCS7_add_certificate(p7,sess->cert);

p7bio=PKCS7_dataInit(p7,NULL);



ret=BIO_write(p7bio,buf->v,buf->l);
BIO_flush(p7bio);

PKCS7_dataFinal(p7,p7bio);

derlen=i2d_PKCS7(p7,NULL);
if(derlen==0)
{
plog(LLV_ERR,LOCATION,NULL,"failed to i2d_PKCS7\n");
goto end;
}
else
{
p7der=vcalloc(derlen);
if(p7der==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"Out of memory\n");
goto end;
}
unsigned char *p=NULL;
p=(unsigned char *)(p7der->v);

i2d_PKCS7(p7,&p);
}

p7der_b64=b64_encode(p7der);
if(p7der_b64==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"Conv encode b64 failed\n");
goto end;
}

if(p7der)
vfree(&p7der);
if(p7)
PKCS7_free(p7);
if(p7bio)
BIO_free(p7bio);

return p7der_b64;
end:
if(p7der_b64)
vfree(&p7der_b64);
if(p7der)
vfree(&p7der);
if(p7)
PKCS7_free(p7);
if(p7bio)
BIO_free(p7bio);
return NULL;
}

vchar_t *pkcs7_decode(vchar_t *buf,struct pkcs7_sess **sess)
{
vchar_t *plain=NULL;
vchar_t *p7buf=NULL;
PKCS7 *p7=NULL;
EVP_CIPHER *evp_cipher=NULL;
PKCS7_SIGNER_INFO *info=NULL;
BIO *p7bio=NULL,*databio=NULL;
int ret=0;
STACK_OF(PKCS7_SIGNER_INFO) *sk=NULL;
int signcount=0;
X509 *sign_cert=NULL;
unsigned char src[20000]={0};
size_t srclen=0;

assert((buf!=NULL)&&((*sess)!=NULL));

p7buf=b64_decode(buf);
if(p7buf==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"failed to b64_decode for pkcs7_decode\n");
return NULL;
}

const unsigned char *p=NULL;
p=(const unsigned char *)(p7buf->v);

p7=d2i_PKCS7(NULL,&p,p7buf->l);
if(p7==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"failed to d2i pkcs7\n");
//ERR_print_errors();
goto end;
}

p7bio=PKCS7_dataDecode(p7,(*sess)->evp_pkey,NULL,(*sess)->cert);
if(p7bio==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"PKCS7 data Decode failed\n");
ERR_print_errors(p7bio);
goto end;
}

sk=PKCS7_get_signer_info(p7);

signcount=sk_PKCS7_SIGNER_INFO_num(sk);

if(signcount!=1)
{
plog(LLV_ERR,LOCATION,NULL,"Sign num too much,Expect one sign\n");
goto end;
}

info=sk_PKCS7_SIGNER_INFO_value(sk,0);
if(info==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"Pkcs7 get signer info value failed\n");
goto end;
}

sign_cert=X509_find_by_issuer_and_serial(p7->d.signed_and_enveloped->cert,info->issuer_and_serial->issuer,info->issuer_and_serial->serial);
if(sign_cert==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"pkcs7 get sign cert from signer info failed\n");
goto end;
}


if(PKCS7_signatureVerify(p7bio,p7,info,sign_cert)! =1)
{
plog(LLV_ERR,LOCATION,NULL,"pkcs7 signature verify failed\n");
goto end;
}

srclen=BIO_read(p7bio,src,20000);

if(srclen==0)
{
plog(LLV_ERR,LOCATION,NULL,"get plain data failed\n");
goto end;
}
#ifdef DEBUG
plog(LLV_DEBUG,LOCATION,NULL,"decrypt data:%s\n",src);
#endif

plain=vcalloc(srclen);
if(plain==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"Out of memory\n");
goto end;
}
else
{
memcpy(plain->v,src,srclen);
#ifdef DEBUG
plogdump(LLV_DEBUG2,(unsigned char *)plain->v,plain->l);
#endif
}
(*sess)->x509_RecCert=sign_cert;

(*sess)->subject_RecCert=x509_get_subject_string(sign_cert) ;
if((*sess)->subject_RecCert==NULL)
{
plog(LLV_ERR,LOCATION,NULL,"failed to get peer subject");
goto end;
}

if(p7bio)
BIO_free(p7bio);
if(p7)
PKCS7_free(p7);
if(p7buf)
vfree(&p7buf);

return plain;
end:
if(plain)
vfree(&plain);
if(p7bio)
BIO_free(p7bio);
if(p7)
PKCS7_free(p7);
if(p7buf)
vfree(&p7buf);
return NULL;
}


--
Best regards,

Tongyi ,Zhao