Please can anybody help? This is kind of priority issue for me.
 
I have following set of certificates with X509 extensions defined for code 
signing in PKCS7 format.

Root CA - Key usage (critical): Certificate Sign, CRL Sign
CVC Sub-CA - Key usage (critical): Certificate Sign, CRL Sign
CVC cert - Key usage(critical): Digital Signature, Key Encipherment. Extended 
Key Usage(critical): Code Sigining

PKCS#7 signature includes CVC sub-CA and CVC certs. When I verify the signature 
using PKCS7_verify() I am getting
error:  "unsupported certificate purpose"

As a work-around suggested by Dr.Stephen I tried setting purpose to any and it 
works fine using following command line:

"openssl smime -verify -CAfile Root-CA -purpose any -inform PEM -in pk7blob 
-content data-signed"

But fails when using Openssl API's and the error is 
X509_STORE_CTX_purpose_inherit: unknown purpose id.

Following is the code snippet. Most of it is taken from PKCS7_verify() itself 
in pkcs7_smime.c

void my_verify_api(PKCS7 *pkcs7, unsigned char *signed_data, int s_len)
{
    /* Root CA */
    static unsigned char my_root_ca[900]={......};
    BIO    *bio_t;    
    
    const unsigned char *der_cert = my_root_ca;
    X509_STORE      *cert_store = NULL;
    X509          *x509 = NULL;
    
    STACK_OF(X509)    *signers;
    X509        *signer;
    X509_STORE_CTX    cert_ctx;
    int    i, k, num_signers;
    
    if (!bio_t = BIO_new_mem_buf((void *)signed_data, s_len))) {
        printf("BIO_new_mem_buf failed\n\n");
        goto end;
    }
    OpenSSL_add_all_algorithms();

    x509 = d2i_X509(NULL, &der_cert, sizeof(my_root_ca));

    if (x509 == NULL) {
        printf("x509 is NULL.\n");
        goto end;
    }

    cert_store=X509_STORE_new();
    if (cert_store == NULL) {
        printf("Failed to create new cert store using X509_STORE_new().\n");
        goto end;
    }    

    X509_STORE_add_cert(cert_store,x509);

    signers = PKCS7_get0_signers(pkcs7, NULL, 0);

    if (!signers) {
        printf("Error getting signers--\n");
        goto end;
    }
    num_signers = sk_X509_num(signers);
    printf("num_signers: %d\n", num_signers);

    for (k = 0; k < num_signers; k++) {
        signer = sk_X509_value(signers, k);
        if (!X509_STORE_CTX_init(&cert_ctx, cert_store, signer, 
pkcs7->d.sign->cert)) {        
            printf("X509_STORE_CTX_init failed.\n");
            sk_X509_free(signers);
            goto end;
        }
                
        X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_ANY);

        i = X509_verify_cert(&cert_ctx);

        X509_STORE_CTX_cleanup(&cert_ctx);
        if (i <= 0) {
            unsigned long e;
            const char *file = NULL, *data = NULL;
            int line, flgs;

            while ((e = ERR_get_error_line_data(&file, &line, &data, &flgs))) {
                printf("Error: %d\nError String: %s\n", e, ERR_error_string(e, 
NULL));
                if (data) {
                    printf("data: %s\n", data);
                }
            }
            ERR_clear_error();
            sk_X509_free(signers);
            goto end;
        } else {
            printf("Certificate got verified--\n\n");
        }
    }
    sk_X509_free(signers);    

end:
    if (x509 != NULL) {
        X509_free(x509);
    }
    if (cert_store != NULL) {
        X509_STORE_free(cert_store);
    }
    if (bio_t) {
        BIO_flush(bio_t);
        BIO_free_all(bio_t);
    }
    EVP_cleanup();
}    

Am I doing something wrong here?

Any help is appreciated.

Thanks,
Prkj


                                          

Reply via email to