Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using custom root CA with HttpClient

In C#, when using HttpClient, how can I connect to the https server that is using either self-signed certificate (for testing) or a custom CA that is not part of the machine's trust-store? Note that I m not needing client certificates, only need HttpClient to validate the server certificate that is not signed by one of the trusted root CA on the machine. I know that i could just add the self-signed certificate or the CA to the local trust-store on the machine, but let's say I want to avoid doing this. What i need is basically to supply extra root CA to the running application.

There are quite simple ways to do this in other languages as I know:

  1. In java, using "javax.net.ssl.trustStore" system property.

  2. In Node.js, using NODE_EXTRA_CA_CERT environment variable.

But I couldn't find anything like this for .Net so far. Is there a simple way like the above?

like image 500
Yevgeniy P Avatar asked Aug 07 '26 12:08

Yevgeniy P


1 Answers

I fought with this for a while, there don't seem to be good answers out there other than "write your own callback handler" as user evk mentioned with the link to https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler.servercertificatecustomvalidationcallback?view=net-5.0 in the comments above, but that doesn't really explain what should be inside that callback. Then I stumbled upon this comment https://github.com/dotnet/runtime/issues/39835#issuecomment-663020581

Turns out, using a custom root cert is pretty straight forward. Basically, alter the chain policy to use custom roots, add your custom root, and call build on the chain.

private static bool ServerCertificateCustomValidation(
    HttpRequestMessage requestMessage,
    X509Certificate2? certificate,
    X509Chain? chain,
    SslPolicyErrors sslErrors)
{
    if (certificate == null) return false;
    if (chain == null) return false;
    chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
    chain.ChainPolicy.CustomTrustStore.Add(GetTrustedRootCert());
    return chain.Build(certificate);
}

Keep in mind you may still want to check some other things, like if there are other policy errors. This answer only covers the using a custom trusted root.

like image 90
William Leader Avatar answered Aug 10 '26 16:08

William Leader



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!