winapi - 在 CertAddEncodedCertificateToSystemStore 对面从 Windows 证书存储中获取 ASN1 证书?

标签 winapi ssl openssl certificate

我需要以编程方式检索 Windows 证书存储中的所有 CA 证书,以便在 OpenSSL 中使用。 Win32 有一个名为 CertAddEncodedCertificateToSystemStore 的函数,它与我需要的完全相反:

BOOL WINAPI CertAddEncodedCertificateToSystemStore(
  _In_  LPCSTR szCertStoreName,
  _In_  const BYTE *pbCertEncoded,
  _In_  DWORD cbCertEncoded
);

CertAddEncodedCertificateToSystemStore 从 X509 ASN1 数据缓冲区创建 PCCERT_CONTEXT 并将其添加到系统证书存储区。我需要通过系统证书存储,将 PCCERT_CONTEXT 转换为 X509 ASN1 数据缓冲区。

看起来 CertSerializeCertificateStoreElement 非常接近我想要的:

BOOL WINAPI CertSerializeCertificateStoreElement(
  _In_     PCCERT_CONTEXT pCertContext,
  _In_     DWORD dwFlags,
  _Out_    BYTE *pbElement,
  _Inout_  DWORD *pcbElement
);

...但显然 CertSerializeCertificateStoreElement() 返回的数据缓冲区不是正确的 DER ASN 编码 - 它有额外的“东西” - 某种 Windows 证书存储属性 - 我将无法使用它用于转换为 OpenSSL X509。

有什么想法吗?

最佳答案

这是我能够用来从系统存储中转储证书的内容。清理对象没有做任何特别的事情。它们只是关闭句柄、释放内存等。我还取消了错误检查以减小大小。

HCERTSTORE hCertStore = CertOpenSystemStore(NULL, _T("ROOT"));
CertStoreCleanup cleanup1(hCertStore);

PCCERT_CONTEXT pCertContext = NULL;
CertContextCleanup cleanup2(pCertContext);

while(pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext))
{
    CHAR filename[256] = {0};
    INT rc = sprintf_s(filename, sizeof(filename), "cert-%02d.der", i);

    FILE* fp = NULL;
    errno_t et = fopen_s(&fp, filename, "w");
    FileCleanup cleanup3(fp);

    BYTE* pCert = pCertContext->pbCertEncoded;
    DWORD dwSize = pCertContext->cbCertEncoded;

    fwrite(pCert, (size_t)dwSize, 1, fp);
}

不幸的是,Gutmann 的 dumpasn1 或 OpenSSL 的 asn1parse 都不能处理它们。有趣的是,Microsoft 自己的 Certificates snap-in 无法解析它。 Microsoft Connect 上有一个错误报告:CertEnumCertificatesInStore and friends provide a malformed certifcate .

它们一开始看起来很正常,但在解析中途中断了。例如,这是 Gutmann 在 Microsoft 根证书上的 dumpasn1:

enter image description here

OpenSSL 的 asn1parse 有同样的提示:

enter image description here


最后,Microsoft 在 Using Certificates 提供了一些示例.

关于winapi - 在 CertAddEncodedCertificateToSystemStore 对面从 Windows 证书存储中获取 ASN1 证书?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24276431/

相关文章:

php - 在哪里可以找到 PHP 默认使用的默认系统证书?

c++ - 将 PAGE_GUARD 保护设置为大页面

c++ - 最小化全屏窗口的最佳方法

ubuntu - SSL 证书不工作 - "no start line"错误 - Apache2 Ubuntu 16.04.1

java - 提取服务器证书

c - openssl 编译错误

c++ - 无法将 struct** 转换为 const POINT* 作为参数?

c - LeaveCriticalSection() 是否将缓存的变量刷新到内存中?

ssl - 如何在树莓派上验证 openssl 证书?

rest - 使用 SSL 的 SoapUI REST 模拟服务