SPENSSL Убедитесь, что Сертификат Peer (Client) в C ++
-
27-09-2019 - |
Вопрос
У меня есть рабочее приложение, которое устанавливает соединение 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 для связи.