CertGetCertificateChain 函数 (wincrypt.h)

CertGetCertificateChain 函数从结束证书开始生成证书链上下文,并尽可能返回到受信任的 根证书

语法

BOOL CertGetCertificateChain(
  [in, optional] HCERTCHAINENGINE     hChainEngine,
  [in]           PCCERT_CONTEXT       pCertContext,
  [in, optional] LPFILETIME           pTime,
  [in]           HCERTSTORE           hAdditionalStore,
  [in]           PCERT_CHAIN_PARA     pChainPara,
  [in]           DWORD                dwFlags,
  [in]           LPVOID               pvReserved,
  [out]          PCCERT_CHAIN_CONTEXT *ppChainContext
);

参数

[in, optional] hChainEngine

要使用的链引擎(命名空间和缓存)的句柄。 如果 hChainEngineNULL,则使用默认链引擎 HCCE_CURRENT_USER。 此参数可以设置为 HCCE_LOCAL_MACHINE

[in] pCertContext

指向要为其生成链的证书的结束证书 CERT_CONTEXT 的指针。 此证书上下文将是第一个简单链中的零索引元素。

[in, optional] pTime

指向 FILETIME 变量的指针,该变量指示要验证链的时间。 请注意,时间不会影响信任列表、吊销或根存储检查。 如果 NULL 传递给此参数,则使用当前系统时间。 对作为受信任根目录的特定证书的信任基于根存储的当前 状态,而不是此参数传入的根存储的状态。 对于吊销,证书吊销列表(CRL)本身必须在当前时间有效。 此参数的值用于确定是否吊销了 CRL 中列出的证书。

[in] hAdditionalStore

用于搜索支持证书和 证书信任列表(CCL)的任何其他存储的句柄。 如果未搜索其他存储,则可以 NULL 此参数。

[in] pChainPara

指向包含链式生成参数的 CERT_CHAIN_PARA 结构的指针。

[in] dwFlags

指示特殊处理的标志值。 此参数可以是以下一个或多个标志的组合。

价值 意义
CERT_CHAIN_CACHE_END_CERT
0x00000001
设置此标志后,将缓存结束证书,这可能会加快链生成过程。 默认情况下,不会缓存结束证书,并且每次为其生成链时都需要对其进行验证。
CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY
0x80000000
吊销检查仅访问缓存的 URL。 这会阻止对最终证书或 CA 证书的网络检索 CRL 或 OCSP。 CACHE_ONLY 取决于计算机上已从网络检索 CRL 或 OCSP 的好友。
CERT_CHAIN_REVOCATION_CHECK_OCSP_CERT
0x04000000
此标志在链生成过程中用于 联机证书状态协议(OCSP)签名者证书,以防止循环吊销检查。 在链生成期间,如果 OCSP 响应由独立的 OCSP 签名者签名,则除了原始链生成之外,还有一个为 OCSP 签名者证书本身构建的第二个链。 此标志在第二个链生成期间用于抑制递归独立 OCSP 签名者证书。 如果签名者证书包含 szOID_PKIX_OCSP_NOCHECK 扩展,则会跳过叶签名者证书的吊销检查。 允许 OCSP 和 CRL 检查。

Windows Server 2003 和 Windows XP: 不支持此值。
CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL
0x00000004
仅在生成证书链时使用缓存的 URL。 Internet 和 Intranet 不会搜索基于 URL 的对象,例如 CTL cab、第三方根和 AIA 颁发者。 大多数根应位于 crypt32.dll 资源中。 如果不是,则此检索是防止链生成错误所必需的。 这些 cab 和根托管在高性能Microsoft CDN 服务器上。

注意: 此标志不适用于吊销检查。 将 CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY 设置为仅使用缓存的 URL 进行吊销检查。 通常,CTL cab 已通过 cryptsvc 服务预提取。
CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING0x00000040 出于性能原因,链生成的第二个通道只考虑质量大于或等于第一次通过期间确定的最高质量的潜在链路径。 第一个传递仅考虑有效的签名、完整的链和受信任的根来计算链质量。 可以将此标志设置为禁用此优化,并在第二次传递期间考虑所有潜在的链路径。
CERT_CHAIN_DISABLE_MY_PEER_TRUST
0x00000800
不支持此标志。 “我的”存储中的证书永远不会被视为对等信任。
CERT_CHAIN_ENABLE_PEER_TRUST
0x00000400
“TrustedPeople”存储中的结束实体证书是受信任的,无需执行任何链生成。 此函数不设置 CERT_TRUST_IS_PARTIAL_CHAINCERT_TRUST_IS_UNTRUSTED_ROOTdwErrorStatusppChainContext 参数的成员位。

