aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2015-05-09 10:38:23 -0500
committerPaul Kehrer <paul.l.kehrer@gmail.com>2015-05-09 10:38:23 -0500
commit4e8dacd02ec4c4b8238e5ebdfcd5ab26348ec658 (patch)
tree5ea4ca72489bd85f20dd94b4c4135b19da5cf15d
parent5a48552b4b7fc4d108b6d45232769f111fe38896 (diff)
downloadcryptography-4e8dacd02ec4c4b8238e5ebdfcd5ab26348ec658.tar.gz
cryptography-4e8dacd02ec4c4b8238e5ebdfcd5ab26348ec658.tar.bz2
cryptography-4e8dacd02ec4c4b8238e5ebdfcd5ab26348ec658.zip
separate full_name/relative_name and change reasons to an enumeration
-rw-r--r--docs/x509.rst49
-rw-r--r--src/cryptography/x509.py124
-rw-r--r--tests/test_x509_ext.py207
3 files changed, 185 insertions, 195 deletions
diff --git a/docs/x509.rst b/docs/x509.rst
index 9ef8e149..3cf4f905 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -812,11 +812,19 @@ X.509 Extensions
.. versionadded:: 0.9
- .. attribute:: distribution_point
+ .. attribute:: full_name
- :type: list of :class:`GeneralName` instances, :class:`Name`, or None
+ :type: list of :class:`GeneralName` instances or None
+
+ This field describes methods to retrieve the CRL. If this is not None
+ then ``relative_name`` must be None.
+
+ .. attribute:: relative_name
+
+ :type: :class:`Name` or None
- This field describes methods to retrieve the CRL.
+ This field describes methods to retrieve the CRL relative to the CRL
+ issuer. If this is not None then ``full_name`` must be None.
.. attribute:: crl_issuer
@@ -826,7 +834,7 @@ X.509 Extensions
.. attribute:: reasons
- :type: :class:`ReasonFlags` or None
+ :type: list of :class:`ReasonFlags` or None
The reasons a given distribution point may be used for when performing
revocation checks.
@@ -835,40 +843,53 @@ X.509 Extensions
.. versionadded:: 0.9
- This class holds reasons a distribution point may be used for when
- performing revocation checks.
+ An enumeration for CRL reasons.
+
+ .. attribute:: unspecified
+
+ It is unspecified why the certificate was revoked. This reason cannot
+ be used as a reason flag in a :class:`DistributionPoint`.
.. attribute:: key_compromise
- :type: bool
+ This reason indicates that the private key was compromised.
.. attribute:: ca_compromise
- :type: bool
+ This reason indicates that the CA issuing the certificate was
+ compromised.
.. attribute:: affiliation_changed
- :type: bool
+ This reason indicates that the subject's name or other information has
+ changed.
.. attribute:: superseded
- :type: bool
+ This reason indicates that a certificate has been superseded.
.. attribute:: cessation_of_operation
- :type: bool
+ This reason indicates that the certificate is no longer required.
.. attribute:: certificate_hold
- :type: bool
+ This reason indicates that the certificate is on hold.
.. attribute:: privilege_withdrawn
- :type: bool
+ This reason indicates that the privilege granted by this certificate
+ have been withdrawn.
.. attribute:: aa_compromise
- :type: bool
+ When an attribute authority has been compromised.
+
+ .. attribute:: remove_from_crl
+
+ This reason indicates that the certificate was on hold and should be
+ removed from the CRL. This reason cannot be used as a reason flag
+ in a :class:`DistributionPoint`.
Object Identifiers
~~~~~~~~~~~~~~~~~~
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 671294e2..cee0cc39 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -513,20 +513,21 @@ class CRLDistributionPoints(object):
class DistributionPoint(object):
- def __init__(self, distribution_point, reasons, crl_issuer):
- if distribution_point:
- if (
- (
- isinstance(distribution_point, list) and
- not all(
- isinstance(x, GeneralName) for x in distribution_point
- )
- ) or not isinstance(distribution_point, (list, Name))
- ):
- raise TypeError(
- "distribution_point must be None, a list of general names"
- ", or a Name"
- )
+ def __init__(self, full_name, relative_name, reasons, crl_issuer):
+ if full_name and relative_name:
+ raise ValueError(
+ "At least one of full_name and relative_name must be None"
+ )
+
+ if full_name and not all(
+ isinstance(x, GeneralName) for x in full_name
+ ):
+ raise TypeError(
+ "full_name must be a list of GeneralName objects"
+ )
+
+ if relative_name and not isinstance(relative_name, Name):
+ raise TypeError("relative_name must be a Name")
if crl_issuer and not all(
isinstance(x, GeneralName) for x in crl_issuer
@@ -535,23 +536,36 @@ class DistributionPoint(object):
"crl_issuer must be None or a list of general names"
)
- if reasons and not isinstance(reasons, ReasonFlags):
- raise TypeError("reasons must be None or ReasonFlags")
+ if reasons and not all(
+ isinstance(x, ReasonFlags) for x in reasons
+ ):
+ raise TypeError("reasons must be None or list of ReasonFlags")
+
+ if reasons and (
+ ReasonFlags.unspecified in reasons or
+ ReasonFlags.remove_from_crl in reasons
+ ):
+ raise ValueError(
+ "unspecified and remove_from_crl are not valid reasons in a "
+ "DistributionPoint"
+ )
- if reasons and not crl_issuer and not distribution_point:
+ if reasons and not crl_issuer and not (full_name or relative_name):
raise ValueError(
- "You must supply crl_issuer or distribution_point when "
+ "You must supply crl_issuer, full_name, or relative_name when "
"reasons is not None"
)
- self._distribution_point = distribution_point
+ self._full_name = full_name
+ self._relative_name = relative_name
self._reasons = reasons
self._crl_issuer = crl_issuer
def __repr__(self):
return (
- "<DistributionPoint(distribution_point={0.distribution_point}, rea"
- "sons={0.reasons}, crl_issuer={0.crl_issuer})>".format(self)
+ "<DistributionPoint(full_name={0.full_name}, relative_name={0.rela"
+ "tive_name}, reasons={0.reasons}, crl_issuer={0.crl_is"
+ "suer})>".format(self)
)
def __eq__(self, other):
@@ -559,7 +573,8 @@ class DistributionPoint(object):
return NotImplemented
return (
- self.distribution_point == other.distribution_point and
+ self.full_name == other.full_name and
+ self.relative_name == other.relative_name and
self.reasons == other.reasons and
self.crl_issuer == other.crl_issuer
)
@@ -567,62 +582,23 @@ class DistributionPoint(object):
def __ne__(self, other):
return not self == other
- distribution_point = utils.read_only_property("_distribution_point")
+ full_name = utils.read_only_property("_full_name")
+ relative_name = utils.read_only_property("_relative_name")
reasons = utils.read_only_property("_reasons")
crl_issuer = utils.read_only_property("_crl_issuer")
-class ReasonFlags(object):
- def __init__(self, key_compromise, ca_compromise, affiliation_changed,
- superseded, cessation_of_operation, certificate_hold,
- privilege_withdrawn, aa_compromise):
- self._key_compromise = key_compromise
- self._ca_compromise = ca_compromise
- self._affiliation_changed = affiliation_changed
- self._superseded = superseded
- self._cessation_of_operation = cessation_of_operation
- self._certificate_hold = certificate_hold
- self._privilege_withdrawn = privilege_withdrawn
- self._aa_compromise = aa_compromise
-
- def __repr__(self):
- return (
- "<ReasonFlags(key_compromise={0.key_compromise}, ca_compromise"
- "={0.ca_compromise}, affiliation_changed={0.affiliation_changed},"
- "superseded={0.superseded}, cessation_of_operation={0.cessation_o"
- "f_operation}, certificate_hold={0.certificate_hold}, privilege_w"
- "ithdrawn={0.privilege_withdrawn}, aa_compromise={0.aa_compromise"
- "})>".format(self)
- )
-
- def __eq__(self, other):
- if not isinstance(other, ReasonFlags):
- return NotImplemented
-
- return (
- self.key_compromise == other.key_compromise and
- self.ca_compromise == other.ca_compromise and
- self.affiliation_changed == other.affiliation_changed and
- self.superseded == other.superseded and
- self.cessation_of_operation == other.cessation_of_operation and
- self.certificate_hold == other.certificate_hold and
- self.privilege_withdrawn == other.privilege_withdrawn and
- self.aa_compromise == other.aa_compromise
- )
-
- def __ne__(self, other):
- return not self == other
-
- key_compromise = utils.read_only_property("_key_compromise")
- ca_compromise = utils.read_only_property("_ca_compromise")
- affiliation_changed = utils.read_only_property("_affiliation_changed")
- superseded = utils.read_only_property("_superseded")
- cessation_of_operation = utils.read_only_property(
- "_cessation_of_operation"
- )
- certificate_hold = utils.read_only_property("_certificate_hold")
- privilege_withdrawn = utils.read_only_property("_privilege_withdrawn")
- aa_compromise = utils.read_only_property("_aa_compromise")
+class ReasonFlags(Enum):
+ unspecified = "unspecified"
+ key_compromise = "keyCompromise"
+ ca_compromise = "cACompromise"
+ affiliation_changed = "affiliationChanged"
+ superseded = "superseded"
+ cessation_of_operation = "cessationOfOperation"
+ certificate_hold = "certificateHold"
+ privilege_withdrawn = "privilegeWithdrawn"
+ aa_compromise = "aACompromise"
+ remove_from_crl = "removeFromCRL"
@six.add_metaclass(abc.ABCMeta)
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index 1ccb361b..e0858c76 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -1320,69 +1320,46 @@ class TestAuthorityKeyIdentifierExtension(object):
assert ext.value.authority_cert_serial_number == 3
-class TestReasonFlags(object):
- def test_flags(self):
- flags = x509.ReasonFlags(
- True, True, False, False, True, True, False, False
- )
- assert flags.key_compromise is True
- assert flags.ca_compromise is True
- assert flags.affiliation_changed is False
- assert flags.superseded is False
- assert flags.cessation_of_operation is True
- assert flags.certificate_hold is True
- assert flags.privilege_withdrawn is False
- assert flags.aa_compromise is False
-
- def test_eq(self):
- flags = x509.ReasonFlags(
- True, True, False, False, True, True, False, False
- )
- flags2 = x509.ReasonFlags(
- True, True, False, False, True, True, False, False
- )
- assert flags == flags2
-
- def test_ne(self):
- flags = x509.ReasonFlags(
- True, True, False, False, True, True, False, False
- )
- flags2 = x509.ReasonFlags(
- True, True, False, False, True, True, False, True
- )
- assert flags != flags2
- assert flags != object()
-
- def test_repr(self):
- flags = x509.ReasonFlags(
- True, True, False, False, True, True, False, False
- )
- assert repr(flags) == (
- "<ReasonFlags(key_compromise=True, ca_compromise=True, affiliatio"
- "n_changed=False,superseded=False, cessation_of_operation=True, c"
- "ertificate_hold=True, privilege_withdrawn=False, aa_compromise=F"
- "alse)>"
- )
-
-
class TestDistributionPoint(object):
- def test_distribution_point_list_not_general_names(self):
+ def test_distribution_point_full_name_not_general_names(self):
with pytest.raises(TypeError):
- x509.DistributionPoint(["notgn"], None, None)
+ x509.DistributionPoint(["notgn"], None, None, None)
- def test_distribution_point_not_name(self):
+ def test_distribution_point_relative_name_not_name(self):
with pytest.raises(TypeError):
- x509.DistributionPoint("notname", None, None)
+ x509.DistributionPoint(None, "notname", None, None)
+
+ def test_distribution_point_full_and_relative_not_none(self):
+ with pytest.raises(ValueError):
+ x509.DistributionPoint("data", "notname", None, None)
def test_crl_issuer_not_general_names(self):
with pytest.raises(TypeError):
- x509.DistributionPoint(None, None, ["notgn"])
+ x509.DistributionPoint(None, None, None, ["notgn"])
def test_reason_not_reasonflags(self):
with pytest.raises(TypeError):
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"http://crypt.og/crl")],
- "notreasonflags",
+ None,
+ ["notreasonflags"],
+ None
+ )
+
+ def test_disallowed_reasons(self):
+ with pytest.raises(ValueError):
+ x509.DistributionPoint(
+ [x509.UniformResourceIdentifier(u"http://crypt.og/crl")],
+ None,
+ [x509.ReasonFlags.unspecified],
+ None
+ )
+
+ with pytest.raises(ValueError):
+ x509.DistributionPoint(
+ [x509.UniformResourceIdentifier(u"http://crypt.og/crl")],
+ None,
+ [x509.ReasonFlags.remove_from_crl],
None
)
@@ -1390,18 +1367,16 @@ class TestDistributionPoint(object):
with pytest.raises(ValueError):
x509.DistributionPoint(
None,
- x509.ReasonFlags(
- True, True, False, False, True, True, False, False
- ),
+ None,
+ [x509.ReasonFlags.aa_compromise],
None
)
def test_eq(self):
dp = x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"http://crypt.og/crl")],
- x509.ReasonFlags(
- False, False, False, False, False, True, False, False
- ),
+ None,
+ [x509.ReasonFlags.superseded],
[
x509.DirectoryName(
x509.Name([
@@ -1414,9 +1389,8 @@ class TestDistributionPoint(object):
)
dp2 = x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"http://crypt.og/crl")],
- x509.ReasonFlags(
- False, False, False, False, False, True, False, False
- ),
+ None,
+ [x509.ReasonFlags.superseded],
[
x509.DirectoryName(
x509.Name([
@@ -1432,9 +1406,10 @@ class TestDistributionPoint(object):
def test_ne(self):
dp = x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"http://crypt.og/crl")],
- x509.ReasonFlags(
- False, False, False, False, False, True, False, False
- ),
+ None,
+ [
+ x509.ReasonFlags.superseded,
+ ],
[
x509.DirectoryName(
x509.Name([
@@ -1448,6 +1423,7 @@ class TestDistributionPoint(object):
dp2 = x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"http://crypt.og/crl")],
None,
+ None,
None
)
assert dp != dp2
@@ -1455,12 +1431,14 @@ class TestDistributionPoint(object):
def test_repr(self):
dp = x509.DistributionPoint(
+ None,
x509.Name([
x509.NameAttribute(x509.OID_COMMON_NAME, "myCN")
]),
- x509.ReasonFlags(
- False, False, False, False, False, True, False, False
- ),
+ [
+ x509.ReasonFlags.key_compromise,
+ x509.ReasonFlags.ca_compromise,
+ ],
[
x509.DirectoryName(
x509.Name([
@@ -1472,14 +1450,12 @@ class TestDistributionPoint(object):
],
)
assert repr(dp) == (
- "<DistributionPoint(distribution_point=<Name([<NameAttribute(oid="
- "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>, value='myCN')>"
- "])>, reasons=<ReasonFlags(key_compromise=False, ca_compromise=Fa"
- "lse, affiliation_changed=False,superseded=False, cessation_of_op"
- "eration=False, certificate_hold=True, privilege_withdrawn=False,"
- " aa_compromise=False)>, crl_issuer=[<DirectoryName(value=<Name(["
- "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commonNam"
- "e)>, value='Important CA')>])>)>])>"
+ "<DistributionPoint(full_name=None, relative_name=<Name([<NameAtt"
+ "ribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commonName)>, val"
+ "ue='myCN')>])>, reasons=[<ReasonFlags.key_compromise: 'keyCompro"
+ "mise'>, <ReasonFlags.ca_compromise: 'cACompromise'>], crl_issuer"
+ "=[<DirectoryName(value=<Name([<NameAttribute(oid=<ObjectIdentifi"
+ "er(oid=2.5.4.3, name=commonName)>, value='Important CA')>])>)>])>"
)
@@ -1493,13 +1469,16 @@ class TestCRLDistributionPoints(object):
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"http://domain")],
None,
+ None,
None
),
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"ftp://domain")],
- x509.ReasonFlags(
- True, True, True, True, True, True, True, True
- ),
+ None,
+ [
+ x509.ReasonFlags.key_compromise,
+ x509.ReasonFlags.ca_compromise,
+ ],
None
),
])
@@ -1508,13 +1487,16 @@ class TestCRLDistributionPoints(object):
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"http://domain")],
None,
+ None,
None
),
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"ftp://domain")],
- x509.ReasonFlags(
- True, True, True, True, True, True, True, True
- ),
+ None,
+ [
+ x509.ReasonFlags.key_compromise,
+ x509.ReasonFlags.ca_compromise,
+ ],
None
),
]
@@ -1523,37 +1505,41 @@ class TestCRLDistributionPoints(object):
cdp = x509.CRLDistributionPoints([
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"ftp://domain")],
- x509.ReasonFlags(
- True, True, True, True, True, True, True, True
- ),
+ None,
+ [
+ x509.ReasonFlags.key_compromise,
+ x509.ReasonFlags.ca_compromise,
+ ],
None
),
])
assert repr(cdp) == (
- "<CRLDistributionPoints([<DistributionPoint(distribution_point=[<"
- "UniformResourceIdentifier(value=ftp://domain)>], reasons=<Reason"
- "Flags(key_compromise=True, ca_compromise=True, affiliation_chang"
- "ed=True,superseded=True, cessation_of_operation=True, certificat"
- "e_hold=True, privilege_withdrawn=True, aa_compromise=True)>, crl"
- "_issuer=None)>])>"
+ "<CRLDistributionPoints([<DistributionPoint(full_name=[<UniformRes"
+ "ourceIdentifier(value=ftp://domain)>], relative_name=None, reason"
+ "s=[<ReasonFlags.key_compromise: 'keyCompromise'>, <ReasonFlags.ca"
+ "_compromise: 'cACompromise'>], crl_issuer=None)>])>"
)
def test_eq(self):
cdp = x509.CRLDistributionPoints([
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"ftp://domain")],
- x509.ReasonFlags(
- True, True, True, True, True, True, True, True
- ),
+ None,
+ [
+ x509.ReasonFlags.key_compromise,
+ x509.ReasonFlags.ca_compromise,
+ ],
[x509.UniformResourceIdentifier(u"uri://thing")],
),
])
cdp2 = x509.CRLDistributionPoints([
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"ftp://domain")],
- x509.ReasonFlags(
- True, True, True, True, True, True, True, True
- ),
+ None,
+ [
+ x509.ReasonFlags.key_compromise,
+ x509.ReasonFlags.ca_compromise,
+ ],
[x509.UniformResourceIdentifier(u"uri://thing")],
),
])
@@ -1563,36 +1549,43 @@ class TestCRLDistributionPoints(object):
cdp = x509.CRLDistributionPoints([
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"ftp://domain")],
- x509.ReasonFlags(
- True, True, True, True, True, True, True, True
- ),
+ None,
+ [
+ x509.ReasonFlags.key_compromise,
+ x509.ReasonFlags.ca_compromise,
+ ],
[x509.UniformResourceIdentifier(u"uri://thing")],
),
])
cdp2 = x509.CRLDistributionPoints([
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"ftp://domain2")],
- x509.ReasonFlags(
- True, True, True, True, True, True, True, True
- ),
+ None,
+ [
+ x509.ReasonFlags.key_compromise,
+ x509.ReasonFlags.ca_compromise,
+ ],
[x509.UniformResourceIdentifier(u"uri://thing")],
),
])
cdp3 = x509.CRLDistributionPoints([
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"ftp://domain")],
- x509.ReasonFlags(
- True, True, True, True, True, True, True, False
- ),
+ None,
+ [
+ x509.ReasonFlags.key_compromise,
+ ],
[x509.UniformResourceIdentifier(u"uri://thing")],
),
])
cdp4 = x509.CRLDistributionPoints([
x509.DistributionPoint(
[x509.UniformResourceIdentifier(u"ftp://domain")],
- x509.ReasonFlags(
- True, True, True, True, True, True, True, True
- ),
+ None,
+ [
+ x509.ReasonFlags.key_compromise,
+ x509.ReasonFlags.ca_compromise,
+ ],
[x509.UniformResourceIdentifier(u"uri://thing2")],
),
])