有没有API可以在Windows上预先检索受信任的根证书列表?

前端之家收集整理的这篇文章主要介绍了有没有API可以在Windows上预先检索受信任的根证书列表?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用 Python和OpenSSL连接到使用TLS的站点(在某些跨平台的软件中,因此为了切换到CryptoAPI将会是太多的工作);不过,我不想分发(和更新)自定义的证书列表.我想从平台上得到他们.在OS X和Linux上,这是非常简单的,但Windows附带了TLS的受信任根证书颁发机构的不完整列表;基本上只是微软自己的证书,然后当高级别的TLS(例如通过HTTPS加载Internet Explorer中的网页)必须验证以前没有看到的信任根时,才会向商店动态添加信任根. (This process is explained here.)这意味着我可以 enumerate the Windows root certificate store with wincertstore,但它是无用的,因为在具有最近安装的操作系统的机器上,该商店几乎是空的.

Microsoft提供detailed instructions for administrators预先检索该列表,以便能够操作具有严格控制的网络访问的机器;但是,我找不到任何可以做同样事情的API的引用,只需从Microsoft下载所有受信任的根证书. (老实说,在每周多兆字节系统更新的时代,我不明白为什么预先下载这些是如此之大,如果它只是一个缓存;奖金积分请解释为什么这需要发生.)

那么,是否有API可以让我告诉系统只是根据它使用的规则预先缓存受信任的根证书?如果这是真的不可能的话(如果CryptoAPI只能一次下载一个信任根,并且只有在给它一个根目录下签名的证书的话)时,是否有办法将OpenSSL证书验证连接到CryptoAPI的信任存储,以便验证将下载并缓存信任根,就像一个本机TLS连接一样?

这不是一个理想的方法,但它应该是一个捏,它可能会让你在某个地方开始.此代码将使用certutil -generateSSTFromWU生成的.sst文件,并将所有证书添加到根存储区中:
#include <Windows.h>

#include <WinCrypt.h>

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

#include <stdio.h>

void process_cert(PCCERT_CONTEXT cert)
{
    PCCERT_CHAIN_CONTEXT ccc;
    CERT_CHAIN_PARA ccp = {sizeof(CERT_CHAIN_PARA)};
    DWORD flags;
    char certname[256];

    CertGetNameStringA(cert,CERT_NAME_SIMPLE_DISPLAY_TYPE,NULL,certname,_countof(certname));

    flags = 0;

    if (!CertGetCertificateChain(HCCE_LOCAL_MACHINE,cert,&ccp,flags,&ccc))
    {
        printf("Certificate %s CertGetCertificateChain: %u\n",GetLastError());
    }
    else
    {
        printf("Certificate %s : %x (%x)\n",ccc->TrustStatus.dwErrorStatus,ccc->TrustStatus.dwInfoStatus);
    }
}

void mainfn(void)
{
    HCERTSTORE sst;
    PCCERT_CONTEXT cert;
    DWORD count;

    sst = CertOpenStore(CERT_STORE_PROV_FILENAME_W,(HCRYPTPROV)NULL,CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG,L"c:\\downloads\\roots.sst");

    if (sst == NULL)
    {
        printf("CertOpenStore: %x\n",GetLastError());
        return;
    }

    for (cert = NULL,count = 0; cert = CertEnumCertificatesInStore(sst,cert); count++) process_cert(cert);

    {
        DWORD err = GetLastError();
        if (err != CRYPT_E_NOT_FOUND)
        {
            printf("CertEnumCertificate: %u\n",err);
            return;
        }
    }
}

int main(int argc,char ** argv)
{
    mainfn();
    return 0;
}

或者,在您的上下文中,您可能希望直接在.sst文件中使用根证书,而不必将其添加到根存储. (在这种情况下,您应该可以枚举根存储以及.sst文件,以便包括任何本地添加的证书.)

猜你在找的Windows相关文章