Search code examples
opensslx509certificatex509pkcs#7

PKCS#7 Signed Code Image extracting


I wanted to extract the Signer Informations from PKCS#7 Signed Code Image using C/CPP. I wanted to know the openssl API's. I am Able to extract Using bouncy castle (CMSSignedData).

Please let me know the openssl API's which I can use in C/CPP to extract the each signers and signer informations and verify the Signers.

is there any API like X509_LOOKUP_buffer() instead of X509_LOOKUP_file() ???

Thanks in advance opensid


Solution

  • I had a similar problem. I had to extract signingTime attribute from a PKCS#7 signature. I couldn't find the ultimate solution on the Internet but I could pick up bits and parts from various places and came up to this. Maybe there is a nicer/better/safer way, it's the first time I amd doing this but it seems to work.

    In a function I have p_pkcs7SigSize bytes of PKCS#7 signature in a buffer pointing by const void *p_pkcs7Sig. I got signing time by this. I've removed the error handling, do not use this code verbose!

    BIO                         *v_in          = NULL;
    PKCS7                       *v_p7          = NULL;
    STACK_OF(PKCS7_SIGNER_INFO) *v_signerInfos = NULL;
    PKCS7_SIGNER_INFO           *v_signerInfo  = NULL;
    ASN1_TYPE                   *v_asn1SigningTime  = NULL;
    
    /* make BIO for input buffer */
    v_in = BIO_new_mem_buf( (void*)(uintptr_t) p_pkcs7Sig, p_pkcs7SigSize );
    
    /* make a PKCS7 object of it */
    v_p7 = d2i_PKCS7_bio( v_in, NULL);
    
    /* get all signer infos */
    v_signerInfos = PKCS7_get_signer_info( v_p7 );
    
    /* if you need all signer infos then loop through all, 
     * count you get by k_PKCS7_SIGNER_INFO_num(v_signerInfos) 
     */
    
    /* get the first signer info */
    v_signerInfo = sk_PKCS7_SIGNER_INFO_value(v_signerInfos,0);
    
    /* get signing time */
    v_asn1SigningTime = PKCS7_get_signed_attribute( v_signerInfo, NID_pkcs9_signingTime );
    
    /* You should got a v_asn1SigningTime->type == V_ASN1_UTCTIME, 
     * if yes then the actual value is in the string buffer at
     * v_asn1SigningTime->value.utctime->data 
     */
    
    if ( v_in )
    {
       BIO_free_all( v_in );
       v_in = NULL;
    }