def __check_crls(self, cert, ca_dict):
"""Determines whether the certificate has been revoked by one of
its CRLs.
The 'cert' parameter is the certificate to check for revocation.
The 'ca_dict' is a dictionary which maps subject hashes to
certs treated as trust anchors."""
# If the certificate doesn't have a CRL location listed, treat
# it as valid.
# The CRLs to be retrieved are stored in the
# CRLDistributionPoints extensions which is structured like
# this:
#
# CRLDitsributionPoints = [
# CRLDistributionPoint = [
# union {
# full_name = [ GeneralName, ... ]
# relative_name = [ GeneralName, ... ]
# }, ... ]
# , ... ]
#
# Relative names are a feature in X509 certs which allow to
# specify a location relative to another certificate. We are not
# supporting this and I'm not sure anybody is using this for
# CRLs.
# Full names are absolute locations but can be in different
# formats (refer to RFC5280) but in general only the URI type is
# used for CRLs. So this is the only thing we support here.
try:
dps = cert.extensions.get_extension_for_oid(
x509.oid.ExtensionOID.CRL_DISTRIBUTION_POINTS).value
except x509.ExtensionNotFound:
return
crl_uris = []
for dp in dps:
if not dp.full_name:
# we don't support relative names
continue
for uri in dp.full_name:
if not isinstance(uri,
x509.UniformResourceIdentifier):
# we only support URIs
continue
crl_uris.append(str(uri.value))
for i, uri in enumerate(crl_uris):
more_uris = i < len(crl_uris) - 1
self.__check_crl(cert, ca_dict, uri,
more_uris=more_uris)