add crl.get_revoked_certificate method (#4331)

* add crl.get_revoked_certificate method

* lexicographic is the best ographic

* rename
This commit is contained in:
Paul Kehrer 2018-07-16 20:49:51 +05:30 committed by Alex Gaynor
parent 2e85a925b4
commit 5d18740277
6 changed files with 52 additions and 0 deletions

View file

@ -16,6 +16,9 @@ Changelog
``cryptography`` release.
* Fixed multiple issues preventing ``cryptography`` from compiling against
LibreSSL 2.7.x.
* Added
:class:`~cryptography.x509.CertificateRevocationList.get_revoked_certificate_by_serial_number`
for quick serial number searches in CRLs.
* The :class:`~cryptography.x509.RelativeDistinguishedName` class now
preserves the order of attributes. Duplicate attributes now raise an error
instead of silently discarding duplicates.

View file

@ -463,6 +463,15 @@ X.509 CRL (Certificate Revocation List) Object
>>> crl.fingerprint(hashes.SHA256())
b'e\xcf.\xc4:\x83?1\xdc\xf3\xfc\x95\xd7\xb3\x87\xb3\x8e\xf8\xb93!\x87\x07\x9d\x1b\xb4!\xb9\xe4W\xf4\x1f'
.. method:: get_revoked_certificate_by_serial_number(serial_number)
.. versionadded:: 2.3
:param serial_number: The serial as a Python integer.
:returns: :class:`~cryptography.x509.RevokedCertificate` if the
``serial_number`` is present in the CRL or ``None`` if it
is not.
.. attribute:: signature_hash_algorithm
:type: :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`

View file

@ -238,6 +238,8 @@ X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *, int);
X509_EXTENSION *X509_CRL_get_ext(X509_CRL *, int);
int X509_CRL_get_ext_count(X509_CRL *);
int X509_CRL_get0_by_serial(X509_CRL *, X509_REVOKED **, ASN1_INTEGER *);
/* these CRYPTO_EX_DATA functions became macros in 1.1.0 */
int X509_get_ex_new_index(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *,
CRYPTO_EX_free *);

View file

@ -16,6 +16,9 @@ from cryptography.hazmat.backends.openssl.decode_asn1 import (
_REVOKED_CERTIFICATE_EXTENSION_PARSER, _asn1_integer_to_int,
_asn1_string_to_bytes, _decode_x509_name, _obj2txt, _parse_asn1_time
)
from cryptography.hazmat.backends.openssl.encode_asn1 import (
_encode_asn1_int_gc
)
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
@ -235,6 +238,22 @@ class _CertificateRevocationList(object):
h.update(der)
return h.finalize()
def get_revoked_certificate_by_serial_number(self, serial_number):
revoked = self._backend._ffi.new("X509_REVOKED **")
asn1_int = _encode_asn1_int_gc(self._backend, serial_number)
res = self._backend._lib.X509_CRL_get0_by_serial(
self._x509_crl, revoked, asn1_int
)
if res == 0:
return None
else:
self._backend.openssl_assert(
revoked[0] != self._backend._ffi.NULL
)
return _RevokedCertificate(
self._backend, self._x509_crl, revoked[0]
)
@property
def signature_hash_algorithm(self):
oid = self.signature_algorithm_oid

View file

@ -189,6 +189,13 @@ class CertificateRevocationList(object):
Returns bytes using digest passed.
"""
@abc.abstractmethod
def get_revoked_certificate_by_serial_number(self, serial_number):
"""
Returns an instance of RevokedCertificate or None if the serial_number
is not in the CRL.
"""
@abc.abstractproperty
def signature_hash_algorithm(self):
"""

View file

@ -181,6 +181,18 @@ class TestCertificateRevocationList(object):
# Check that len() works for CRLs.
assert len(crl) == 12
def test_get_revoked_certificate_by_serial_number(self, backend):
crl = _load_cert(
os.path.join(
"x509", "PKITS_data", "crls", "LongSerialNumberCACRL.crl"),
x509.load_der_x509_crl,
backend
)
serial_number = 725064303890588110203033396814564464046290047507
revoked = crl.get_revoked_certificate_by_serial_number(serial_number)
assert revoked.serial_number == serial_number
assert crl.get_revoked_certificate_by_serial_number(500) is None
def test_revoked_cert_retrieval_retain_only_revoked(self, backend):
"""
This test attempts to trigger the crash condition described in