我需要以编程方式检索 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
:
OpenSSL 的 asn1parse
有同样的提示:
最后,Microsoft 在 Using Certificates 提供了一些示例.
关于winapi - 在 CertAddEncodedCertificateToSystemStore 对面从 Windows 证书存储中获取 ASN1 证书?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24276431/