CertificateValidationCallback Delegate
Represents the method that handles the validation of a remote certificate. This delegate is used by the SslStream class.
Syntax
object sender,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors
);
Parameters
| Parameter | Description |
|---|---|
sender |
The object that initiated the callback. This is typically an SslStream object. |
certificate |
An X509Certificate object that represents the remote certificate used to authenticate the server. |
chain |
An X509Chain object that represents the certificate chain associated with the remote certificate. |
sslPolicyErrors |
A bitwise combination of the SslPolicyErrors values that result from server certificate validation. |
Return Value
true if the certificate is accepted; otherwise, false.
Remarks
The CertificateValidationCallback delegate is used to provide custom certificate validation logic for SSL/TLS connections. When an SslStream attempts to establish a secure connection, it performs a series of default validation steps on the server's certificate. If any of these default checks fail, or if you want to implement additional checks, you can assign a method to the RemoteCertificateValidationCallback property of the SslStream.
The callback method receives the remote certificate, the certificate chain, and any SSL policy errors that occurred during the default validation. Your custom logic can then inspect these parameters and decide whether to trust the certificate.
If your callback returns true, the connection is allowed to proceed despite any SslPolicyErrors that might have occurred. If it returns false, the connection is aborted.
The sslPolicyErrors parameter provides valuable information about why the default validation might have failed. Common errors include:
RemoteCertificateChainErrors: The certificate chain is invalid.RemoteCertificateNameMismatch: The certificate's subject name does not match the server's hostname.RemoteCertificateNotAvailable: The server did not provide a certificate.
You can check for specific errors using bitwise operations:
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
{
// Handle name mismatch
}
Example
The following example demonstrates how to create a custom validation callback that accepts any certificate, which is generally not recommended for production environments. This is for illustrative purposes only.
using System;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
public class SslClientExample
{
public static async Task ConnectAsync(string host, int port)
{
using (var client = new TcpClient(host, port))
using (var sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
{
try
{
// The server name is the name of the server that the client is connecting to.
await sslStream.AuthenticateAsClientAsync(host);
// Do work with the sslStream.
Console.WriteLine("SSL connection established.");
// ... send and receive data ...
}
catch (AuthenticationException e)
{
Console.WriteLine("Authentication failed: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
return;
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
}
// Custom certificate validation callback.
// In a real-world scenario, you would implement more robust validation logic.
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
{
// Server certificate is trusted.
return true;
}
// The following code demonstrates a trust-all approach.
// THIS IS NOT SECURE AND SHOULD NOT BE USED IN PRODUCTION.
Console.WriteLine($"SSL Policy Errors: {sslPolicyErrors}");
Console.WriteLine("Warning: Accepting server certificate despite policy errors.");
return true; // In production, you would validate the certificate more thoroughly.
}
public static async Task Main(string[] args)
{
// Example usage:
// await ConnectAsync("example.com", 443);
Console.WriteLine("This is an example of how to use CertificateValidationCallback.");
Console.WriteLine("In a real application, replace 'example.com' with the target server.");
}
}
Requirements
| Assembly | Framework |
|---|---|
| System.Net.Primitives.dll | .NET Standard 2.0, .NET Core 2.0, .NET Framework 4.6.1 |
| System.dll | .NET Framework 2.0, 3.0, 3.5, 4.0, 4.5 |