我需要在应用程序中信任一些自签名证书,因此我像这样覆盖了验证回调:
ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
...
public static bool MyRemoteCertificateValidationCallback(
Object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
if (IsAprrovedByMyApplication(sender, certificate)) // <-- no matter what the check here is
return true;
else
return false; // <-- here I'd like to call the default Windows handler rather than returning 'false'
}
但是当出现某些策略错误并且我连接的站点未经应用程序批准时,会抛出异常。问题在于它与标准的 Windows 行为不同。
考虑这个网站:https://www.dscoduc.com/。它的证书具有未知颁发者,因此不受信任。我已经使用 MMC 将其添加到本地计算机的受信任人员 (它是 Windows 7) 中。
如果我在没有覆盖证书验证回调的情况下运行此代码:
HttpWebRequest http = (HttpWebRequest)HttpWebRequest.Create("https://www.dscoduc.com/");
using (WebResponse resp = http.GetResponse())
{
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
string htmlpage = sr.ReadToEnd();
}
}
它成功连接。 这意味着Windows默认验证器决定信任此证书。
但是一旦我覆盖了ServerCertificateValidationCallback,我的回调函数就会收到SslPolicyErrors.RemoteCertificateChainErrors, 并且链中包含一个状态为X509ChainStatusFlags.PartialChain的元素(实际上,我希望在这里不收到任何错误,因为当前证书应该是受信任的)
此站点未包含在我的受信任列表中,也不想从我的回调函数中返回“true”。 但我也不想返回“false”,否则我会收到异常:“根据验证过程,远程证书无效”,这显然对于https://www.dscoduc.com/来说是不符合预期的,因为它已添加到受信任人员存储,并且在未覆盖证书回调时被Windows批准。 因此,我希望Windows对此站点采取默认的验证程序。我不想自己查看Windows受信任存储并浏览所有链元素,因为它已经(并且希望正确地)在Windows中实现。
换句话说,我需要显式信任由用户批准的站点(存储在其设置的某个位置),并对所有其他站点调用默认的认证检查。
ServicePointManager.ServerCertificateValidationCallback 的默认值为 null,因此没有“默认”回调供我稍后调用。我该如何调用此“默认”证书处理程序?