我正在尝试根据UTN_USERFirst_硬件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");
}
所以,我的流程是:在socket(BIO)级别建立连接->调用
SSL_get_peer_certificate
->进行证书验证,这是正确的吗?SSL_get_verify_result
和X509_verify_cert
之间有什么区别?应该先使用哪个?抱歉,如果这太笼统了,我需要一点指导,文档只是一个没有太多相关信息的手动页面,我发现很难获得一个有组织的OpenSSL视图。
“如何在OpenSSL中尽可能简单地验证对等证书?”
最佳答案
我正在尝试根据UTN_USERFirst_硬件CA验证IRC服务器的证书
我认为那是错误的根CA。
“如何在OpenSSL中尽可能简单地验证对等证书?”
我想你就在你需要的地方你只需要稍微调整一下。
当我检查链中最上面的颁发者时(s:
表示主题,而i:
表示颁发者):
$ openssl s_client -connect irc.freenode.net:6697 -servername irc.freenode.net -tls1_2
CONNECTED(00000005)
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify error:num=20:unable to get local issuer certificate
Server did acknowledge servername extension.
---
Certificate chain
0 s:/OU=Domain Control Validated/OU=Gandi Standard Wildcard SSL/CN=*.freenode.net
i:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2
1 s:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2
i:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
2 s:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
...
<skip certificate and lots of other stuff>
...
Start Time: 1475924259
Timeout : 7200 (sec)
Verify return code: 20 (unable to get local issuer certificate)
看起来你希望你的信任根在
CN=AddTrust External CA Root
;而不是UTN_USERFirst_Hardware_Root_CA
你可以在科摩多的网站[Root] AddTrust External CA Root找到它。文件
addtrustexternalcaroot.crt
采用PEM格式您只需指定-CAfile
选项即可成功完成命令(X509_V_OK
):$ openssl s_client -connect irc.freenode.net:6697 -servername irc.freenode.net -tls1_2 -CAfile addtrustexternalcaroot.crt
CONNECTED(00000005)
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = FR, ST = Paris, L = Paris, O = Gandi, CN = Gandi Standard SSL CA 2
verify return:1
depth=0 OU = Domain Control Validated, OU = Gandi Standard Wildcard SSL, CN = *.freenode.net
verify return:1
Server did acknowledge servername extension.
---
Certificate chain
0 s:/OU=Domain Control Validated/OU=Gandi Standard Wildcard SSL/CN=*.freenode.net
i:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2
1 s:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2
i:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
2 s:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
...
<skip certificate and lots of other stuff>
...
Start Time: 1475924761
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
既然您知道如何测试它,以及好的测试用例是什么样子的,下面介绍如何在代码中修复它:
rv = SSL_CTX_load_verify_locations(
ssl_context,
".../addtrustexternalcaroot.crt",
NULL;
下面是CA根的外观:
$ cat addtrustexternalcaroot.crt | openssl x509 -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
Validity
Not Before: May 30 10:48:38 2000 GMT
Not After : May 30 10:48:38 2020 GMT
Subject: C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:b7:f7:1a:33:e6:f2:00:04:2d:39:e0:4e:5b:ed:
1f:bc:6c:0f:cd:b5:fa:23:b6:ce:de:9b:11:33:97:
a4:29:4c:7d:93:9f:bd:4a:bc:93:ed:03:1a:e3:8f:
cf:e5:6d:50:5a:d6:97:29:94:5a:80:b0:49:7a:db:
2e:95:fd:b8:ca:bf:37:38:2d:1e:3e:91:41:ad:70:
56:c7:f0:4f:3f:e8:32:9e:74:ca:c8:90:54:e9:c6:
5f:0f:78:9d:9a:40:3c:0e:ac:61:aa:5e:14:8f:9e:
87:a1:6a:50:dc:d7:9a:4e:af:05:b3:a6:71:94:9c:
71:b3:50:60:0a:c7:13:9d:38:07:86:02:a8:e9:a8:
69:26:18:90:ab:4c:b0:4f:23:ab:3a:4f:84:d8:df:
ce:9f:e1:69:6f:bb:d7:42:d7:6b:44:e4:c7:ad:ee:
6d:41:5f:72:5a:71:08:37:b3:79:65:a4:59:a0:94:
37:f7:00:2f:0d:c2:92:72:da:d0:38:72:db:14:a8:
45:c4:5d:2a:7d:b7:b4:d6:c4:ee:ac:cd:13:44:b7:
c9:2b:dd:43:00:25:fa:61:b9:69:6a:58:23:11:b7:
a7:33:8f:56:75:59:f5:cd:29:d7:46:b7:0a:2b:65:
b6:d3:42:6f:15:b2:b8:7b:fb:ef:e9:5d:53:d5:34:
5a:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
X509v3 Key Usage:
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Authority Key Identifier:
keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
DirName:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
serial:01
Signature Algorithm: sha1WithRSAEncryption
b0:9b:e0:85:25:c2:d6:23:e2:0f:96:06:92:9d:41:98:9c:d9:
84:79:81:d9:1e:5b:14:07:23:36:65:8f:b0:d8:77:bb:ac:41:
6c:47:60:83:51:b0:f9:32:3d:e7:fc:f6:26:13:c7:80:16:a5:
bf:5a:fc:87:cf:78:79:89:21:9a:e2:4c:07:0a:86:35:bc:f2:
de:51:c4:d2:96:b7:dc:7e:4e:ee:70:fd:1c:39:eb:0c:02:51:
14:2d:8e:bd:16:e0:c1:df:46:75:e7:24:ad:ec:f4:42:b4:85:
93:70:10:67:ba:9d:06:35:4a:18:d3:2b:7a:cc:51:42:a1:7a:
63:d1:e6:bb:a1:c5:2b:c2:36:be:13:0d:e6:bd:63:7e:79:7b:
a7:09:0d:40:ab:6a:dd:8f:8a:c3:f6:f6:8c:1a:42:05:51:d4:
45:f5:9f:a7:62:21:68:15:20:43:3c:99:e7:7c:bd:24:d8:a9:
91:17:73:88:3f:56:1b:31:38:18:b4:71:0f:9a:cd:c8:0e:9e:
8e:2e:1b:e1:8c:98:83:cb:1f:31:f1:44:4c:c6:04:73:49:76:
60:0f:c7:f8:bd:17:80:6b:2e:e9:cc:4c:0e:5a:9a:79:0f:20:
0a:2e:d5:9e:63:26:1e:55:92:94:d8:82:17:5a:7b:d0:bc:c7:
8f:4e:86:04
关于c - SSL_get_verify_result为irc.freenode.net返回错误20,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39930636/