aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2015-12-21 21:17:39 -0600
committerPaul Kehrer <paul.l.kehrer@gmail.com>2015-12-21 21:17:39 -0600
commit51f39cbf4f18ad2d9ddb05f07aa6992a3960eab3 (patch)
tree86e94011a160d3bb507ac9c4a2bb058621d7a80a
parenta04e032be907759af8d5b838fc94d581c49b484a (diff)
downloadcryptography-51f39cbf4f18ad2d9ddb05f07aa6992a3960eab3.tar.gz
cryptography-51f39cbf4f18ad2d9ddb05f07aa6992a3960eab3.tar.bz2
cryptography-51f39cbf4f18ad2d9ddb05f07aa6992a3960eab3.zip
support parsing CRL extensions in the OpenSSL backend
-rw-r--r--CHANGELOG.rst3
-rw-r--r--docs/x509/reference.rst6
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py19
-rw-r--r--src/cryptography/x509/oid.py2
-rw-r--r--tests/test_x509.py22
5 files changed, 46 insertions, 6 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 71944611..0cbfdbad 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -19,6 +19,9 @@ Changelog
* Support serialization of certificate revocation lists using the
:meth:`~cryptography.x509.CertificateRevocationList.public_bytes` method of
:class:`~cryptography.x509.CertificateRevocationList`.
+* Add support for parsing :class:`~cryptography.x509.CertificateRevocationList`
+ :meth:`~cryptography.x509.CertificateRevocationList.extensions` in the
+ OpenSSL backend.
1.1.2 - 2015-12-10
~~~~~~~~~~~~~~~~~~
diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst
index d0606330..dace8c1b 100644
--- a/docs/x509/reference.rst
+++ b/docs/x509/reference.rst
@@ -2097,6 +2097,12 @@ instances. The following common OIDs are available as constants.
identifier for the :class:`~cryptography.x509.OCSPNoCheck` extension
type.
+ .. attribute:: CRL_NUMBER
+
+ Corresponds to the dotted string ``"2.5.29.20"``. The identifier for
+ the ``CRLNumber`` extension type. This extension only has meaning
+ for certificate revocation lists.
+
Exceptions
~~~~~~~~~~
.. currentmodule:: cryptography.x509
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index b7a88a4a..6f335f48 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -179,6 +179,12 @@ def _decode_ocsp_no_check(backend, ext):
return x509.OCSPNoCheck()
+def _decode_crl_number(backend, ext):
+ asn1_int = backend._ffi.cast("ASN1_INTEGER *", ext)
+ asn1_int = backend._ffi.gc(asn1_int, backend._lib.ASN1_INTEGER_free)
+ return backend._asn1_integer_to_int(asn1_int)
+
+
class _X509ExtensionParser(object):
def __init__(self, ext_count, get_ext, handlers, unsupported_exts=None):
self.ext_count = ext_count
@@ -870,7 +876,7 @@ class _CertificateRevocationList(object):
@property
def extensions(self):
- raise NotImplementedError()
+ return _CRL_EXTENSION_PARSER.parse(self._backend, self._x509_crl)
@utils.register_interface(x509.CertificateSigningRequest)
@@ -978,6 +984,11 @@ _REVOKED_UNSUPPORTED_EXTENSIONS = set([
CRLExtensionOID.CERTIFICATE_ISSUER,
])
+_CRL_EXTENSION_HANDLERS = {
+ ExtensionOID.CRL_NUMBER: _decode_crl_number,
+ ExtensionOID.AUTHORITY_KEY_IDENTIFIER: _decode_authority_key_identifier,
+}
+
_CERTIFICATE_EXTENSION_PARSER = _X509ExtensionParser(
ext_count=lambda backend, x: backend._lib.X509_get_ext_count(x),
get_ext=lambda backend, x, i: backend._lib.X509_get_ext(x, i),
@@ -996,3 +1007,9 @@ _REVOKED_CERTIFICATE_EXTENSION_PARSER = _X509ExtensionParser(
handlers=_REVOKED_EXTENSION_HANDLERS,
unsupported_exts=_REVOKED_UNSUPPORTED_EXTENSIONS
)
+
+_CRL_EXTENSION_PARSER = _X509ExtensionParser(
+ ext_count=lambda backend, x: backend._lib.X509_CRL_get_ext_count(x),
+ get_ext=lambda backend, x, i: backend._lib.X509_CRL_get_ext(x, i),
+ handlers=_CRL_EXTENSION_HANDLERS,
+)
diff --git a/src/cryptography/x509/oid.py b/src/cryptography/x509/oid.py
index 7b4df1c9..6509527f 100644
--- a/src/cryptography/x509/oid.py
+++ b/src/cryptography/x509/oid.py
@@ -85,6 +85,7 @@ class ExtensionOID(object):
AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
+ CRL_NUMBER = ObjectIdentifier("2.5.29.20")
class CRLExtensionOID(object):
@@ -234,6 +235,7 @@ _OID_NAMES = {
ExtensionOID.AUTHORITY_INFORMATION_ACCESS: "authorityInfoAccess",
ExtensionOID.SUBJECT_INFORMATION_ACCESS: "subjectInfoAccess",
ExtensionOID.OCSP_NO_CHECK: "OCSPNoCheck",
+ ExtensionOID.CRL_NUMBER: "CRLNumber",
AuthorityInformationAccessOID.OCSP: "OCSP",
AuthorityInformationAccessOID.CA_ISSUERS: "caIssuers",
CertificatePoliciesOID.CPS_QUALIFIER: "id-qt-cps",
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 27ce21e2..8d943225 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -175,14 +175,26 @@ class TestCertificateRevocationList(object):
def test_extensions(self, backend):
crl = _load_cert(
- os.path.join("x509", "custom", "crl_all_reasons.pem"),
- x509.load_pem_x509_crl,
+ os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
+ x509.load_der_x509_crl,
backend
)
- # CRL extensions are currently not supported in the OpenSSL backend.
- with pytest.raises(NotImplementedError):
- crl.extensions
+ crl_number = crl.extensions.get_extension_for_oid(
+ ExtensionOID.CRL_NUMBER
+ )
+ aki = crl.extensions.get_extension_for_class(
+ x509.AuthorityKeyIdentifier
+ )
+ assert crl_number.value == 1
+ assert crl_number.critical is False
+ assert aki.value == x509.AuthorityKeyIdentifier(
+ key_identifier=(
+ b'X\x01\x84$\x1b\xbc+R\x94J=\xa5\x10r\x14Q\xf5\xaf:\xc9'
+ ),
+ authority_cert_issuer=None,
+ authority_cert_serial_number=None
+ )
def test_signature(self, backend):
crl = _load_cert(