需要帮助按模板检索 Windows 证书

Need help to retrieve a Windows Certificate by Template?

本文关键字:检索 Windows 证书 帮助      更新时间:2023-10-16

我需要使用Windows API C++按模板名称检索Windows证书(模板在扩展字段中)。

我的步骤:

  1. Open store: CertOpenStore(..) (完成;我可以使用 CertEnumCertificatesInStore(..) 枚举证书,但我只看到它们的"版本 1 字段",而不是"扩展"。模板在扩展中,所以我找不到它。

  2. 我试图使用CertFindCertificateInStore()找到它,但没有成功。任何人都可以帮助我正确的查找类型和参数或使用其他函数吗?

  3. CertFreeCertificateContext(..), CertCloseStore(..) (完成).

我想发布我的代码,希望它对某人有所帮助。

void GetCertificateByTemplate(char *certificateTemplate)
{
    HCERTSTORE          hCertStore;
    PCCERT_CONTEXT      pCertContext = NULL;
    BYTE               *pbDecoded;
    DWORD               cbDecoded;
    _CERT_TEMPLATE_EXT *pbDecodedTemplate = NULL;
    // 1). Open Local Machine certificate store
    if (hCertStore = CertOpenStore(
        CERT_STORE_PROV_SYSTEM,
        0,
        NULL,
        CERT_SYSTEM_STORE_LOCAL_MACHINE,
        L"My"))
    {
        fprintf(stderr, "The store has been opened. n");
    }
    // 2). Enumerate certificates
    while (pCertContext = CertEnumCertificatesInStore(
        hCertStore,
        pCertContext))
    {
        // 3). Check certificate extended data
        for (int i = 0; i < pCertContext->pCertInfo->cExtension; i++)
        {
            // 4). Decode certificate extended data
            if (CryptDecodeObject(
                X509_ASN_ENCODING,
                pCertContext->pCertInfo->rgExtension[i].pszObjId,
                pCertContext->pCertInfo->rgExtension[i].Value.pbData,
                pCertContext->pCertInfo->rgExtension[i].Value.cbData,
                0,
                NULL,
                &cbDecoded))
            {
                ; // error !!!
            }
            if (!(pbDecoded = (BYTE*)malloc(cbDecoded)))
            {
                ; // error !!!
            }
            if (CryptDecodeObject(
                X509_ASN_ENCODING,
                pCertContext->pCertInfo->rgExtension[i].pszObjId,
                pCertContext->pCertInfo->rgExtension[i].Value.pbData,
                pCertContext->pCertInfo->rgExtension[i].Value.cbData,
                0,
                pbDecoded,
                &cbDecoded))
            {
                pbDecodedTemplate = (_CERT_TEMPLATE_EXT*)pbDecoded;
                char* objectId = pbDecodedTemplate->pszObjId;
                // todo: check pDecodeTemplate->pszObjId
                // 5). Compare the template string with the search one
                if (strcmp(pbDecodedTemplate->pszObjId, certificateTemplate) == 0)
                {
                    // todo: return certificate
                    printf("nCertificate template found: %s n", pbDecodedTemplate->pszObjId);   
                    break;
                }
            }
        }
    }
    // 6). Free certificate, close store
    if (pCertContext)
    {
        CertFreeCertificateContext(pCertContext);
    }
    CertCloseStore(hCertStore, 0);
}