Я пытаюсь проверить сертификат IRC-сервера на UTN_USERFirst_Hardware CA. Я столкнулся с кодом ошибки 20 от SSL_get_verify_result
(что, если я прав, означает, что ему не удалось получить сертификат сверстника?). Кроме того, я не слишком уверен в том, какой приоритет «шагов» в этом процессе.SSL_get_verify_result возвращает ошибку 20 для irc.freenode.net
Вот что я починил:
int tallis_ssl_verify(tallis_t *tallis, X509 *cert)
{
int rv;
X509_VERIFY_PARAM_set_hostflags(
tallis->param,
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
SSL_CTX_set_default_verify_paths(tallis->ssl_context);
ERR_clear_error();
rv = SSL_CTX_load_verify_locations(
tallis->ssl_context,
"/etc/ssl/certs/AddTrust_External_Root.pem",
"/etc/ssl/certs");
if (!rv)
{
fprintf(stderr, ERR_error_string(ERR_get_error(), NULL));
return 1;
}
X509_VERIFY_PARAM_set1_host(tallis->param, tallis->host, 0);
SSL_CTX_set_verify(tallis->ssl_context, SSL_VERIFY_PEER, NULL);
SSL_set_verify(tallis->ssl_connection, SSL_VERIFY_PEER, NULL);
ERR_clear_error();
rv = SSL_get_verify_result(tallis->ssl_connection);
if (rv != X509_V_OK)
{
printf("%d\n", rv);
fprintf(stderr, ERR_error_string(ERR_get_error(), NULL));
return 1;
}
ERR_clear_error();
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
if (!ctx)
{
fprintf(stderr, ERR_error_string(ERR_get_error(), NULL));
return 1;
}
ERR_clear_error();
X509_STORE *store = X509_STORE_new();
if (!store)
{
X509_STORE_free(store);
fprintf(stderr, ERR_error_string(ERR_get_error(), NULL));
return 1;
}
ERR_clear_error();
rv = X509_STORE_CTX_init(ctx, store, cert, NULL);
if (!rv)
{
X509_STORE_free(store);
fprintf(stderr, ERR_error_string(ERR_get_error(), NULL));
return 1;
}
X509_STORE_set_flags(store, X509_V_FLAG_CB_ISSUER_CHECK);
X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
X509_STORE_load_locations(
store,
"/etc/ssl/certs/AddTrust_External_Root.pem",
NULL);
X509_STORE_set_default_paths(store);
X509_LOOKUP_load_file(
lookup,
"/etc/ssl/certs/AddTrust_External_Root.pem",
X509_FILETYPE_PEM);
X509_STORE_add_cert(store, cert);
ERR_clear_error();
rv = X509_verify_cert(ctx);
if (rv != 1)
{
X509_STORE_free(store);
fprintf(
stderr,
"%s\n%s\n",
ERR_error_string(ERR_get_error(), NULL),
X509_verify_cert_error_string(ctx->error));
return 1;
}
return 0;
}
И вызывающий рутина для контекста:
int main(int argc, char *argv[])
{
tallis_t *tallis = malloc(sizeof(tallis_t));
tallis->host = "irc.freenode.net";
tallis->port = "6697";
tallis->bio = NULL;
tallis->ssl_connection = NULL;
ssl_init(tallis->ssl_connection);
tallis->ssl_context = SSL_CTX_new(TLSv1_2_client_method());
tallis->ssl_connection = SSL_new(tallis->ssl_context);
tallis->param = SSL_get0_param(tallis->ssl_connection);
int rv;
rv = tallis_connect(tallis);
if (rv)
DIE("%s\n", "connection failed");
ERR_clear_error();
X509 *cert = SSL_get_peer_certificate(tallis->ssl_connection);
if (!cert)
DIE("%s\n", ERR_error_string(ERR_get_error(), NULL));
rv = tallis_ssl_verify(tallis, cert);
X509_free(cert);
if (rv)
DIE("%s\n", "certificate verificiation failed");
else
printf("%s\n", "certificate verification succeeded");
rv = tallis_loop(tallis);
if (rv)
DIE("%s\n", "socket connection terminated");
rv = ssl_shutdown(tallis);
if (rv)
DIE("%s\n", "ssl shutdown failed");
}
Так, как он стоит мой поток заключается в следующем: Установить соединение на сокет (BIO) -> вызов SSL_get_peer_certificate
-> проверить сертификат, это правильно?
В чем разница между SSL_get_verify_result
и X509_verify_cert
и какой из них следует использовать в первую очередь? Извините, если это слишком общее, мне нужно небольшое руководство, и документы - это просто страницы с малой информацией с не очень соответствующей корреляционной информацией, мне сложно получить организованный вид OpenSSL.
Как насчет «Как проверить сертификат однорангового соединения в OpenSSL как можно проще?»
Код подтверждения подтверждения 20 «* не может получить сертификат местного эмитента» *. Коды определены в 'x509_vfy.h', а 20 -' X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY'. На странице руководства OpenSSL, которая их обсуждает, есть ['openssl verify'] (http://www.openssl.org/docs/manmaster/apps/verify.html). См. [OpenSSL Verify return code: 20 (невозможно получить сертификат локального эмитента)] (http://stackoverflow.com/q/11548336) в разделе «Переполнение стека». Также см. [SSL/TLS Client] (http://wiki.openssl.org/index.php/SSL/TLS_Client) в вики OpenSSL. Страница вики будет отвечать * «Как проверить сертификат однорангового узла ...» * – jww