RemoteCertificateChain Class

Namespace: System.Net.Security
Assembly: System.Net.Primitives.dll

Description

Represents the certificate chain for an X.509 certificate.

This class is used in conjunction with the SslStream class to validate the certificate chain of a remote server. It provides access to the individual certificates in the chain, allowing you to inspect their properties and determine the validity of the connection.

Syntax

public sealed class RemoteCertificateChain

Remarks

When an SslStream establishes a secure connection to a remote server, it validates the server's certificate chain. If the validation is successful, the RemoteCertificateChain property of the SslStream object will contain the validated certificate chain. You can then iterate through the certificates in the chain to perform further checks or to display information about the certificate to the user.

The RemoteCertificateChain class provides read-only access to the certificate chain. You cannot modify the chain directly. Instead, you rely on the underlying security protocols to build and validate the chain.

Inheritance Hierarchy

Object
    System.Net.Security.RemoteCertificateChain

Members

Properties

  • ChainElements Gets a collection of X509Certificate2 objects that represent the certificates in the chain.
  • ChainPolicy Gets the chain policy that was used to build the certificate chain.
  • ChainStatus Gets an array of X509ChainStatus objects that describe the results of the certificate chain validation.
  • IsTrusted Gets a value indicating whether the certificate chain is trusted.

Methods

  • ToString() Returns a string representation of the RemoteCertificateChain object.

Fields

This class has no fields.

Events

This class has no events.

Example

The following example demonstrates how to access and inspect the remote certificate chain after establishing an SSL connection.

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

public class SslExample
{
    public static async Task ConnectAndInspectCertAsync(string host, int port)
    {
        try
        {
            using (TcpClient client = new TcpClient())
            {
                await client.ConnectAsync(host, port);
                using (SslStream sslStream = new SslStream(client.GetStream(), false,
                    (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        // In a real-world scenario, you would implement robust certificate validation here.
                        // For this example, we'll accept any certificate, but this is NOT recommended for production.
                        Console.WriteLine($"SSL Policy Errors: {sslPolicyErrors}");
                        return true; // Always validate server certificate in production!
                    }))
                {
                    await sslStream.AuthenticateAsClientAsync(host);

                    if (sslStream.RemoteCertificate != null)
                    {
                        Console.WriteLine("Remote certificate received:");
                        Console.WriteLine($"Subject: {sslStream.RemoteCertificate.Subject}");
                        Console.WriteLine($"Issuer: {sslStream.RemoteCertificate.Issuer}");

                        // Accessing the RemoteCertificateChain
                        RemoteCertificateChain certChain = sslStream.TransportContext.GetRemoteCertificateChain();
                        if (certChain != null)
                        {
                            Console.WriteLine("\n--- Certificate Chain Details ---");
                            foreach (X509Certificate2 cert in certChain.ChainElements)
                            {
                                Console.WriteLine($"\nCertificate:");
                                Console.WriteLine($"  Subject: {cert.Subject}");
                                Console.WriteLine($"  Issuer: {cert.Issuer}");
                                Console.WriteLine($"  Thumbprint: {cert.Thumbprint}");
                            }

                            Console.WriteLine("\n--- Chain Status ---");
                            foreach (X509ChainStatus status in certChain.ChainStatus)
                            {
                                Console.WriteLine($"Status: {status.StatusInformation}");
                                Console.WriteLine($"Description: {status.Status}");
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("No remote certificate was received.");
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");
        }
    }

    // To run this example, uncomment the following Main method and call ConnectAndInspectCertAsync
    // public static async Task Main(string[] args)
    // {
    //     await ConnectAndInspectCertAsync("www.google.com", 443);
    // }
}