0

当服务器提供的证书上的名称都与 pszTargetName 参数(本质上是服务器的名称)不匹配时,InitializeSecurityContext (Schannel) 失败并显示 SEC_E_WRONG_PRINCIPAL。

如果您有一个完整的安全上下文,您可以通过调用 QueryContextAttributes 获取 SECPKG_ATTR_REMOTE_CERT_CONTEXT 来获取服务器的证书。如果将来自失败的 InitializeSecurityContext 协商的部分形成的安全上下文用作 phContext 参数,则对 QueryContextAttributes 的调用失败并显示 SEC_E_INVALID_HANDLE。

在这种情况下,客户端是否有办法访问服务器发送的证书,以便我们可以报告证书上的名称?

注意。如果我们真的想这样做,我们可能会重做协商,指定 ISC_REQ_MANUAL_CRED_VALIDATION,然后在安全上下文上调用 QueryContextAttributes(然后立即销毁它),但这似乎很愚蠢。

4

1 回答 1

0

您可以尝试SCH_CRED_NO_SERVERNAME_CHECKSCH_CREDENTIALS.dwFlags. 您可能必须与 结合使用SCH_CRED_SNI_CREDENTIAL。但是,您必须在检查名称后通过在代码中发送 TLS 警报来中止连接。这些链接可能会有所帮助:
https ://github.com/tokio-rs/tokio-tls/issues/32
https://social.msdn.microsoft.com/Forums/vstudio/en-US/0b7e3858-00ef-41f9 -8772-dd1896e519ac/how-to-add-sni-client-hello-extension-using-schannel-api

否则,如果您希望内联执行此操作,您可能不得不在手动协商时对接收到的数据进行手动 ASN.1 解析以查找证书。此功能可能有用:CertCreateCertificateContext

于 2021-01-28T12:55:40.143 回答