2016-09-29 37 views
1

私は有効な証明書(ルートCAによって署名された)に接続するためにboost asioを使用しています。私が使用しているコードは、boost docsから入手可能なssl client exampleです。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などの環境変数を設定しないでください。どのようにして、ブースト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ストアから証明書をロードします。 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

関連する問題