Как вызвать проверку сертификата по умолчанию при переопределении ServicePointManager.ServerCertificateValidationCallback в C#?

Мне нужно доверять некоторым самоподписанным сертификатам в приложении, поэтому я переопределяю обратный вызов проверки следующим образом:

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 Windwos 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, мой callback вызывается с SslPolicyErrors.RemoteCertificateChainErrors и цепочка содержит один элемент со статусом X509ChainStatusFlags.PartialChain (на самом деле я ожидал бы не получить никаких ошибок здесь, потому что текущий сертификат должен быть доверенным)

Этот сайт не включен в мой список доверенных, и я не хочу возвращать 'true' из моего обратного вызова. Но я также не хочу возвращать 'false', иначе я получу исключение: "The remote certificate is invalid according to the validation procedure", что явно не ожидается для https://www.dscoduc.com/, поскольку он добавлен в хранилище Trusted People, и одобрен Windows, когда обратный вызов сертификата не переопределен. Поэтому я хочу, чтобы Windows использовала процедуру проверки по умолчанию для этого сайта. Я не хочу сам разбираться в хранилищах Windows Trusted и проходить через все элементы цепочки, потому что это уже (и, надеюсь, правильно) реализовано в Windows".

Другими словами, мне нужно явно доверять сайтам, одобренным пользователем (которые хранятся где-то в его настройках), и вызывать проверку сертификации по умолчанию для всех остальных.

Значение по умолчанию для ServicePointManager.ServerCertificateValidationCallback равно null, поэтому нет никакого обратного вызова "по умолчанию", который я мог бы вызвать позже. Как я должен вызвать этот обработчик сертификата "по умолчанию"?

Спасибо

15
задан mistika 30 January 2012 в 08:07
поделиться