System.Net.Security Namespace

RemoteCertificateRequest Class

Namespace: System.Net.Security

Represents a request for a remote certificate in the context of SSL/TLS communication.

public sealed class RemoteCertificateRequest

Remarks

The RemoteCertificateRequest class is used in the RemoteCertificateValidationCallback delegate. This delegate is invoked when the client needs to validate the certificate presented by the server during an SSL/TLS handshake. The RemoteCertificateRequest object provides information about the certificate being requested or the one that was received.

This class is particularly useful for scenarios where you need to inspect the server's certificate before deciding whether to trust it. You can access properties like the certificate itself, chain information, and any errors that occurred during its validation.

Inheritance

System.Object

System.Net.Security.RemoteCertificateRequest

Direct Descendants

None.

Implements

None.

Constructors

Name Description
internal RemoteCertificateRequest() Initializes a new instance of the RemoteCertificateRequest class. This constructor is internal and not intended for direct use by developers.

Properties

Name Type Description
Certificate System.Security.Cryptography.X509Certificates.X509Certificate2 Gets the remote certificate.
CertificateChain System.Security.Cryptography.X509Certificates.X509Certificate2Collection Gets the certificate chain for the remote certificate.
Errors System.Net.Security.SslPolicyErrors Gets the SSL policy errors associated with the remote certificate.

Methods

Name Description
public bool Equals(object obj) Determines whether the specified object is equal to the current object.
protected override int GetHashCode() Serves as the default hash function.
public override string ToString() Returns a string that represents the current object.

Examples

The following example shows how to implement a custom certificate validation callback using RemoteCertificateRequest.


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

public class SslClient
{
    public 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)))
        {
            try
            {
                await sslStream.AuthenticateAsClientAsync(host);

                // Now you can send/receive data securely
                Console.WriteLine("SSL connection established.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Authentication failed: {ex.Message}");
            }
        }
    }

    private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        // In a real-world scenario, you would implement robust validation logic here.
        // For demonstration purposes, we'll allow self-signed certificates and check for specific errors.

        Console.WriteLine($"SSL Policy Errors: {sslPolicyErrors}");

        // If there are certificate errors, examine them.
        if (sslPolicyErrors != SslPolicyErrors.None)
        {
            // Example: Allow self-signed certificates (NOT recommended for production)
            if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
            {
                // Check if the chain errors are due to untrusted root certificate
                foreach (X509ChainStatus status in chain.ChainStatus)
                {
                    if (status.Status == X509ChainStatusFlags.UntrustedRoot)
                    {
                        // You might want to add the certificate's thumbprint to a trusted list
                        Console.WriteLine($"Untrusted root detected. Thumbprint: {certificate.GetCertHashString()}");
                        // For this example, we'll allow it. In production, you should NOT blindly trust.
                        return true;
                    }
                }
            }
            else
            {
                // For other errors, we won't allow the connection.
                return false;
            }
        }

        // If there are no errors, or the errors were handled, the certificate is considered valid.
        return true;
    }
}
            

Requirements

Namespace: System.Net.Security

Assembly: System.Net.Primitives (in .NET Core, .NET 5+, and .NET Standard)

Assembly: System (in .NET Framework)