2012-02-29 19 views
25

SSL_get_verify_result()X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLYを返すので、LinuxからWindowsに移植している動作中のC++コードの一部がウィンドウで失敗しています。WindowsのOpenSSLはシステム証明書ストアを使用できますか?

このコードでは、Linux上でSSL_CTX_set_default_verify_paths()を使用して、証明書ストアの標準のデフォルトの場所を調べるようにSSLに指示していました。

OpenSSLでシステム証明書ストアを使用することはできますか?

答えて

34

私はこれまでに行っています。 これがあなたが探しているものであれば、これが役に立ちます。

  1. クリプトAPIを使用してWindows証明書ストアから証明書(PCCERT_CONTEXTの構造内)をロードします。
  2. 暗号化されたコンテンツをそのままバイナリ形式で取得します。 [PCCERT_CONTEXT->pbCertEncoded]。
  3. OpenSSLのd2i_X509()メソッドを使用して、このバイナリバッファをX509証明書オブジェクトに解析します。
  4. SSL_CTX_get_cert_store()メソッドを使用して、OpenSSLのトラストストアへのハンドルを取得します。
  5. X509_STORE_add_cert()メソッドを使用して、このトラストストアに解析済みのX509証明書をロードします。
  6. あなたは完了です!
+0

情報ありがとうございます。私はこれにいくつかの注意を追加する必要があります:1. "ルート"( "CA"ではない)とウィンドウズストアを列挙する。 2.接続/ハンドシェイクの前に証明書を追加し、接続/ハンドシェイク後に確認する必要があります。そうでないと、検証は失敗します。 –

2

いいえ、すぐに使用できます。

いいえはありませんの商品です。追加プログラミングが必要になります。 OpenSSLのを使用すると、2(ボックス外)のオプションがあります。

  1. 使用OpenSSLの独自の証明書ストアで作成された
  2. のみを使用して証明書チェーンファイル(これには、OpenSSLを提供するのperlスクリプトによって作成されたディレクトリの階層です)あなた(これは、信頼チェーン内のすべてのPEMエンコードされた証明書を含むテキストファイルです)。このようなファイルを作成するのは簡単です(追加するだけです)。
+0

窓からメモリにPEMファイルを作成することができるかもしれませんpkcsファイルですか?それをロードする?私は見つかりました:http://marc.info/?l=openssl-users&m=119583966725315 pkcsパッケージからのPEMファイルの作成について説明しています...そして、http://stackoverflow.com/questions/5052563/c-openssl-useバッファよりもむしろ-root-ca-from-buffer-ssl-ctx-load-verify-locatはバッファからPEMファイルをロードするメカニズムを記述しています...? – dicroce

+0

はい、確かに可能です。 – sirgeorge

+0

Yuck ...何らかの理由で、(そのページのコードで作られた)私のファイルが好きではありません...私の前に誰かがこれをしたと思いますか? – dicroce

2

はい

動作として、通常のためOpenSSLを使用し、唯一の証明書検証プロセスのためCryptoAPIを使用することが可能です。私はこのトピックの周りにいくつかのスレッドを見て、そしてほとんどが前後に刻まれています。 CryptoAPI

あなたがする必要があります:CryptStringToBinary()DER

  • デコードPEM
  • CertCreateCertificateContext()
  • CERT_CONTEXTオブジェクトを作成し、十分に文書化/知られた手順により、この形式で証明書を検証します。 (たとえばhere at ETutorialsため。)

    最後のステップが機能するためには、あなたもMYのいずれかのHCERTSTOREROOTCAシステムストアを初期化するか、またはそれらを反復処理...あなたが望む行動に依存する必要があります。私がされているとしても、このに苦しんであなたのそれらのために

10

、ここにあなたが始めるためのサンプルコードです:

#include <stdio.h> 
#include <windows.h> 
#include <wincrypt.h> 
#include <cryptuiapi.h> 
#include <iostream> 
#include <tchar.h> 

#include "openssl\x509.h" 

#pragma comment (lib, "crypt32.lib") 
#pragma comment (lib, "cryptui.lib") 

#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) 

int main(void) 
{ 
    HCERTSTORE hStore; 
    PCCERT_CONTEXT pContext = NULL; 
    X509 *x509; 
    X509_STORE *store = X509_STORE_new(); 

    hStore = CertOpenSystemStore(NULL, L"ROOT"); 

    if (!hStore) 
     return 1; 

    while (pContext = CertEnumCertificatesInStore(hStore, pContext)) 
    { 
     //uncomment the line below if you want to see the certificates as pop ups 
     //CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, pContext, NULL, NULL, 0, NULL); 

     x509 = NULL; 
     x509 = d2i_X509(NULL, (const unsigned char **)&pContext->pbCertEncoded, pContext->cbCertEncoded); 
     if (x509) 
     { 
      int i = X509_STORE_add_cert(store, x509); 

      if (i == 1) 
       std::cout << "certificate added" << std::endl; 

      X509_free(x509); 
     } 
    } 

CertFreeCertificateContext(pContext); 
CertCloseStore(hStore, 0); 
system("pause"); 
return 0; 

} 
+1

'd2i_X509'は、' d2i_X509'が '* in'引数をインクリメントするため(コンパイラエラーを避けるためにキャストを使用しているため)、無効です。メモリの問題を回避するには、次のようにtemp変数を使用する必要があります: 'const unsigned char * encoded_cert = win_cert_context-> pbCertEncoded; d2i_X509(nullptr、&encoded_cert、... ' – herolover

関連する問題