2012-02-29 59 views
25

我正在从Linux移植到Windows的一些正在运行的C++代码在Windows上失败,因为SSL_get_verify_result()正在返回X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLYWindows上的OpenSSL可以使用系统证书存储吗?

该代码在Linux上使用SSL_CTX_set_default_verify_paths()来告诉SSL仅查看证书存储的标准默认位置。

是否有可能让OpenSSL使用系统证书存储?

回答

34

我已经做了更早。 希望这有助于,如果这正是你正在寻找。

  1. 使用Crypto API从Windows Cert存储中加载您的证书(在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.使用“ROOT”(而不是“CA”)的enum windows商店。 2.您需要在连接/握手之前添加证书,并在连接/握手之后进行验证,否则验证将失败。 – 2016-07-29 04:46:19

2

不是开箱即用。

不,它是不可能开箱即用。这将需要额外的编程。使用OpenSSL你有两个(开箱)选项:

  1. 使用OpenSSL自己的证书存储(它是提供与OpenSSL的Perl脚本创建的目录层次结构)
  2. 只能使用一个证书链文件的创建你(它是一个包含信任链中所有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-rather-file-ssl-ctx-load-verify-locat描述了从缓冲区加载PEM文件的机制......? – dicroce 2012-02-29 23:26:01

+0

是的,这当然是可能的。 – sirgeorge 2012-03-01 00:36:34

+0

Yuck ...由于某种原因,它不喜欢我的文件(用该页面的代码制作)......我以前会认为有人会这样做吗? – dicroce 2012-03-01 00:58:57

2

它可以使用OpenSSL操作照常,并使用仅CryptoAPI为证书验证过程。我在这里看到围绕这个主题的几条线索,大多数都围绕着/通过。

随着CryptoAPI你必须:

  • 解码PEMDERCryptStringToBinary()
  • 创建CertCreateCertificateContext()
  • 一个CERT_CONTEXT对象,并验证证书以这种形式通过众所周知/文件的程序。 (例如here at ETutorials

    对于最后一步工作,你还需要初始化HCERTSTOREMY之一,ROOTCA系统存储,或通过他们根据你想要的行为迭代...。

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'参数(您使用转换来避免编译器错误)。您必须使用临时变量来避免内存问题,如下所示:'const unsigned char * encoded_cert = win_cert_context-> pbCertEncoded; d2i_X509(nullptr,&encoded_cert,...' – herolover 2017-11-07 07:57:56

相关问题