Skip to content

Commit 5d18740

Browse files
reaperhulkalex
authored andcommitted
add crl.get_revoked_certificate method (#4331)
* add crl.get_revoked_certificate method * lexicographic is the best ographic * rename
1 parent 2e85a92 commit 5d18740

File tree

6 files changed

+52
-0
lines changed

6 files changed

+52
-0
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ Changelog
1616
``cryptography`` release.
1717
* Fixed multiple issues preventing ``cryptography`` from compiling against
1818
LibreSSL 2.7.x.
19+
* Added
20+
:class:`~cryptography.x509.CertificateRevocationList.get_revoked_certificate_by_serial_number`
21+
for quick serial number searches in CRLs.
1922
* The :class:`~cryptography.x509.RelativeDistinguishedName` class now
2023
preserves the order of attributes. Duplicate attributes now raise an error
2124
instead of silently discarding duplicates.

docs/x509/reference.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,15 @@ X.509 CRL (Certificate Revocation List) Object
463463
>>> crl.fingerprint(hashes.SHA256())
464464
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'
465465

466+
.. method:: get_revoked_certificate_by_serial_number(serial_number)
467+
468+
.. versionadded:: 2.3
469+
470+
:param serial_number: The serial as a Python integer.
471+
:returns: :class:`~cryptography.x509.RevokedCertificate` if the
472+
``serial_number`` is present in the CRL or ``None`` if it
473+
is not.
474+
466475
.. attribute:: signature_hash_algorithm
467476

468477
:type: :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`

src/_cffi_src/openssl/x509.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@
238238
X509_EXTENSION *X509_CRL_get_ext(X509_CRL *, int);
239239
int X509_CRL_get_ext_count(X509_CRL *);
240240
241+
int X509_CRL_get0_by_serial(X509_CRL *, X509_REVOKED **, ASN1_INTEGER *);
242+
241243
/* these CRYPTO_EX_DATA functions became macros in 1.1.0 */
242244
int X509_get_ex_new_index(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *,
243245
CRYPTO_EX_free *);

src/cryptography/hazmat/backends/openssl/x509.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
_REVOKED_CERTIFICATE_EXTENSION_PARSER, _asn1_integer_to_int,
1717
_asn1_string_to_bytes, _decode_x509_name, _obj2txt, _parse_asn1_time
1818
)
19+
from cryptography.hazmat.backends.openssl.encode_asn1 import (
20+
_encode_asn1_int_gc
21+
)
1922
from cryptography.hazmat.primitives import hashes, serialization
2023
from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
2124

@@ -235,6 +238,22 @@ def fingerprint(self, algorithm):
235238
h.update(der)
236239
return h.finalize()
237240

241+
def get_revoked_certificate_by_serial_number(self, serial_number):
242+
revoked = self._backend._ffi.new("X509_REVOKED **")
243+
asn1_int = _encode_asn1_int_gc(self._backend, serial_number)
244+
res = self._backend._lib.X509_CRL_get0_by_serial(
245+
self._x509_crl, revoked, asn1_int
246+
)
247+
if res == 0:
248+
return None
249+
else:
250+
self._backend.openssl_assert(
251+
revoked[0] != self._backend._ffi.NULL
252+
)
253+
return _RevokedCertificate(
254+
self._backend, self._x509_crl, revoked[0]
255+
)
256+
238257
@property
239258
def signature_hash_algorithm(self):
240259
oid = self.signature_algorithm_oid

src/cryptography/x509/base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ def fingerprint(self, algorithm):
189189
Returns bytes using digest passed.
190190
"""
191191

192+
@abc.abstractmethod
193+
def get_revoked_certificate_by_serial_number(self, serial_number):
194+
"""
195+
Returns an instance of RevokedCertificate or None if the serial_number
196+
is not in the CRL.
197+
"""
198+
192199
@abc.abstractproperty
193200
def signature_hash_algorithm(self):
194201
"""

tests/x509/test_x509.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,18 @@ def test_revoked_cert_retrieval(self, backend):
181181
# Check that len() works for CRLs.
182182
assert len(crl) == 12
183183

184+
def test_get_revoked_certificate_by_serial_number(self, backend):
185+
crl = _load_cert(
186+
os.path.join(
187+
"x509", "PKITS_data", "crls", "LongSerialNumberCACRL.crl"),
188+
x509.load_der_x509_crl,
189+
backend
190+
)
191+
serial_number = 725064303890588110203033396814564464046290047507
192+
revoked = crl.get_revoked_certificate_by_serial_number(serial_number)
193+
assert revoked.serial_number == serial_number
194+
assert crl.get_revoked_certificate_by_serial_number(500) is None
195+
184196
def test_revoked_cert_retrieval_retain_only_revoked(self, backend):
185197
"""
186198
This test attempts to trigger the crash condition described in

0 commit comments

Comments
 (0)