diff options
-rw-r--r-- | CHANGELOG.rst | 2 | ||||
-rw-r--r-- | docs/x509/reference.rst | 3 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/x509.py | 9 | ||||
-rw-r--r-- | tests/test_x509.py | 6 | ||||
-rw-r--r-- | tests/test_x509_ext.py | 22 |
5 files changed, 37 insertions, 5 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 74749062..07b4f5a8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -45,6 +45,8 @@ Changelog * Added :class:`~cryptography.x509.CertificateRevocationListBuilder` and :class:`~cryptography.x509.RevokedCertificateBuilder` to allow creation of CRLs. +* Unrecognized non-critical X.509 extensions are now parsed into an + :class:`~cryptography.x509.UnrecognizedExtension` object. 1.1.2 - 2015-12-10 ~~~~~~~~~~~~~~~~~~ diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index df17f954..01a5d94c 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -2435,7 +2435,8 @@ Exceptions .. class:: UnsupportedExtension - This is raised when a certificate contains an unsupported extension type. + This is raised when a certificate contains an unsupported extension type + that is marked critical. .. attribute:: oid diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 293c6288..b8614e0b 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -213,6 +213,15 @@ class _X509ExtensionParser(object): "Critical extension {0} is not currently supported" .format(oid), oid ) + else: + # Dump the DER payload into an UnrecognizedExtension object + data = backend._lib.X509_EXTENSION_get_data(ext) + backend.openssl_assert(data != backend._ffi.NULL) + der = backend._ffi.buffer(data.data, data.length)[:] + unrecognized = x509.UnrecognizedExtension(oid, der) + extensions.append( + x509.Extension(oid, critical, unrecognized) + ) else: # For extensions which are not supported by OpenSSL we pass the # extension object directly to the parsing routine so it can diff --git a/tests/test_x509.py b/tests/test_x509.py index 578015ec..6145edb1 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -1093,7 +1093,11 @@ class TestRSACertificateRequest(object): backend ) extensions = request.extensions - assert len(extensions) == 0 + assert len(extensions) == 1 + assert extensions[0].oid == x509.ObjectIdentifier("1.2.3.4") + assert extensions[0].value == x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.2.3.4"), b"value" + ) def test_request_basic_constraints(self, backend): request = _load_cert( diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py index 7c5ca5f2..ec6127ab 100644 --- a/tests/test_x509_ext.py +++ b/tests/test_x509_ext.py @@ -1032,17 +1032,33 @@ class TestExtensions(object): assert exc.value.oid == x509.ObjectIdentifier("1.2.3.4") + @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) def test_unsupported_extension(self, backend): - # TODO: this will raise an exception when all extensions are complete cert = _load_cert( os.path.join( - "x509", "custom", "unsupported_extension.pem" + "x509", "custom", "unsupported_extension_2.pem" ), x509.load_pem_x509_certificate, backend ) extensions = cert.extensions - assert len(extensions) == 0 + assert len(extensions) == 2 + assert extensions[0].critical is False + assert extensions[0].oid == x509.ObjectIdentifier( + "1.3.6.1.4.1.41482.2" + ) + assert extensions[0].value == x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.3.6.1.4.1.41482.2"), + b"1.3.6.1.4.1.41482.1.2" + ) + assert extensions[1].critical is False + assert extensions[1].oid == x509.ObjectIdentifier( + "1.3.6.1.4.1.45724.2.1.1" + ) + assert extensions[1].value == x509.UnrecognizedExtension( + x509.ObjectIdentifier("1.3.6.1.4.1.45724.2.1.1"), + b"\x03\x02\x040" + ) def test_no_extensions_get_for_class(self, backend): cert = _load_cert( |