From 69aeb2d86f3ce83f51830f5d8ff6c3c16126486d Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Wed, 19 May 2021 09:32:30 +0200 Subject: [PATCH] x509_crl_info: allow to not enumerate revoked certificates (#232) * Allow to not enumerate revoked certificates. * Forgot to remove one instance. * Add example. --- ...509_crl_info-list_revoked_certificates.yml | 2 ++ .../crypto/module_backends/crl_info.py | 17 ++++++----- plugins/modules/x509_crl_info.py | 20 +++++++++++-- .../targets/x509_crl/tasks/impl.yml | 30 +++++++++++++++++++ .../targets/x509_crl/tests/validate.yml | 5 ++++ 5 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 changelogs/fragments/232-x509_crl_info-list_revoked_certificates.yml diff --git a/changelogs/fragments/232-x509_crl_info-list_revoked_certificates.yml b/changelogs/fragments/232-x509_crl_info-list_revoked_certificates.yml new file mode 100644 index 00000000..cd30978d --- /dev/null +++ b/changelogs/fragments/232-x509_crl_info-list_revoked_certificates.yml @@ -0,0 +1,2 @@ +minor_changes: +- "x509_crl_info - add ``list_revoked_certificates`` option to avoid enumerating all revoked certificates (https://github.com/ansible-collections/community.crypto/pull/232)." diff --git a/plugins/module_utils/crypto/module_backends/crl_info.py b/plugins/module_utils/crypto/module_backends/crl_info.py index 41ce9302..3f15b9cf 100644 --- a/plugins/module_utils/crypto/module_backends/crl_info.py +++ b/plugins/module_utils/crypto/module_backends/crl_info.py @@ -46,10 +46,11 @@ else: class CRLInfoRetrieval(object): - def __init__(self, module, content): + def __init__(self, module, content, list_revoked_certificates=True): # content must be a bytes string self.module = module self.content = content + self.list_revoked_certificates = list_revoked_certificates def get_info(self): self.crl_pem = identify_pem_format(self.content) @@ -69,7 +70,6 @@ class CRLInfoRetrieval(object): 'digest': None, 'issuer_ordered': None, 'issuer': None, - 'revoked_certificates': [], } result['last_update'] = self.crl.last_update.strftime(TIMESTAMP_FORMAT) @@ -82,18 +82,19 @@ class CRLInfoRetrieval(object): result['issuer'] = {} for k, v in issuer: result['issuer'][k] = v - result['revoked_certificates'] = [] - for cert in self.crl: - entry = cryptography_decode_revoked_certificate(cert) - result['revoked_certificates'].append(cryptography_dump_revoked(entry)) + if self.list_revoked_certificates: + result['revoked_certificates'] = [] + for cert in self.crl: + entry = cryptography_decode_revoked_certificate(cert) + result['revoked_certificates'].append(cryptography_dump_revoked(entry)) return result -def get_crl_info(module, content): +def get_crl_info(module, content, list_revoked_certificates=True): if not CRYPTOGRAPHY_FOUND: module.fail_json(msg=missing_required_lib('cryptography >= {0}'.format(MINIMAL_CRYPTOGRAPHY_VERSION)), exception=CRYPTOGRAPHY_IMP_ERR) - info = CRLInfoRetrieval(module, content) + info = CRLInfoRetrieval(module, content, list_revoked_certificates=list_revoked_certificates) return info.get_info() diff --git a/plugins/modules/x509_crl_info.py b/plugins/modules/x509_crl_info.py index ee66c43f..decb1511 100644 --- a/plugins/modules/x509_crl_info.py +++ b/plugins/modules/x509_crl_info.py @@ -30,6 +30,15 @@ options: - Content of the X.509 CRL in PEM format, or Base64-encoded X.509 CRL. - Either I(path) or I(content) must be specified, but not both. type: str + list_revoked_certificates: + description: + - If set to C(false), the list of revoked certificates is not included in the result. + - This is useful when retrieving information on large CRL files. Enumerating all revoked + certificates can take some time, including serializing the result as JSON, sending it to + the Ansible controller, and decoding it again. + type: bool + default: true + version_added: 1.7.0 notes: - All timestamp values are provided in ASN.1 TIME format, in other words, following the C(YYYYMMDDHHMMSSZ) pattern. @@ -48,6 +57,12 @@ EXAMPLES = r''' - name: Print the information ansible.builtin.debug: msg: "{{ result }}" + +- name: Get information on CRL without list of revoked certificates + community.crypto.x509_crl_info: + path: /etc/ssl/very-large.crl + list_revoked_certificates: false + register: result ''' RETURN = r''' @@ -87,7 +102,7 @@ digest: sample: sha256WithRSAEncryption revoked_certificates: description: List of certificates to be revoked. - returned: success + returned: success if I(list_revoked_certificates=true) type: list elements: dict contains: @@ -157,6 +172,7 @@ def main(): argument_spec=dict( path=dict(type='path'), content=dict(type='str'), + list_revoked_certificates=dict(type='bool', default=True), ), required_one_of=( ['path', 'content'], @@ -182,7 +198,7 @@ def main(): module.fail_json(msg='Error while Base64 decoding content: {0}'.format(e)) try: - result = get_crl_info(module, data) + result = get_crl_info(module, data, list_revoked_certificates=module.params['list_revoked_certificates']) module.exit_json(**result) except OpenSSLObjectError as e: module.fail_json(msg=to_native(e)) diff --git a/tests/integration/targets/x509_crl/tasks/impl.yml b/tests/integration/targets/x509_crl/tasks/impl.yml index 68ed2fc7..77803d16 100644 --- a/tests/integration/targets/x509_crl/tasks/impl.yml +++ b/tests/integration/targets/x509_crl/tasks/impl.yml @@ -19,6 +19,7 @@ revocation_date: 20191001000000Z check_mode: yes register: crl_1_check + - name: Create CRL 1 x509_crl: path: '{{ output_dir }}/ca-crl1.crl' @@ -38,18 +39,22 @@ - serial_number: 1234 revocation_date: 20191001000000Z register: crl_1 + - name: Retrieve CRL 1 infos x509_crl_info: path: '{{ output_dir }}/ca-crl1.crl' register: crl_1_info_1 + - name: Retrieve CRL 1 infos via file content x509_crl_info: content: '{{ lookup("file", output_dir ~ "/ca-crl1.crl") }}' register: crl_1_info_2 + - name: Retrieve CRL 1 infos via file content (Base64) x509_crl_info: content: '{{ lookup("file", output_dir ~ "/ca-crl1.crl") | b64encode }}' register: crl_1_info_3 + - name: Create CRL 1 (idempotent, check mode) x509_crl: path: '{{ output_dir }}/ca-crl1.crl' @@ -70,6 +75,7 @@ revocation_date: 20191001000000Z check_mode: yes register: crl_1_idem_check + - name: Create CRL 1 (idempotent) x509_crl: path: '{{ output_dir }}/ca-crl1.crl' @@ -89,6 +95,7 @@ - serial_number: 1234 revocation_date: 20191001000000Z register: crl_1_idem + - name: Create CRL 1 (idempotent with content, check mode) x509_crl: path: '{{ output_dir }}/ca-crl1.crl' @@ -109,6 +116,7 @@ revocation_date: 20191001000000Z check_mode: yes register: crl_1_idem_content_check + - name: Create CRL 1 (idempotent with content) x509_crl: path: '{{ output_dir }}/ca-crl1.crl' @@ -128,6 +136,7 @@ - serial_number: 1234 revocation_date: 20191001000000Z register: crl_1_idem_content + - name: Create CRL 1 (format, check mode) x509_crl: path: '{{ output_dir }}/ca-crl1.crl' @@ -149,6 +158,7 @@ revocation_date: 20191001000000Z check_mode: yes register: crl_1_format_check + - name: Create CRL 1 (format) x509_crl: path: '{{ output_dir }}/ca-crl1.crl' @@ -169,6 +179,7 @@ - serial_number: 1234 revocation_date: 20191001000000Z register: crl_1_format + - name: Create CRL 1 (format, idempotent, check mode) x509_crl: path: '{{ output_dir }}/ca-crl1.crl' @@ -190,6 +201,7 @@ revocation_date: 20191001000000Z check_mode: yes register: crl_1_format_idem_check + - name: Create CRL 1 (format, idempotent) x509_crl: path: '{{ output_dir }}/ca-crl1.crl' @@ -211,14 +223,17 @@ revocation_date: 20191001000000Z return_content: yes register: crl_1_format_idem + - name: Retrieve CRL 1 infos via file x509_crl_info: path: '{{ output_dir }}/ca-crl1.crl' register: crl_1_info_4 + - name: Read ca-crl1.crl slurp: src: "{{ output_dir }}/ca-crl1.crl" register: content + - name: Retrieve CRL 1 infos via file content (Base64) x509_crl_info: content: '{{ content.content }}' @@ -241,6 +256,7 @@ - serial_number: 1234 check_mode: yes register: crl_2_check + - name: Create CRL 2 x509_crl: path: '{{ output_dir }}/ca-crl2.crl' @@ -257,6 +273,7 @@ invalidity_date: 20191012000000Z - serial_number: 1234 register: crl_2 + - name: Create CRL 2 (idempotent, check mode) x509_crl: path: '{{ output_dir }}/ca-crl2.crl' @@ -275,6 +292,7 @@ ignore_timestamps: yes check_mode: yes register: crl_2_idem_check + - name: Create CRL 2 (idempotent) x509_crl: path: '{{ output_dir }}/ca-crl2.crl' @@ -292,6 +310,7 @@ - serial_number: 1234 ignore_timestamps: yes register: crl_2_idem + - name: Create CRL 2 (idempotent update, check mode) x509_crl: path: '{{ output_dir }}/ca-crl2.crl' @@ -306,6 +325,7 @@ mode: update check_mode: yes register: crl_2_idem_update_change_check + - name: Create CRL 2 (idempotent update) x509_crl: path: '{{ output_dir }}/ca-crl2.crl' @@ -319,6 +339,7 @@ ignore_timestamps: yes mode: update register: crl_2_idem_update_change + - name: Create CRL 2 (idempotent update, check mode) x509_crl: path: '{{ output_dir }}/ca-crl2.crl' @@ -336,6 +357,7 @@ mode: update check_mode: yes register: crl_2_idem_update_check + - name: Create CRL 2 (idempotent update) x509_crl: path: '{{ output_dir }}/ca-crl2.crl' @@ -352,6 +374,7 @@ ignore_timestamps: yes mode: update register: crl_2_idem_update + - name: Create CRL 2 (changed timestamps, check mode) x509_crl: path: '{{ output_dir }}/ca-crl2.crl' @@ -369,6 +392,7 @@ mode: update check_mode: yes register: crl_2_change_check + - name: Create CRL 2 (changed timestamps) x509_crl: path: '{{ output_dir }}/ca-crl2.crl' @@ -386,3 +410,9 @@ mode: update return_content: yes register: crl_2_change + +- name: Retrieve CRL 2 infos + x509_crl_info: + path: '{{ output_dir }}/ca-crl2.crl' + list_revoked_certificates: false + register: crl_2_info_1 diff --git a/tests/integration/targets/x509_crl/tests/validate.yml b/tests/integration/targets/x509_crl/tests/validate.yml index c31fa942..7dddc237 100644 --- a/tests/integration/targets/x509_crl/tests/validate.yml +++ b/tests/integration/targets/x509_crl/tests/validate.yml @@ -80,3 +80,8 @@ - crl_2_change_check is changed - crl_2_change is changed - crl_2_change.crl == lookup('file', output_dir ~ '/ca-crl2.crl', rstrip=False) + +- name: Validate CRL 2 info + assert: + that: + - "'revoked_certificates' not in crl_2_info_1"