1

I am trying to validate a client certificate using HttpClientHandler.ServerCertificateCustomValidationCallback. I have built my x509chain with my ChainPolicy parameters.

I have locally my CRL (.pem) file and i would like to add it to the revocation process.

I was thinking of doing something like CRL validation, importing into my X509Certificate an X509Extension with a distributionPoint oid but i have trouble understanding it.

Here is a piece of my callback code

private static Func<HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool>
    ServerCertificateCustomValidationCallback()
{
    return (sender, cert, chain, sslPolicyErrors) =>
    {
        X509Certificate2 ca = new X509Certificate2(@"pathToCa\\ca.crt");

        X509Chain chai = new X509Chain();
        chai.ChainPolicy.ExtraStore.Add(ca);
        chai.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
        chai.ChainPolicy.RevocationMode = X509RevocationMode.Online;
        chai.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
        chai.ChainPolicy.VerificationTime = DateTime.Now;
        try
        {
            if (!chai.Build(cert))
            {
                return false;
            }
            foreach (X509ChainStatus status in chai.ChainStatus)
            {
                if (status.Status == X509ChainStatusFlags.UntrustedRoot) continue;
                if (status.Status == X509ChainStatusFlags.OfflineRevocation) continue;
                if (status.Status == X509ChainStatusFlags.RevocationStatusUnknown) continue;
                return false;
            }

        }
        catch (Exception e)
        {
            throw e;
        }

        return true;
    };
}

Thank for your help & clarification

1 Answers1

0

If you want to host your own CRL, you will need server set up somewhere, so it can host your crl just like an html page.

So, for example, if you using openSSL or preferably LibreSSL to create your own certs, in your config file, you will add the following:

crlDistributionPoints  = URI:http://myserver.com/mycert.crl
nsCaRevocationUrl =  http://myserver.com/mycert.crl

(You could try using absolute paths to the keys above, but I am not sure that would work, if it does let me know)

There are several tutorials to help get this set up, https://jamielinux.com/docs/openssl-certificate-authority/ is pretty good and detailed.

While doing this myself, I found that when you call build chain, the .Net framework checks the chain, so you should not need to add and extra code to insure that it checks the CRL as this happens automatically. (You can check that the crl is being fetched by checking your server log files)

You can test this by adding your own cert to your CRL, and you should find that you get

X509ChainStatusFlags.Revoked 

Hope that helps

Dai Bok
  • 3,451
  • 2
  • 53
  • 70
  • All right, your solution works well but my question is about offline revocation from a local file.. – Nicolas Terisse Jan 12 '17 at 15:22
  • did you try change the path for nsCaRevocationUrl /crlDistributionPoints to something like \\Machinename\c$\certrevlist\my.crl – Dai Bok Jan 12 '17 at 15:27
  • I have found that dotnet check only crls with http source: [dotnet cource](https://github.com/dotnet/corefx/blob/bffef76f6af208e2042a2f27bc081ee908bb390b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs#L255) – Nicolas Terisse Jan 17 '17 at 15:06
  • Thanks, that is good to know. I guess it is not possible, unless you install a "local" webserver. – Dai Bok Jan 17 '17 at 16:07