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

Reply via email to