1

In my C# project I pass a custom implementation of the RemoteCertificateValidationCallback delegate to an SslStream. It is then used to validate a server certificate. The custom implementation checks the sslPolicyErrors flag that the default implementation has set and invokes custom logic based on the results. The default implementation sets flags for several types of certificate issues such as mismatched Subject name, an incomplete certificate chain or if the certificate is expired. My question: Can I infer in any way, from the result of the default implementation of RemoteCertificateValidationCallback, that the certificate is revoked (i.e. is listed in any type of CRL)? Or am I required to add custom logic to my own implementation of RemoteCertificateValidationCallback for a revocation check?

In other words, in the sample code below, if the certificate is revoked will this in any way be reflected in the sslPolicyErrors flag, the certificate object, or the chain object? Or will I have to add additional logic for the revocation check?

RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;
    }
    else if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch)
    {
        // Custom check by additional data available for the certificate...
    }
    else
    {
        return false;
    }
}
JonyVol
  • 366
  • 1
  • 9
  • Possible duplicate of [How to verify chain in RemoteCertificateValidationCallback?](https://stackoverflow.com/q/22518525/608639) I believe you need to set `ChainPolicy.VerificationFlags` and `ChainPolicy.RevocationMode` to opt-in to various checks. Also see `ChainPolicy.RevocationMode`, `X509RevocationMode.Online` and `X509RevocationMode.Offline`. – jww Oct 06 '19 at 04:02

1 Answers1

2

If revocation was checked and the certificate was revoked, it will be detectable by two things

  1. sslPolicyErrors will have the RemoteCertificateChainErrors bit set.
  2. Looping over chain.ChainStatus one of the X509ChainStatus.Status values will be X509ChainStatusFlags.Revoked.

If revocation was requested, but it couldn't be determined, then one of the ChainStatus values will be X509ChainStatusFlags.RevocationUnknown.

And, finally, to determine whether or not revocation was requested, you could check chain.ChainPolicy.RevocationMode. Online means yes, NoCheck means no, and Offline is complicated (cached answers are checked, but if there's no cached answer it becomes RevocationUnknown).

bartonjs
  • 30,352
  • 2
  • 71
  • 111
  • Thanks, @bartonjs. Is there any way to influence the behavior of the default check in order to make it perform a revocation check? I only have access to the chain object within the handler, after the default check has concluded, and in my case it shows RevocationMode==NoCheck. Any way to influence this in advance? – JonyVol Jul 29 '19 at 14:59
  • 1
    @JonyVol Depending on how you're using SslStream, either set the `CertificateRevocationCheckMode` property on the options class, or call a longer overload of `(Begin)AuthenticateAs[Client|Server]` and specify `checkCertificateRevocation: true`. – bartonjs Jul 29 '19 at 15:05