tags:

views:

122

answers:

2

I have created a CA cert, and used it to issue a public key. At a date in the future, I need to verify that the certificate loaded was issued by my CA.

How do I do that with the OpenSSL API (c++)?

A: 

The openssl verify -CAfile <CA_cert_filename> <unknown_cert_filename> command will do what you want -- it's miserable to try to find the API that will do what you want, so I'd suggest finding the source code for the openssl verify routine.

(If you have choice of implementations, gnutls looks promising:

   #include <gnutls/x509.h>

   int gnutls_x509_crt_verify(gnutls_x509_crt_t cert, const  gnutls_x509_crt_t
   * CA_list, int CA_list_length, unsigned int flags, unsigned int * verify);

But OpenSSL is installed everywhere..)

sarnold
+1  A: 

I've reduced verify.c (in openssl/apps/) to the minimum functions required. Assumptions: cert and CA cert are both PEM format files. There are no CRLS or trusted list checks required.

Call verify() with the path to your cert and CA PEM files.

static int verify(const char* certfile, const char* CAfile);
static X509 *load_cert(const char *file);
static int check(X509_STORE *ctx, const char *file);

int verify(const char* certfile, const char* CAfile)
{
    int ret=0;
    X509_STORE *cert_ctx=NULL;
    X509_LOOKUP *lookup=NULL;

    cert_ctx=X509_STORE_new();
    if (cert_ctx == NULL) goto end;

    OpenSSL_add_all_algorithms();

    lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_file());
    if (lookup == NULL)
        goto end;

    if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
        goto end;

    lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_hash_dir());
    if (lookup == NULL)
        goto end;

    X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);

    ret = check(cert_ctx, certfile);
end:
    if (cert_ctx != NULL) X509_STORE_free(cert_ctx);

    return ret;
}

static X509 *load_cert(const char *file)
{
    X509 *x=NULL;
    BIO *cert;

    if ((cert=BIO_new(BIO_s_file())) == NULL)
        goto end;

    if (BIO_read_filename(cert,file) <= 0)
        goto end;

    x=PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL);
end:
    if (cert != NULL) BIO_free(cert);
    return(x);
}

static int check(X509_STORE *ctx, const char *file)
{
    X509 *x=NULL;
    int i=0,ret=0;
    X509_STORE_CTX *csc;

    x = load_cert(file);
    if (x == NULL)
        goto end;

    csc = X509_STORE_CTX_new();
    if (csc == NULL)
        goto end;
    X509_STORE_set_flags(ctx, 0);
    if(!X509_STORE_CTX_init(csc,ctx,x,0))
        goto end;
    i=X509_verify_cert(csc);
    X509_STORE_CTX_free(csc);

    ret=0;
end:
    ret = (i > 0);
    if (x != NULL)
        X509_free(x);

    return(ret);
}
John