Hi there,

I wrote a server-like program in charge of verifying incoming users' X.509 certificates
using a list of CAs and their associated CRLs.
The program uses a global X509_STORE to hold CA certificates and CRLs.
The global X509_STORE is built during the initialization of the server
using X509_STORE_add_cert() and X509_STORE_add_crl() functions.

The verification of each user certificate uses the following code:

bool verify_certificate ( X509 *pCert )
{
// Global variable: X509_STORE *g_pStore
    X509_STORE_CTX *pContext = X509_STORE_CTX_new();

if ( ! X509_STORE_CTX_init(pContext, g_pStore, pCert,NULL)) return false;

    // Make sure the issuing CA is known
    X509_OBJECT xObj; memset(&xObj,0,sizeof(X509_OBJECT));
    int iErr = X509_STORE_get_by_subject(pContext,
                X509_LU_X509,
                X509_get_issuer_name(pCert),
&xObj);
    if ( iErr <= 0 ) {
        printf("X509_STORE_get_by_subject: %s\n",
            X509_verify_cert_error_string(pContext->error));
        OPENSSL_free(pContext);
        return false;
    }

    // Verify certificate using CA Certs and CRL in the STORE
    int iErr = x509_verify_cert(pContext);
    if ( iErr != 1 )
    {
        printf("x509_verify_cert: %s\n",
            X509_verify_cert_error_string(pContext->error));
        OPENSSL_free(pContext);
        return false;
    }

    // Make sure certificate is not in one CRL
    X509_OBJECT xCRL; memset(&xCRL,0,sizeof(X509_OBJECT));
    iErr = X509_STORE_get_by_subject(pContext,
                X509_LU_CRL,
                X509_get_issuer_name(pCert),
&xCRL);
    X509_CRL *pCRL = xCRL.data.crl;
    if (iErr > 0 && pCRL)
    {
        STACK_OF(X509_REVOKED) *pRevoked = X509_CRL_get_REVOKED(pCRL);
        if ( sk_X509_REVOKED_num(pRevoked) > 0 )
        {
X509_REVOKED revoked; revoked.serialNumber = X509_get_serialNumber(pCert);
            int rv = sk_X509_REVOKED_find(pRevoked, &revoked);
            if ( sk_X509_REVOKED_find(pRevoked, &revoked) >= 0 )
            {
                OPENSSL_free(pContext);
                return false;
            }
        }
    }
    OPENSSL_free(pContext);
}

The above function works only once: the second time I invoke the function
(even with the same X.509 user's certificate!), it always fails with error:
X509_V_ERR_CERT_SIGNATURE_FAILURE.

If I destroy and rebuild the global X509_STORE before verifying each certificate,
then the x509_verify_cert() function works as expected.

I tried to track changes inside the X509_STORE during x509_verify_cert()
but to no avail. Only the g_pStore->objs.sorted member seems to change when
X509_STORE_get_by_subject() is invoked for the first time.

What did I miss when using X509_STORE[_CTX]?

Thanks in advance for your help,

--
Jacques.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to