Allow to configure how serial numbers are provided to x509_crl. (#715)
parent
6b1a3d6e68
commit
1736602ce7
|
@ -0,0 +1,5 @@
|
||||||
|
minor_changes:
|
||||||
|
- "x509_crl - the new option ``serial_numbers`` allow to configure in which format serial numbers can be provided
|
||||||
|
to ``revoked_certificates[].serial_number``. The default is as integers (``serial_numbers=integer``) for backwards compatibility;
|
||||||
|
setting ``serial_numbers=hex-octets`` allows to specify colon-separated hex octet strings like ``00:11:22:FF``
|
||||||
|
(https://github.com/ansible-collections/community.crypto/issues/687, https://github.com/ansible-collections/community.crypto/pull/715)."
|
|
@ -164,6 +164,21 @@ options:
|
||||||
type: str
|
type: str
|
||||||
default: sha256
|
default: sha256
|
||||||
|
|
||||||
|
serial_numbers:
|
||||||
|
description:
|
||||||
|
- This option determines which values will be accepted for O(revoked_certificates[].serial_number).
|
||||||
|
- If set to V(integer) (default), serial numbers are assumed to be integers, for example V(66223).
|
||||||
|
(This example value is equivalent to the hex octet string V(01:02:AF).)
|
||||||
|
- If set to V(hex-octets), serial numbers are assumed to be colon-separated hex octet strings,
|
||||||
|
for example V(01:02:AF).
|
||||||
|
(This example value is equivalent to the integer V(66223).)
|
||||||
|
type: str
|
||||||
|
choices:
|
||||||
|
- integer
|
||||||
|
- hex-octets
|
||||||
|
default: integer
|
||||||
|
version_added: 2.18.0
|
||||||
|
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
description:
|
description:
|
||||||
- List of certificates to be revoked.
|
- List of certificates to be revoked.
|
||||||
|
@ -193,9 +208,13 @@ options:
|
||||||
- Mutually exclusive with O(revoked_certificates[].path) and
|
- Mutually exclusive with O(revoked_certificates[].path) and
|
||||||
O(revoked_certificates[].content). One of these three options must
|
O(revoked_certificates[].content). One of these three options must
|
||||||
be specified.
|
be specified.
|
||||||
- This option accepts an B(integer). If you want to provide serial numbers as colon-separated hex strings,
|
- This option accepts integers or hex octet strings, depending on the value
|
||||||
such as C(11:22:33), you need to convert them to an integer with P(community.crypto.parse_serial#filter).
|
of O(serial_numbers).
|
||||||
type: int
|
- If O(serial_numbers=integer), integers such as V(66223) must be provided.
|
||||||
|
- If O(serial_numbers=hex-octets), strings such as V(01:02:AF) must be provided.
|
||||||
|
- You can use the filters P(community.crypto.parse_serial#filter) and
|
||||||
|
P(community.crypto.to_serial#filter) to convert these two representations.
|
||||||
|
type: raw
|
||||||
revocation_date:
|
revocation_date:
|
||||||
description:
|
description:
|
||||||
- The point in time the certificate was revoked.
|
- The point in time the certificate was revoked.
|
||||||
|
@ -431,7 +450,9 @@ import traceback
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||||
|
from ansible.module_utils.common.validation import check_type_int, check_type_str
|
||||||
|
|
||||||
|
from ansible_collections.community.crypto.plugins.module_utils.serial import parse_serial
|
||||||
from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
|
from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
|
||||||
|
|
||||||
from ansible_collections.community.crypto.plugins.module_utils.io import (
|
from ansible_collections.community.crypto.plugins.module_utils.io import (
|
||||||
|
@ -520,6 +541,7 @@ class CRL(OpenSSLObject):
|
||||||
self.ignore_timestamps = module.params['ignore_timestamps']
|
self.ignore_timestamps = module.params['ignore_timestamps']
|
||||||
self.return_content = module.params['return_content']
|
self.return_content = module.params['return_content']
|
||||||
self.name_encoding = module.params['name_encoding']
|
self.name_encoding = module.params['name_encoding']
|
||||||
|
self.serial_numbers_format = module.params['serial_numbers']
|
||||||
self.crl_content = None
|
self.crl_content = None
|
||||||
|
|
||||||
self.privatekey_path = module.params['privatekey_path']
|
self.privatekey_path = module.params['privatekey_path']
|
||||||
|
@ -545,6 +567,8 @@ class CRL(OpenSSLObject):
|
||||||
if self.digest is None:
|
if self.digest is None:
|
||||||
raise CRLError('The digest "{0}" is not supported'.format(module.params['digest']))
|
raise CRLError('The digest "{0}" is not supported'.format(module.params['digest']))
|
||||||
|
|
||||||
|
self.module = module
|
||||||
|
|
||||||
self.revoked_certificates = []
|
self.revoked_certificates = []
|
||||||
for i, rc in enumerate(module.params['revoked_certificates']):
|
for i, rc in enumerate(module.params['revoked_certificates']):
|
||||||
result = {
|
result = {
|
||||||
|
@ -576,7 +600,7 @@ class CRL(OpenSSLObject):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Specify serial_number (and potentially issuer) directly
|
# Specify serial_number (and potentially issuer) directly
|
||||||
result['serial_number'] = rc['serial_number']
|
result['serial_number'] = self._parse_serial_number(rc['serial_number'], i)
|
||||||
# All other options
|
# All other options
|
||||||
if rc['issuer']:
|
if rc['issuer']:
|
||||||
result['issuer'] = [cryptography_get_name(issuer, 'issuer') for issuer in rc['issuer']]
|
result['issuer'] = [cryptography_get_name(issuer, 'issuer') for issuer in rc['issuer']]
|
||||||
|
@ -596,8 +620,6 @@ class CRL(OpenSSLObject):
|
||||||
result['invalidity_date_critical'] = rc['invalidity_date_critical']
|
result['invalidity_date_critical'] = rc['invalidity_date_critical']
|
||||||
self.revoked_certificates.append(result)
|
self.revoked_certificates.append(result)
|
||||||
|
|
||||||
self.module = module
|
|
||||||
|
|
||||||
self.backup = module.params['backup']
|
self.backup = module.params['backup']
|
||||||
self.backup_file = None
|
self.backup_file = None
|
||||||
|
|
||||||
|
@ -631,6 +653,25 @@ class CRL(OpenSSLObject):
|
||||||
|
|
||||||
self.diff_after = self.diff_before = self._get_info(data)
|
self.diff_after = self.diff_before = self._get_info(data)
|
||||||
|
|
||||||
|
def _parse_serial_number(self, value, index):
|
||||||
|
if self.serial_numbers_format == 'integer':
|
||||||
|
try:
|
||||||
|
return check_type_int(value)
|
||||||
|
except TypeError as exc:
|
||||||
|
self.module.fail_json(msg='Error while parsing revoked_certificates[{idx}].serial_number as an integer: {exc}'.format(
|
||||||
|
idx=index + 1,
|
||||||
|
exc=to_native(exc),
|
||||||
|
))
|
||||||
|
if self.serial_numbers_format == 'hex-octets':
|
||||||
|
try:
|
||||||
|
return parse_serial(check_type_str(value))
|
||||||
|
except (TypeError, ValueError) as exc:
|
||||||
|
self.module.fail_json(msg='Error while parsing revoked_certificates[{idx}].serial_number as an colon-separated hex octet string: {exc}'.format(
|
||||||
|
idx=index + 1,
|
||||||
|
exc=to_native(exc),
|
||||||
|
))
|
||||||
|
raise RuntimeError('Unexpected value %s of serial_numbers' % (self.serial_numbers_format, ))
|
||||||
|
|
||||||
def _get_info(self, data):
|
def _get_info(self, data):
|
||||||
if data is None:
|
if data is None:
|
||||||
return dict()
|
return dict()
|
||||||
|
@ -896,7 +937,7 @@ def main():
|
||||||
options=dict(
|
options=dict(
|
||||||
path=dict(type='path'),
|
path=dict(type='path'),
|
||||||
content=dict(type='str'),
|
content=dict(type='str'),
|
||||||
serial_number=dict(type='int'),
|
serial_number=dict(type='raw'),
|
||||||
revocation_date=dict(type='str', default='+0s'),
|
revocation_date=dict(type='str', default='+0s'),
|
||||||
issuer=dict(type='list', elements='str'),
|
issuer=dict(type='list', elements='str'),
|
||||||
issuer_critical=dict(type='bool', default=False),
|
issuer_critical=dict(type='bool', default=False),
|
||||||
|
@ -916,6 +957,7 @@ def main():
|
||||||
mutually_exclusive=[['path', 'content', 'serial_number']],
|
mutually_exclusive=[['path', 'content', 'serial_number']],
|
||||||
),
|
),
|
||||||
name_encoding=dict(type='str', default='ignore', choices=['ignore', 'idna', 'unicode']),
|
name_encoding=dict(type='str', default='ignore', choices=['ignore', 'idna', 'unicode']),
|
||||||
|
serial_numbers=dict(type='str', default='integer', choices=['integer', 'hex-octets']),
|
||||||
),
|
),
|
||||||
required_if=[
|
required_if=[
|
||||||
('state', 'present', ['privatekey_path', 'privatekey_content'], True),
|
('state', 'present', ['privatekey_path', 'privatekey_content'], True),
|
||||||
|
|
|
@ -119,7 +119,7 @@
|
||||||
- cert-2.pem
|
- cert-2.pem
|
||||||
register: slurp
|
register: slurp
|
||||||
|
|
||||||
- name: Create CRL 1 (idempotent with content, check mode)
|
- name: Create CRL 1 (idempotent with content and octet string serial, check mode)
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl1.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl1.crl'
|
||||||
privatekey_content: "{{ slurp.results[0].content | b64decode }}"
|
privatekey_content: "{{ slurp.results[0].content | b64decode }}"
|
||||||
|
@ -127,6 +127,7 @@
|
||||||
CN: Ansible
|
CN: Ansible
|
||||||
last_update: 20191013000000Z
|
last_update: 20191013000000Z
|
||||||
next_update: 20191113000000Z
|
next_update: 20191113000000Z
|
||||||
|
serial_numbers: hex-octets
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
- content: "{{ slurp.results[1].content | b64decode }}"
|
- content: "{{ slurp.results[1].content | b64decode }}"
|
||||||
revocation_date: 20191013000000Z
|
revocation_date: 20191013000000Z
|
||||||
|
@ -135,12 +136,12 @@
|
||||||
reason: key_compromise
|
reason: key_compromise
|
||||||
reason_critical: true
|
reason_critical: true
|
||||||
invalidity_date: 20191012000000Z
|
invalidity_date: 20191012000000Z
|
||||||
- serial_number: 1234
|
- serial_number: 04:D2
|
||||||
revocation_date: 20191001000000Z
|
revocation_date: 20191001000000Z
|
||||||
check_mode: true
|
check_mode: true
|
||||||
register: crl_1_idem_content_check
|
register: crl_1_idem_content_check
|
||||||
|
|
||||||
- name: Create CRL 1 (idempotent with content)
|
- name: Create CRL 1 (idempotent with content and octet string serial)
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl1.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl1.crl'
|
||||||
privatekey_content: "{{ slurp.results[0].content | b64decode }}"
|
privatekey_content: "{{ slurp.results[0].content | b64decode }}"
|
||||||
|
@ -148,6 +149,7 @@
|
||||||
CN: Ansible
|
CN: Ansible
|
||||||
last_update: 20191013000000Z
|
last_update: 20191013000000Z
|
||||||
next_update: 20191113000000Z
|
next_update: 20191113000000Z
|
||||||
|
serial_numbers: hex-octets
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
- content: "{{ slurp.results[1].content | b64decode }}"
|
- content: "{{ slurp.results[1].content | b64decode }}"
|
||||||
revocation_date: 20191013000000Z
|
revocation_date: 20191013000000Z
|
||||||
|
@ -156,7 +158,7 @@
|
||||||
reason: key_compromise
|
reason: key_compromise
|
||||||
reason_critical: true
|
reason_critical: true
|
||||||
invalidity_date: 20191012000000Z
|
invalidity_date: 20191012000000Z
|
||||||
- serial_number: 1234
|
- serial_number: 04:D2
|
||||||
revocation_date: 20191001000000Z
|
revocation_date: 20191001000000Z
|
||||||
register: crl_1_idem_content
|
register: crl_1_idem_content
|
||||||
|
|
||||||
|
@ -220,7 +222,7 @@
|
||||||
reason: key_compromise
|
reason: key_compromise
|
||||||
reason_critical: true
|
reason_critical: true
|
||||||
invalidity_date: 20191012000000Z
|
invalidity_date: 20191012000000Z
|
||||||
- serial_number: 1234
|
- serial_number: "1234"
|
||||||
revocation_date: 20191001000000Z
|
revocation_date: 20191001000000Z
|
||||||
check_mode: true
|
check_mode: true
|
||||||
register: crl_1_format_idem_check
|
register: crl_1_format_idem_check
|
||||||
|
@ -242,7 +244,7 @@
|
||||||
reason: key_compromise
|
reason: key_compromise
|
||||||
reason_critical: true
|
reason_critical: true
|
||||||
invalidity_date: 20191012000000Z
|
invalidity_date: 20191012000000Z
|
||||||
- serial_number: 1234
|
- serial_number: "1234"
|
||||||
revocation_date: 20191001000000Z
|
revocation_date: 20191001000000Z
|
||||||
return_content: true
|
return_content: true
|
||||||
register: crl_1_format_idem
|
register: crl_1_format_idem
|
||||||
|
|
Loading…
Reference in New Issue