2010-11-23 5 views
3

У меня есть рабочее приложение, которое устанавливает SSL-соединение с сервером. Сервер использует самозаверяющий сертификат, и клиент загружает цепочку полномочий центра сертификации, чтобы сообщить, что сервер в порядке, чтобы доверять. Я сделал это с помощью следующего кода на клиенте:OpenSSL Verify Peer (Client) Certificate в C++

SSL_METHOD* method = TLSv1_client_method(); 
_ctx = SSL_CTX_new(method); 
if (SSL_CTX_load_verify_locations(_ctx, "ca-all.crt", NULL) != 1) 
{ 
    return false; 
} 
_ssl = SSL_new(_ctx); 
int val = SSL_set_fd(_ssl, _socket->GetFD()); 
if (val != SSL_SUCCESS) 
{ 
    int err = SSL_get_error(_ssl, val); 
    return false; 
} 
val = SSL_connect(_ssl); 

А на сервере:

if (SSL_CTX_use_certificate_chain_file(g_ctx, "ca-chain1.crt") <= 0) { 
    return 1; 
    } 
    ppem_file = getenv("PEM_FILE"); 
    if (ppem_file == NULL) { 
    ppem_file = pem_file; 
    } 
    if (SSL_CTX_use_certificate_file(g_ctx, ppem_file, 
            SSL_FILETYPE_PEM) <= 0) { 
    return 1; 
    } 
    if (SSL_CTX_use_PrivateKey_file(g_ctx, ppem_file, 
            SSL_FILETYPE_PEM) <= 0) { 
    return 2; 
    } 

Я пытаюсь изменить этот код, чтобы сервер также проверяет сертификат партнера клиента (самостоятельно - назначается, используя тот же эмитент, что и сервер) и имеет немного проблем. Я не нашел хорошую документацию «концептуального обзора» в любом месте, и это кажется типичным препятствием для библиотек OpenSSL.

На клиенте я добавил это после SSL_CTX_load_verify_locations() вызов:

if (SSL_CTX_use_certificate_file(_ctx, "generic_client.pem", SSL_FILETYPE_PEM) != 1) 
{ 
    return false; 
} 

На сервере я добавил это после (вызов SSL_CTX_use_PrivateKey_file):

STACK_OF(X509_NAME) *list; 
    list = SSL_load_client_CA_file("ca_chain2.crt"); 
    if(list == NULL) { 
    return 4; 
    } 
    SSL_CTX_set_client_CA_list(g_ctx, list); 
    SSL_CTX_set_verify(g_ctx, SSL_VERIFY_PEER, NULL); 

соединение не удается, так как сертификат не подтверждается. Вероятно, клиент загружает сертификат и, если я прокомментирую строку SSL_CTX_set_verify, клиент подключается без проблем (потому что его сертификат никогда не проверяется).

Похоже, что сервер не считает, что цепочка сертификатов клиента хороша. Что мне здесь не хватает?

Из командной строки можно запустить: OpenSSL проверить -CAfile ча-chain2.crt generic_client.pem И она проходит, поэтому у меня есть данные правильные сертификат доступны, я должен просто использовать это неправильно как-то.

ответ

6

На сервере вы также должны позвонить SSL_CTX_load_verify_locations(). Эта функция сообщает серверу, какие сертификаты использовать для проверки сертификата; функция SSL_CTX_set_client_CA_list() задает список разрешенных ЦС, которые отправляются клиенту в рукопожатии. Оба они требуются.

(Вам также нужен звонок SSL_CTX_use_PrivateKey_file(), после вызова use_certificate_file, но я думаю, вы это делаете и просто оставили его).

+0

Спасибо, это было именно то, что мне нужно. – 2010-12-02 22:41:57

0

SSL_CTX_set_client_CA_list устанавливает список CA. Сертификат ЦС по определению отличается от сертификата пользователя (например, он имеет набор бит ЦС). Поэтому я рекомендую вам создать правильный ЦС (сертификат ЦС сам по себе) и использовать его для подписания как сертификата клиента, так и сертификата сервера. Я предполагаю, что OpenSSL не ожидает, что клиент действительно будет использовать сертификат CA для связи.