Search code examples
c#sslx509

Get CA certificate that is used to check server certificate


I have a simple console app in (.NET / C#) that is creating a TLS connection. The connection is working and I can send a ping to the server that will reply with a pong. The code to send and receive is omitted, minimal example is this.

internal class Program
{
    static void Main(string[] args)
    {
        string server = "172.16.62.21";
        TcpClient client = new TcpClient(server, 8081);

        using (SslStream sslStream = new SslStream(client.GetStream(), false,
            new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
        {
            sslStream.AuthenticateAsClient(server);

            // Sending ping here 
            // Reading pong reply here

            Console.WriteLine("waiting for keypress");
            Console.ReadKey();
        }

        client.Close();
    }

    public static bool ValidateServerCertificate(object sender, X509Certificate? certificate,
    X509Chain? chain, SslPolicyErrors sslPolicyErrors)
    {
        return true;
    }
}

As I have a TLS connection (verified with Wireshark), and because this example works, I assume that I have a secured connection.

Is there any way that I can check which CA certificate is used on the client side (this program) to validate the server certificate?


Solution

  • As I have a TLS connection (verified with Wireshark), and because this example works, I assume that I have a secured connection.

    Well, it's secure only in that it's encrypted. But the encryption relies on you accepting any certificate, even self-signed or untrusted CA, so anyone can MITM.

    Is there any way that I can check wich CA certificate is used on the client side (this program) to validate the server certificate ?

    There isn't a root certificate because you haven't validated anything. You've just gone return true so accepting it regardless.

    Either way, you can output the last element of the X509Chain, and this will be the root CA certificate, or the highest up the chain that could be found.

    public static bool ValidateServerCertificate(object sender, X509Certificate? certificate,
        X509Chain? chain, SslPolicyErrors sslPolicyErrors)
    {
        var lastChainElement = chain.ChainElements.Last();
    
        Console.WriteLine(lastChainElement.Certificate.ToString());
    
        return sslPolicyErrors == 0;
    }