Вопрос

У меня есть рабочее приложение, которое устанавливает соединение 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_BLOAD_VERIFY_LOCATION () CALL:

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

На сервере я добавил это после SSL_CTX_USE_PRIVATEKEY_FILE () CALL:

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

Это было полезно?

Решение

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

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top