Windows Server 2003 和 Windows XP:不支持 此标志。
CERT_CHAIN_OPT_IN_WEAK_SIGNATURE
0x00010000
设置此标志表示调用方希望选择弱签名检查。

此标志在从 Windows 7 和 Windows Server 2008 R2 开始的每个 OS 的汇总更新中可用。
CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS
0x00000080
默认值为仅返回最高质量的链路径。 设置此标志将返回质量较低的链。 这些在链上下文的 cLowerQualityChainContextrgpLowerQualityChainContext 字段中返回。
CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE
0x00000100
设置此标志会阻止 Windows 更新 Web Server 中第三方根的自动更新。
CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT
0x08000000
设置 CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT 并且还指定 CERT_CHAIN_PARA 结构的 dwUrlRetrievalTimeout 成员的值时,在 dwUrlRetrievalTimeout 中指定的值表示所有吊销 URL 检索的累积超时。

如果设置 CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT 但不指定 dwUrlRetrievalTimeout 值,则默认将最大累积超时设置为 20 秒。 经过测试的每个 URL 将在剩余累积余额的一半后超时。 也就是说,第一个 URL 在 10 秒后超时,第二个 URL 在 5 秒后,第三个在 2.5 秒后等时间,直到 URL 成功,20 秒才通过,或者没有更多要测试的 URL。

如果未设置 CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT,则链中的每个吊销 URL 将分配最大超时值,等于 dwUrlRetrievalTimeout中指定的值。 如果未为 dwUrlRetrievalTimeout 成员指定值,则会为每个吊销 URL 分配最大默认超时 15 秒。 如果未成功 URL,则最大累积超时值为 15 秒,乘以链中的 URL 数。

可以使用组策略设置默认值。
CERT_CHAIN_TIMESTAMP_TIME
0x00000200
设置此标志时,pTime 用作时间戳时间,以确定结束证书是否有效。 当前时间还可用于确定结束证书是否保持有效时间。 链中的所有其他 证书颁发机构(CA)和根证书均使用当前时间进行检查,而不是 pTime
CERT_CHAIN_DISABLE_AIA
0x00002000
设置此标志会显式关闭颁发机构信息访问(AIA)检索。 有时 TLS 服务器配置不正确,并且不会在握手中包含正确的 CA 证书。

还可以设置以下吊销标志,但一次只能设置此组中的一个标志。

价值 意义
CERT_CHAIN_REVOCATION_CHECK_END_CERT
0x10000000
吊销检查是在结束证书上完成的,仅对结束证书执行。
CERT_CHAIN_REVOCATION_CHECK_CHAIN
0x20000000
对每个链中的所有证书执行吊销检查。
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
0x40000000
对除根证书以外的所有链中的所有证书执行吊销检查。

[in] pvReserved

此参数是保留的,必须 NULL

[out] ppChainContext

指向所创建的链上下文的指针的地址。 使用完链上下文后,通过调用 CertFreeCertificateChain 函数释放链。

返回值

如果函数成功,该函数将返回非零(TRUE)。

如果函数失败,则返回零(FALSE)。 有关扩展错误信息,请调用 GetLastError

言论

当应用程序请求证书链时,返回的结构采用 CERT_CHAIN_CONTEXT的形式。 此上下文包含一组 CERT_SIMPLE_CHAIN 结构,其中每个简单链从一个结束证书到自签名证书。 链上下文通过信任列表连接简单链。 每个简单链都包含证书链、有关链的摘要信任信息,以及有关链中每个证书元素的信任信息。

