ValidationCallback Delegate

Defines a callback method that is called when the server's certificate is validated during an SSL/TLS handshake. This delegate is used by the RemoteCertificateValidationCallback property of the SslClientAuthenticationOptions class.

Syntax

public delegate bool ValidationCallback(object sender, X509Certificate certificate, X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors);

Parameters

sender
The object that initiated the callback.
certificate
The X.509 certificate that was issued to the server.
chain
The chain of certificates that represents the hierarchy of trust that the certificate belongs to.
sslPolicyErrors
One or more errors associated with the certificate validation.

Return Value

true if the certificate is valid for use; otherwise, false.

Remarks

The ValidationCallback delegate provides a mechanism for applications to customize the server certificate validation process. By default, .NET performs a standard validation of the server's certificate. However, in certain scenarios, such as working with self-signed certificates or certificates issued by private Certificate Authorities (CAs), you may need to override this behavior.

When the RemoteCertificateValidationCallback property is set to a custom method, that method will be invoked during the SSL/TLS handshake if any validation errors are detected. Your custom callback method can then inspect the provided certificate, chain, and sslPolicyErrors to determine whether to trust the certificate.

Security Warning: Implementing a custom validation callback can have significant security implications. If not implemented carefully, it could expose your application to man-in-the-middle attacks. Only bypass certificate validation if you fully understand the risks and have appropriate compensating controls in place.

The sslPolicyErrors parameter provides detailed information about why the default validation failed. Common errors include:

  • RemoteCertificateChainErrors: The certificate chain is not trusted.
  • RemoteCertificateNameMismatch: The certificate's subject name does not match the server's hostname.
  • RemoteCertificateNotAvailable: The server did not provide a certificate.

Your callback should generally check if sslPolicyErrors is SslPolicyErrors.None. If it is, the certificate is considered valid by the default logic, and you can typically return true. If there are errors, you can then implement your custom logic to decide whether to trust the certificate based on other criteria (e.g., checking the certificate's thumbprint, issuer, or specific properties).

Example

The following example demonstrates how to create a custom validation callback to accept any server certificate. Note: This is for demonstration purposes only and is generally not recommended for production environments.

C#

using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.IO;

public class SslValidationExample
{
    // Custom callback method to accept any certificate
    public static bool AcceptAllCertificates(
        object sender,
        X509Certificate certificate,
        X509Chain chain,
        SslPolicyErrors sslPolicyErrors)
    {
        // In a real application, you would implement robust validation here.
        // For demonstration, we accept all certificates.
        return true;
    }

    public static void MakeRequest()
    {
        // Set the remote certificate validation callback
        ServicePointManager.ServerCertificateValidationCallback = AcceptAllCertificates;

        // Create an HttpClient or HttpWebRequest and make a request
        using (HttpClient client = new HttpClient())
        {
            try
            {
                string url = "https://example.com"; // Replace with a URL that uses HTTPS
                HttpResponseMessage response = client.GetAsync(url).Result;
                response.EnsureSuccessStatusCode();
                string responseBody = response.Content.ReadAsStringAsync().Result;
                Console.WriteLine("Request successful!");
                // Console.WriteLine(responseBody);
            }
            catch (Exception ex)
            {
                Console.WriteLine("An error occurred: " + ex.Message);
            }
        }

        // Reset the callback if necessary for other operations
        ServicePointManager.ServerCertificateValidationCallback = null;
    }

    public static void Main()
    {
        MakeRequest();
    }
}