Allow to specify subject (for CSRs) and issuer (for CRLs) ordered (#316)
* Allow to specify subject (for CSRs) and issuer (for CRLs) ordered.
* Forgot import.
* Apply suggestions from code review
Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
* Apply suggestions from code review
Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
* Fix typo.
* Simplify error handling, reject empty values outright.
* Document d497231e1c
.
Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
pull/328/head
parent
ecbd44df22
commit
589e7c72ef
|
@ -0,0 +1,9 @@
|
||||||
|
minor_changes:
|
||||||
|
- "acme_certificate - the ``subject`` and ``issuer`` fields in in the ``select_chain`` entries are now more strictly validated (https://github.com/ansible-collections/community.crypto/pull/316)."
|
||||||
|
- "openssl_csr, openssl_csr_pipe - there is now stricter validation of the values of the ``subject`` option (https://github.com/ansible-collections/community.crypto/pull/316)."
|
||||||
|
- "openssl_csr, openssl_csr_pipe - provide a new ``subject_ordered`` option if the order of the components in the subject is of importance (https://github.com/ansible-collections/community.crypto/issues/291, https://github.com/ansible-collections/community.crypto/pull/316)."
|
||||||
|
- "x509_crl - there is now stricter validation of the values of the ``issuer`` option (https://github.com/ansible-collections/community.crypto/pull/316)."
|
||||||
|
- "x509_crl - provide a new ``issuer_ordered`` option if the order of the components in the issuer is of importance (https://github.com/ansible-collections/community.crypto/issues/291, https://github.com/ansible-collections/community.crypto/pull/316)."
|
||||||
|
breaking_changes:
|
||||||
|
- "openssl_csr, openssl_csr_pipe, x509_crl - the ``subject`` respectively ``issuer`` fields no longer ignore empty values, but instead fail when encountering them (https://github.com/ansible-collections/community.crypto/pull/316)."
|
||||||
|
- "x509_crl - for idempotency checks, the ``issuer`` order is ignored. If order is important, use the new ``issuer_ordered`` option (https://github.com/ansible-collections/community.crypto/pull/316)."
|
|
@ -52,7 +52,20 @@ options:
|
||||||
description:
|
description:
|
||||||
- Key/value pairs that will be present in the subject name field of the certificate signing request.
|
- Key/value pairs that will be present in the subject name field of the certificate signing request.
|
||||||
- If you need to specify more than one value with the same key, use a list as value.
|
- If you need to specify more than one value with the same key, use a list as value.
|
||||||
|
- If the order of the components is important, use I(subject_ordered).
|
||||||
|
- Mutually exclusive with I(subject_ordered).
|
||||||
type: dict
|
type: dict
|
||||||
|
subject_ordered:
|
||||||
|
description:
|
||||||
|
- A list of dictionaries, where every dictionary must contain one key/value pair. This key/value pair
|
||||||
|
will be present in the subject name field of the certificate signing request.
|
||||||
|
- If you want to specify more than one value with the same key in a row, you can use a list as value.
|
||||||
|
- Mutually exclusive with I(subject), and any other subject field option, such as I(country_name),
|
||||||
|
I(state_or_province_name), I(locality_name), I(organization_name), I(organizational_unit_name),
|
||||||
|
I(common_name), or I(email_address).
|
||||||
|
type: list
|
||||||
|
elements: dict
|
||||||
|
version_added: 2.0.0
|
||||||
country_name:
|
country_name:
|
||||||
description:
|
description:
|
||||||
- The countryName field of the certificate signing request subject.
|
- The countryName field of the certificate signing request subject.
|
||||||
|
|
|
@ -118,11 +118,11 @@ class CryptographyChainMatcher(ChainMatcher):
|
||||||
self.issuer = []
|
self.issuer = []
|
||||||
if criterium.subject:
|
if criterium.subject:
|
||||||
self.subject = [
|
self.subject = [
|
||||||
(cryptography_name_to_oid(k), to_native(v)) for k, v in parse_name_field(criterium.subject)
|
(cryptography_name_to_oid(k), to_native(v)) for k, v in parse_name_field(criterium.subject, 'subject')
|
||||||
]
|
]
|
||||||
if criterium.issuer:
|
if criterium.issuer:
|
||||||
self.issuer = [
|
self.issuer = [
|
||||||
(cryptography_name_to_oid(k), to_native(v)) for k, v in parse_name_field(criterium.issuer)
|
(cryptography_name_to_oid(k), to_native(v)) for k, v in parse_name_field(criterium.issuer, 'issuer')
|
||||||
]
|
]
|
||||||
self.subject_key_identifier = CryptographyChainMatcher._parse_key_identifier(
|
self.subject_key_identifier = CryptographyChainMatcher._parse_key_identifier(
|
||||||
criterium.subject_key_identifier, 'subject_key_identifier', criterium.index, module)
|
criterium.subject_key_identifier, 'subject_key_identifier', criterium.index, module)
|
||||||
|
|
|
@ -16,7 +16,7 @@ from distutils.version import LooseVersion
|
||||||
|
|
||||||
from ansible.module_utils import six
|
from ansible.module_utils import six
|
||||||
from ansible.module_utils.basic import missing_required_lib
|
from ansible.module_utils.basic import missing_required_lib
|
||||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||||
|
|
||||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||||
OpenSSLObjectError,
|
OpenSSLObjectError,
|
||||||
|
@ -27,6 +27,7 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.support im
|
||||||
load_privatekey,
|
load_privatekey,
|
||||||
load_certificate_request,
|
load_certificate_request,
|
||||||
parse_name_field,
|
parse_name_field,
|
||||||
|
parse_ordered_name_field,
|
||||||
select_message_digest,
|
select_message_digest,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -119,6 +120,7 @@ class CertificateSigningRequestBackend(object):
|
||||||
if self.create_subject_key_identifier and self.subject_key_identifier is not None:
|
if self.create_subject_key_identifier and self.subject_key_identifier is not None:
|
||||||
module.fail_json(msg='subject_key_identifier cannot be specified if create_subject_key_identifier is true')
|
module.fail_json(msg='subject_key_identifier cannot be specified if create_subject_key_identifier is true')
|
||||||
|
|
||||||
|
self.ordered_subject = False
|
||||||
self.subject = [
|
self.subject = [
|
||||||
('C', module.params['country_name']),
|
('C', module.params['country_name']),
|
||||||
('ST', module.params['state_or_province_name']),
|
('ST', module.params['state_or_province_name']),
|
||||||
|
@ -128,11 +130,19 @@ class CertificateSigningRequestBackend(object):
|
||||||
('CN', module.params['common_name']),
|
('CN', module.params['common_name']),
|
||||||
('emailAddress', module.params['email_address']),
|
('emailAddress', module.params['email_address']),
|
||||||
]
|
]
|
||||||
|
|
||||||
if module.params['subject']:
|
|
||||||
self.subject = self.subject + parse_name_field(module.params['subject'])
|
|
||||||
self.subject = [(entry[0], entry[1]) for entry in self.subject if entry[1]]
|
self.subject = [(entry[0], entry[1]) for entry in self.subject if entry[1]]
|
||||||
|
|
||||||
|
try:
|
||||||
|
if module.params['subject']:
|
||||||
|
self.subject = self.subject + parse_name_field(module.params['subject'], 'subject')
|
||||||
|
if module.params['subject_ordered']:
|
||||||
|
if self.subject:
|
||||||
|
raise CertificateSigningRequestError('subject_ordered cannot be combined with any other subject field')
|
||||||
|
self.subject = parse_ordered_name_field(module.params['subject_ordered'], 'subject_ordered')
|
||||||
|
self.ordered_subject = True
|
||||||
|
except ValueError as exc:
|
||||||
|
raise CertificateSigningRequestError(to_native(exc))
|
||||||
|
|
||||||
self.using_common_name_for_san = False
|
self.using_common_name_for_san = False
|
||||||
if not self.subjectAltName and module.params['use_common_name_for_san']:
|
if not self.subjectAltName and module.params['use_common_name_for_san']:
|
||||||
for sub in self.subject:
|
for sub in self.subject:
|
||||||
|
@ -401,7 +411,10 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||||
def _check_subject(csr):
|
def _check_subject(csr):
|
||||||
subject = [(cryptography_name_to_oid(entry[0]), to_text(entry[1])) for entry in self.subject]
|
subject = [(cryptography_name_to_oid(entry[0]), to_text(entry[1])) for entry in self.subject]
|
||||||
current_subject = [(sub.oid, sub.value) for sub in csr.subject]
|
current_subject = [(sub.oid, sub.value) for sub in csr.subject]
|
||||||
return set(subject) == set(current_subject)
|
if self.ordered_subject:
|
||||||
|
return subject == current_subject
|
||||||
|
else:
|
||||||
|
return set(subject) == set(current_subject)
|
||||||
|
|
||||||
def _find_extension(extensions, exttype):
|
def _find_extension(extensions, exttype):
|
||||||
return next(
|
return next(
|
||||||
|
@ -592,6 +605,7 @@ def get_csr_argument_spec():
|
||||||
privatekey_passphrase=dict(type='str', no_log=True),
|
privatekey_passphrase=dict(type='str', no_log=True),
|
||||||
version=dict(type='int', default=1, choices=[1]),
|
version=dict(type='int', default=1, choices=[1]),
|
||||||
subject=dict(type='dict'),
|
subject=dict(type='dict'),
|
||||||
|
subject_ordered=dict(type='list', elements='dict'),
|
||||||
country_name=dict(type='str', aliases=['C', 'countryName']),
|
country_name=dict(type='str', aliases=['C', 'countryName']),
|
||||||
state_or_province_name=dict(type='str', aliases=['ST', 'stateOrProvinceName']),
|
state_or_province_name=dict(type='str', aliases=['ST', 'stateOrProvinceName']),
|
||||||
locality_name=dict(type='str', aliases=['L', 'localityName']),
|
locality_name=dict(type='str', aliases=['L', 'localityName']),
|
||||||
|
@ -645,6 +659,7 @@ def get_csr_argument_spec():
|
||||||
],
|
],
|
||||||
mutually_exclusive=[
|
mutually_exclusive=[
|
||||||
['privatekey_path', 'privatekey_content'],
|
['privatekey_path', 'privatekey_content'],
|
||||||
|
['subject', 'subject_ordered'],
|
||||||
],
|
],
|
||||||
required_one_of=[
|
required_one_of=[
|
||||||
['privatekey_path', 'privatekey_content'],
|
['privatekey_path', 'privatekey_content'],
|
||||||
|
|
|
@ -237,16 +237,43 @@ def load_certificate_request(path, content=None, backend='cryptography'):
|
||||||
raise OpenSSLObjectError(exc)
|
raise OpenSSLObjectError(exc)
|
||||||
|
|
||||||
|
|
||||||
def parse_name_field(input_dict):
|
def parse_name_field(input_dict, name_field_name=None):
|
||||||
|
"""Take a dict with key: value or key: list_of_values mappings and return a list of tuples"""
|
||||||
|
error_str = '{key}' if name_field_name is None else '{key} in {name}'
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for key, value in input_dict.items():
|
||||||
|
if isinstance(value, list):
|
||||||
|
for entry in value:
|
||||||
|
if not isinstance(entry, six.string_types):
|
||||||
|
raise TypeError(('Values %s must be strings' % error_str).format(key=key, name=name_field_name))
|
||||||
|
if not entry:
|
||||||
|
raise ValueError(('Values for %s must not be empty strings' % error_str).format(key=key))
|
||||||
|
result.append((key, entry))
|
||||||
|
elif isinstance(value, six.string_types):
|
||||||
|
if not value:
|
||||||
|
raise ValueError(('Value for %s must not be an empty string' % error_str).format(key=key))
|
||||||
|
result.append((key, value))
|
||||||
|
else:
|
||||||
|
raise TypeError(('Value for %s must be either a string or a list of strings' % error_str).format(key=key))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def parse_ordered_name_field(input_list, name_field_name):
|
||||||
"""Take a dict with key: value or key: list_of_values mappings and return a list of tuples"""
|
"""Take a dict with key: value or key: list_of_values mappings and return a list of tuples"""
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
for key in input_dict:
|
for index, entry in enumerate(input_list):
|
||||||
if isinstance(input_dict[key], list):
|
if len(entry) != 1:
|
||||||
for entry in input_dict[key]:
|
raise ValueError(
|
||||||
result.append((key, entry))
|
'Entry #{index} in {name} must be a dictionary with exactly one key-value pair'.format(
|
||||||
else:
|
name=name_field_name, index=index + 1))
|
||||||
result.append((key, input_dict[key]))
|
try:
|
||||||
|
result.extend(parse_name_field(entry, name_field_name=name_field_name))
|
||||||
|
except (TypeError, ValueError) as exc:
|
||||||
|
raise ValueError(
|
||||||
|
'Error while processing entry #{index} in {name}: {error}'.format(
|
||||||
|
name=name_field_name, index=index + 1, error=exc))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -580,9 +580,12 @@ class ACMECertificateClient(object):
|
||||||
|
|
||||||
if self.module.params['select_chain']:
|
if self.module.params['select_chain']:
|
||||||
for criterium_idx, criterium in enumerate(self.module.params['select_chain']):
|
for criterium_idx, criterium in enumerate(self.module.params['select_chain']):
|
||||||
self.select_chain_matcher.append(
|
try:
|
||||||
self.client.backend.create_chain_matcher(
|
self.select_chain_matcher.append(
|
||||||
Criterium(criterium, index=criterium_idx)))
|
self.client.backend.create_chain_matcher(
|
||||||
|
Criterium(criterium, index=criterium_idx)))
|
||||||
|
except ValueError as exc:
|
||||||
|
self.module.warn('Error while parsing criterium: {error}. Ignoring criterium.'.format(error=exc))
|
||||||
|
|
||||||
# Make sure account exists
|
# Make sure account exists
|
||||||
modify_account = module.params['modify_account']
|
modify_account = module.params['modify_account']
|
||||||
|
|
|
@ -92,8 +92,21 @@ options:
|
||||||
description:
|
description:
|
||||||
- Key/value pairs that will be present in the issuer name field of the CRL.
|
- Key/value pairs that will be present in the issuer name field of the CRL.
|
||||||
- If you need to specify more than one value with the same key, use a list as value.
|
- If you need to specify more than one value with the same key, use a list as value.
|
||||||
- Required if I(state) is C(present).
|
- If the order of the components is important, use I(issuer_ordered).
|
||||||
|
- One of I(issuer) and I(issuer_ordered) is required if I(state) is C(present).
|
||||||
|
- Mutually exclusive with I(issuer_ordered).
|
||||||
type: dict
|
type: dict
|
||||||
|
issuer_ordered:
|
||||||
|
description:
|
||||||
|
- A list of dictionaries, where every dictionary must contain one key/value pair.
|
||||||
|
This key/value pair will be present in the issuer name field of the CRL.
|
||||||
|
- If you want to specify more than one value with the same key in a row, you can
|
||||||
|
use a list as value.
|
||||||
|
- One of I(issuer) and I(issuer_ordered) is required if I(state) is C(present).
|
||||||
|
- Mutually exclusive with I(issuer).
|
||||||
|
type: list
|
||||||
|
elements: dict
|
||||||
|
version_added: 2.0.0
|
||||||
|
|
||||||
last_update:
|
last_update:
|
||||||
description:
|
description:
|
||||||
|
@ -386,6 +399,7 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.support im
|
||||||
load_privatekey,
|
load_privatekey,
|
||||||
load_certificate,
|
load_certificate,
|
||||||
parse_name_field,
|
parse_name_field,
|
||||||
|
parse_ordered_name_field,
|
||||||
get_relative_time_option,
|
get_relative_time_option,
|
||||||
select_message_digest,
|
select_message_digest,
|
||||||
)
|
)
|
||||||
|
@ -462,8 +476,15 @@ class CRL(OpenSSLObject):
|
||||||
self.privatekey_content = self.privatekey_content.encode('utf-8')
|
self.privatekey_content = self.privatekey_content.encode('utf-8')
|
||||||
self.privatekey_passphrase = module.params['privatekey_passphrase']
|
self.privatekey_passphrase = module.params['privatekey_passphrase']
|
||||||
|
|
||||||
self.issuer = parse_name_field(module.params['issuer'])
|
try:
|
||||||
self.issuer = [(entry[0], entry[1]) for entry in self.issuer if entry[1]]
|
if module.params['issuer_ordered']:
|
||||||
|
self.issuer_ordered = True
|
||||||
|
self.issuer = parse_ordered_name_field(module.params['issuer_ordered'], 'issuer_ordered')
|
||||||
|
else:
|
||||||
|
self.issuer_ordered = False
|
||||||
|
self.issuer = parse_name_field(module.params['issuer'], 'issuer')
|
||||||
|
except (TypeError, ValueError) as exc:
|
||||||
|
module.fail_json(msg=to_native(exc))
|
||||||
|
|
||||||
self.last_update = get_relative_time_option(module.params['last_update'], 'last_update')
|
self.last_update = get_relative_time_option(module.params['last_update'], 'last_update')
|
||||||
self.next_update = get_relative_time_option(module.params['next_update'], 'next_update')
|
self.next_update = get_relative_time_option(module.params['next_update'], 'next_update')
|
||||||
|
@ -616,7 +637,11 @@ class CRL(OpenSSLObject):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
want_issuer = [(cryptography_name_to_oid(entry[0]), entry[1]) for entry in self.issuer]
|
want_issuer = [(cryptography_name_to_oid(entry[0]), entry[1]) for entry in self.issuer]
|
||||||
if want_issuer != [(sub.oid, sub.value) for sub in self.crl.issuer]:
|
is_issuer = [(sub.oid, sub.value) for sub in self.crl.issuer]
|
||||||
|
if not self.issuer_ordered:
|
||||||
|
want_issuer = set(want_issuer)
|
||||||
|
is_issuer = set(is_issuer)
|
||||||
|
if want_issuer != is_issuer:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
old_entries = [self._compress_entry(cryptography_decode_revoked_certificate(cert)) for cert in self.crl]
|
old_entries = [self._compress_entry(cryptography_decode_revoked_certificate(cert)) for cert in self.crl]
|
||||||
|
@ -782,6 +807,7 @@ def main():
|
||||||
privatekey_content=dict(type='str', no_log=True),
|
privatekey_content=dict(type='str', no_log=True),
|
||||||
privatekey_passphrase=dict(type='str', no_log=True),
|
privatekey_passphrase=dict(type='str', no_log=True),
|
||||||
issuer=dict(type='dict'),
|
issuer=dict(type='dict'),
|
||||||
|
issuer_ordered=dict(type='list', elements='dict'),
|
||||||
last_update=dict(type='str', default='+0s'),
|
last_update=dict(type='str', default='+0s'),
|
||||||
next_update=dict(type='str'),
|
next_update=dict(type='str'),
|
||||||
digest=dict(type='str', default='sha256'),
|
digest=dict(type='str', default='sha256'),
|
||||||
|
@ -815,10 +841,12 @@ def main():
|
||||||
),
|
),
|
||||||
required_if=[
|
required_if=[
|
||||||
('state', 'present', ['privatekey_path', 'privatekey_content'], True),
|
('state', 'present', ['privatekey_path', 'privatekey_content'], True),
|
||||||
('state', 'present', ['issuer', 'next_update', 'revoked_certificates'], False),
|
('state', 'present', ['issuer', 'issuer_ordered'], True),
|
||||||
|
('state', 'present', ['next_update', 'revoked_certificates'], False),
|
||||||
],
|
],
|
||||||
mutually_exclusive=(
|
mutually_exclusive=(
|
||||||
['privatekey_path', 'privatekey_content'],
|
['privatekey_path', 'privatekey_content'],
|
||||||
|
['issuer', 'issuer_ordered'],
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
add_file_common_args=True,
|
add_file_common_args=True,
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
openssl_csr:
|
openssl_csr:
|
||||||
path: '{{ remote_tmp_dir }}/csr.csr'
|
path: '{{ remote_tmp_dir }}/csr.csr'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
||||||
subject:
|
subject_ordered:
|
||||||
commonName: www.ansible.com
|
- commonName: www.ansible.com
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
return_content: yes
|
return_content: yes
|
||||||
register: generate_csr_idempotent
|
register: generate_csr_idempotent
|
||||||
|
@ -517,23 +517,23 @@
|
||||||
openssl_csr:
|
openssl_csr:
|
||||||
path: '{{ remote_tmp_dir }}/csr_everything.csr'
|
path: '{{ remote_tmp_dir }}/csr_everything.csr'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
||||||
subject:
|
subject_ordered:
|
||||||
commonName: www.example.com
|
- commonName: www.example.com
|
||||||
C: de
|
- C: de
|
||||||
L: Somewhere
|
- L: Somewhere
|
||||||
ST: Zürich
|
- ST: Zürich
|
||||||
streetAddress: Welcome Street N° 5
|
- streetAddress: Welcome Street N° 5
|
||||||
O: Ansiblé
|
- O: Ansiblé
|
||||||
organizationalUnitName: Crÿpto Depârtment ☺
|
- organizationalUnitName: Crÿpto Depârtment ☺
|
||||||
serialNumber: "1234"
|
- serialNumber: "1234"
|
||||||
SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
|
- SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
|
||||||
GN: First Name
|
- GN: First Name
|
||||||
title: Chïeff
|
- title: Chïeff
|
||||||
pseudonym: test
|
- pseudonym: test
|
||||||
UID: asdf
|
- UID: asdf
|
||||||
emailAddress: test@example.com
|
- emailAddress: test@example.com
|
||||||
postalAddress: 1234 Somewhere
|
- postalAddress: 1234 Somewhere
|
||||||
postalCode: "1234"
|
- postalCode: "1234"
|
||||||
useCommonNameForSAN: no
|
useCommonNameForSAN: no
|
||||||
key_usage:
|
key_usage:
|
||||||
- digitalSignature
|
- digitalSignature
|
||||||
|
@ -602,23 +602,23 @@
|
||||||
openssl_csr:
|
openssl_csr:
|
||||||
path: '{{ remote_tmp_dir }}/csr_everything.csr'
|
path: '{{ remote_tmp_dir }}/csr_everything.csr'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
||||||
subject:
|
subject_ordered:
|
||||||
CN: www.example.com
|
- CN: www.example.com
|
||||||
countryName: de
|
- countryName: de
|
||||||
L: Somewhere
|
- L: Somewhere
|
||||||
ST: Zürich
|
- ST: Zürich
|
||||||
streetAddress: Welcome Street N° 5
|
- streetAddress: Welcome Street N° 5
|
||||||
organizationName: Ansiblé
|
- organizationName: Ansiblé
|
||||||
organizationalUnitName: Crÿpto Depârtment ☺
|
- organizationalUnitName: Crÿpto Depârtment ☺
|
||||||
serialNumber: "1234"
|
- serialNumber: "1234"
|
||||||
SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
|
- SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
|
||||||
GN: First Name
|
- GN: First Name
|
||||||
title: Chïeff
|
- title: Chïeff
|
||||||
pseudonym: test
|
- pseudonym: test
|
||||||
UID: asdf
|
- UID: asdf
|
||||||
emailAddress: test@example.com
|
- emailAddress: test@example.com
|
||||||
postalAddress: 1234 Somewhere
|
- postalAddress: 1234 Somewhere
|
||||||
postalCode: "1234"
|
- postalCode: "1234"
|
||||||
useCommonNameForSAN: no
|
useCommonNameForSAN: no
|
||||||
key_usage:
|
key_usage:
|
||||||
- digitalSignature
|
- digitalSignature
|
||||||
|
@ -689,18 +689,19 @@
|
||||||
path: '{{ remote_tmp_dir }}/csr_everything.csr'
|
path: '{{ remote_tmp_dir }}/csr_everything.csr'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
||||||
subject:
|
subject:
|
||||||
|
# Subject has been reordered, but is inside 'subject' and not 'subject_ordered'
|
||||||
CN: www.example.com
|
CN: www.example.com
|
||||||
countryName: de
|
|
||||||
L: Somewhere
|
L: Somewhere
|
||||||
|
countryName: de
|
||||||
ST: Zürich
|
ST: Zürich
|
||||||
streetAddress: Welcome Street N° 5
|
streetAddress: Welcome Street N° 5
|
||||||
organizationName: Ansiblé
|
|
||||||
organizationalUnitName: Crÿpto Depârtment ☺
|
organizationalUnitName: Crÿpto Depârtment ☺
|
||||||
|
organizationName: Ansiblé
|
||||||
serialNumber: "1234"
|
serialNumber: "1234"
|
||||||
SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
|
SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
|
||||||
GN: First Name
|
GN: First Name
|
||||||
title: Chïeff
|
|
||||||
pseudonym: test
|
pseudonym: test
|
||||||
|
title: Chïeff
|
||||||
UID: asdf
|
UID: asdf
|
||||||
emailAddress: test@example.com
|
emailAddress: test@example.com
|
||||||
postalAddress: 1234 Somewhere
|
postalAddress: 1234 Somewhere
|
||||||
|
@ -769,6 +770,93 @@
|
||||||
- "IP:0::0:1:0:0/112"
|
- "IP:0::0:1:0:0/112"
|
||||||
register: everything_3
|
register: everything_3
|
||||||
|
|
||||||
|
- name: "({{ select_crypto_backend }}) Generate CSR with everything (not idempotent, check mode)"
|
||||||
|
openssl_csr:
|
||||||
|
path: '{{ remote_tmp_dir }}/csr_everything.csr'
|
||||||
|
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
||||||
|
subject_ordered:
|
||||||
|
# Subject has been reordered, this should force a change
|
||||||
|
- CN: www.example.com
|
||||||
|
- L: Somewhere
|
||||||
|
- countryName: de
|
||||||
|
- ST: Zürich
|
||||||
|
- streetAddress: Welcome Street N° 5
|
||||||
|
- organizationalUnitName: Crÿpto Depârtment ☺
|
||||||
|
- organizationName: Ansiblé
|
||||||
|
- serialNumber: "1234"
|
||||||
|
- SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
|
||||||
|
- GN: First Name
|
||||||
|
- pseudonym: test
|
||||||
|
- title: Chïeff
|
||||||
|
- UID: asdf
|
||||||
|
- emailAddress: test@example.com
|
||||||
|
- postalAddress: 1234 Somewhere
|
||||||
|
- postalCode: "1234"
|
||||||
|
useCommonNameForSAN: no
|
||||||
|
key_usage:
|
||||||
|
- digitalSignature
|
||||||
|
- keyAgreement
|
||||||
|
- Non Repudiation
|
||||||
|
- Key Encipherment
|
||||||
|
- dataEncipherment
|
||||||
|
- Certificate Sign
|
||||||
|
- cRLSign
|
||||||
|
- Encipher Only
|
||||||
|
- decipherOnly
|
||||||
|
key_usage_critical: yes
|
||||||
|
extended_key_usage: '{{ value_for_extended_key_usage }}'
|
||||||
|
subject_alt_name: '{{ value_for_san }}'
|
||||||
|
basic_constraints:
|
||||||
|
- "CA:TRUE"
|
||||||
|
- "pathlen:23"
|
||||||
|
basic_constraints_critical: yes
|
||||||
|
name_constraints_permitted: '{{ value_for_name_constraints_permitted }}'
|
||||||
|
name_constraints_excluded:
|
||||||
|
- "DNS:.org"
|
||||||
|
- "DNS:.example.com"
|
||||||
|
name_constraints_critical: yes
|
||||||
|
ocsp_must_staple: yes
|
||||||
|
subject_key_identifier: 00:11:22:33
|
||||||
|
authority_key_identifier: 44:55:66:77
|
||||||
|
authority_cert_issuer: '{{ value_for_authority_cert_issuer }}'
|
||||||
|
authority_cert_serial_number: 12345
|
||||||
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
vars:
|
||||||
|
value_for_extended_key_usage:
|
||||||
|
- serverAuth # the same as "TLS Web Server Authentication"
|
||||||
|
- TLS Web Server Authentication
|
||||||
|
- TLS Web Client Authentication
|
||||||
|
- Code Signing
|
||||||
|
- E-mail Protection
|
||||||
|
- timeStamping
|
||||||
|
- OCSPSigning
|
||||||
|
- Any Extended Key Usage
|
||||||
|
- qcStatements
|
||||||
|
- DVCS
|
||||||
|
- IPSec User
|
||||||
|
- biometricInfo
|
||||||
|
- 1.2.3.4.5.6
|
||||||
|
value_for_authority_cert_issuer:
|
||||||
|
- "DNS:ca.example.org"
|
||||||
|
- "IP:1.2.3.4"
|
||||||
|
value_for_san:
|
||||||
|
- "DNS:www.ansible.com"
|
||||||
|
- "IP:1.2.3.4"
|
||||||
|
- "IP:::1"
|
||||||
|
- "email:test@example.org"
|
||||||
|
- "URI:https://example.org/test/index.html"
|
||||||
|
- "RID:1.2.3.4"
|
||||||
|
- "otherName:1.2.3.4;0c:07:63:65:72:74:72:65:71"
|
||||||
|
- "otherName:1.3.6.1.4.1.311.20.2.3;UTF8:bob@localhost"
|
||||||
|
- "dirName:CN= example.net, O =Example Net"
|
||||||
|
- "dirName:/CN= example.com/O =Example Com"
|
||||||
|
value_for_name_constraints_permitted:
|
||||||
|
- "DNS:www.example.com"
|
||||||
|
- "IP:1.2.3.0/255.255.255.0"
|
||||||
|
- "IP:0::0:1:0:0/112"
|
||||||
|
register: everything_4
|
||||||
|
check_mode: true
|
||||||
|
|
||||||
- name: "({{ select_crypto_backend }}) Get info from CSR with everything"
|
- name: "({{ select_crypto_backend }}) Get info from CSR with everything"
|
||||||
community.crypto.openssl_csr_info:
|
community.crypto.openssl_csr_info:
|
||||||
path: '{{ remote_tmp_dir }}/csr_everything.csr'
|
path: '{{ remote_tmp_dir }}/csr_everything.csr'
|
||||||
|
|
|
@ -195,6 +195,7 @@
|
||||||
- everything_1 is changed
|
- everything_1 is changed
|
||||||
- everything_2 is not changed
|
- everything_2 is not changed
|
||||||
- everything_3 is not changed
|
- everything_3 is not changed
|
||||||
|
- everything_4 is changed
|
||||||
- everything_info.basic_constraints == [
|
- everything_info.basic_constraints == [
|
||||||
"CA:TRUE",
|
"CA:TRUE",
|
||||||
"pathlen:23",
|
"pathlen:23",
|
||||||
|
@ -233,6 +234,25 @@
|
||||||
- everything_info.subject.title == "Chïeff"
|
- everything_info.subject.title == "Chïeff"
|
||||||
- everything_info.subject.userId == "asdf"
|
- everything_info.subject.userId == "asdf"
|
||||||
- everything_info.subject | length == 16
|
- everything_info.subject | length == 16
|
||||||
|
- >
|
||||||
|
everything_info.subject_ordered == [
|
||||||
|
["commonName", "www.example.com"],
|
||||||
|
["countryName", "de"],
|
||||||
|
["localityName", "Somewhere"],
|
||||||
|
["stateOrProvinceName", "Zürich"],
|
||||||
|
["streetAddress", "Welcome Street N° 5"],
|
||||||
|
["organizationName", "Ansiblé"],
|
||||||
|
["organizationalUnitName", "Crÿpto Depârtment ☺"],
|
||||||
|
["serialNumber", "1234"],
|
||||||
|
["surname", "Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr."],
|
||||||
|
["givenName", "First Name"],
|
||||||
|
["title", "Chïeff"],
|
||||||
|
["pseudonym", "test"],
|
||||||
|
["userId", "asdf"],
|
||||||
|
["emailAddress", "test@example.com"],
|
||||||
|
["postalAddress", "1234 Somewhere"],
|
||||||
|
["postalCode", "1234"],
|
||||||
|
]
|
||||||
- everything_info.subject_alt_name_critical == false
|
- everything_info.subject_alt_name_critical == false
|
||||||
- everything_info.name_constraints_excluded == [
|
- everything_info.name_constraints_excluded == [
|
||||||
"DNS:.example.com",
|
"DNS:.example.com",
|
||||||
|
|
|
@ -1,25 +1,4 @@
|
||||||
---
|
---
|
||||||
- name: Create CRL 1 (check mode)
|
|
||||||
x509_crl:
|
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl1.crl'
|
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
|
||||||
issuer:
|
|
||||||
CN: Ansible
|
|
||||||
last_update: 20191013000000Z
|
|
||||||
next_update: 20191113000000Z
|
|
||||||
revoked_certificates:
|
|
||||||
- path: '{{ remote_tmp_dir }}/cert-1.pem'
|
|
||||||
revocation_date: 20191013000000Z
|
|
||||||
- path: '{{ remote_tmp_dir }}/cert-2.pem'
|
|
||||||
revocation_date: 20191013000000Z
|
|
||||||
reason: key_compromise
|
|
||||||
reason_critical: yes
|
|
||||||
invalidity_date: 20191012000000Z
|
|
||||||
- serial_number: 1234
|
|
||||||
revocation_date: 20191001000000Z
|
|
||||||
check_mode: yes
|
|
||||||
register: crl_1_check
|
|
||||||
|
|
||||||
- name: Create CRL 1 (check mode)
|
- name: Create CRL 1 (check mode)
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl1.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl1.crl'
|
||||||
|
@ -283,8 +262,11 @@
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
issuer:
|
issuer_ordered:
|
||||||
CN: Ansible
|
- CN: Ansible
|
||||||
|
- CN: CRL
|
||||||
|
- countryName: US
|
||||||
|
- CN: Test
|
||||||
last_update: +0d
|
last_update: +0d
|
||||||
next_update: +0d
|
next_update: +0d
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
|
@ -301,8 +283,11 @@
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
issuer:
|
issuer_ordered:
|
||||||
CN: Ansible
|
- CN: Ansible
|
||||||
|
- CN: CRL
|
||||||
|
- countryName: US
|
||||||
|
- CN: Test
|
||||||
last_update: +0d
|
last_update: +0d
|
||||||
next_update: +0d
|
next_update: +0d
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
|
@ -318,8 +303,11 @@
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
issuer:
|
issuer_ordered:
|
||||||
CN: Ansible
|
- CN: Ansible
|
||||||
|
- CN: CRL
|
||||||
|
- C: US
|
||||||
|
- CN: Test
|
||||||
last_update: +0d
|
last_update: +0d
|
||||||
next_update: +0d
|
next_update: +0d
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
|
@ -337,8 +325,11 @@
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
issuer:
|
issuer_ordered:
|
||||||
CN: Ansible
|
- CN: Ansible
|
||||||
|
- CN: CRL
|
||||||
|
- countryName: US
|
||||||
|
- CN: Test
|
||||||
last_update: +0d
|
last_update: +0d
|
||||||
next_update: +0d
|
next_update: +0d
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
|
@ -355,8 +346,11 @@
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
issuer:
|
issuer_ordered:
|
||||||
CN: Ansible
|
- CN: Ansible
|
||||||
|
- CN: CRL
|
||||||
|
- countryName: US
|
||||||
|
- CN: Test
|
||||||
last_update: +0d
|
last_update: +0d
|
||||||
next_update: +0d
|
next_update: +0d
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
|
@ -370,8 +364,11 @@
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
issuer:
|
issuer_ordered:
|
||||||
CN: Ansible
|
- CN: Ansible
|
||||||
|
- CN: CRL
|
||||||
|
- countryName: US
|
||||||
|
- CN: Test
|
||||||
last_update: +0d
|
last_update: +0d
|
||||||
next_update: +0d
|
next_update: +0d
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
|
@ -384,8 +381,11 @@
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
issuer:
|
issuer_ordered:
|
||||||
CN: Ansible
|
- CN: Ansible
|
||||||
|
- CN: CRL
|
||||||
|
- countryName: US
|
||||||
|
- CN: Test
|
||||||
last_update: +0d
|
last_update: +0d
|
||||||
next_update: +0d
|
next_update: +0d
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
|
@ -402,8 +402,11 @@
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
issuer:
|
issuer_ordered:
|
||||||
CN: Ansible
|
- CN: Ansible
|
||||||
|
- CN: CRL
|
||||||
|
- countryName: US
|
||||||
|
- CN: Test
|
||||||
last_update: +0d
|
last_update: +0d
|
||||||
next_update: +0d
|
next_update: +0d
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
|
@ -419,8 +422,11 @@
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
issuer:
|
issuer_ordered:
|
||||||
CN: Ansible
|
- CN: Ansible
|
||||||
|
- CN: CRL
|
||||||
|
- countryName: US
|
||||||
|
- CN: Test
|
||||||
last_update: +0d
|
last_update: +0d
|
||||||
next_update: +0d
|
next_update: +0d
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
|
@ -437,8 +443,11 @@
|
||||||
x509_crl:
|
x509_crl:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
issuer:
|
issuer_ordered:
|
||||||
CN: Ansible
|
- CN: Ansible
|
||||||
|
- CN: CRL
|
||||||
|
- countryName: US
|
||||||
|
- CN: Test
|
||||||
last_update: +0d
|
last_update: +0d
|
||||||
next_update: +0d
|
next_update: +0d
|
||||||
revoked_certificates:
|
revoked_certificates:
|
||||||
|
@ -451,8 +460,67 @@
|
||||||
return_content: yes
|
return_content: yes
|
||||||
register: crl_2_change
|
register: crl_2_change
|
||||||
|
|
||||||
|
- name: Read ca-crl2.crl
|
||||||
|
slurp:
|
||||||
|
src: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
|
register: slurp_crl2_1
|
||||||
|
|
||||||
- name: Retrieve CRL 2 infos
|
- name: Retrieve CRL 2 infos
|
||||||
x509_crl_info:
|
x509_crl_info:
|
||||||
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
list_revoked_certificates: false
|
list_revoked_certificates: false
|
||||||
register: crl_2_info_1
|
register: crl_2_info_1
|
||||||
|
|
||||||
|
- name: Create CRL 2 (changed order, should be ignored)
|
||||||
|
x509_crl:
|
||||||
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
|
issuer:
|
||||||
|
countryName: US
|
||||||
|
CN:
|
||||||
|
- Ansible
|
||||||
|
- CRL
|
||||||
|
- Test
|
||||||
|
last_update: +0d
|
||||||
|
next_update: +0d
|
||||||
|
revoked_certificates:
|
||||||
|
- path: '{{ remote_tmp_dir }}/cert-2.pem'
|
||||||
|
reason: key_compromise
|
||||||
|
reason_critical: yes
|
||||||
|
invalidity_date: 20191012000000Z
|
||||||
|
ignore_timestamps: true
|
||||||
|
mode: update
|
||||||
|
return_content: yes
|
||||||
|
register: crl_2_change_order_ignore
|
||||||
|
|
||||||
|
- name: Create CRL 2 (changed order)
|
||||||
|
x509_crl:
|
||||||
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
|
privatekey_path: '{{ remote_tmp_dir }}/ca.key'
|
||||||
|
issuer_ordered:
|
||||||
|
- CN: Ansible
|
||||||
|
- countryName: US
|
||||||
|
- CN: CRL
|
||||||
|
- CN: Test
|
||||||
|
last_update: +0d
|
||||||
|
next_update: +0d
|
||||||
|
revoked_certificates:
|
||||||
|
- path: '{{ remote_tmp_dir }}/cert-2.pem'
|
||||||
|
reason: key_compromise
|
||||||
|
reason_critical: yes
|
||||||
|
invalidity_date: 20191012000000Z
|
||||||
|
ignore_timestamps: true
|
||||||
|
mode: update
|
||||||
|
return_content: yes
|
||||||
|
register: crl_2_change_order
|
||||||
|
|
||||||
|
- name: Read ca-crl2.crl
|
||||||
|
slurp:
|
||||||
|
src: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
|
register: slurp_crl2_2
|
||||||
|
|
||||||
|
- name: Retrieve CRL 2 infos again
|
||||||
|
x509_crl_info:
|
||||||
|
path: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
||||||
|
list_revoked_certificates: false
|
||||||
|
register: crl_2_info_2
|
||||||
|
|
|
@ -66,11 +66,6 @@
|
||||||
that:
|
that:
|
||||||
- crl_1_format_idem.crl | b64decode == content.content | b64decode
|
- crl_1_format_idem.crl | b64decode == content.content | b64decode
|
||||||
|
|
||||||
- name: Read ca-crl2.crl
|
|
||||||
slurp:
|
|
||||||
src: '{{ remote_tmp_dir }}/ca-crl2.crl'
|
|
||||||
register: slurp
|
|
||||||
|
|
||||||
- name: Validate CRL 2
|
- name: Validate CRL 2
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
|
@ -84,9 +79,26 @@
|
||||||
- crl_2_idem_update is not changed
|
- crl_2_idem_update is not changed
|
||||||
- crl_2_change_check is changed
|
- crl_2_change_check is changed
|
||||||
- crl_2_change is changed
|
- crl_2_change is changed
|
||||||
- crl_2_change.crl == (slurp.content | b64decode)
|
- crl_2_change.crl == (slurp_crl2_1.content | b64decode)
|
||||||
|
- crl_2_change_order_ignore is not changed
|
||||||
|
- crl_2_change_order is changed
|
||||||
|
- crl_2_change_order.crl == (slurp_crl2_2.content | b64decode)
|
||||||
|
|
||||||
- name: Validate CRL 2 info
|
- name: Validate CRL 2 info
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "'revoked_certificates' not in crl_2_info_1"
|
- "'revoked_certificates' not in crl_2_info_1"
|
||||||
|
- >
|
||||||
|
crl_2_info_1.issuer_ordered == [
|
||||||
|
['commonName', 'Ansible'],
|
||||||
|
['commonName', 'CRL'],
|
||||||
|
['countryName', 'US'],
|
||||||
|
['commonName', 'Test'],
|
||||||
|
]
|
||||||
|
- >
|
||||||
|
crl_2_info_2.issuer_ordered == [
|
||||||
|
['commonName', 'Ansible'],
|
||||||
|
['countryName', 'US'],
|
||||||
|
['commonName', 'CRL'],
|
||||||
|
['commonName', 'Test'],
|
||||||
|
]
|
||||||
|
|
Loading…
Reference in New Issue