diff --git a/ChangeLog b/ChangeLog index e872eca4a..6dc82badc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-10-13 Dominic Chen + + * OpenSSL/crypto.py: Implement the ``dump_crl()`` function to dump a + certificate revocation list out to a string buffer. + 2015-09-07 Sam Lee * OpenSSL/SSL.py, OpenSSL/test/test_ssl.py: Implemented @@ -45,7 +50,7 @@ Connection.shutdown() is called when the underlying transport has gone away. -2011-09-02 Hynek Schlawack +2015-04-14 Hynek Schlawack * Release 0.15 diff --git a/doc/api/crypto.rst b/doc/api/crypto.rst index e2f2bcadc..95fb4df80 100644 --- a/doc/api/crypto.rst +++ b/doc/api/crypto.rst @@ -90,6 +90,8 @@ Private keys Certificate revocation lists ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. autofunction:: dump_crl + .. py:function:: load_crl(type, buffer) Load Certificate Revocation List (CRL) data from a string *buffer*. diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py index 132d98d7b..871bad219 100644 --- a/src/OpenSSL/crypto.py +++ b/src/OpenSSL/crypto.py @@ -1998,23 +1998,9 @@ def export(self, cert, key, type=FILETYPE_PEM, days=100, if not sign_result: _raise_current_error() - if type == FILETYPE_PEM: - ret = _lib.PEM_write_bio_X509_CRL(bio, self._crl) - elif type == FILETYPE_ASN1: - ret = _lib.i2d_X509_CRL_bio(bio, self._crl) - elif type == FILETYPE_TEXT: - ret = _lib.X509_CRL_print(bio, self._crl) - else: - raise ValueError( - "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or " - "FILETYPE_TEXT" - ) + return dump_crl(type, self) - if not ret: - # TODO: This is untested. - _raise_current_error() - return _bio_to_string(bio) CRLType = CRL @@ -2577,6 +2563,33 @@ def verify(cert, signature, data, digest): _raise_current_error() +def dump_crl(type, crl): + """ + Dump a certificate revocation list to a buffer. + + :param type: The file type (one of ``FILETYPE_PEM``, ``FILETYPE_ASN1``, or + ``FILETYPE_TEXT``). + :param cert: The CRL to dump. + :return: The buffer with the CRL. + :rtype: :py:data:`bytes` + """ + bio = _new_mem_buf() + + if type == FILETYPE_PEM: + ret = _lib.PEM_write_bio_X509_CRL(bio, crl._crl) + elif type == FILETYPE_ASN1: + ret = _lib.i2d_X509_CRL_bio(bio, crl._crl) + elif type == FILETYPE_TEXT: + ret = _lib.X509_CRL_print(bio, crl._crl) + else: + raise ValueError( + "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or " + "FILETYPE_TEXT") + + assert ret == 1 + return _bio_to_string(bio) + + def load_crl(type, buffer): """ Load a certificate revocation list from a buffer diff --git a/tests/test_crypto.py b/tests/test_crypto.py index 196e49050..d9a9526cf 100644 --- a/tests/test_crypto.py +++ b/tests/test_crypto.py @@ -31,7 +31,7 @@ from OpenSSL.crypto import dump_certificate_request, dump_privatekey from OpenSSL.crypto import PKCS7Type, load_pkcs7_data from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12 -from OpenSSL.crypto import CRL, Revoked, load_crl +from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType from OpenSSL.crypto import ( sign, verify, get_elliptic_curve, get_elliptic_curves) @@ -3206,6 +3206,14 @@ def test_load_crl_bad_data(self): """ self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world") + def test_dump_crl(self): + """ + The dumped CRL matches the original input. + """ + crl = load_crl(FILETYPE_PEM, crlData) + buf = dump_crl(FILETYPE_PEM, crl) + assert buf == crlData + class X509StoreContextTests(TestCase): """