OpenSSL Verify Peer (Client) сертификат в C ++ - PullRequest
4 голосов
/ 24 ноября 2010

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

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 verify -CAfile ca-chain2.crt generic_client.pem И это проходит, поэтому у меня есть правильные данные сертификата, я просто должен как-то неправильно их использовать.

Ответы [ 2 ]

6 голосов
/ 25 ноября 2010

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

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

0 голосов
/ 24 ноября 2010

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

...