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:
OfflineRevocation
RevocationStatusUnknown
When i check the intermediate, it has CRL pointing to a valid URL that i can reach. When i get this CRL
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:
- the CA has a fetchable CRL distribution point, that
- distribute an expired CRL, for the intermediate, and
- 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:
- Does the
ChainStatus
andcertutil
mean that the CRL is expired, and therefore i can only make the chain build if i do aNoCheck
, and - Is it the correct process for a CA to not update their CRL? Shouldn't they just have none at all?
CtlNotTimeValid
andCtlNotValidForUsage
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
andRevocationStatusUnknown
. 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.