我需要以编程方式检索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。
有什么想法吗?
答案 0 :(得分:0)
这是我能用于从系统存储转储证书的内容。清理对象不做任何特别的事情。他们只是关闭句柄,释放内存等等。我还抽出了错误检查以保持大小不变。
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 Connect的错误报告:CertEnumCertificatesInStore and friends provide a malformed certifcate。
他们看起来很正常,但他们在解析中途中断了。例如,这是微软根证书上的Gutmann的dumpasn1
:
OpenSSL' asn1parse
也有同样的抱怨:
最后,Microsoft在Using Certificates上有一些示例。