我正在使用boost asio连接到我的有效证书(由根CA签名)。我正在使用的代码是来自boost docs的ssl client example。
我添加的唯一一行是:
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23_client);
ctx.set_default_verify_paths(); <------------- Add default verification paths
ctx.set_password_callback(&password_callback);
client c(io_service, ctx, iterator);
io_service.run();
问题是:将此代码与本地安装的openSSH副本(从msi安装程序安装)一起使用时,可以正确找到路径并验证我的证书。当我下载我自己的openSSH存储库副本并编译它时,这一行不再有效,我没有根CA证书来验证我自己的那个(因此它失败)。
由于我想最终在客户机器上分发这些客户端,我想避免设置像SSL_CERT_DIR
之类的环境变量。如何可靠地使用boost asio找到根CA证书,或者从源代码编译中配置我的openSSH以找到它们?
答案 0 :(得分:5)
您可以从Windows CA存储加载根CA.它已包含“默认”受信任的根CA证书,可以通过certmgr进行管理。使用以下函数替换windows:
下的set_default_verify_paths#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) {
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);
SSL_CTX_set_cert_store(ctx.native_handle(), store);
}
这将从windows ca store加载证书。它使用d2i_X509将它们转换为内部OpenSSL格式,并将它们添加到OpenSSL X509_STORE。然后SSL_CTX_set_cert_store将该存储附加到boost 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);
#if BOOST_OS_WINDOWS
add_windows_root_certs(ctx);
#else
ctx.set_default_verify_paths();
#endif
ctx.set_password_callback(&password_callback);
client c(io_service, ctx, iterator);
io_service.run();
注意:您可能需要将crypt32添加到链接库中。
注2:BOOST_OS_WINDOWS需要Boost Predef