2016-09-29 401 views
1

我使用boost asio连接到我的有效证书(由根CA签名)。我正在使用的代码是ssl client example可从boost文档中获得。在Windows上获取根CA证书的可靠方法

我加入的唯一路线是:

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以查找它们?

回答

2

您可以从Windows CA存储加载根CA.它已包含“默认”可信根CA证书,可通过certmgr进行管理。使用以下函数替换窗口下的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