提振.Asio SSL上下文没有验证证书
Boost.Asio SSL context not verifying certificate(s)
这是我上一个问题的延续,Boost。Asio SSL上下文load_verify_paths未加载证书。
我有一个从Windows上的系统CA存储生成的CA文件。生成的文件中不包含任何无效/过期的证书。
我的Boost Asio代码不希望使用此CA存储进行验证。文件加载正常,ssl::context::load_verify_file
返回时没有错误,但是当preverified
设置为false
时,校验回调继续被调用。
下面是一个使用证书文件运行openssl的例子:
Loading 'screen' into random state - done
CONNECTED(00000178)
depth=3 /C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
verify return:1
depth=2 /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA
Certification Authority
verify return:1
depth=1 /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA
Domain Validation Secure Server CA
verify return:1
depth=0 /OU=Domain Control Validated/OU=PositiveSSL/CN=example.org
verify return:1
---
Certificate chain
0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=example.org
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
...snipped...
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/OU=PositiveSSL/CN=example.org
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
Acceptable client certificate CA names
/OU=Domain Control Validated/OU=PositiveSSL/CN=example.org
/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
SSL handshake has read 5399 bytes and written 334 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: 8C04CCAE22F4B111AD13F10448ACDAD0C7F567F22C0D05829BDAE1DF9F29A005
Session-ID-ctx:
Master-Key: B99A5E1D0C3CF5421C41CDE88B6F21FD9816800409775C497859FAFCAE3A8942
1A670D72808C804A33A10BF9A26B22AB
Key-Arg : None
Start Time: 1477664766
Timeout : 300 (sec)
Verify return code: 0 (ok)
再运行一次没有证书文件的openssl:
Loading 'screen' into random state - done
CONNECTED(00000178)
depth=2 /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=example.org
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
...snipped...
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/OU=PositiveSSL/CN=example.org
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
Acceptable client certificate CA names
/OU=Domain Control Validated/OU=PositiveSSL/CN=example.org
/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
SSL handshake has read 5399 bytes and written 334 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: 18036DF0E136729F9FE1BD8F51AA2FEF687D84D43918895B3F5847A2EB8C7109
Session-ID-ctx:
Master-Key: DA4BCC28FB9F4F5BCD9C9FBB51AA02B8A380F0580258A0F67E56BA2BFD627C54
AB700C343F0741A77AC037E54272EB1E
Key-Arg : None
Start Time: 1477665097
Timeout : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
您可以看到,证书文件包含适当的根证书,因为openssl只在使用该文件时连接。
我的问题是,为什么openssl使用这个文件进行验证,而Boost Asio没有?我如何纠正这个问题,以便Boost Asio使用生成的CA存储进行验证?
如果您的目标是将windows ca存储与boost ssl一起使用,您可以将存储中的证书"附加"到boost ssl上下文中,如下所示:
#include <boost/asio/ssl/context.hpp>
#include <wincrypt.h>
void add_windows_root_certs(boost::asio::ssl::context &ctx)
{
HCERTSTORE hStore = CertOpenSystemStore(0, "ROOT");
if (hStore == NULL) {
return;
}
X509_STORE *store = X509_STORE_new();
PCCERT_CONTEXT pContext = NULL;
while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) != NULL) {
// convert from DER to internal format
X509 *x509 = d2i_X509(NULL,
(const unsigned char **)&pContext->pbCertEncoded,
pContext->cbCertEncoded);
if(x509 != NULL) {
X509_STORE_add_cert(store, x509);
X509_free(x509);
}
}
CertFreeCertificateContext(pContext);
CertCloseStore(hStore, 0);
// attach X509_STORE to boost ssl context
SSL_CTX_set_cert_store(ctx.native_handle(), store);
}
这将从windows ca存储加载证书(类似于您链接的问题)。但是,它没有将证书转换为base64,而是使用d2i_X509将它们转换为内部OpenSSL格式,并将它们添加到OpenSSL X509_STORE中。然后SSL_CTX_set_cert_store将该存储附加到boost ssl上下文。你可以用它来设置ssl上下文然后用它来设置ssl套接字:
namespace ssl = boost::asio::ssl;
ssl::context ctx(ssl::context::tlsv12_client);
ctx.set_options(ssl::context::default_workarounds
| ssl::context::no_sslv2
| ssl::context::no_sslv3
| ssl::context::tlsv12_client);
add_windows_root_certs(ctx);
ctx.set_verify_mode(ssl::verify_peer | ssl::verify_fail_if_no_peer_cert);
// use custom verify_callback here for debugging purposes
ctx.set_verify_callback(ssl::rfc2818_verification(address));
ssl::stream<boost::asio::ip::tcp::socket> socket(io, ctx);
// socket ready to connect to ssl host
问题是创建了另一个没有加载系统证书的boost::asio::ssl::context
,相反,它使用的是set_default_verify_paths
,它在Linux上工作,但不能在Windows上工作。它在Linux上工作,因为系统证书在默认的验证路径中,但在Windows上,它是一个空目录(我没有为我的OpenSSL安装任何证书)。
对于其他遇到类似问题的人,请确保您实际使用的是正在加载证书的boost::asio::ssl::context
,这样您就不会像我一样浪费那么多时间了。
- 如何使用OPENSL使用OCSP验证证书
- 如何使用相应的 X509 证书验证专用 RSA 签名签名
- 如何读取证书以使用 openssl 验证签名
- 使用 WinInet 的客户端身份验证(证书 + 私钥)
- 证书验证在客户端服务器通信中使用boost :: asio和openssl失败
- 如何验证视频卡驱动程序证书
- 验证 x509 证书
- 无法使用OpenSSL验证服务器证书
- 使用libcurl的CA证书身份验证
- 由于SSL3_GET_CLIENT_CERTIFICATE:未返回证书,验证 SSL 客户端真实性失败
- 验证 Char[] 中加载的 SSL 证书或 C/C++ 中的内存
- Boost、asio、https 和主机/证书验证
- 在Windows上创建一个SSL套接字,该套接字使用WinCrypt证书进行身份验证
- Boost:asio验证证书同步
- 验证加载的DLL是否具有有效证书的最安全方法是什么
- Casablanca C++Rest-如何禁用证书验证
- 提振.Asio SSL上下文没有验证证书
- 读取和验证证书
- 从可执行文件中读取并验证证书
- 在STACK_OF(X509)中验证证书链