2012-01-30 13 views
15

muszę zaufać kilka certyfikatów z podpisem własnym w aplikacji, więc zastępują zwrotnego walidacji tak:Jak wywołać domyślne sprawdzanie certyfikatu podczas zastępowania ServicePointManager.ServerCertificateValidationCallback w języku 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' 
} 

Ale kiedy tam jesteśmy pewne błędy polityczne, a strona Łączę się nie jest zatwierdzony przez aplikacji, zgłaszany jest wyjątek. Problem polega na tym, że różni się od standardowego zachowania Windows.

Rozważmy witrynie: https://www.dscoduc.com/

certyfikat Za ma nieznaną emitenta, a zatem niezaufane. Dodałem go z MMC do Zaufanych Ludzi Lokalnych Kmuterów (to Windows 7).

Jeśli uruchomić ten kod bez przesłanianie callback poprawności certyfikatu:

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(); 
    } 
} 

łączy pomyślnie. Oznacza to, że domyślny weryfikator systemu Windows postanowił zaufać temu certyfikatowi.

Ale kiedyś zastąpić ServerCertificateValidationCallback moja zwrotna jest wywoływana z SslPolicyErrors.RemoteCertificateChainErrors i łańcucha zawiera jeden element ze statusem X509ChainStatusFlags.PartialChain (w rzeczywistości byłoby oczekiwać, aby otrzymać błędów tutaj, ponieważ posiadał prądu cert ma być zaufany)

Ta strona nie znajduje się na mojej zaufanej liście i nie chce zwracać "prawdziwości" z mojego wywołania zwrotnego. Ale nie chcę zwracać "fałszu", albo otrzymam wyjątek: "Zdalny certyfikat jest nieprawidłowy zgodnie z procedurą sprawdzania oryginalności", co oczywiście nie jest oczekiwane dla https://www.dscoduc.com/, ponieważ jest on dodawany do sklepu Zaufane osoby i jest zatwierdzony przez system Windows, gdy odwołanie zwrotne certyfikatu nie zostało zmienione. Chcę, aby system Windows zastosował domyślną procedurę sprawdzania poprawności dla tej witryny. Nie chcę zaglądać do sklepów Windows Trusted i przechodzić przez wszystkie elementy łańcucha, ponieważ jest już (i miejmy nadzieję poprawnie) zaimplementowany w systemie Windows.

Innymi słowy, muszę wyraźnie zaufać witrynom zatwierdzonym przez użytkownika (które są przechowywane gdzieś w jego ustawieniach) i zadzwonić do domyślnego sprawdzenia certyfikacji dla wszystkich innych.

Domyślna wartość ServicePointManager.ServerCertificateValidationCallback ma wartość null, więc nie ma "domyślnego" połączenia zwrotnego, z którego mógłbym zadzwonić później. Jak powinienem nazwać tę "domyślną" procedurę obsługi certyfikatów?

Dzięki

Odpowiedz

6

To łatwiejsze niż myślisz chodzić łańcuch z poziomu zwrotnego.

Wystarczy popatrzeć na http://msdn.microsoft.com/en-us/library/dd633677(v=exchg.80).aspx

Kod w tej próbce bada łańcuch certyfikatów do pracy, czy certyfikat jest podpisem własnym, a jeśli tak, to zaufać. Możesz to zaadaptować, aby zaakceptować PartialChain zamiast lub równie dobrze.Byłbyś chce zrobić coś takiego:

if (status.Status == X509ChainStatusFlags.PartialChain || 
    (certificate.Subject == certificate.Issuer && 
    status.Status == X509ChainStatusFlags.UntrustedRoot) 
{ 
    // Certificates with a broken chain and 
    // self-signed certificates with an untrusted root are valid. 
    continue; 
} 
else if (status.Status != X509ChainStatusFlags.NoError) 
{ 
    // If there are any other errors in the certificate chain, 
    // the certificate is invalid, so the method returns false. 
    return false; 
} 

Alternatywnie, inspekcję nieruchomości Subject:

private static bool CertificateValidationCallBack(
    object sender, 
    System.Security.Cryptography.X509Certificates.X509Certificate certificate, 
    System.Security.Cryptography.X509Certificates.X509Chain chain, 
    System.Net.Security.SslPolicyErrors sslPolicyErrors) 
{ 
    return certificate.Subject.Contains(".dsoduc.com"); 
} 
3

Coś jak to może działać. Zauważ, że X509CertificateValidator pozwala Ci wybrać, czy chcesz, aby sklep Trusted People był uwzględniany w walidacji.

private static bool CertificateValidationCallBack(
    object sender, 
    X509Certificate certificate, 
    X509Chain chain, 
    SslPolicyErrors sslPolicyErrors) 
{ 
    // Your custom check here... 
    if (isYourSpecialCase) 
    { 
     return true; 
    } 

    // If it is not your special case then revert to default checks... 

    // Convert the certificate to a X509Certificate2 
    var certificate2 = certificate as X509Certificate2 ?? new X509Certificate2(certificate); 

    try 
    { 
     // Choose the type of certificate validation you want 
     X509CertificateValidator.PeerOrChainTrust.Validate(certificate2); 
     //X509CertificateValidator.ChainTrust.Validate(certificate2); 
    } 
    catch 
    { 
     return false; 
    } 

    // Sender is always either a WebReqest or a hostname string 
    var request = sender as WebRequest; 
    string requestHostname = request != null ? request.RequestUri.Host : (string)sender; 

    // Get the hostname from the certificate 
    string certHostname = certificate2.GetNameInfo(X509NameType.DnsName, false); 

    return requestHostname.Equals(certHostname, StringComparison.InvariantCultureIgnoreCase); 
} 
Powiązane problemy