1

I'm using a .NET HttpClient to connect to a server over HTTPS. For best practice, I want to check the certificate hasn't been revoked, by setting HttpClientHandler.CheckCertificateRevocationList = true.

This check is failing because the firewall is replacing the certificate with a one signed by a private CA (which has been installed on the machine), which passes the other validity checks but fails the revocation checks. I think this is because the new certificate doesn't have any revocation information. How can I allow these certificates while still checking other ones?

3
  • 1
    How is it going to trust a self-signed certificate anyway, leaving aside the revocation? Are you sure it's not actually signed by a private CA, which your company/firewall installed on your machine? Commented Aug 14 at 12:56
  • Sorry, yes - the certificate is signed by a private CA installed on the machine. I'll edit the question to fix the terminology. Commented Aug 14 at 13:00
  • Why CA-issued TLS certificate doesn't include revocation information? The problem isn't about the code or HTTP client, the problem is with your CA. Commented Aug 14 at 14:21

1 Answer 1

1

I've fixed this by specifying a custom ServerCertificateCustomValidationCallback. The HttpClient is configured not to check the certificate revocation list, and then the callback checks to see if the certificate has CRL distribution points (which will have OID "2.5.29.31"), and does its own check including revocation if so.

private static readonly HttpClient httpClient = new(new HttpClientHandler
{
    ServerCertificateCustomValidationCallback = createCallback(),
});

private static Func<HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> createCallback()
{
    var x509ChainWhichChecksRevocation = new X509Chain();
    return (_, certificate, _, sslPolicyErrors) =>
    {
        if ( sslPolicyErrors != SslPolicyErrors.None )
            return false;

        const string crlDistributionPointsOid = "2.5.29.31";
        var hasCrlDistributionPoints= certificate.Extensions.Cast<X509Extension>()
            .Any(e => e.Oid.Value == crlDistributionPointsOid);

        return !hasCrlDistributionPoints
            || x509ChainWhichChecksRevocation.Build(certificate);
    };
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.