diff options
-rw-r--r-- | docs/x509/reference.rst | 21 | ||||
-rw-r--r-- | src/cryptography/x509/__init__.py | 3 | ||||
-rw-r--r-- | src/cryptography/x509/extensions.py | 31 | ||||
-rw-r--r-- | tests/test_x509_ext.py | 51 |
4 files changed, 105 insertions, 1 deletions
diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index bbea490e..14727e76 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -1880,6 +1880,27 @@ X.509 Extensions :type: int +.. class:: UnrecognizedExtension + + .. versionadded:: 1.2 + + A generic extension class used to hold the raw value of **non-critical** + extensions that ``cryptography`` does not know how to parse. Extensions + marked critical will still raise + :class:`~cryptography.x509.UnsupportedExtension`. + + .. attribute:: oid + + :type: :class:`ObjectIdentifier` + + Returns the OID associated with this extension. + + .. attribute:: value + + :type: byte + + Returns the DER encoded bytes payload of the extension. + .. class:: CertificatePolicies(policies) .. versionadded:: 0.9 diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py index dc19161e..a1deb7f4 100644 --- a/src/cryptography/x509/__init__.py +++ b/src/cryptography/x509/__init__.py @@ -21,7 +21,7 @@ from cryptography.x509.extensions import ( InhibitAnyPolicy, InvalidityDate, IssuerAlternativeName, KeyUsage, NameConstraints, NoticeReference, OCSPNoCheck, PolicyInformation, ReasonFlags, SubjectAlternativeName, SubjectKeyIdentifier, - UnsupportedExtension, UserNotice + UnrecognizedExtension, UnsupportedExtension, UserNotice ) from cryptography.x509.general_name import ( DNSName, DirectoryName, GeneralName, IPAddress, OtherName, RFC822Name, @@ -169,4 +169,5 @@ __all__ = [ "CertificateIssuer", "CRLReason", "InvalidityDate", + "UnrecognizedExtension", ] diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index 4e7a53b6..0c5b5523 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -1065,3 +1065,34 @@ class InvalidityDate(object): return hash(self.invalidity_date) invalidity_date = utils.read_only_property("_invalidity_date") + + +@utils.register_interface(ExtensionType) +class UnrecognizedExtension(object): + def __init__(self, oid, value): + if not isinstance(oid, ObjectIdentifier): + raise TypeError("oid must be an ObjectIdentifier") + self._oid = oid + self._value = value + + oid = utils.read_only_property("_oid") + value = utils.read_only_property("_value") + + def __repr__(self): + return ( + "<UnrecognizedExtension(oid={0.oid}, value={0.value!r})>".format( + self + ) + ) + + def __eq__(self, other): + if not isinstance(other, UnrecognizedExtension): + return NotImplemented + + return self.oid == other.oid and self.value == other.value + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self.oid, self.value)) diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py index 7cd24a69..258be12d 100644 --- a/tests/test_x509_ext.py +++ b/tests/test_x509_ext.py @@ -75,6 +75,57 @@ class TestExtension(object): assert ext1 != object() +class TestUnrecognizedExtension(object): + def test_invalid_oid(self): + with pytest.raises(TypeError): + x509.UnrecognizedExtension("notanoid", b"somedata") + + def test_eq(self): + ext1 = x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01" + ) + ext2 = x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01" + ) + assert ext1 == ext2 + + def test_ne(self): + ext1 = x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01" + ) + ext2 = x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x02" + ) + ext3 = x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.2.3.5"), b"\x03\x02\x01" + ) + assert ext1 != ext2 + assert ext1 != ext3 + assert ext1 != object() + + def test_repr(self): + ext1 = x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01" + ) + assert repr(ext1) == ( + "<UnrecognizedExtension(oid=<ObjectIdentifier(oid=1.2.3.4, name=" + "Unknown OID)>, value='\\x03\\x02\\x01')>" + ) + + def test_hash(self): + ext1 = x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01" + ) + ext2 = x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01" + ) + ext3 = x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.2.3.5"), b"\x03\x02\x01" + ) + assert hash(ext1) == hash(ext2) + assert hash(ext1) != hash(ext3) + + class TestCertificateIssuer(object): def test_iter_names(self): ci = x509.CertificateIssuer([ |