Syntax
public sealed class ValidationContext
// Fields
public readonly System.Security.Cryptography.X509Certificates.X509ChainStatusFlags SslPolicyErrors;
public readonly string CertificateStoreName;
public readonly System.Security.Cryptography.X509Certificates.StoreLocation CertificateStoreLocation;
// Constructors
public ValidationContext(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate, string targetHost, System.Security.Cryptography.X509Certificates.X509ChainStatusFlags sslPolicyErrors, string certificateStoreName, System.Security.Cryptography.X509Certificates.StoreLocation certificateStoreLocation, object userState);
// Properties
public System.Security.Cryptography.X509Certificates.X509Certificate2 Certificate { get; }
public System.Security.Cryptography.X509Certificates.X509Chain Chain { get; }
public System.Security.Cryptography.X509Certificates.X509ChainStatus[] ChainStatus { get; }
public string TargetHost { get; }
public object UserState { get; }
Example
The following example demonstrates how to use a custom RemoteCertificateValidationCallback to validate an SSL certificate. In this example, we simply accept any certificate for demonstration purposes, but in a real-world scenario, you would implement more robust validation logic.
using System;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
public class CustomCertificateValidation
{
public static async Task ConnectWithCustomValidation(string host, int port)
{
try
{
TcpClient client = new TcpClient(host, port);
// Create an SslStream using the network stream.
SslStream sslStream = new SslStream(
client.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null);
// The server certificate validation service is asynchronous.
await sslStream.AuthenticateAsClientAsync(host);
Console.WriteLine("SSL connection established.");
// ... perform communication over sslStream ...
sslStream.Close();
client.Close();
}
catch (Exception ex)
{
Console.WriteLine($"Connection failed: {ex.Message}");
}
}
// Custom certificate validation callback.
public static bool ValidateServerCertificate(
object sender,
X509Certificate? certificate,
X509Chain? chain,
SslPolicyErrors sslPolicyErrors)
{
// In this example, we always return true. Otherwise, we would
// check the sslPolicyErrors and the certificate chain.
// For a real-world application, you should implement proper validation logic here.
Console.WriteLine($"SSL Policy Errors: {sslPolicyErrors}");
Console.WriteLine($"Certificate: {certificate?.Subject}");
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true; // Certificate is valid.
}
// In a real-world scenario, you would inspect the errors and potentially
// the chain to decide whether to trust the certificate.
// For example, you might check if the errors are expected or if the certificate
// is issued by a trusted root authority.
// For demonstration purposes, we'll return true even if there are errors, but log them.
// WARNING: Do not do this in production code!
return true;
}
}