How do you verify a public key was issued by your private CA?
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 wa开发者_运维知识库s issued by my CA.
How do I do that with the OpenSSL API (c++)?
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);
}
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..)
精彩评论