CertificatePolicy

public delegate bool CertificatePolicy(string targetHost, X509CertificateCollection localCertificates, X509Certificate2 remoteCertificate, bool acceptable);

Summary

Represents a method that validates an X.509 certificate used for authentication. This delegate is used by the System.Net.Security.SslStream class to determine if an X.509 certificate is acceptable for use in authenticating a remote party.

Remarks

The CertificatePolicy delegate is invoked when the SslStream encounters a certificate validation issue. The delegate receives information about the target host, the local certificates presented, the remote certificate, and an initial assessment of acceptability. The delegate should return true if the certificate is considered acceptable, and false otherwise.

In typical scenarios, relying on the default certificate validation provided by the .NET Framework is sufficient. However, custom validation logic can be implemented using this delegate for specific security requirements, such as:

  • Allowing self-signed certificates in development environments.
  • Implementing domain-specific certificate checks beyond standard PKI validation.
  • Handling certificates from untrusted root authorities with caution.

Note: Implementing custom certificate policies can have significant security implications. Ensure that your custom logic does not inadvertently weaken the security of your application. It is generally recommended to use the built-in validation mechanisms whenever possible.

Delegate Signature

public delegate bool CertificatePolicy(string targetHost, X509CertificateCollection localCertificates, X509Certificate2 remoteCertificate, bool acceptable);

Parameters

Name Type Description
targetHost string The hostname of the server to which the client is connected.
localCertificates X509CertificateCollection A collection of X.509 certificates that are available to the client for authentication. This parameter is typically null if the client is not required to authenticate itself.
remoteCertificate X509Certificate2 The X.509 certificate presented by the remote party.
acceptable bool A boolean value indicating whether the certificate is considered acceptable by the default validation logic. This parameter provides an initial assessment and can be overridden by the custom policy.

Return Value

Type Description
bool true if the remoteCertificate is acceptable; otherwise, false.

See Also

Example


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

// Assume `stream` is an established SslStream

// Define a custom certificate policy that accepts self-signed certificates for a specific host
public static bool MyCustomCertificatePolicy(string targetHost, X509CertificateCollection localCertificates, X509Certificate2 remoteCertificate, bool acceptable)
{
    // If the default validation already found it acceptable, trust it.
    if (acceptable)
    {
        return true;
    }

    // For demonstration, we'll accept any self-signed certificate for "localhost"
    // In a real-world scenario, you'd have more sophisticated validation.
    if (targetHost.Equals("localhost", StringComparison.OrdinalIgnoreCase) &&
        remoteCertificate != null &&
        remoteCertificate.Issuer == remoteCertificate.Subject) // Basic check for self-signed
    {
        Console.WriteLine($"Accepting self-signed certificate for {targetHost}");
        return true;
    }

    // Otherwise, reject the certificate
    return false;
}

// Assign the custom policy (this would typically be done during SslStream creation or configuration)
// For example, if using HttpClient:
// var httpClientHandler = new HttpClientHandler
// {
//     ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
//     {
//         // Replicate the logic of MyCustomCertificatePolicy or adapt it
//         if (errors == SslPolicyErrors.None)
//             return true;
//
//         // Example: Allow self-signed for localhost
//         if (message.RequestUri.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase) &&
//             cert != null && cert.Subject == cert.Issuer)
//         {
//             Console.WriteLine($"Accepting self-signed certificate for {message.RequestUri.Host}");
//             return true;
//         }
//
//         return false; // Reject otherwise
//     }
// };
//
// using (var client = new HttpClient(httpClientHandler))
// {
//     // Your HTTP client operations
// }

// For SslStream directly, you'd often use RemoteCertificateValidationCallback
// SslStream sslStream = new SslStream(
//     innerStream,
//     false,
//     new RemoteCertificateValidationCallback(MyCustomCertificatePolicy) // Using the delegate directly
// );