【发布时间】:2016-10-10 14:32:37
【问题描述】:
我正在尝试根据 UTN_USERFirst_Hardware CA 验证 IRC 服务器的证书。
我遇到了来自SSL_get_verify_result 的错误代码 20(如果我是正确的,这意味着它无法获得对等证书?)。
另外,我不太确定“步骤”在此过程中的优先级是什么。
这是我拼凑出来的:
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。请参阅 Stack Overflow 上的 OpenSSL Verify return code: 20 (unable to get local issuer certificate)。另请参阅 OpenSSL wiki 上的 SSL/TLS Client。 wiki 页面将回答 “我如何验证对等证书...” -
您是否尝试过使用
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);设置dafult CA文件路径?