Search code examples
c#x509certificate2cacertutil

CRL is expired, but ChainStatus is telling me RevocationStatusUnknown


I am doing a chain validation with this

var ca = new X509Certificate2(caBytes);
var intermediate = new X509Certificate2(intermediateBytes);

chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.CustomTrustStore.Add(ca);
chain.ChainPolicy.CustomTrustStore.Add(intermediate);
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;

var build = chain.Build(intermediate);

build reports back false and the chain status contains:

  1. OfflineRevocation
  2. RevocationStatusUnknown

When i check the intermediate, it has CRL pointing to a valid URL that i can reach. When i get this CRL

enter image description here

Nothing is wrong here, except that Next date is a bit in the past. I see this as expired. When i do a certutil -verify -urlfetch Tesla_Intermediate_BAM_CRAS.crt i get the following

Issuer:
    CN=Tesla CA
    OU=CA
    O=Tesla Asics
    C=CI
  Name Hash(sha1): 444444444444444444444444
  Name Hash(md5): 555555555555555555555555
Subject:
    CN=Tesla Intermediate BAM CRAS
    OU=IT
    O=Tesla Asics
    C=CI
  Name Hash(sha1): 222222222222222222222222222
  Name Hash(md5): 33333333333333333333333333
Cert Serial Number: 02

dwFlags = CA_VERIFY_FLAGS_CONSOLE_TRACE (0x20000000)
dwFlags = CA_VERIFY_FLAGS_DUMP_CHAIN (0x40000000)
ChainFlags = CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT (0x40000000)
HCCE_LOCAL_MACHINE
CERT_CHAIN_POLICY_BASE
-------- CERT_CHAIN_CONTEXT --------
ChainContext.dwInfoStatus = CERT_TRUST_HAS_PREFERRED_ISSUER (0x100)
ChainContext.dwErrorStatus = CERT_TRUST_REVOCATION_STATUS_UNKNOWN (0x40)
ChainContext.dwErrorStatus = CERT_TRUST_IS_OFFLINE_REVOCATION (0x1000000)
ChainContext.dwRevocationFreshnessTime: 2158 Days, 54 Minutes, 33 Seconds

SimpleChain.dwInfoStatus = CERT_TRUST_HAS_PREFERRED_ISSUER (0x100)
SimpleChain.dwErrorStatus = CERT_TRUST_REVOCATION_STATUS_UNKNOWN (0x40)
SimpleChain.dwErrorStatus = CERT_TRUST_IS_OFFLINE_REVOCATION (0x1000000)
SimpleChain.dwRevocationFreshnessTime: 2158 Days, 54 Minutes, 33 Seconds

CertContext[0][0]: dwInfoStatus=101 dwErrorStatus=1000040
  Issuer: CN=Tesla CA, OU=CA, O=Tesla Asics, C=CI
  NotBefore: 16/01/2018 13:57
  NotAfter: 16/01/2028 13:57
  Subject: CN=Tesla Intermediate BAM CRAS, OU=IT, O=Tesla Asics, C=CI
  Serial: 02
  Cert: 111111111111111111111
  Element.dwInfoStatus = CERT_TRUST_HAS_EXACT_MATCH_ISSUER (0x1)
  Element.dwInfoStatus = CERT_TRUST_HAS_PREFERRED_ISSUER (0x100)
  Element.dwErrorStatus = CERT_TRUST_REVOCATION_STATUS_UNKNOWN (0x40)
  Element.dwErrorStatus = CERT_TRUST_IS_OFFLINE_REVOCATION (0x1000000)
  ----------------  Certificate AIA  ----------------
  No URLs "None" Time: 0 (null)
  ----------------  Certificate CDP  ----------------
  Expired "Base CRL (01)" Time: 0 666666666666666666
    [0.0] http://crl.Tesla.ca/Tesla_CA_Root.crl

  ----------------  Base CRL CDP  ----------------
  No URLs "None" Time: 0 (null)
  ----------------  Certificate OCSP  ----------------
  No URLs "None" Time: 0 (null)
  --------------------------------
    CRL 01:
    Issuer: CN=Tesla CA, OU=CA, O=Tesla Asics, C=CI
    ThisUpdate: 22/01/2018 15:50
    NextUpdate: 21/02/2018 15:50
    CRL: 666666666666666666

