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