2010-08-05 1 views
12

Я создал сертификат CA и использовал его для публикации открытого ключа. На дату в будущем мне нужно проверить, что сертификат был отправлен моим центром сертификации.Как вы подтверждаете, что открытый ключ был выдан вашим CA?

Как это сделать с помощью API OpenSSL (C++)?

ответ

15

Я уменьшил verify.c (в OpenSSL/приложений /) к минимальным требуемым функциям. Предположения: сертификаты cert и CA являются файлами формата PEM. Нет необходимости проверять CRLS или доверенные списки.

Вызовите проверку() с помощью пути к файлам сертификатов и CA PEM.

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); 
} 
+4

вы можете объяснить код с комментариями я не могу понять логику этого процесса проверки – Balamurugan

+0

Можно ли использовать память вместо файла? Я хотел бы иметь сертификат отправки в B и проверить. Кому-то нравится делиться кодом? Большое спасибо. – user180574

+0

user180574 - Мне кажется, вам нужно использовать BIO_new_mem_buf – John

1

Команда openssl verify -CAfile <CA_cert_filename> <unknown_cert_filename> сделает все, что вы пожелаете - вам будет сложно найти API, который будет делать то, что вы хотите, поэтому я бы предложил найти исходный код для процедуры openssl verify.

(Если у вас есть выбор реализаций, GnuTLS выглядит многообещающим:

#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); 

Но OpenSSL является установлен везде ..)