Tim
Tim

Reputation: 8921

Confusion over ServicePointManager ServerCertificateValidationCallback

I am writing a class that inherits from System.Net.WebClient.

The ServiceCertificateValidationCallback is firing and (errors == SslPolicyErrors.None) returns true.

System.Net.ServicePointManager.ServerCertificateValidationCallback =
               delegate (Object obj, X509Certificate certificate, X509Chain chain,
               System.Net.Security.SslPolicyErrors errors)
               {
                  isTrusted = (errors == SslPolicyErrors.None);
               };

Which object or process invokes that callback? And since it is being invoked, do I understand correctly that chain.Build() would be an unnecessary redundant step?

        X509Certificate2 rootCert = (X509Certificate2)certificate;
        X509Certificate2 clientCert =store.Certificates.Find(X509FindType.FindByThumbprint, 
                                                                     rootCert.thumbprint, false)[0]

        chain.ChainPolicy.ExtraStore.Add((X509Certificate2) certificate);
        if (chain.Build(clientCert))
        {
            // trusted chain
        }
        

Upvotes: 0

Views: 931

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174445

Which object or process invokes that callback?

In .NET Framework it roughly goes:

  • WebClient creates an HttpWebRequest
  • HttpWebRequest calls ServicePointManager.FindServicePoint(uri)
  • Resulting ServicePoint instance creates connection and registers ServerCertificateValidationCallback as a post-handshake hook on any enclosing TLS tunnel.

This is a gross oversimplification, but those are the key public members involved.

do I understand correctly that chain.Build() would be an unnecessary redundant step?

Unless you have a specific need to inspect the certificate chain as part of your custom validation routine, yes, it would be redundant.

The OS/platform has already completed the handshake and given its verdict, the ServerCertificateValidationCallback is simply a last chance for you as a user to either discard the connection or go ahead with the web request, based on what was actually negotiated.

Upvotes: 1

Related Questions