以下注释适用于强签名检查:

  • 可以通过设置 pChainPara 参数指向的 CERT_CHAIN_PARA 结构的 pStrongSignPara 成员来为此函数启用强签名检查。
  • 如果在链中找到没有强签名的证书,则会在 CERT_TRUST_STATUS 结构的 dwErrorStatus 字段中设置 CERT_TRUST_HAS_WEAK_SIGNATURECERT_TRUST_IS_NOT_SIGNATURE_VALID 错误。 ppChainContext 参数指向 CERT_CHAIN_CONTEXT 结构,而该结构又指向 CERT_TRUST_STATUS 结构。
  • 如果链具有强签名,则会检查最终证书中的公钥,以确定它是否满足强签名的最低公钥长度要求。 如果未满足条件,则会在 CERT_TRUST_STATUS 结构的 dwErrorStatus 字段中设置 CERT_TRUST_HAS_WEAK_SIGNATURECERT_TRUST_IS_NOT_SIGNATURE_VALID 错误。 若要禁用检查密钥长度,请在 pChainPara 参数指向的 CERT_CHAIN_PARA 结构 成员中设置 dwStrongSignFlags 中的 CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG 值。
  • 如果在 CERT_STRONG_SIGN_SERIALIZED_INFO 结构中设置了 CERT_STRONG_SIGN_ENABLE_CRL_CHECKCERT_STRONG_SIGN_ENABLE_OCSP_CHECK 标志,并且未找到具有强签名的 CRL 或 OCSP 响应,CRL 或 OCSP 响应将被视为脱机。 也就是说,在 CERT_TRUST_STATUS 结构的 dwErrorStatus 字段中设置 CERT_TRUST_IS_OFFLINE_REVOCATIONCERT_TRUST_REVOCATION_STATUS_UNKNOWN 错误。 此外,CERT_REVOCATION_INFO 结构的 dwRevocationResult 成员设置为 NTE_BAD_ALGID

以下建议适用于调用这些 API 的任何 Windows 应用程序,以验证 TLS 服务器身份验证证书:

  • 仅对结束证书启用吊销检查。
    • 设置 CERT_CHAIN_REVOCATION_CHECK_END_CERT 标志。
    • 大多数 CA 证书的 CRL 有效期为 1 到 6 个月。
      • 由于缓存了下载的 CRL,因此此有效性太长,无法产生太多值。
    • 如果存在 CA 泄露,则证书也会添加到 Windows 不允许的 CTL
    • TLS 服务器的建议做法是支持用于结束证书的 OCSP 装订。
      • 在这种情况下,除非装订的 OCSP 响应已过期,否则不需要网络检索。
  • 为 CRL、OCSP、AIA 颁发者和 Windows 平台 CTL cab 和第三方根启用网络检索。
    • 设置上述 CERT_CHAIN_REVOCATION_CHECK_END_CERT 时,这是默认值。
    • 不要设置以下任何标志来防止网络检索。 有关这些标志的详细信息,请参阅上面的 dwFlags 表:
      • CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL
      • CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY
      • CERT_CHAIN_DISABLE_AIA
  • 为 CRL 和 OCSP 网络检索启用累积超时。
    • 设置传递给 CertGetCertificateChainCERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT 标志。
    • 提供 CRL 和 OCSP 网络检索允许的总时间上限。
  • 将每个网络检索允许的最大时间从 15 秒减少到 10 秒。
    • 将传递给 CertGetCertificateChain 的 CERT_CHAIN_PARA 中的 dwUrlRetrievalTimeout 字段设置为 10 * 1000 毫秒。
    • 这还会将累积超时从 20 秒减少到 10 秒。
      • 只应下载用于结束证书的 OCSP 响应。 5 秒应该足以下载该下载。
  • 忽略脱机吊销错误。
  • 缓存结束证书验证信息。
    • 设置 CERT_CHAIN_CACHE_END_CERT
      • 除了中间证书之外,还支持对结束证书的信息进行 LRU 缓存。
    • 与同一服务器建立多个 TLS 连接很常见。

例子

有关使用此函数的示例,请参阅 示例 C 程序:创建证书链

要求

要求 价值
最低支持的客户端 Windows XP [桌面应用 |UWP 应用]
支持的最低服务器 Windows Server 2003 [桌面应用 |UWP 应用]
目标平台 窗户
标头 wincrypt.h
Crypt32.lib
DLL Crypt32.dll

另请参阅

CERT_CHAIN_PARA

CertDuplicateCertificateChain

CertFreeCertificateChain

证书链验证函数