CertContext[0][1]: dwInfoStatus=109 dwErrorStatus=0
  Issuer: CN=Tesla CA, OU=CA, O=Tesla Asics, C=CI
  NotBefore: 16/01/2018 13:55
  NotAfter: 16/01/2038 13:55
  Subject: CN=Tesla CA, OU=CA, O=Tesla Asics, C=CI
  Serial: 01
  Cert: 7777777777777777777
  Element.dwInfoStatus = CERT_TRUST_HAS_EXACT_MATCH_ISSUER (0x1)
  Element.dwInfoStatus = CERT_TRUST_IS_SELF_SIGNED (0x8)
  Element.dwInfoStatus = CERT_TRUST_HAS_PREFERRED_ISSUER (0x100)
  ----------------  Certificate AIA  ----------------
  No URLs "None" Time: 0 (null)
  ----------------  Certificate CDP  ----------------
  No URLs "None" Time: 0 (null)
  ----------------  Certificate OCSP  ----------------
  No URLs "None" Time: 0 (null)
  --------------------------------

Exclude leaf cert:
  Chain: 88888888888888888888888
Full chain:
  Chain: 999999999999999999999999999
  Issuer: CN=Tesla CA, OU=CA, O=Tesla Asics, C=CI
  NotBefore: 16/01/2018 13:57
  NotAfter: 16/01/2028 13:57
  Subject: CN=Tesla Intermediate BAM CRAS, OU=IT, O=Tesla Asics, C=CI
  Serial: 02
  Cert: 111111111111111111111
Tilbagekaldsfunktionen kunne ikke kontrollere tilbagekaldelsen, fordi tilbagekaldsserveren var offline. 0x80092013 (-2146885613 CRYPT_E_REVOCATION_OFFLINE)
------------------------------------
Revocation check skipped -- server offline
Cert is a CA certificate

ERROR: Verifying leaf certificate revocation status returned Tilbagekaldsfunktionen kunne ikke kontrollere tilbagekaldelsen, fordi tilbagekaldsserveren var offline. 0x80092013 (-2146885613 CRYPT_E_REVOCATION_OFFLINE)
CertUtil: Tilbagekaldsfunktionen kunne ikke kontrollere tilbagekaldelsen, fordi tilbagekaldsserveren var offline.

CertUtil: -verify command completed successfully.

i am not a pro to certutil, but i can see that it tells me that the CRL is expired:

  Expired "Base CRL (01)" Time: 0 666666666666666666
    [0.0] http://crl.Tesla.ca/Tesla_CA_Root.crl

or does it mean something else?

I would expect the ChainStatus to report back something else, like CtlNotTimeValid, but it does not. Am i doing something wrong? When i talk to the service support, that runs the CA, they tell me that they have a valid CRL distribution point, but i don't see anything valid here, except that i can reach the endpoint.

What i feel like i am hearing is:

  1. the CA has a fetchable CRL distribution point, that
  2. distribute an expired CRL, for the intermediate, and
  3. have a CA that is offline

If they don't have a valid non-expired CRL, i see no other way of solving this, than going for a NoCheck. The CA says they will inform me when the CA or intermediate is revoked, so i am not completely in the dark.

Is this a professional way of operating? I would expect them to either have an updated CRL, or not one at all.

Questions:

  1. Does the ChainStatus and certutil mean that the CRL is expired, and therefore i can only make the chain build if i do a NoCheck, and
  2. Is it the correct process for a CA to not update their CRL? Shouldn't they just have none at all?

Solution

  • CtlNotTimeValid and CtlNotValidForUsage are not for CRL checks, they are for CTL (certificate trust list), which is a mechanism to decide which CA certificates are trusted, and for what purposes.

    A CRL is only for revocation checks, and that only has the flags OfflineRevocation and RevocationStatusUnknown. If the CRL at the defined URL is not valid (expired) then it is essentially "offline" or unavailable, i.e. revocation status cannot be determined.

    I suggest you speak to the CA, and explain to them that they need to issue CRLs frequently. 14 or 30 days is more common. If they are not doing that then they are not following standardized practices for CAs, and should be reported for non-compliance.

    If you are running your own CA in-house then it's usually pretty simple to set up a CRL distribution cycle.