Compare commits

...

19 Commits
1.8.0 ... 1.9.3

Author SHA1 Message Date
Felix Fontein
d90cc5142b Release 1.9.3. 2021-09-14 08:15:32 +02:00
Felix Fontein
37aab65396 Prepare 1.9.3 release. 2021-09-14 07:14:03 +02:00
Felix Fontein
baff003ea8 Fix changelog from last time. 2021-09-14 07:13:25 +02:00
Felix Fontein
03427e35a7 Fix idempotency for non-ASCII string comparisons. (#271) 2021-09-14 07:06:35 +02:00
Felix Fontein
170fa40014 ipaddress is part of stdlib for Python 3. (#275) 2021-09-12 17:21:10 +02:00
Felix Fontein
330b30d5d2 certificate_complete_chain tests need cryptography installed on the target, so use setup_openssl. (#272) 2021-09-11 11:29:03 +02:00
Felix Fontein
67b8274faf openssl_csr: fix error in docs (#269)
* Fix error in docs.

* Add missing word.
2021-09-10 20:53:50 +02:00
Felix Fontein
02ee3fb974 Improve CI (#268)
* Remove superfluous remote_src.

* Use temp dir twice instead of output_dir.

* Use remote temp directory instead of output_dir.

* Fix syntax error.

* Add some fixes.

* Copy more files to remote.

* More fixes.

* Fixing ACME/'cloud' tests.

* Forgot when.

* Try to fix filters.

* Skip unnecessary steps.

* Avoid collision.
2021-09-07 22:37:40 +02:00
Felix Fontein
93ced1956c The next expected release is again 1.10.0. 2021-08-30 22:01:49 +02:00
Felix Fontein
a9e358ea57 Bugfix release 1.9.2. 2021-08-30 22:01:16 +02:00
Felix Fontein
ffcdbc5d0c Add non-existing 1.9.1 release. 2021-08-30 22:00:39 +02:00
Felix Fontein
6740cae10f Next release is expected to be 1.10.0. 2021-08-30 20:46:46 +02:00
Felix Fontein
915379459d Release 1.9.0. 2021-08-30 20:12:47 +02:00
Felix Fontein
a4a12bae27 Prepare 1.9.0 release. 2021-08-27 05:54:45 +02:00
Felix Fontein
94fc356338 https://github.com/diafygi/acme-tiny/pull/254 has been merged. (#265) 2021-08-22 12:41:41 +02:00
Ajpantuso
08ada24a53 openssh_keypair - Add diff support and general cleanup (#260)
* Initial commit

* Matching tests to overwritten permissions behavior with cryptography

* Ensuring key validation only occurs when state=present and accomodating CentOS6 restrictions

* Making ssh-keygen behavior explicit by version in tests

* Ensuring cyrptography not excluded in new conditions

* Adding changelog fragment

* Fixing sanity checks

* Improving readability

* Applying review suggestions

* addressing restore_on_failure conflict
2021-08-18 09:22:31 +02:00
Ajpantuso
b59846b9fa get_certificate - add starttls option with support for mysql (#264)
* Initial commit

* Adding changelog fragment

* Applying initial review suggestion
2021-08-15 15:40:54 +02:00
Felix Fontein
c9ec463893 Fix sanity failures (#263)
* Fix sanity failures.

* Add changelog fragment.
2021-08-12 09:23:11 +00:00
Felix Fontein
38ce150f80 Next expected release is 1.9.0. 2021-08-10 18:26:55 +02:00
117 changed files with 2458 additions and 1899 deletions

View File

@@ -5,6 +5,57 @@ Community Crypto Release Notes
.. contents:: Topics
v1.9.3
======
Release Summary
---------------
Regular bugfix release.
Bugfixes
--------
- openssl_csr and openssl_csr_pipe - make sure that Unicode strings are used to compare strings with the cryptography backend. This fixes idempotency problems with non-ASCII letters on Python 2 (https://github.com/ansible-collections/community.crypto/issues/270, https://github.com/ansible-collections/community.crypto/pull/271).
v1.9.2
======
Release Summary
---------------
Bugfix release to fix the changelog. No other change compared to 1.9.0.
v1.9.1
======
Release Summary
---------------
Accidental 1.9.1 release. Identical to 1.9.0.
v1.9.0
======
Release Summary
---------------
Regular feature release.
Minor Changes
-------------
- get_certificate - added ``starttls`` option to retrieve certificates from servers which require clients to request an encrypted connection (https://github.com/ansible-collections/community.crypto/pull/264).
- openssh_keypair - added ``diff`` support (https://github.com/ansible-collections/community.crypto/pull/260).
Bugfixes
--------
- keypair_backend module utils - simplify code to pass sanity tests (https://github.com/ansible-collections/community.crypto/pull/263).
- openssh_keypair - fixed ``cryptography`` backend to preserve original file permissions when regenerating a keypair requires existing files to be overwritten (https://github.com/ansible-collections/community.crypto/pull/260).
- openssh_keypair - fixed error handling to restore original keypair if regeneration fails (https://github.com/ansible-collections/community.crypto/pull/260).
- x509_crl - restore inherited function signature to pass sanity tests (https://github.com/ansible-collections/community.crypto/pull/263).
v1.8.0
======

View File

@@ -503,3 +503,47 @@ releases:
- 257-openssh-keypair-fix-pubkey-permissions.yml
- ansible-core-_text.yml
release_date: '2021-08-10'
1.9.0:
changes:
bugfixes:
- keypair_backend module utils - simplify code to pass sanity tests (https://github.com/ansible-collections/community.crypto/pull/263).
- openssh_keypair - fixed ``cryptography`` backend to preserve original file
permissions when regenerating a keypair requires existing files to be overwritten
(https://github.com/ansible-collections/community.crypto/pull/260).
- openssh_keypair - fixed error handling to restore original keypair if regeneration
fails (https://github.com/ansible-collections/community.crypto/pull/260).
- x509_crl - restore inherited function signature to pass sanity tests (https://github.com/ansible-collections/community.crypto/pull/263).
minor_changes:
- get_certificate - added ``starttls`` option to retrieve certificates from
servers which require clients to request an encrypted connection (https://github.com/ansible-collections/community.crypto/pull/264).
- openssh_keypair - added ``diff`` support (https://github.com/ansible-collections/community.crypto/pull/260).
release_summary: Regular feature release.
fragments:
- 1.9.0.yml
- 260-openssh_keypair-diff-support.yml
- 263-sanity.yml
- 264-get_certificate-add-starttls-option.yml
release_date: '2021-08-30'
1.9.1:
changes:
release_summary: Accidental 1.9.1 release. Identical to 1.9.0.
release_date: '2021-08-30'
1.9.2:
changes:
release_summary: Bugfix release to fix the changelog. No other change compared
to 1.9.0.
fragments:
- 1.9.2.yml
release_date: '2021-08-30'
1.9.3:
changes:
bugfixes:
- openssl_csr and openssl_csr_pipe - make sure that Unicode strings are used
to compare strings with the cryptography backend. This fixes idempotency problems
with non-ASCII letters on Python 2 (https://github.com/ansible-collections/community.crypto/issues/270,
https://github.com/ansible-collections/community.crypto/pull/271).
release_summary: Regular bugfix release.
fragments:
- 1.9.3.yml
- 271-openssl_csr-utf8.yml
release_date: '2021-09-14'

View File

@@ -1,6 +1,6 @@
namespace: community
name: crypto
version: 1.8.0
version: 1.9.3
readme: README.md
authors:
- Ansible (github.com/ansible)

View File

@@ -227,12 +227,11 @@ options:
description:
- The authority key identifier as a hex string, where two bytes are separated by colons.
- "Example: C(00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22:33)"
- If specified, I(authority_cert_issuer) must also be specified.
- "Please note that commercial CAs ignore this value, respectively use a value of their
own choice. Specifying this option is mostly useful for self-signed certificates
or for own CAs."
- Note that this is only supported if the C(cryptography) backend is used!
- The C(AuthorityKeyIdentifier) will only be added if at least one of I(authority_key_identifier),
- The C(AuthorityKeyIdentifier) extension will only be added if at least one of I(authority_key_identifier),
I(authority_cert_issuer) and I(authority_cert_serial_number) is specified.
type: str
authority_cert_issuer:
@@ -241,23 +240,24 @@ options:
- Values must be prefixed by their options. (i.e., C(email), C(URI), C(DNS), C(RID), C(IP), C(dirName),
C(otherName) and the ones specific to your CA)
- "Example: C(DNS:ca.example.org)"
- If specified, I(authority_key_identifier) must also be specified.
- If specified, I(authority_cert_serial_number) must also be specified.
- "Please note that commercial CAs ignore this value, respectively use a value of their
own choice. Specifying this option is mostly useful for self-signed certificates
or for own CAs."
- Note that this is only supported if the C(cryptography) backend is used!
- The C(AuthorityKeyIdentifier) will only be added if at least one of I(authority_key_identifier),
- The C(AuthorityKeyIdentifier) extension will only be added if at least one of I(authority_key_identifier),
I(authority_cert_issuer) and I(authority_cert_serial_number) is specified.
type: list
elements: str
authority_cert_serial_number:
description:
- The authority cert serial number.
- If specified, I(authority_cert_issuer) must also be specified.
- Note that this is only supported if the C(cryptography) backend is used!
- "Please note that commercial CAs ignore this value, respectively use a value of their
own choice. Specifying this option is mostly useful for self-signed certificates
or for own CAs."
- The C(AuthorityKeyIdentifier) will only be added if at least one of I(authority_key_identifier),
- The C(AuthorityKeyIdentifier) extension will only be added if at least one of I(authority_key_identifier),
I(authority_cert_issuer) and I(authority_cert_serial_number) is specified.
type: int
crl_distribution_points:

View File

@@ -592,7 +592,7 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
def _check_csr(self):
"""Check whether provided parameters, assuming self.existing_csr and self.privatekey have been populated."""
def _check_subject(csr):
subject = [(cryptography_name_to_oid(entry[0]), 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]
return set(subject) == set(current_subject)
@@ -604,8 +604,8 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
def _check_subjectAltName(extensions):
current_altnames_ext = _find_extension(extensions, cryptography.x509.SubjectAlternativeName)
current_altnames = [str(altname) for altname in current_altnames_ext.value] if current_altnames_ext else []
altnames = [str(cryptography_get_name(altname)) for altname in self.subjectAltName] if self.subjectAltName else []
current_altnames = [to_text(altname) for altname in current_altnames_ext.value] if current_altnames_ext else []
altnames = [to_text(cryptography_get_name(altname)) for altname in self.subjectAltName] if self.subjectAltName else []
if set(altnames) != set(current_altnames):
return False
if altnames:
@@ -678,10 +678,10 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
def _check_nameConstraints(extensions):
current_nc_ext = _find_extension(extensions, cryptography.x509.NameConstraints)
current_nc_perm = [str(altname) for altname in current_nc_ext.value.permitted_subtrees] if current_nc_ext else []
current_nc_excl = [str(altname) for altname in current_nc_ext.value.excluded_subtrees] if current_nc_ext else []
nc_perm = [str(cryptography_get_name(altname, 'name constraints permitted')) for altname in self.name_constraints_permitted]
nc_excl = [str(cryptography_get_name(altname, 'name constraints excluded')) for altname in self.name_constraints_excluded]
current_nc_perm = [to_text(altname) for altname in current_nc_ext.value.permitted_subtrees] if current_nc_ext else []
current_nc_excl = [to_text(altname) for altname in current_nc_ext.value.excluded_subtrees] if current_nc_ext else []
nc_perm = [to_text(cryptography_get_name(altname, 'name constraints permitted')) for altname in self.name_constraints_permitted]
nc_excl = [to_text(cryptography_get_name(altname, 'name constraints excluded')) for altname in self.name_constraints_excluded]
if set(nc_perm) != set(current_nc_perm) or set(nc_excl) != set(current_nc_excl):
return False
if nc_perm or nc_excl:
@@ -710,9 +710,9 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
aci = None
csr_aci = None
if self.authority_cert_issuer is not None:
aci = [str(cryptography_get_name(n, 'authority cert issuer')) for n in self.authority_cert_issuer]
aci = [to_text(cryptography_get_name(n, 'authority cert issuer')) for n in self.authority_cert_issuer]
if ext.value.authority_cert_issuer is not None:
csr_aci = [str(n) for n in ext.value.authority_cert_issuer]
csr_aci = [to_text(n) for n in ext.value.authority_cert_issuer]
return (ext.value.key_identifier == self.authority_key_identifier
and csr_aci == aci
and ext.value.authority_cert_serial_number == self.authority_cert_serial_number)

View File

@@ -18,7 +18,15 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import abc
import os
import stat
from ansible.module_utils import six
from ansible_collections.community.crypto.plugins.module_utils.openssh.utils import (
parse_openssh_version,
)
def restore_on_failure(f):
@@ -40,3 +48,278 @@ def restore_on_failure(f):
@restore_on_failure
def safe_atomic_move(module, path, destination):
module.atomic_move(path, destination)
def _restore_all_on_failure(f):
def backup_and_restore(self, sources_and_destinations, *args, **kwargs):
backups = [(d, self.module.backup_local(d)) for s, d in sources_and_destinations if os.path.exists(d)]
try:
f(self, sources_and_destinations, *args, **kwargs)
except Exception:
for destination, backup in backups:
self.module.atomic_move(backup, destination)
raise
else:
for destination, backup in backups:
self.module.add_cleanup_file(backup)
return backup_and_restore
@six.add_metaclass(abc.ABCMeta)
class OpensshModule(object):
def __init__(self, module):
self.module = module
self.changed = False
self.check_mode = self.module.check_mode
def execute(self):
self._execute()
self.module.exit_json(**self.result)
@abc.abstractmethod
def _execute(self):
pass
@property
def result(self):
result = self._result
result['changed'] = self.changed
if self.module._diff:
result['diff'] = self.diff
return result
@property
@abc.abstractmethod
def _result(self):
pass
@property
@abc.abstractmethod
def diff(self):
pass
@staticmethod
def skip_if_check_mode(f):
def wrapper(self, *args, **kwargs):
if not self.check_mode:
f(self, *args, **kwargs)
return wrapper
@staticmethod
def trigger_change(f):
def wrapper(self, *args, **kwargs):
f(self, *args, **kwargs)
self.changed = True
return wrapper
def _check_if_base_dir(self, path):
base_dir = os.path.dirname(path) or '.'
if not os.path.isdir(base_dir):
self.module.fail_json(
name=base_dir,
msg='The directory %s does not exist or the file is not a directory' % base_dir
)
def _get_ssh_version(self):
ssh_bin = self.module.get_bin_path('ssh')
if not ssh_bin:
return ""
return parse_openssh_version(self.module.run_command([ssh_bin, '-V', '-q'])[2].strip())
@_restore_all_on_failure
def _safe_secure_move(self, sources_and_destinations):
"""Moves a list of files from 'source' to 'destination' and restores 'destination' from backup upon failure.
If 'destination' does not already exist, then 'source' permissions are preserved to prevent
exposing protected data ('atomic_move' uses the 'destination' base directory mask for
permissions if 'destination' does not already exists).
"""
for source, destination in sources_and_destinations:
if os.path.exists(destination):
self.module.atomic_move(source, destination)
else:
self.module.preserved_copy(source, destination)
def _update_permissions(self, path):
file_args = self.module.load_file_common_arguments(self.module.params)
file_args['path'] = path
if not self.module.check_file_absent_if_check_mode(path):
self.changed = self.module.set_fs_attributes_if_different(file_args, self.changed)
else:
self.changed = True
class KeygenCommand(object):
def __init__(self, module):
self._bin_path = module.get_bin_path('ssh-keygen', True)
self._run_command = module.run_command
def generate_certificate(self, certificate_path, identifier, options, pkcs11_provider, principals,
serial_number, signing_key_path, type, time_parameters, use_agent, **kwargs):
args = [self._bin_path, '-s', signing_key_path, '-P', '', '-I', identifier]
if options:
for option in options:
args.extend(['-O', option])
if pkcs11_provider:
args.extend(['-D', pkcs11_provider])
if principals:
args.extend(['-n', ','.join(principals)])
if serial_number is not None:
args.extend(['-z', str(serial_number)])
if type == 'host':
args.extend(['-h'])
if use_agent:
args.extend(['-U'])
if time_parameters.validity_string:
args.extend(['-V', time_parameters.validity_string])
args.append(certificate_path)
return self._run_command(args, **kwargs)
def generate_keypair(self, private_key_path, size, type, comment, **kwargs):
args = [
self._bin_path,
'-q',
'-N', '',
'-b', str(size),
'-t', type,
'-f', private_key_path,
'-C', comment or ''
]
# "y" must be entered in response to the "overwrite" prompt
data = 'y' if os.path.exists(private_key_path) else None
return self._run_command(args, data=data, **kwargs)
def get_certificate_info(self, certificate_path, **kwargs):
return self._run_command([self._bin_path, '-L', '-f', certificate_path], **kwargs)
def get_matching_public_key(self, private_key_path, **kwargs):
return self._run_command([self._bin_path, '-P', '', '-y', '-f', private_key_path], **kwargs)
def get_private_key(self, private_key_path, **kwargs):
return self._run_command([self._bin_path, '-l', '-f', private_key_path], **kwargs)
def update_comment(self, private_key_path, comment, **kwargs):
if os.path.exists(private_key_path) and not os.access(private_key_path, os.W_OK):
try:
os.chmod(private_key_path, stat.S_IWUSR + stat.S_IRUSR)
except (IOError, OSError) as e:
raise e("The private key at %s is not writeable preventing a comment update" % private_key_path)
return self._run_command([self._bin_path, '-q', '-o', '-c', '-C', comment, '-f', private_key_path], **kwargs)
class PrivateKey(object):
def __init__(self, size, key_type, fingerprint):
self._size = size
self._type = key_type
self._fingerprint = fingerprint
@property
def size(self):
return self._size
@property
def type(self):
return self._type
@property
def fingerprint(self):
return self._fingerprint
@classmethod
def from_string(cls, string):
properties = string.split()
return cls(
size=int(properties[0]),
key_type=properties[-1][1:-1].lower(),
fingerprint=properties[1],
)
def to_dict(self):
return {
'size': self._size,
'type': self._type,
'fingerprint': self._fingerprint,
}
class PublicKey(object):
def __init__(self, type_string, data, comment):
self._type_string = type_string
self._data = data
self._comment = comment
def __eq__(self, other):
if not isinstance(other, type(self)):
return NotImplemented
return all([
self._type_string == other._type_string,
self._data == other._data,
(self._comment == other._comment) if self._comment is not None and other._comment is not None else True
])
def __ne__(self, other):
return not self == other
def __str__(self):
return "%s %s" % (self._type_string, self._data)
@property
def comment(self):
return self._comment
@comment.setter
def comment(self, value):
self._comment = value
@property
def data(self):
return self._data
@property
def type_string(self):
return self._type_string
@classmethod
def from_string(cls, string):
properties = string.strip('\n').split(' ', 2)
return cls(
type_string=properties[0],
data=properties[1],
comment=properties[2] if len(properties) > 2 else ""
)
@classmethod
def load(cls, path):
try:
with open(path, 'r') as f:
properties = f.read().strip(' \n').split(' ', 2)
except (IOError, OSError):
raise
if len(properties) < 2:
return None
return cls(
type_string=properties[0],
data=properties[1],
comment='' if len(properties) <= 2 else properties[2],
)
def to_dict(self):
return {
'comment': self._comment,
'public_key': self._data,
}

View File

@@ -20,16 +20,13 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
import abc
import errno
import os
import stat
from distutils.version import LooseVersion
from ansible.module_utils import six
from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.common.text.converters import to_native, to_text, to_bytes
from ansible_collections.community.crypto.plugins.module_utils.openssh.utils import parse_openssh_version
from ansible_collections.community.crypto.plugins.module_utils.openssh.cryptography import (
HAS_OPENSSH_SUPPORT,
HAS_OPENSSH_PRIVATE_FORMAT,
@@ -39,322 +36,334 @@ from ansible_collections.community.crypto.plugins.module_utils.openssh.cryptogra
OpenSSHError,
OpensshKeypair,
)
from ansible_collections.community.crypto.plugins.module_utils.openssh.backends.common import (
KeygenCommand,
OpensshModule,
PrivateKey,
PublicKey,
)
from ansible_collections.community.crypto.plugins.module_utils.openssh.utils import (
any_in,
file_mode,
secure_write,
)
@six.add_metaclass(abc.ABCMeta)
class KeypairBackend(object):
class KeypairBackend(OpensshModule):
def __init__(self, module):
self.module = module
super(KeypairBackend, self).__init__(module)
self.path = module.params['path']
self.force = module.params['force']
self.size = module.params['size']
self.type = module.params['type']
self.comment = module.params['comment']
self.passphrase = module.params['passphrase']
self.regenerate = module.params['regenerate']
self.comment = self.module.params['comment']
self.private_key_path = self.module.params['path']
self.public_key_path = self.private_key_path + '.pub'
self.regenerate = self.module.params['regenerate'] if not self.module.params['force'] else 'always'
self.state = self.module.params['state']
self.type = self.module.params['type']
self.changed = False
self.fingerprint = ''
self.public_key = {}
self.size = self._get_size(self.module.params['size'])
self._validate_path()
if self.regenerate == 'always':
self.force = True
self.original_private_key = None
self.original_public_key = None
self.private_key = None
self.public_key = None
def _get_size(self, size):
if self.type in ('rsa', 'rsa1'):
self.size = 4096 if self.size is None else self.size
if self.size < 1024:
module.fail_json(msg=('For RSA keys, the minimum size is 1024 bits and the default is 4096 bits. '
'Attempting to use bit lengths under 1024 will cause the module to fail.'))
result = 4096 if size is None else size
if result < 1024:
return self.module.fail_json(
msg="For RSA keys, the minimum size is 1024 bits and the default is 4096 bits. " +
"Attempting to use bit lengths under 1024 will cause the module to fail."
)
elif self.type == 'dsa':
self.size = 1024 if self.size is None else self.size
if self.size != 1024:
module.fail_json(msg=('DSA keys must be exactly 1024 bits as specified by FIPS 186-2.'))
result = 1024 if size is None else size
if result != 1024:
return self.module.fail_json(msg="DSA keys must be exactly 1024 bits as specified by FIPS 186-2.")
elif self.type == 'ecdsa':
self.size = 256 if self.size is None else self.size
if self.size not in (256, 384, 521):
module.fail_json(msg=('For ECDSA keys, size determines the key length by selecting from '
'one of three elliptic curve sizes: 256, 384 or 521 bits. '
'Attempting to use bit lengths other than these three values for '
'ECDSA keys will cause this module to fail. '))
result = 256 if size is None else size
if result not in (256, 384, 521):
return self.module.fail_json(
msg="For ECDSA keys, size determines the key length by selecting from one of " +
"three elliptic curve sizes: 256, 384 or 521 bits. " +
"Attempting to use bit lengths other than these three values for ECDSA keys will " +
"cause this module to fail."
)
elif self.type == 'ed25519':
# User input is ignored for `key size` when `key type` is ed25519
self.size = 256
result = 256
else:
module.fail_json(msg="%s is not a valid value for key type" % self.type)
return self.module.fail_json(msg="%s is not a valid value for key type" % self.type)
def generate(self):
if self.force or not self.is_private_key_valid(perms_required=False):
try:
if self.exists() and not os.access(self.path, os.W_OK):
os.chmod(self.path, stat.S_IWUSR + stat.S_IRUSR)
self._generate_keypair()
self.changed = True
except (IOError, OSError) as e:
self.remove()
self.module.fail_json(msg="%s" % to_native(e))
return result
self.fingerprint = self._get_current_key_properties()[2]
self.public_key = self._get_public_key()
elif not self.is_public_key_valid(perms_required=False):
pubkey = self._get_public_key()
try:
with open(self.path + ".pub", "w") as pubkey_f:
pubkey_f.write(pubkey + '\n')
os.chmod(self.path + ".pub", stat.S_IWUSR + stat.S_IRUSR + stat.S_IRGRP + stat.S_IROTH)
except (IOError, OSError):
self.module.fail_json(
msg='The public key is missing or does not match the private key. '
'Unable to regenerate the public key.')
self.changed = True
self.public_key = pubkey
def _validate_path(self):
self._check_if_base_dir(self.private_key_path)
if self.comment:
try:
if self.exists() and not os.access(self.path, os.W_OK):
os.chmod(self.path, stat.S_IWUSR + stat.S_IRUSR)
except (IOError, OSError):
self.module.fail_json(msg='Unable to update the comment for the public key.')
self._update_comment()
if os.path.isdir(self.private_key_path):
self.module.fail_json(msg='%s is a directory. Please specify a path to a file.' % self.private_key_path)
private_key_perms_changed = self._permissions_changed()
public_key_perms_changed = self._permissions_changed(public_key=True)
if private_key_perms_changed or public_key_perms_changed:
self.changed = True
def _execute(self):
self.original_private_key = self._load_private_key()
self.original_public_key = self._load_public_key()
def is_private_key_valid(self, perms_required=True):
if not self.exists():
return False
if self.state == 'present':
self._validate_key_load()
if self._check_pass_protected_or_broken_key():
if self.regenerate in ('full_idempotence', 'always'):
return False
self.module.fail_json(msg='Unable to read the key. The key is protected with a passphrase or broken.'
' Will not proceed. To force regeneration, call the module with `generate`'
' set to `full_idempotence` or `always`, or with `force=yes`.')
if self._should_generate():
self._generate()
elif not self._public_key_valid():
self._restore_public_key()
if not self._private_key_loadable():
if os.path.isdir(self.path):
self.module.fail_json(msg='%s is a directory. Please specify a path to a file.' % self.path)
self.private_key = self._load_private_key()
self.public_key = self._load_public_key()
if self.regenerate in ('full_idempotence', 'always'):
return False
self.module.fail_json(msg='Unable to read the key. The key is protected with a passphrase or broken.'
' Will not proceed. To force regeneration, call the module with `generate`'
' set to `full_idempotence` or `always`, or with `force=yes`.')
keysize, keytype, self.fingerprint = self._get_current_key_properties()
if self.regenerate == 'never':
return True
if not (self.type == keytype and self.size == keysize):
if self.regenerate in ('partial_idempotence', 'full_idempotence', 'always'):
return False
self.module.fail_json(
msg='Key has wrong type and/or size.'
' Will not proceed. To force regeneration, call the module with `generate`'
' set to `partial_idempotence`, `full_idempotence` or `always`, or with `force=yes`.'
)
# Perms required short-circuits evaluation to prevent the side-effects of running _permissions_changed
# when check_mode is not enabled
return not (perms_required and self._permissions_changed())
def is_public_key_valid(self, perms_required=True):
def _get_pubkey_content():
if self.exists(public_key=True):
with open(self.path + ".pub", "r") as pubkey_f:
present_pubkey = pubkey_f.read().strip(' \n')
return present_pubkey
else:
return ''
def _parse_pubkey(pubkey_content):
if pubkey_content:
parts = pubkey_content.split(' ', 2)
if len(parts) < 2:
return ()
return parts[0], parts[1], '' if len(parts) <= 2 else parts[2]
return ()
def _pubkey_valid(pubkey):
if pubkey_parts and _parse_pubkey(pubkey):
return pubkey_parts[:2] == _parse_pubkey(pubkey)[:2]
return False
def _comment_valid():
if pubkey_parts:
return pubkey_parts[2] == self.comment
return False
pubkey_parts = _parse_pubkey(_get_pubkey_content())
pubkey = self._get_public_key()
if _pubkey_valid(pubkey):
self.public_key = pubkey
for path in (self.private_key_path, self.public_key_path):
self._update_permissions(path)
else:
return False
if self._should_remove():
self._remove()
if self.comment and not _comment_valid():
return False
# Perms required short-circuits evaluation to prevent the side-effects of running _permissions_changes
# when check_mode is not enabled
return not (perms_required and self._permissions_changed(public_key=True))
def _permissions_changed(self, public_key=False):
file_args = self.module.load_file_common_arguments(self.module.params)
if public_key:
file_args['path'] = file_args['path'] + '.pub'
if self.module.check_file_absent_if_check_mode(file_args['path']):
return True
return self.module.set_fs_attributes_if_different(file_args, False)
@property
def result(self):
return {
'changed': self.changed,
'size': self.size,
'type': self.type,
'filename': self.path,
'fingerprint': self.fingerprint if self.fingerprint else '',
'public_key': self.public_key,
'comment': self.comment if self.comment else '',
}
def remove(self):
"""Remove the resource from the filesystem."""
try:
os.remove(self.path)
self.changed = True
except (IOError, OSError) as exc:
if exc.errno != errno.ENOENT:
self.module.fail_json(msg=to_native(exc))
else:
def _load_private_key(self):
result = None
if self._private_key_exists():
try:
result = self._get_private_key()
except Exception:
pass
if self.exists(public_key=True):
return result
def _private_key_exists(self):
return os.path.exists(self.private_key_path)
@abc.abstractmethod
def _get_private_key(self):
pass
def _load_public_key(self):
result = None
if self._public_key_exists():
try:
os.remove(self.path + ".pub")
self.changed = True
except (IOError, OSError) as exc:
if exc.errno != errno.ENOENT:
self.module.fail_json(msg=to_native(exc))
else:
pass
result = PublicKey.load(self.public_key_path)
except (IOError, OSError):
pass
return result
def exists(self, public_key=False):
return os.path.exists(self.path if not public_key else self.path + ".pub")
def _public_key_exists(self):
return os.path.exists(self.public_key_path)
def _validate_key_load(self):
if (self._private_key_exists()
and self.regenerate in ('never', 'fail', 'partial_idempotence')
and (self.original_private_key is None or not self._private_key_readable())):
self.module.fail_json(
msg="Unable to read the key. The key is protected with a passphrase or broken. " +
"Will not proceed. To force regeneration, call the module with `generate` " +
"set to `full_idempotence` or `always`, or with `force=yes`."
)
@abc.abstractmethod
def _generate_keypair(self):
def _private_key_readable(self):
pass
def _should_generate(self):
if self.regenerate == 'never':
return self.original_private_key is None
elif self.regenerate == 'fail':
if not self._private_key_valid():
self.module.fail_json(
msg="Key has wrong type and/or size. Will not proceed. " +
"To force regeneration, call the module with `generate` set to " +
"`partial_idempotence`, `full_idempotence` or `always`, or with `force=yes`."
)
return self.original_private_key is None
elif self.regenerate in ('partial_idempotence', 'full_idempotence'):
return not self._private_key_valid()
else:
return True
def _private_key_valid(self):
if self.original_private_key is None:
return False
return all([
self.size == self.original_private_key.size,
self.type == self.original_private_key.type,
])
@OpensshModule.trigger_change
@OpensshModule.skip_if_check_mode
def _generate(self):
temp_private_key, temp_public_key = self._generate_temp_keypair()
try:
self._safe_secure_move([(temp_private_key, self.private_key_path), (temp_public_key, self.public_key_path)])
except OSError as e:
self.module.fail_json(msg=to_native(e))
def _generate_temp_keypair(self):
temp_private_key = os.path.join(self.module.tmpdir, os.path.basename(self.private_key_path))
temp_public_key = temp_private_key + '.pub'
try:
self._generate_keypair(temp_private_key)
except (IOError, OSError) as e:
self.module.fail_json(msg=to_native(e))
for f in (temp_private_key, temp_public_key):
self.module.add_cleanup_file(f)
return temp_private_key, temp_public_key
@abc.abstractmethod
def _get_current_key_properties(self):
def _generate_keypair(self, private_key_path):
pass
def _public_key_valid(self):
if self.original_public_key is None:
return False
valid_public_key = self._get_public_key()
valid_public_key.comment = self.comment
return self.original_public_key == valid_public_key
@abc.abstractmethod
def _get_public_key(self):
pass
@OpensshModule.trigger_change
@OpensshModule.skip_if_check_mode
def _restore_public_key(self):
try:
temp_public_key = self._create_temp_public_key(str(self._get_public_key()) + '\n')
self._safe_secure_move([
(temp_public_key, self.public_key_path)
])
except (IOError, OSError):
self.module.fail_json(
msg="The public key is missing or does not match the private key. " +
"Unable to regenerate the public key."
)
if self.comment:
self._update_comment()
def _create_temp_public_key(self, content):
temp_public_key = os.path.join(self.module.tmpdir, os.path.basename(self.public_key_path))
default_permissions = 0o644
existing_permissions = file_mode(self.public_key_path)
try:
secure_write(temp_public_key, existing_permissions or default_permissions, to_bytes(content))
except (IOError, OSError) as e:
self.module.fail_json(msg=to_native(e))
self.module.add_cleanup_file(temp_public_key)
return temp_public_key
@abc.abstractmethod
def _update_comment(self):
pass
@abc.abstractmethod
def _private_key_loadable(self):
pass
def _should_remove(self):
return self._private_key_exists() or self._public_key_exists()
@abc.abstractmethod
def _check_pass_protected_or_broken_key(self):
pass
@OpensshModule.trigger_change
@OpensshModule.skip_if_check_mode
def _remove(self):
try:
if self._private_key_exists():
os.remove(self.private_key_path)
if self._public_key_exists():
os.remove(self.public_key_path)
except (IOError, OSError) as e:
self.module.fail_json(msg=to_native(e))
@property
def _result(self):
private_key = self.private_key or self.original_private_key
public_key = self.public_key or self.original_public_key
return {
'size': self.size,
'type': self.type,
'filename': self.private_key_path,
'fingerprint': private_key.fingerprint if private_key else '',
'public_key': str(public_key) if public_key else '',
'comment': public_key.comment if public_key else '',
}
@property
def diff(self):
before = self.original_private_key.to_dict() if self.original_private_key else {}
before.update(self.original_public_key.to_dict() if self.original_public_key else {})
after = self.private_key.to_dict() if self.private_key else {}
after.update(self.public_key.to_dict() if self.public_key else {})
return {
'before': before,
'after': after,
}
class KeypairBackendOpensshBin(KeypairBackend):
def __init__(self, module):
super(KeypairBackendOpensshBin, self).__init__(module)
self.openssh_bin = module.get_bin_path('ssh-keygen')
self.ssh_keygen = KeygenCommand(self.module)
def _load_privatekey(self):
return self.module.run_command([self.openssh_bin, '-lf', self.path])
def _generate_keypair(self, private_key_path):
self.ssh_keygen.generate_keypair(private_key_path, self.size, self.type, self.comment)
def _get_publickey_from_privatekey(self):
# -P '' is always included as an option to induce the expected standard output for
# _check_pass_protected_or_broken_key, but introduces no side-effects when used to
# output a matching public key
return self.module.run_command([self.openssh_bin, '-P', '', '-yf', self.path])
def _generate_keypair(self):
args = [
self.openssh_bin,
'-q',
'-N', '',
'-b', str(self.size),
'-t', self.type,
'-f', self.path,
'-C', self.comment if self.comment else ''
]
# "y" must be entered in response to the "overwrite" prompt
stdin_data = 'y' if self.exists() else None
self.module.run_command(args, data=stdin_data)
def _get_current_key_properties(self):
rc, stdout, stderr = self._load_privatekey()
properties = stdout.split()
keysize = int(properties[0])
fingerprint = properties[1]
keytype = properties[-1][1:-1].lower()
return keysize, keytype, fingerprint
def _get_private_key(self):
private_key_content = self.ssh_keygen.get_private_key(self.private_key_path)[1]
return PrivateKey.from_string(private_key_content)
def _get_public_key(self):
rc, stdout, stderr = self._get_publickey_from_privatekey()
return stdout.strip('\n')
public_key_content = self.ssh_keygen.get_matching_public_key(self.private_key_path)[1]
return PublicKey.from_string(public_key_content)
def _private_key_readable(self):
rc, stdout, stderr = self.ssh_keygen.get_matching_public_key(self.private_key_path)
return not (rc == 255 or any_in(stderr, 'is not a public key file', 'incorrect passphrase', 'load failed'))
def _update_comment(self):
return self.module.run_command([self.openssh_bin, '-q', '-o', '-c', '-C', self.comment, '-f', self.path])
def _private_key_loadable(self):
rc, stdout, stderr = self._load_privatekey()
return rc == 0
def _check_pass_protected_or_broken_key(self):
rc, stdout, stderr = self._get_publickey_from_privatekey()
return rc == 255 or any_in(stderr, 'is not a public key file', 'incorrect passphrase', 'load failed')
try:
self.ssh_keygen.update_comment(self.private_key_path, self.comment)
except (IOError, OSError) as e:
self.module.fail_json(msg=to_native(e))
class KeypairBackendCryptography(KeypairBackend):
def __init__(self, module):
super(KeypairBackendCryptography, self).__init__(module)
if module.params['private_key_format'] == 'auto':
ssh = module.get_bin_path('ssh')
if ssh:
proc = module.run_command([ssh, '-Vq'])
ssh_version = parse_openssh_version(proc[2].strip())
else:
# Default to OpenSSH 7.8 compatibility when OpenSSH is not installed
ssh_version = "7.8"
if self.type == 'rsa1':
self.module.fail_json(msg="RSA1 keys are not supported by the cryptography backend")
self.private_key_format = 'SSH'
self.passphrase = to_bytes(module.params['passphrase']) if module.params['passphrase'] else None
self.private_key_format = self._get_key_format(module.params['private_key_format'])
def _get_key_format(self, key_format):
result = 'SSH'
if key_format == 'auto':
# Default to OpenSSH 7.8 compatibility when OpenSSH is not installed
ssh_version = self._get_ssh_version() or "7.8"
if LooseVersion(ssh_version) < LooseVersion("7.8") and self.type != 'ed25519':
# OpenSSH made SSH formatted private keys available in version 6.5,
# but still defaulted to PKCS1 format with the exception of ed25519 keys
self.private_key_format = 'PKCS1'
result = 'PKCS1'
if self.private_key_format == 'SSH' and not HAS_OPENSSH_PRIVATE_FORMAT:
module.fail_json(
if result == 'SSH' and not HAS_OPENSSH_PRIVATE_FORMAT:
self.module.fail_json(
msg=missing_required_lib(
'cryptography >= 3.0',
reason="to load/dump private keys in the default OpenSSH format for OpenSSH >= 7.8 " +
@@ -362,96 +371,72 @@ class KeypairBackendCryptography(KeypairBackend):
)
)
if self.type == 'rsa1':
module.fail_json(msg="RSA1 keys are not supported by the cryptography backend")
return result
self.passphrase = to_bytes(self.passphrase) if self.passphrase else None
def _load_privatekey(self):
return OpensshKeypair.load(path=self.path, passphrase=self.passphrase, no_public_key=True)
def _generate_keypair(self):
def _generate_keypair(self, private_key_path):
keypair = OpensshKeypair.generate(
keytype=self.type,
size=self.size,
passphrase=self.passphrase,
comment=self.comment if self.comment else "",
comment=self.comment or '',
)
with open(self.path, 'w+b') as f:
f.write(
OpensshKeypair.encode_openssh_privatekey(
keypair.asymmetric_keypair,
self.private_key_format
)
)
# ssh-keygen defaults private key permissions to 0600 octal
os.chmod(self.path, stat.S_IWUSR + stat.S_IRUSR)
with open(self.path + '.pub', 'w+b') as f:
f.write(keypair.public_key)
# ssh-keygen defaults public key permissions to 0644 octal
os.chmod(self.path + ".pub", stat.S_IWUSR + stat.S_IRUSR + stat.S_IRGRP + stat.S_IROTH)
def _get_current_key_properties(self):
keypair = self._load_privatekey()
encoded_private_key = OpensshKeypair.encode_openssh_privatekey(
keypair.asymmetric_keypair, self.private_key_format
)
secure_write(private_key_path, 0o600, encoded_private_key)
return keypair.size, keypair.key_type, keypair.fingerprint
public_key_path = private_key_path + '.pub'
secure_write(public_key_path, 0o644, keypair.public_key)
def _get_private_key(self):
keypair = OpensshKeypair.load(path=self.private_key_path, passphrase=self.passphrase, no_public_key=True)
return PrivateKey(
size=keypair.size,
key_type=keypair.key_type,
fingerprint=keypair.fingerprint,
)
def _get_public_key(self):
try:
keypair = self._load_privatekey()
keypair = OpensshKeypair.load(path=self.private_key_path, passphrase=self.passphrase, no_public_key=True)
except OpenSSHError:
# Simulates the null output of ssh-keygen
return ""
return to_text(keypair.public_key)
return PublicKey.from_string(to_text(keypair.public_key))
def _update_comment(self):
keypair = self._load_privatekey()
def _private_key_readable(self):
try:
keypair.comment = self.comment
with open(self.path + ".pub", "w+b") as pubkey_file:
pubkey_file.write(keypair.public_key + b'\n')
except (InvalidCommentError, IOError, OSError) as e:
# Return values while unused currently are made to simulate the output of run_command()
return 1, "Comment could not be updated", to_native(e)
return 0, "Comment updated successfully", ""
def _private_key_loadable(self):
try:
self._load_privatekey()
except OpenSSHError:
return False
return True
def _check_pass_protected_or_broken_key(self):
try:
OpensshKeypair.load(
path=self.path,
passphrase=self.passphrase,
no_public_key=True,
)
OpensshKeypair.load(path=self.private_key_path, passphrase=self.passphrase, no_public_key=True)
except (InvalidPrivateKeyFileError, InvalidPassphraseError):
return True
return False
# Cryptography >= 3.0 uses a SSH key loader which does not raise an exception when a passphrase is provided
# when loading an unencrypted key
if self.passphrase:
try:
OpensshKeypair.load(
path=self.path,
passphrase=None,
no_public_key=True,
)
OpensshKeypair.load(path=self.private_key_path, passphrase=None, no_public_key=True)
except (InvalidPrivateKeyFileError, InvalidPassphraseError):
return False
else:
return True
else:
return False
return False
return True
def _update_comment(self):
keypair = OpensshKeypair.load(path=self.private_key_path, passphrase=self.passphrase, no_public_key=True)
try:
keypair.comment = self.comment
except InvalidCommentError as e:
self.module.fail_json(msg=to_native(e))
def any_in(sequence, *elements):
return any([e in sequence for e in elements])
try:
temp_public_key = self._create_temp_public_key(keypair.public_key + b'\n')
self._safe_secure_move([(temp_public_key, self.public_key_path)])
except (IOError, OSError) as e:
self.module.fail_json(msg=to_native(e))
def select_backend(module, backend):

View File

@@ -19,7 +19,9 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import os
import re
from contextlib import contextmanager
from struct import Struct
from ansible.module_utils.six import PY3
@@ -54,6 +56,16 @@ _UINT64 = Struct(b'!Q')
_UINT64_MAX = 0xFFFFFFFFFFFFFFFF
def any_in(sequence, *elements):
return any(e in sequence for e in elements)
def file_mode(path):
if not os.path.exists(path):
return 0o000
return os.stat(path).st_mode & 0o777
def parse_openssh_version(version_string):
"""Parse the version output of ssh -V and return version numbers that can be compared"""
@@ -68,6 +80,20 @@ def parse_openssh_version(version_string):
return version
@contextmanager
def secure_open(path, mode):
fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, mode)
try:
yield fd
finally:
os.close(fd)
def secure_write(path, mode, content):
with secure_open(path, mode) as fd:
os.write(fd, content)
# See https://datatracker.ietf.org/doc/html/rfc4251#section-5 for SSH data types
class OpensshParser(object):
"""Parser for OpenSSH encoded objects"""

View File

@@ -50,6 +50,14 @@ options:
- Proxy port used when get a certificate.
type: int
default: 8080
starttls:
description:
- Requests a secure connection for protocols which require clients to initiate encryption.
- Only available for C(mysql) currently.
type: str
choices:
- mysql
version_added: 1.9.0
timeout:
description:
- The timeout in seconds
@@ -209,6 +217,20 @@ else:
CRYPTOGRAPHY_FOUND = True
def send_starttls_packet(sock, server_type):
if server_type == 'mysql':
ssl_request_packet = (
b'\x20\x00\x00\x01\x85\xae\x7f\x00' +
b'\x00\x00\x00\x01\x21\x00\x00\x00' +
b'\x00\x00\x00\x00\x00\x00\x00\x00' +
b'\x00\x00\x00\x00\x00\x00\x00\x00' +
b'\x00\x00\x00\x00'
)
sock.recv(8192) # discard initial handshake from server for this naive implementation
sock.send(ssl_request_packet)
def main():
module = AnsibleModule(
argument_spec=dict(
@@ -220,6 +242,7 @@ def main():
server_name=dict(type='str'),
timeout=dict(type='int', default=10),
select_crypto_backend=dict(type='str', choices=['auto', 'pyopenssl', 'cryptography'], default='auto'),
starttls=dict(type='str', choices=['mysql']),
),
)
@@ -230,6 +253,7 @@ def main():
proxy_port = module.params.get('proxy_port')
timeout = module.params.get('timeout')
server_name = module.params.get('server_name')
start_tls_server_type = module.params.get('starttls')
backend = module.params.get('select_crypto_backend')
if backend == 'auto':
@@ -305,6 +329,9 @@ def main():
ctx.check_hostname = False
ctx.verify_mode = CERT_NONE
if start_tls_server_type is not None:
send_starttls_packet(sock, start_tls_server_type)
cert = ctx.wrap_socket(sock, server_hostname=server_name or host).getpeercert(True)
cert = DER_cert_to_PEM_cert(cert)
except Exception as e:

View File

@@ -44,8 +44,8 @@ options:
required: true
regenerate:
description:
- When C(never) the task will fail if a certificate already exists at I(path) and is unreadable.
Otherwise, a new certificate will only be generated if there is no existing certificate.
- When C(never) the task will fail if a certificate already exists at I(path) and is unreadable
otherwise a new certificate will only be generated if there is no existing certificate.
- When C(fail) the task will fail if a certificate already exists at I(path) and does not
match the module's options.
- When C(partial_idempotence) an existing certificate will be regenerated based on
@@ -239,12 +239,15 @@ info:
import os
from distutils.version import LooseVersion
from sys import version_info
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible_collections.community.crypto.plugins.module_utils.openssh.backends.common import safe_atomic_move
from ansible_collections.community.crypto.plugins.module_utils.openssh.backends.common import (
KeygenCommand,
OpensshModule,
PrivateKey,
)
from ansible_collections.community.crypto.plugins.module_utils.openssh.certificate import (
OpensshCertificate,
@@ -252,153 +255,120 @@ from ansible_collections.community.crypto.plugins.module_utils.openssh.certifica
parse_option_list,
)
from ansible_collections.community.crypto.plugins.module_utils.openssh.utils import (
parse_openssh_version,
)
PY27 = version_info[0:2] >= (2, 7)
class Certificate(object):
class Certificate(OpensshModule):
def __init__(self, module):
self.check_mode = module.check_mode
self.module = module
self.ssh_keygen = module.get_bin_path('ssh-keygen', True)
super(Certificate, self).__init__(module)
self.ssh_keygen = KeygenCommand(self.module)
self.force = module.params['force']
self.identifier = module.params['identifier'] or ""
self.options = module.params['options'] or []
self.path = module.params['path']
self.pkcs11_provider = module.params['pkcs11_provider']
self.principals = module.params['principals'] or []
self.public_key = module.params['public_key']
self.regenerate = module.params['regenerate'] if not self.force else 'always'
self.serial_number = module.params['serial_number']
self.signing_key = module.params['signing_key']
self.state = module.params['state']
self.type = module.params['type']
self.use_agent = module.params['use_agent']
self.valid_at = module.params['valid_at']
self.identifier = self.module.params['identifier'] or ""
self.options = self.module.params['options'] or []
self.path = self.module.params['path']
self.pkcs11_provider = self.module.params['pkcs11_provider']
self.principals = self.module.params['principals'] or []
self.public_key = self.module.params['public_key']
self.regenerate = self.module.params['regenerate'] if not self.module.params['force'] else 'always'
self.serial_number = self.module.params['serial_number']
self.signing_key = self.module.params['signing_key']
self.state = self.module.params['state']
self.type = self.module.params['type']
self.use_agent = self.module.params['use_agent']
self.valid_at = self.module.params['valid_at']
self._check_if_base_dir(self.path)
if self.state == 'present':
self._validate_parameters()
self.changed = False
self.data = None
self.original_data = None
if self._exists():
self._load_certificate()
self.time_parameters = None
if self.state == 'present':
try:
self.time_parameters = OpensshCertificateTimeParameters(
valid_from=module.params['valid_from'],
valid_to=module.params['valid_to'],
)
except ValueError as e:
self.module.fail_json(msg=to_native(e))
self._set_time_parameters()
if self.exists():
try:
self.original_data = OpensshCertificate.load(self.path)
except (TypeError, ValueError) as e:
if self.regenerate in ('never', 'fail'):
self.module.fail_json(msg="Unable to read existing certificate: %s" % to_native(e))
self.module.warn("Unable to read existing certificate: %s" % to_native(e))
def _validate_parameters(self):
for path in (self.public_key, self.signing_key):
self._check_if_base_dir(path)
self._validate_parameters()
if self.options and self.type == "host":
self.module.fail_json(msg="Options can only be used with user certificates.")
def exists(self):
return os.path.exists(self.path)
if self.use_agent:
self._use_agent_available()
def generate(self):
if self._should_generate():
if not self.check_mode:
temp_cert = self._generate_temp_certificate()
try:
safe_atomic_move(self.module, temp_cert, self.path)
except OSError as e:
self.module.fail_json(msg="Unable to write certificate to %s: %s" % (self.path, to_native(e)))
try:
self.data = OpensshCertificate.load(self.path)
except (TypeError, ValueError) as e:
self.module.fail_json(msg="Unable to read new certificate: %s" % to_native(e))
self.changed = True
if self.exists():
self._update_permissions()
def remove(self):
if self.exists():
if not self.check_mode:
try:
os.remove(self.path)
except OSError as e:
self.module.fail_json(msg="Unable to remove existing certificate: %s" % to_native(e))
self.changed = True
@property
def result(self):
result = {'changed': self.changed}
if self.module._diff:
result['diff'] = {
'before': get_cert_dict(self.original_data),
'after': get_cert_dict(self.data)
}
if self.state == 'present':
result.update({
'type': self.type,
'filename': self.path,
'info': format_cert_info(self._get_cert_info()),
})
return result
def _check_if_base_dir(self, path):
base_dir = os.path.dirname(path) or '.'
if not os.path.isdir(base_dir):
def _use_agent_available(self):
ssh_version = self._get_ssh_version()
if not ssh_version:
self.module.fail_json(msg="Failed to determine ssh version")
elif LooseVersion(ssh_version) < LooseVersion("7.6"):
self.module.fail_json(
name=base_dir,
msg='The directory %s does not exist or the file is not a directory' % base_dir
msg="Signing with CA key in ssh agent requires ssh 7.6 or newer." +
" Your version is: %s" % ssh_version
)
def _command_arguments(self, key_copy_path):
result = [
self.ssh_keygen,
'-s', self.signing_key,
'-P', '',
'-I', self.identifier,
]
def _exists(self):
return os.path.exists(self.path)
if self.options:
for option in self.options:
result.extend(['-O', option])
if self.pkcs11_provider:
result.extend(['-D', self.pkcs11_provider])
if self.principals:
result.extend(['-n', ','.join(self.principals)])
if self.serial_number is not None:
result.extend(['-z', str(self.serial_number)])
if self.type == 'host':
result.extend(['-h'])
if self.use_agent:
result.extend(['-U'])
if self.time_parameters.validity_string:
result.extend(['-V', self.time_parameters.validity_string])
result.append(key_copy_path)
return result
def _compare_options(self):
def _load_certificate(self):
try:
critical_options, extensions = parse_option_list(self.options)
except ValueError as e:
return self.module.fail_json(msg=to_native(e))
self.original_data = OpensshCertificate.load(self.path)
except (TypeError, ValueError) as e:
if self.regenerate in ('never', 'fail'):
self.module.fail_json(msg="Unable to read existing certificate: %s" % to_native(e))
self.module.warn("Unable to read existing certificate: %s" % to_native(e))
def _set_time_parameters(self):
try:
self.time_parameters = OpensshCertificateTimeParameters(
valid_from=self.module.params['valid_from'],
valid_to=self.module.params['valid_to'],
)
except ValueError as e:
self.module.fail_json(msg=to_native(e))
def _execute(self):
if self.state == 'present':
if self._should_generate():
self._generate()
self._update_permissions(self.path)
else:
if self._exists():
self._remove()
def _should_generate(self):
if self.regenerate == 'never':
return self.original_data is None
elif self.regenerate == 'fail':
if self.original_data and not self._is_fully_valid():
self.module.fail_json(
msg="Certificate does not match the provided options.",
cert=get_cert_dict(self.original_data)
)
return self.original_data is None
elif self.regenerate == 'partial_idempotence':
return self.original_data is None or not self._is_partially_valid()
elif self.regenerate == 'full_idempotence':
return self.original_data is None or not self._is_fully_valid()
else:
return True
def _is_fully_valid(self):
return self._is_partially_valid() and all([
self._compare_options(),
self.original_data.key_id == self.identifier,
self.original_data.public_key == self._get_key_fingerprint(self.public_key),
self.original_data.signing_key == self._get_key_fingerprint(self.signing_key),
])
def _is_partially_valid(self):
return all([
set(self.original_data.critical_options) == set(critical_options),
set(self.original_data.extensions) == set(extensions)
set(self.original_data.principals) == set(self.principals),
self.original_data.serial == self.serial_number if self.serial_number is not None else True,
self.original_data.type == self.type,
self._compare_time_parameters(),
])
def _compare_time_parameters(self):
@@ -415,6 +385,35 @@ class Certificate(object):
original_time_parameters.within_range(self.valid_at)
])
def _compare_options(self):
try:
critical_options, extensions = parse_option_list(self.options)
except ValueError as e:
return self.module.fail_json(msg=to_native(e))
return all([
set(self.original_data.critical_options) == set(critical_options),
set(self.original_data.extensions) == set(extensions)
])
def _get_key_fingerprint(self, path):
private_key_content = self.ssh_keygen.get_private_key(path, check_rc=True)[1]
return PrivateKey.from_string(private_key_content).fingerprint
@OpensshModule.trigger_change
@OpensshModule.skip_if_check_mode
def _generate(self):
try:
temp_certificate = self._generate_temp_certificate()
self._safe_secure_move([(temp_certificate, self.path)])
except OSError as e:
self.module.fail_json(msg="Unable to write certificate to %s: %s" % (self.path, to_native(e)))
try:
self.data = OpensshCertificate.load(self.path)
except (TypeError, ValueError) as e:
self.module.fail_json(msg="Unable to read new certificate: %s" % to_native(e))
def _generate_temp_certificate(self):
key_copy = os.path.join(self.module.tmpdir, os.path.basename(self.public_key))
@@ -424,77 +423,44 @@ class Certificate(object):
self.module.fail_json(msg="Unable to stage temporary key: %s" % to_native(e))
self.module.add_cleanup_file(key_copy)
self.module.run_command(self._command_arguments(key_copy), environ_update=dict(TZ="UTC"), check_rc=True)
self.ssh_keygen.generate_certificate(
key_copy, self.identifier, self.options, self.pkcs11_provider, self.principals, self.serial_number,
self.signing_key, self.type, self.time_parameters, self.use_agent,
environ_update=dict(TZ="UTC"), check_rc=True
)
temp_cert = os.path.splitext(key_copy)[0] + '-cert.pub'
self.module.add_cleanup_file(temp_cert)
return temp_cert
def _get_cert_info(self):
return self.module.run_command([self.ssh_keygen, '-Lf', self.path])[1]
@OpensshModule.trigger_change
@OpensshModule.skip_if_check_mode
def _remove(self):
try:
os.remove(self.path)
except OSError as e:
self.module.fail_json(msg="Unable to remove existing certificate: %s" % to_native(e))
def _get_key_fingerprint(self, path):
stdout = self.module.run_command([self.ssh_keygen, '-lf', path], check_rc=True)[1]
return stdout.split()[1]
@property
def _result(self):
if self.state != 'present':
return {}
def _is_valid(self):
partial_result = all([
set(self.original_data.principals) == set(self.principals),
self.original_data.serial == self.serial_number if self.serial_number is not None else True,
self.original_data.type == self.type,
self._compare_time_parameters(),
])
certificate_info = self.ssh_keygen.get_certificate_info(self.path)[1]
if self.regenerate == 'partial_idempotence':
return partial_result
return {
'type': self.type,
'filename': self.path,
'info': format_cert_info(certificate_info),
}
return partial_result and all([
self._compare_options(),
self.original_data.key_id == self.identifier,
self.original_data.public_key == self._get_key_fingerprint(self.public_key),
self.original_data.signing_key == self._get_key_fingerprint(self.signing_key),
])
def _should_generate(self):
if self.regenerate == 'never':
return self.original_data is None
elif self.regenerate == 'fail':
if self.original_data and not self._is_valid():
self.module.fail_json(
msg="Certificate does not match the provided options.",
cert=get_cert_dict(self.original_data)
)
return self.original_data is None
elif self.regenerate in ('partial_idempotence', 'full_idempotence'):
return self.original_data is None or not self._is_valid()
else:
return True
def _update_permissions(self):
file_args = self.module.load_file_common_arguments(self.module.params)
self.changed = self.module.set_fs_attributes_if_different(file_args, self.changed)
def _validate_parameters(self):
self._check_if_base_dir(self.path)
if self.state == 'present':
for path in (self.public_key, self.signing_key):
self._check_if_base_dir(path)
if self.options and self.type == "host":
self.module.fail_json(msg="Options can only be used with user certificates.")
if self.use_agent:
ssh_version_string = self.module.run_command([self.module.get_bin_path('ssh', True), '-Vq'])[2].strip()
ssh_version = parse_openssh_version(ssh_version_string)
if ssh_version is None:
self.module.fail_json(msg="Failed to parse ssh version from: %s" % ssh_version_string)
elif LooseVersion(ssh_version) < LooseVersion("7.6"):
self.module.fail_json(
msg="Signing with CA key in ssh agent requires ssh 7.6 or newer." +
" Your version is: %s" % ssh_version_string
)
@property
def diff(self):
return {
'before': get_cert_dict(self.original_data),
'after': get_cert_dict(self.data)
}
def format_cert_info(cert_info):
@@ -551,14 +517,7 @@ def main():
required_if=[('state', 'present', ['type', 'signing_key', 'public_key', 'valid_from', 'valid_to'])],
)
certificate = Certificate(module)
if certificate.state == 'present':
certificate.generate()
else:
certificate.remove()
module.exit_json(**certificate.result)
Certificate(module).execute()
if __name__ == '__main__':

View File

@@ -186,8 +186,6 @@ comment:
sample: test@comment
'''
import os
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.module_utils.openssh.backends.keypair_backend import (
@@ -218,32 +216,9 @@ def main():
add_file_common_args=True,
)
base_dir = os.path.dirname(module.params['path']) or '.'
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg='The directory %s does not exist or the file is not a directory' % base_dir
)
keypair = select_backend(module, module.params['backend'])[1]
if module.params['state'] == 'present':
if module.check_mode:
keypair.changed = any([
keypair.force,
not keypair.is_private_key_valid(),
not keypair.is_public_key_valid()
])
else:
keypair.generate()
else:
# When `state=absent` no details from an existing key at the given `path` are returned in the module result
if module.check_mode:
keypair.changed = keypair.exists()
else:
keypair.remove()
module.exit_json(**keypair.result)
keypair.execute()
if __name__ == '__main__':

View File

@@ -597,7 +597,7 @@ class CRL(OpenSSLObject):
entry['invalidity_date_critical'],
)
def check(self, perms_required=True, ignore_conversion=True):
def check(self, module, perms_required=True, ignore_conversion=True):
"""Ensure the resource is in its desired state."""
state_and_perms = super(CRL, self).check(self.module, perms_required)
@@ -689,9 +689,9 @@ class CRL(OpenSSLObject):
def generate(self):
result = None
if not self.check(perms_required=False, ignore_conversion=True) or self.force:
if not self.check(self.module, perms_required=False, ignore_conversion=True) or self.force:
result = self._generate_crl()
elif not self.check(perms_required=False, ignore_conversion=False) and self.crl:
elif not self.check(self.module, perms_required=False, ignore_conversion=False) and self.crl:
if self.format == 'pem':
result = self.crl.public_bytes(Encoding.PEM)
else:
@@ -834,7 +834,7 @@ def main():
if module.params['state'] == 'present':
if module.check_mode:
result = crl.dump(check_mode=True)
result['changed'] = module.params['force'] or not crl.check() or not crl.check(ignore_conversion=False)
result['changed'] = module.params['force'] or not crl.check(module) or not crl.check(module, ignore_conversion=False)
module.exit_json(**result)
crl.generate()

View File

@@ -1,2 +1,3 @@
dependencies:
- setup_acme
- setup_remote_tmp_dir

View File

@@ -1,7 +1,7 @@
- block:
- name: Generate account keys
openssl_privatekey:
path: "{{ output_dir }}/{{ item.name }}.pem"
path: "{{ remote_tmp_dir }}/{{ item.name }}.pem"
passphrase: "{{ item.pass | default(omit, true) }}"
cipher: "{{ 'auto' if item.pass | default() else omit }}"
type: ECC
@@ -11,7 +11,7 @@
- name: Parse account keys (to ease debugging some test failures)
openssl_privatekey_info:
path: "{{ output_dir }}/{{ item.name }}.pem"
path: "{{ remote_tmp_dir }}/{{ item.name }}.pem"
passphrase: "{{ item.pass | default(omit, true) }}"
return_private_key_data: true
loop: "{{ account_keys }}"
@@ -28,7 +28,7 @@
- name: Do not try to create account
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -40,7 +40,7 @@
- name: Create it now (check mode, diff)
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -56,7 +56,7 @@
- name: Create it now
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -70,7 +70,7 @@
- name: Create it now (idempotent)
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -81,10 +81,15 @@
- mailto:example@example.org
register: account_created_idempotent
- name: Read account key
slurp:
src: '{{ remote_tmp_dir }}/accountkey.pem'
register: slurp
- name: Change email address (check mode, diff)
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_content: "{{ lookup('file', output_dir ~ '/accountkey.pem') }}"
account_key_content: "{{ slurp.content | b64decode }}"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -99,7 +104,7 @@
- name: Change email address
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_content: "{{ lookup('file', output_dir ~ '/accountkey.pem') }}"
account_key_content: "{{ slurp.content | b64decode }}"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -112,7 +117,7 @@
- name: Change email address (idempotent)
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_created.account_uri }}"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
@@ -126,7 +131,7 @@
- name: Cannot access account with wrong URI
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_created.account_uri ~ '12345thisdoesnotexist' }}"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
@@ -139,7 +144,7 @@
- name: Clear contact email addresses (check mode, diff)
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -153,7 +158,7 @@
- name: Clear contact email addresses
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -165,7 +170,7 @@
- name: Clear contact email addresses (idempotent)
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -177,11 +182,11 @@
- name: Change account key (check mode, diff)
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
new_account_key_src: "{{ output_dir }}/accountkey2.pem"
new_account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
new_account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
state: changed_key
contact:
@@ -193,11 +198,11 @@
- name: Change account key
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
new_account_key_src: "{{ output_dir }}/accountkey2.pem"
new_account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
new_account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
state: changed_key
contact:
@@ -207,7 +212,7 @@
- name: Deactivate account (check mode, diff)
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey2.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
@@ -220,7 +225,7 @@
- name: Deactivate account
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey2.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
@@ -231,7 +236,7 @@
- name: Deactivate account (idempotent)
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey2.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
@@ -242,7 +247,7 @@
- name: Do not try to create account II
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey2.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
account_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
@@ -255,7 +260,7 @@
- name: Do not try to create account III
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -267,7 +272,7 @@
- name: Create account with External Account Binding
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/{{ item.account }}.pem"
account_key_src: "{{ remote_tmp_dir }}/{{ item.account }}.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no

View File

@@ -17,12 +17,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:

View File

@@ -1,2 +1,3 @@
dependencies:
- setup_acme
- setup_remote_tmp_dir

View File

@@ -2,7 +2,7 @@
- block:
- name: Generate account keys
openssl_privatekey:
path: "{{ output_dir }}/{{ item }}.pem"
path: "{{ remote_tmp_dir }}/{{ item }}.pem"
type: ECC
curve: secp256r1
force: true
@@ -10,7 +10,7 @@
- name: Parse account keys (to ease debugging some test failures)
openssl_privatekey_info:
path: "{{ output_dir }}/{{ item }}.pem"
path: "{{ remote_tmp_dir }}/{{ item }}.pem"
return_private_key_data: true
loop: "{{ account_keys }}"
@@ -22,7 +22,7 @@
- name: Check that account does not exist
acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -31,7 +31,7 @@
- name: Create it now
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -44,16 +44,21 @@
- name: Check that account exists
acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
register: account_created
- name: Read account key
slurp:
src: '{{ remote_tmp_dir }}/accountkey.pem'
register: slurp
- name: Clear email address
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_content: "{{ lookup('file', output_dir ~ '/accountkey.pem') }}"
account_key_content: "{{ slurp.content | b64decode }}"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -64,7 +69,7 @@
- name: Check that account was modified
acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -74,7 +79,7 @@
- name: Check with wrong account URI
acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -84,7 +89,7 @@
- name: Check with wrong account key
acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/accountkey2.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey2.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no

View File

@@ -17,12 +17,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:

View File

@@ -1,2 +1,3 @@
dependencies:
- setup_acme
- setup_remote_tmp_dir

View File

@@ -3,7 +3,7 @@
- block:
- name: Generate account keys
openssl_privatekey:
path: "{{ output_dir }}/{{ item.name }}.pem"
path: "{{ remote_tmp_dir }}/{{ item.name }}.pem"
type: "{{ item.type }}"
size: "{{ item.size | default(omit) }}"
curve: "{{ item.curve | default(omit) }}"
@@ -28,15 +28,19 @@
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
account_key_src: "{{ output_dir }}/account-ec256.pem"
account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
state: absent
- name: Read account key (EC384)
slurp:
src: '{{ remote_tmp_dir }}/account-ec384.pem'
register: slurp
- name: Create ECC384 account
acme_account:
select_crypto_backend: "{{ select_crypto_backend }}"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
account_key_content: "{{ lookup('file', output_dir ~ '/account-ec384.pem') }}"
account_key_content: "{{ slurp.content | b64decode }}"
state: present
allow_creation: yes
terms_agreed: yes
@@ -49,7 +53,7 @@
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
account_key_src: "{{ output_dir }}/account-rsa.pem"
account_key_src: "{{ remote_tmp_dir }}/account-rsa.pem"
state: present
allow_creation: yes
terms_agreed: yes
@@ -115,6 +119,10 @@
set_fact:
cert_2_obtain_results: "{{ certificate_obtain_result }}"
cert_2_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}"
- name: Read account key (RSA)
slurp:
src: '{{ remote_tmp_dir }}/account-rsa.pem'
register: slurp_account_key
- name: Obtain cert 3
include_tasks: obtain-cert.yml
vars:
@@ -123,7 +131,7 @@
key_type: ec384
subject_alt_name: "DNS:*.example.com,DNS:example.org,DNS:t1.example.com"
subject_alt_name_critical: no
account_key_content: "{{ lookup('file', output_dir ~ '/account-rsa.pem') }}"
account_key_content: "{{ slurp_account_key.content | b64decode }}"
challenge: dns-01
modify_account: no
deactivate_authzs: no
@@ -231,6 +239,10 @@
set_fact:
cert_5_recreate_2: "{{ challenge_data is changed }}"
cert_5c_obtain_results: "{{ certificate_obtain_result }}"
- name: Read account key (EC384)
slurp:
src: '{{ remote_tmp_dir }}/account-ec384.pem'
register: slurp_account_key
- name: Obtain cert 5 (should again by force)
include_tasks: obtain-cert.yml
vars:
@@ -239,7 +251,7 @@
key_type: ec521
subject_alt_name: "DNS:t2.example.com"
subject_alt_name_critical: no
account_key_content: "{{ lookup('file', output_dir ~ '/account-ec384.pem') }}"
account_key_content: "{{ slurp_account_key.content | b64decode }}"
challenge: http-01
modify_account: no
deactivate_authzs: yes
@@ -341,100 +353,100 @@
## DISSECT CERTIFICATES #######################################################################
# Make sure certificates are valid. Root certificate for Pebble equals the chain certificate.
- name: Verifying cert 1
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-1-root.pem" -untrusted "{{ output_dir }}/cert-1-chain.pem" "{{ output_dir }}/cert-1.pem"'
command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-1-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-1-chain.pem" "{{ remote_tmp_dir }}/cert-1.pem"'
ignore_errors: yes
register: cert_1_valid
- name: Verifying cert 2
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-2-root.pem" -untrusted "{{ output_dir }}/cert-2-chain.pem" "{{ output_dir }}/cert-2.pem"'
command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-2-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-2-chain.pem" "{{ remote_tmp_dir }}/cert-2.pem"'
ignore_errors: yes
register: cert_2_valid
- name: Verifying cert 3
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-3-root.pem" -untrusted "{{ output_dir }}/cert-3-chain.pem" "{{ output_dir }}/cert-3.pem"'
command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-3-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-3-chain.pem" "{{ remote_tmp_dir }}/cert-3.pem"'
ignore_errors: yes
register: cert_3_valid
- name: Verifying cert 4
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-4-root.pem" -untrusted "{{ output_dir }}/cert-4-chain.pem" "{{ output_dir }}/cert-4.pem"'
command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-4-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-4-chain.pem" "{{ remote_tmp_dir }}/cert-4.pem"'
ignore_errors: yes
register: cert_4_valid
- name: Verifying cert 5
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-5-root.pem" -untrusted "{{ output_dir }}/cert-5-chain.pem" "{{ output_dir }}/cert-5.pem"'
command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-5-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-5-chain.pem" "{{ remote_tmp_dir }}/cert-5.pem"'
ignore_errors: yes
register: cert_5_valid
- name: Verifying cert 6
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-6-root.pem" -untrusted "{{ output_dir }}/cert-6-chain.pem" "{{ output_dir }}/cert-6.pem"'
command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-6-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-6-chain.pem" "{{ remote_tmp_dir }}/cert-6.pem"'
ignore_errors: yes
register: cert_6_valid
- name: Verifying cert 7
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-7-root.pem" -untrusted "{{ output_dir }}/cert-7-chain.pem" "{{ output_dir }}/cert-7.pem"'
command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-7-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-7-chain.pem" "{{ remote_tmp_dir }}/cert-7.pem"'
ignore_errors: yes
register: cert_7_valid
- name: Verifying cert 8
command: '{{ openssl_binary }} verify -CAfile "{{ output_dir }}/cert-8-root.pem" -untrusted "{{ output_dir }}/cert-8-chain.pem" "{{ output_dir }}/cert-8.pem"'
command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-8-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-8-chain.pem" "{{ remote_tmp_dir }}/cert-8.pem"'
ignore_errors: yes
register: cert_8_valid
# Dump certificate info
- name: Dumping cert 1
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-1.pem" -noout -text'
command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-1.pem" -noout -text'
register: cert_1_text
- name: Dumping cert 2
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-2.pem" -noout -text'
command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-2.pem" -noout -text'
register: cert_2_text
- name: Dumping cert 3
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-3.pem" -noout -text'
command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-3.pem" -noout -text'
register: cert_3_text
- name: Dumping cert 4
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-4.pem" -noout -text'
command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-4.pem" -noout -text'
register: cert_4_text
- name: Dumping cert 5
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-5.pem" -noout -text'
command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-5.pem" -noout -text'
register: cert_5_text
- name: Dumping cert 6
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-6.pem" -noout -text'
command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-6.pem" -noout -text'
register: cert_6_text
- name: Dumping cert 7
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-7.pem" -noout -text'
command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-7.pem" -noout -text'
register: cert_7_text
- name: Dumping cert 8
command: '{{ openssl_binary }} x509 -in "{{ output_dir }}/cert-8.pem" -noout -text'
command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-8.pem" -noout -text'
register: cert_8_text
# Dump certificate info
- name: Dumping cert 1
x509_certificate_info:
path: "{{ output_dir }}/cert-1.pem"
path: "{{ remote_tmp_dir }}/cert-1.pem"
register: cert_1_info
- name: Dumping cert 2
x509_certificate_info:
path: "{{ output_dir }}/cert-2.pem"
path: "{{ remote_tmp_dir }}/cert-2.pem"
register: cert_2_info
- name: Dumping cert 3
x509_certificate_info:
path: "{{ output_dir }}/cert-3.pem"
path: "{{ remote_tmp_dir }}/cert-3.pem"
register: cert_3_info
- name: Dumping cert 4
x509_certificate_info:
path: "{{ output_dir }}/cert-4.pem"
path: "{{ remote_tmp_dir }}/cert-4.pem"
register: cert_4_info
- name: Dumping cert 5
x509_certificate_info:
path: "{{ output_dir }}/cert-5.pem"
path: "{{ remote_tmp_dir }}/cert-5.pem"
register: cert_5_info
- name: Dumping cert 6
x509_certificate_info:
path: "{{ output_dir }}/cert-6.pem"
path: "{{ remote_tmp_dir }}/cert-6.pem"
register: cert_6_info
- name: Dumping cert 7
x509_certificate_info:
path: "{{ output_dir }}/cert-7.pem"
path: "{{ remote_tmp_dir }}/cert-7.pem"
register: cert_7_info
- name: Dumping cert 8
x509_certificate_info:
path: "{{ output_dir }}/cert-8.pem"
path: "{{ remote_tmp_dir }}/cert-8.pem"
register: cert_8_info
## GET ACCOUNT ORDERS #########################################################################
- name: Don't retrieve orders
acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec256.pem"
account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -443,7 +455,7 @@
- name: Retrieve orders as URL list (1/2)
acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec256.pem"
account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -452,7 +464,7 @@
- name: Retrieve orders as URL list (2/2)
acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec384.pem"
account_key_src: "{{ remote_tmp_dir }}/account-ec384.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -461,7 +473,7 @@
- name: Retrieve orders as object list (1/2)
acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec256.pem"
account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -470,7 +482,7 @@
- name: Retrieve orders as object list (2/2)
acme_account_info:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec384.pem"
account_key_src: "{{ remote_tmp_dir }}/account-ec384.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no

View File

@@ -8,38 +8,48 @@
- name: Obtain root and intermediate certificates
get_url:
url: "http://{{ acme_host }}:5000/{{ item.0 }}-certificate-for-ca/{{ item.1 }}"
dest: "{{ output_dir }}/acme-{{ item.0 }}-{{ item.1 }}.pem"
dest: "{{ remote_tmp_dir }}/acme-{{ item.0 }}-{{ item.1 }}.pem"
loop: "{{ query('nested', types, root_numbers) }}"
- name: Analyze root certificates
x509_certificate_info:
path: "{{ output_dir }}/acme-root-{{ item }}.pem"
path: "{{ remote_tmp_dir }}/acme-root-{{ item }}.pem"
loop: "{{ root_numbers }}"
register: acme_roots
- name: Analyze intermediate certificates
x509_certificate_info:
path: "{{ output_dir }}/acme-intermediate-{{ item }}.pem"
path: "{{ remote_tmp_dir }}/acme-intermediate-{{ item }}.pem"
loop: "{{ root_numbers }}"
register: acme_intermediates
- set_fact:
x__: "{{ item | dict2items | selectattr('key', 'in', interesting_keys) | list | items2dict }}"
y__: "{{ lookup('file', output_dir ~ '/acme-root-' ~ item.item ~ '.pem', rstrip=False) }}"
loop: "{{ acme_roots.results }}"
register: acme_roots_tmp
- name: Read root certificates
slurp:
src: "{{ remote_tmp_dir ~ '/acme-root-' ~ item ~ '.pem' }}"
loop: "{{ root_numbers }}"
register: slurp_roots
- set_fact:
x__: "{{ item | dict2items | selectattr('key', 'in', interesting_keys) | list | items2dict }}"
loop: "{{ acme_roots.results }}"
register: acme_roots_tmp
- name: Read intermediate certificates
slurp:
src: "{{ remote_tmp_dir ~ '/acme-intermediate-' ~ item ~ '.pem' }}"
loop: "{{ root_numbers }}"
register: slurp_intermediates
- set_fact:
x__: "{{ item | dict2items | selectattr('key', 'in', interesting_keys) | list | items2dict }}"
y__: "{{ lookup('file', output_dir ~ '/acme-intermediate-' ~ item.item ~ '.pem', rstrip=False) }}"
loop: "{{ acme_intermediates.results }}"
register: acme_intermediates_tmp
- set_fact:
acme_roots: "{{ acme_roots_tmp.results | map(attribute='ansible_facts.x__') | list }}"
acme_root_certs: "{{ acme_roots_tmp.results | map(attribute='ansible_facts.y__') | list }}"
acme_root_certs: "{{ slurp_roots.results | map(attribute='content') | map('b64decode') | list }}"
acme_intermediates: "{{ acme_intermediates_tmp.results | map(attribute='ansible_facts.x__') | list }}"
acme_intermediate_certs: "{{ acme_intermediates_tmp.results | map(attribute='ansible_facts.y__') | list }}"
acme_intermediate_certs: "{{ slurp_intermediates.results | map(attribute='content') | map('b64decode') | list }}"
vars:
types:
@@ -88,12 +98,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:

View File

@@ -7,6 +7,14 @@
assert:
that:
- "'DNS:example.com' in cert_1_text.stdout"
- name: Read certificate 1 files
slurp:
src: '{{ remote_tmp_dir }}/{{ item }}'
loop:
- cert-1.pem
- cert-1-chain.pem
- cert-1-fullchain.pem
register: slurp
- name: Check that certificate 1 retrieval got all chains
assert:
that:
@@ -15,9 +23,9 @@
- "'cert' in cert_1_obtain_results.all_chains[cert_1_alternate | int]"
- "'chain' in cert_1_obtain_results.all_chains[cert_1_alternate | int]"
- "'full_chain' in cert_1_obtain_results.all_chains[cert_1_alternate | int]"
- "lookup('file', output_dir ~ '/cert-1.pem', rstrip=False) == cert_1_obtain_results.all_chains[cert_1_alternate | int].cert"
- "lookup('file', output_dir ~ '/cert-1-chain.pem', rstrip=False) == cert_1_obtain_results.all_chains[cert_1_alternate | int].chain"
- "lookup('file', output_dir ~ '/cert-1-fullchain.pem', rstrip=False) == cert_1_obtain_results.all_chains[cert_1_alternate | int].full_chain"
- "(slurp.results[0].content | b64decode) == cert_1_obtain_results.all_chains[cert_1_alternate | int].cert"
- "(slurp.results[1].content | b64decode) == cert_1_obtain_results.all_chains[cert_1_alternate | int].chain"
- "(slurp.results[2].content | b64decode) == cert_1_obtain_results.all_chains[cert_1_alternate | int].full_chain"
- name: Check that certificate 2 is valid
assert:
@@ -28,6 +36,14 @@
that:
- "'DNS:*.example.com' in cert_2_text.stdout"
- "'DNS:example.com' in cert_2_text.stdout"
- name: Read certificate 2 files
slurp:
src: '{{ remote_tmp_dir }}/{{ item }}'
loop:
- cert-2.pem
- cert-2-chain.pem
- cert-2-fullchain.pem
register: slurp
- name: Check that certificate 1 retrieval got all chains
assert:
that:
@@ -36,9 +52,9 @@
- "'cert' in cert_2_obtain_results.all_chains[cert_2_alternate | int]"
- "'chain' in cert_2_obtain_results.all_chains[cert_2_alternate | int]"
- "'full_chain' in cert_2_obtain_results.all_chains[cert_2_alternate | int]"
- "lookup('file', output_dir ~ '/cert-2.pem', rstrip=False) == cert_2_obtain_results.all_chains[cert_2_alternate | int].cert"
- "lookup('file', output_dir ~ '/cert-2-chain.pem', rstrip=False) == cert_2_obtain_results.all_chains[cert_2_alternate | int].chain"
- "lookup('file', output_dir ~ '/cert-2-fullchain.pem', rstrip=False) == cert_2_obtain_results.all_chains[cert_2_alternate | int].full_chain"
- "(slurp.results[0].content | b64decode) == cert_2_obtain_results.all_chains[cert_2_alternate | int].cert"
- "(slurp.results[1].content | b64decode) == cert_2_obtain_results.all_chains[cert_2_alternate | int].chain"
- "(slurp.results[2].content | b64decode) == cert_2_obtain_results.all_chains[cert_2_alternate | int].full_chain"
- name: Check that certificate 3 is valid
assert:
@@ -50,6 +66,14 @@
- "'DNS:*.example.com' in cert_3_text.stdout"
- "'DNS:example.org' in cert_3_text.stdout"
- "'DNS:t1.example.com' in cert_3_text.stdout"
- name: Read certificate 3 files
slurp:
src: '{{ remote_tmp_dir }}/{{ item }}'
loop:
- cert-3.pem
- cert-3-chain.pem
- cert-3-fullchain.pem
register: slurp
- name: Check that certificate 1 retrieval got all chains
assert:
that:
@@ -58,9 +82,9 @@
- "'cert' in cert_3_obtain_results.all_chains[cert_3_alternate | int]"
- "'chain' in cert_3_obtain_results.all_chains[cert_3_alternate | int]"
- "'full_chain' in cert_3_obtain_results.all_chains[cert_3_alternate | int]"
- "lookup('file', output_dir ~ '/cert-3.pem', rstrip=False) == cert_3_obtain_results.all_chains[cert_3_alternate | int].cert"
- "lookup('file', output_dir ~ '/cert-3-chain.pem', rstrip=False) == cert_3_obtain_results.all_chains[cert_3_alternate | int].chain"
- "lookup('file', output_dir ~ '/cert-3-fullchain.pem', rstrip=False) == cert_3_obtain_results.all_chains[cert_3_alternate | int].full_chain"
- "(slurp.results[0].content | b64decode) == cert_3_obtain_results.all_chains[cert_3_alternate | int].cert"
- "(slurp.results[1].content | b64decode) == cert_3_obtain_results.all_chains[cert_3_alternate | int].chain"
- "(slurp.results[2].content | b64decode) == cert_3_obtain_results.all_chains[cert_3_alternate | int].full_chain"
- name: Check that certificate 4 is valid
assert:

View File

@@ -1,2 +1,3 @@
dependencies:
- setup_acme
- setup_remote_tmp_dir

View File

@@ -3,7 +3,7 @@
- block:
- name: Generate account keys
openssl_privatekey:
path: "{{ output_dir }}/{{ item.name }}.pem"
path: "{{ remote_tmp_dir }}/{{ item.name }}.pem"
type: "{{ item.type }}"
size: "{{ item.size | default(omit) }}"
curve: "{{ item.curve | default(omit) }}"
@@ -22,6 +22,10 @@
type: RSA
size: "{{ default_rsa_key_size }}"
## CREATE ACCOUNTS AND OBTAIN CERTIFICATES ####################################################
- name: Read account key (EC256)
slurp:
src: '{{ remote_tmp_dir }}/account-ec256.pem'
register: slurp_account_key
- name: Obtain cert 1
include_tasks: obtain-cert.yml
vars:
@@ -31,7 +35,7 @@
rsa_bits: "{{ default_rsa_key_size }}"
subject_alt_name: "DNS:example.com"
subject_alt_name_critical: no
account_key_content: "{{ lookup('file', output_dir ~ '/account-ec256.pem') }}"
account_key_content: "{{ slurp_account_key.content | b64decode }}"
challenge: http-01
modify_account: yes
deactivate_authzs: no
@@ -76,8 +80,8 @@
- name: Revoke certificate 1 via account key
acme_certificate_revoke:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_src: "{{ output_dir }}/account-ec256.pem"
certificate: "{{ output_dir }}/cert-1.pem"
account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
certificate: "{{ remote_tmp_dir }}/cert-1.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
@@ -86,19 +90,23 @@
- name: Revoke certificate 2 via certificate private key
acme_certificate_revoke:
select_crypto_backend: "{{ select_crypto_backend }}"
private_key_src: "{{ output_dir }}/cert-2.key"
private_key_src: "{{ remote_tmp_dir }}/cert-2.key"
private_key_passphrase: "{{ 'hunter2' if select_crypto_backend != 'openssl' else omit }}"
certificate: "{{ output_dir }}/cert-2.pem"
certificate: "{{ remote_tmp_dir }}/cert-2.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
ignore_errors: yes
register: cert_2_revoke
- name: Read account key (RSA)
slurp:
src: '{{ remote_tmp_dir }}/account-rsa.pem'
register: slurp_account_key
- name: Revoke certificate 3 via account key (fullchain)
acme_certificate_revoke:
select_crypto_backend: "{{ select_crypto_backend }}"
account_key_content: "{{ lookup('file', output_dir ~ '/account-rsa.pem') }}"
certificate: "{{ output_dir }}/cert-3-fullchain.pem"
account_key_content: "{{ slurp_account_key.content | b64decode }}"
certificate: "{{ remote_tmp_dir }}/cert-3-fullchain.pem"
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no

View File

@@ -17,12 +17,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:

View File

@@ -1,2 +1,3 @@
dependencies:
- setup_acme
- setup_remote_tmp_dir

View File

@@ -7,7 +7,7 @@
- block:
- name: Generate ECC256 accoun keys
openssl_privatekey:
path: "{{ output_dir }}/account-ec256.pem"
path: "{{ remote_tmp_dir }}/account-ec256.pem"
type: ECC
curve: secp256r1
force: true

View File

@@ -1,2 +1,3 @@
dependencies:
- setup_acme
- setup_remote_tmp_dir

View File

@@ -2,7 +2,7 @@
- block:
- name: Generate account keys
openssl_privatekey:
path: "{{ output_dir }}/{{ item }}.pem"
path: "{{ remote_tmp_dir }}/{{ item }}.pem"
type: ECC
curve: secp256r1
force: true
@@ -10,7 +10,7 @@
- name: Parse account keys (to ease debugging some test failures)
openssl_privatekey_info:
path: "{{ output_dir }}/{{ item }}.pem"
path: "{{ remote_tmp_dir }}/{{ item }}.pem"
return_private_key_data: true
loop: "{{ account_keys }}"
@@ -32,7 +32,7 @@
acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2
validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
url: "{{ directory.directory.newAccount}}"
method: post
content: '{"termsOfServiceAgreed":true}'
@@ -46,7 +46,7 @@
acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2
validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}"
url: "{{ account_creation.headers.location }}"
method: get
@@ -58,7 +58,7 @@
acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2
validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}"
url: "{{ account_creation.headers.location }}"
method: post
@@ -77,7 +77,7 @@
acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2
validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}"
url: "{{ directory.directory.newOrder }}"
method: post
@@ -100,7 +100,7 @@
acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2
validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}"
url: "{{ new_order.headers.location }}"
method: get
@@ -112,7 +112,7 @@
acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2
validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}"
url: "{{ item }}"
method: get
@@ -125,7 +125,7 @@
acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2
validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}"
url: "{{ (item.challenges | selectattr('type', 'equalto', 'http-01') | list)[0].url }}"
method: get
@@ -138,7 +138,7 @@
acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2
validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}"
url: "{{ item.url }}"
method: post
@@ -152,7 +152,7 @@
acme_directory: https://{{ acme_host }}:14000/dir
acme_version: 2
validate_certs: no
account_key_src: "{{ output_dir }}/accountkey.pem"
account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
account_uri: "{{ account_creation.headers.location }}"
url: "{{ item.url }}"
method: get

View File

@@ -17,12 +17,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:

View File

@@ -1,2 +1,3 @@
dependencies:
- setup_openssl
- setup_remote_tmp_dir

View File

@@ -3,9 +3,6 @@
# and should not be used as examples of how to write Ansible roles #
####################################################################
- name: register cryptography version
command: '{{ ansible_python.executable }} -c ''import cryptography; print(cryptography.__version__)'''
register: cryptography_version
- block:
- name: Make sure testhost directory exists
file:
@@ -16,10 +13,9 @@
copy:
src: '{{ role_path }}/files/'
dest: '{{ remote_tmp_dir }}/files/'
remote_src: yes
- name: Find root for cert 1
certificate_complete_chain:
input_chain: '{{ lookup(''file'', ''cert1-fullchain.pem'', rstrip=False) }}'
input_chain: '{{ lookup("file", "cert1-fullchain.pem", rstrip=False) }}'
root_certificates:
- '{{ remote_tmp_dir }}/files/roots/'
register: cert1_root
@@ -30,7 +26,7 @@
- cert1_root.root == lookup('file', 'cert1-root.pem', rstrip=False)
- name: Find rootchain for cert 1
certificate_complete_chain:
input_chain: '{{ lookup(''file'', ''cert1.pem'', rstrip=False) }}'
input_chain: '{{ lookup("file", "cert1.pem", rstrip=False) }}'
intermediate_certificates:
- '{{ remote_tmp_dir }}/files/cert1-chain.pem'
root_certificates:
@@ -44,7 +40,7 @@
- cert1_rootchain.root == lookup('file', 'cert1-root.pem', rstrip=False)
- name: Find root for cert 2
certificate_complete_chain:
input_chain: '{{ lookup(''file'', ''cert2-fullchain.pem'', rstrip=False) }}'
input_chain: '{{ lookup("file", "cert2-fullchain.pem", rstrip=False) }}'
root_certificates:
- '{{ remote_tmp_dir }}/files/roots/'
register: cert2_root
@@ -55,7 +51,7 @@
- cert2_root.root == lookup('file', 'cert2-root.pem', rstrip=False)
- name: Find rootchain for cert 2
certificate_complete_chain:
input_chain: '{{ lookup(''file'', ''cert2.pem'', rstrip=False) }}'
input_chain: '{{ lookup("file", "cert2.pem", rstrip=False) }}'
intermediate_certificates:
- '{{ remote_tmp_dir }}/files/cert2-chain.pem'
root_certificates:
@@ -69,7 +65,7 @@
- cert2_rootchain.root == lookup('file', 'cert2-root.pem', rstrip=False)
- name: Find alternate rootchain for cert 2
certificate_complete_chain:
input_chain: '{{ lookup(''file'', ''cert2.pem'', rstrip=True) }}'
input_chain: '{{ lookup("file", "cert2.pem", rstrip=True) }}'
intermediate_certificates:
- '{{ remote_tmp_dir }}/files/cert2-altchain.pem'
root_certificates:

View File

@@ -23,16 +23,6 @@
when: pyopenssl_version.stdout is version('0.15', '>=')
- name: Remove output directory
file:
path: "{{ output_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
state: directory
- block:
- include_tasks: ../tests/validate.yml

View File

@@ -97,14 +97,19 @@
# We got the correct response from the module
- "'ca_cert file does not exist' == result.msg"
- name: Get a temp directory
tempfile:
state: directory
register: my_temp_dir
- name: Download CA Cert as pem from server
get_url:
url: "http://ansible.http.tests/cacert.pem"
dest: "{{ output_dir }}/temp.pem"
dest: "{{ my_temp_dir.path }}/temp.pem"
- name: Get servers certificate comparing it to its own ca_cert file
get_certificate:
ca_cert: '{{ output_dir }}/temp.pem'
ca_cert: '{{ my_temp_dir.path }}/temp.pem'
host: "{{ httpbin_host }}"
port: 443
select_crypto_backend: "{{ select_crypto_backend }}"
@@ -115,11 +120,6 @@
- result is not changed
- result is not failed
- name: Get a temp directory
tempfile:
state: directory
register: my_temp_dir
- name: Deploy the bogus_ca.pem file
copy:
src: "bogus_ca.pem"

View File

@@ -0,0 +1,2 @@
dependencies:
- setup_remote_tmp_dir

View File

@@ -4,18 +4,25 @@
# and should not be used as examples of how to write Ansible roles #
####################################################################
- name: Copy keyfiles
copy:
src: '{{ item }}'
dest: '{{ remote_tmp_dir }}/{{ item }}'
loop:
- keyfile1
- keyfile2
- name: Make sure cryptsetup is installed
package:
name: cryptsetup
state: present
become: yes
- name: Create cryptfile
command: dd if=/dev/zero of={{ output_dir.replace('~', ansible_env.HOME) }}/cryptfile bs=1M count=32
command: dd if=/dev/zero of={{ remote_tmp_dir.replace('~', ansible_env.HOME) }}/cryptfile bs=1M count=32
- name: Create lookback device
command: losetup -f {{ output_dir.replace('~', ansible_env.HOME) }}/cryptfile
command: losetup -f {{ remote_tmp_dir.replace('~', ansible_env.HOME) }}/cryptfile
become: yes
- name: Determine loop device name
command: losetup -j {{ output_dir.replace('~', ansible_env.HOME) }}/cryptfile --output name
command: losetup -j {{ remote_tmp_dir.replace('~', ansible_env.HOME) }}/cryptfile --output name
become: yes
register: cryptfile_device_output
- set_fact:
@@ -37,5 +44,5 @@
- command: losetup -d "{{ cryptfile_device }}"
become: yes
- file:
dest: "{{ output_dir }}/cryptfile"
dest: "{{ remote_tmp_dir }}/cryptfile"
state: absent

View File

@@ -3,7 +3,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
check_mode: yes
@@ -13,7 +13,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
become: yes
@@ -22,7 +22,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
become: yes
@@ -31,7 +31,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
check_mode: yes
@@ -48,7 +48,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
check_mode: yes
become: yes
register: open_check
@@ -56,21 +56,21 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes
register: open
- name: Open (idempotent)
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes
register: open_idem
- name: Open (idempotent, check)
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
check_mode: yes
become: yes
register: open_idem_check
@@ -118,7 +118,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes
- name: Closed (via device, check)
@@ -158,7 +158,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes
- name: Absent (check)

View File

@@ -3,7 +3,7 @@
luks_device:
device: /dev/asdfasdfasdf
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
check_mode: yes
@@ -14,7 +14,7 @@
luks_device:
device: /dev/asdfasdfasdf
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
ignore_errors: yes
@@ -31,7 +31,7 @@
luks_device:
device: /tmp/
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
check_mode: yes
@@ -42,7 +42,7 @@
luks_device:
device: /tmp/
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
ignore_errors: yes

View File

@@ -3,7 +3,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: closed
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
become: yes
@@ -14,7 +14,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes
ignore_errors: yes
register: open_try
@@ -31,7 +31,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile2"
keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes
ignore_errors: yes
register: open_try
@@ -43,8 +43,8 @@
luks_device:
device: "{{ cryptfile_device }}"
state: closed
keyfile: "{{ role_path }}/files/keyfile1"
new_keyfile: "{{ role_path }}/files/keyfile2"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
new_keyfile: "{{ remote_tmp_dir }}/keyfile2"
pbkdf:
iteration_time: 0.1
become: yes
@@ -54,8 +54,8 @@
luks_device:
device: "{{ cryptfile_device }}"
state: closed
keyfile: "{{ role_path }}/files/keyfile1"
new_keyfile: "{{ role_path }}/files/keyfile2"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
new_keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes
register: result_2
@@ -70,7 +70,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile2"
keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes
ignore_errors: yes
register: open_try
@@ -91,8 +91,8 @@
luks_device:
device: "{{ cryptfile_device }}"
state: closed
keyfile: "{{ role_path }}/files/keyfile1"
remove_keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
remove_keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes
register: result_1
@@ -100,8 +100,8 @@
luks_device:
device: "{{ cryptfile_device }}"
state: closed
keyfile: "{{ role_path }}/files/keyfile1"
remove_keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
remove_keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes
register: result_2
@@ -116,7 +116,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes
ignore_errors: yes
register: open_try
@@ -128,7 +128,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile2"
keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes
ignore_errors: yes
register: open_try
@@ -149,8 +149,8 @@
luks_device:
device: "{{ cryptfile_device }}"
state: closed
keyfile: "{{ role_path }}/files/keyfile2"
remove_keyfile: "{{ role_path }}/files/keyfile2"
keyfile: "{{ remote_tmp_dir }}/keyfile2"
remove_keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes
ignore_errors: yes
register: remove_last_key
@@ -165,7 +165,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile2"
keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes
ignore_errors: yes
register: open_try
@@ -182,8 +182,8 @@
luks_device:
device: "{{ cryptfile_device }}"
state: closed
keyfile: "{{ role_path }}/files/keyfile2"
remove_keyfile: "{{ role_path }}/files/keyfile2"
keyfile: "{{ remote_tmp_dir }}/keyfile2"
remove_keyfile: "{{ remote_tmp_dir }}/keyfile2"
force_remove_last_key: yes
become: yes
@@ -193,7 +193,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile2"
keyfile: "{{ remote_tmp_dir }}/keyfile2"
become: yes
ignore_errors: yes
register: open_try

View File

@@ -3,7 +3,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
keysize: 256
pbkdf:
iteration_count: 1000
@@ -13,7 +13,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
keysize: 256
pbkdf:
iteration_count: 1000
@@ -23,7 +23,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
keysize: 512
pbkdf:
iteration_count: 1000
@@ -33,7 +33,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: present
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
passphrase: "{{ cryptfile_passphrase1 }}"
pbkdf:
iteration_count: 1000

View File

@@ -54,7 +54,7 @@
state: closed
passphrase: "{{ cryptfile_passphrase1 }}"
new_passphrase: "{{ cryptfile_passphrase2 }}"
new_keyfile: "{{ role_path }}/files/keyfile1"
new_keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
become: yes
@@ -122,7 +122,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes
ignore_errors: yes
register: open_try
@@ -135,7 +135,7 @@
device: "{{ cryptfile_device }}"
state: closed
passphrase: "{{ cryptfile_passphrase1 }}"
new_keyfile: "{{ role_path }}/files/keyfile1"
new_keyfile: "{{ remote_tmp_dir }}/keyfile1"
pbkdf:
iteration_time: 0.1
become: yes
@@ -144,7 +144,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: closed
remove_keyfile: "{{ role_path }}/files/keyfile1"
remove_keyfile: "{{ remote_tmp_dir }}/keyfile1"
remove_passphrase: "{{ cryptfile_passphrase1 }}"
become: yes
ignore_errors: yes
@@ -157,7 +157,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: opened
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
become: yes
ignore_errors: yes
register: open_try
@@ -219,7 +219,7 @@
luks_device:
device: "{{ cryptfile_device }}"
state: closed
keyfile: "{{ role_path }}/files/keyfile1"
keyfile: "{{ remote_tmp_dir }}/keyfile1"
new_passphrase: "{{ cryptfile_passphrase3 }}"
pbkdf:
iteration_time: 0.1

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_ssh_keygen
- setup_ssh_agent
- setup_remote_tmp_dir

View File

@@ -5,9 +5,9 @@
- name: Declare global variables
set_fact:
signing_key: '{{ output_dir }}/id_key'
public_key: '{{ output_dir }}/id_key.pub'
certificate_path: '{{ output_dir }}/id_cert'
signing_key: '{{ remote_tmp_dir }}/id_key'
public_key: '{{ remote_tmp_dir }}/id_key.pub'
certificate_path: '{{ remote_tmp_dir }}/id_cert'
- name: Generate keypair
openssh_keypair:

View File

@@ -4,8 +4,8 @@
####################################################################
- set_fact:
new_signing_key: "{{ output_dir }}/new_key"
new_public_key: "{{ output_dir }}/new_key.pub"
new_signing_key: "{{ remote_tmp_dir }}/new_key"
new_public_key: "{{ remote_tmp_dir }}/new_key.pub"
- name: Generate new test key
openssh_keypair:

View File

@@ -12,7 +12,7 @@
type: user
signing_key: "{{ signing_key }}"
public_key: "{{ public_key }}"
path: '{{ output_dir }}/id_cert_with_agent'
path: '{{ remote_tmp_dir }}/id_cert_with_agent'
use_agent: true
valid_from: always
valid_to: forever
@@ -33,7 +33,7 @@
type: user
signing_key: "{{ signing_key }}"
public_key: "{{ public_key }}"
path: '{{ output_dir }}/id_cert_with_agent'
path: '{{ remote_tmp_dir }}/id_cert_with_agent'
use_agent: true
valid_from: always
valid_to: forever
@@ -44,7 +44,7 @@
type: user
signing_key: "{{ signing_key }}"
public_key: "{{ public_key }}"
path: '{{ output_dir }}/id_cert_with_agent'
path: '{{ remote_tmp_dir }}/id_cert_with_agent'
use_agent: true
valid_from: always
valid_to: forever
@@ -54,7 +54,7 @@
type: user
signing_key: "{{ signing_key }}"
public_key: "{{ public_key }}"
path: '{{ output_dir }}/id_cert_with_agent'
path: '{{ remote_tmp_dir }}/id_cert_with_agent'
use_agent: true
valid_from: always
valid_to: forever
@@ -71,7 +71,7 @@
type: user
signing_key: "{{ signing_key }}"
public_key: "{{ public_key }}"
path: '{{ output_dir }}/id_cert_with_agent'
path: '{{ remote_tmp_dir }}/id_cert_with_agent'
use_agent: true
valid_from: always
valid_to: forever
@@ -80,4 +80,4 @@
- name: Remove certificate
openssh_cert:
state: absent
path: '{{ output_dir }}/id_cert_with_agent'
path: '{{ remote_tmp_dir }}/id_cert_with_agent'

View File

@@ -1,4 +1,5 @@
dependencies:
- setup_ssh_keygen
- setup_openssl
- setup_bcrypt
- setup_bcrypt
- setup_remote_tmp_dir

View File

@@ -6,7 +6,7 @@
- name: Backend auto-detection test
openssh_keypair:
path: '{{ output_dir }}/auto_backend_key'
path: '{{ remote_tmp_dir }}/auto_backend_key'
state: "{{ item }}"
loop: ['present', 'absent']

View File

@@ -6,7 +6,7 @@
- name: "({{ backend }}) Generate key (check mode)"
openssh_keypair:
path: "{{ output_dir }}/core"
path: "{{ remote_tmp_dir }}/core"
size: 2048
backend: "{{ backend }}"
register: check_core_output
@@ -14,14 +14,14 @@
- name: "({{ backend }}) Generate key"
openssh_keypair:
path: "{{ output_dir }}/core"
path: "{{ remote_tmp_dir }}/core"
size: 2048
backend: "{{ backend }}"
register: core_output
- name: "({{ backend }}) Generate key (check mode idempotent)"
openssh_keypair:
path: "{{ output_dir }}/core"
path: "{{ remote_tmp_dir }}/core"
size: 2048
backend: "{{ backend }}"
register: idempotency_check_core_output
@@ -29,7 +29,7 @@
- name: "({{ backend }}) Generate key (idempotent)"
openssh_keypair:
path: '{{ output_dir }}/core'
path: '{{ remote_tmp_dir }}/core'
size: 2048
backend: "{{ backend }}"
register: idempotency_core_output
@@ -52,8 +52,8 @@
that:
- core_output['fingerprint'] is string
- core_output['fingerprint'].startswith('SHA256:')
# only distro old enough that it still gives md5 with no prefix
when: not (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6')
# SHA256 was made the default hashing algorithm for fingerprints in OpenSSH 6.8
when: not (backend == 'opensshbin' and openssh_version is version('6.8', '<'))
- name: "({{ backend }}) Assert key returns public_key"
assert:
@@ -74,7 +74,7 @@
- core_output['type'] == 'rsa'
- name: "({{ backend }}) Retrieve key size from 'ssh-keygen'"
shell: "ssh-keygen -lf {{ output_dir }}/core | grep -o -E '^[0-9]+'"
shell: "ssh-keygen -lf {{ remote_tmp_dir }}/core | grep -o -E '^[0-9]+'"
register: core_size_ssh_keygen
- name: "({{ backend }}) Assert key size matches 'ssh-keygen' output"
@@ -82,13 +82,18 @@
that:
- core_size_ssh_keygen.stdout == '2048'
- name: "({{ backend }}) Read core.pub"
slurp:
src: '{{ remote_tmp_dir }}/core.pub'
register: slurp
- name: "({{ backend }}) Assert public key module return equal to the public key content"
assert:
that:
- "core_output.public_key == lookup('file', output_dir ~ '/core.pub').strip('\n')"
- "core_output.public_key == (slurp.content | b64decode).strip('\n ')"
- name: "({{ backend }}) Remove key"
openssh_keypair:
path: '{{ output_dir }}/core'
path: '{{ remote_tmp_dir }}/core'
backend: "{{ backend }}"
state: absent

View File

@@ -1,10 +1,10 @@
---
- name: Generate a password protected key
command: 'ssh-keygen -f {{ output_dir }}/password_protected -N {{ passphrase }}'
command: 'ssh-keygen -f {{ remote_tmp_dir }}/password_protected -N {{ passphrase }}'
- name: Modify the password protected key with passphrase
openssh_keypair:
path: '{{ output_dir }}/password_protected'
path: '{{ remote_tmp_dir }}/password_protected'
size: 1024
passphrase: "{{ passphrase }}"
backend: cryptography
@@ -12,14 +12,14 @@
- name: Check password protected key idempotency
openssh_keypair:
path: '{{ output_dir }}/password_protected'
path: '{{ remote_tmp_dir }}/password_protected'
size: 1024
passphrase: "{{ passphrase }}"
backend: cryptography
register: password_protected_idempotency_output
- name: Ensure that ssh-keygen can read keys generated with passphrase
command: 'ssh-keygen -yf {{ output_dir }}/password_protected -P {{ passphrase }}'
command: 'ssh-keygen -yf {{ remote_tmp_dir }}/password_protected -P {{ passphrase }}'
register: password_protected_ssh_keygen_output
- name: Check that password protected key with passphrase was regenerated
@@ -31,18 +31,18 @@
- name: Remove password protected key
openssh_keypair:
path: '{{ output_dir }}/password_protected'
path: '{{ remote_tmp_dir }}/password_protected'
backend: cryptography
state: absent
- name: Generate an unprotected key
openssh_keypair:
path: '{{ output_dir }}/unprotected'
path: '{{ remote_tmp_dir }}/unprotected'
backend: cryptography
- name: Modify unprotected key with passphrase
openssh_keypair:
path: '{{ output_dir }}/unprotected'
path: '{{ remote_tmp_dir }}/unprotected'
size: 2048
passphrase: "{{ passphrase }}"
backend: cryptography
@@ -51,7 +51,7 @@
- name: Modify unprotected key with passphrase (force)
openssh_keypair:
path: '{{ output_dir }}/unprotected'
path: '{{ remote_tmp_dir }}/unprotected'
size: 2048
passphrase: "{{ passphrase }}"
force: true
@@ -66,16 +66,16 @@
- name: Remove unprotected key
openssh_keypair:
path: '{{ output_dir }}/unprotected'
path: '{{ remote_tmp_dir }}/unprotected'
backend: cryptography
state: absent
- name: Generate PEM encoded key with passphrase
command: 'ssh-keygen -b 4096 -f {{ output_dir }}/pem_encoded -N {{ passphrase }} -m PEM'
command: 'ssh-keygen -b 4096 -f {{ remote_tmp_dir }}/pem_encoded -N {{ passphrase }} -m PEM'
- name: Try to verify a PEM encoded key
openssh_keypair:
path: '{{ output_dir }}/pem_encoded'
path: '{{ remote_tmp_dir }}/pem_encoded'
passphrase: "{{ passphrase }}"
backend: cryptography
register: pem_encoded_output
@@ -87,6 +87,6 @@
- name: Remove PEM encoded key
openssh_keypair:
path: '{{ output_dir }}/pem_encoded'
path: '{{ remote_tmp_dir }}/pem_encoded'
backend: cryptography
state: absent

View File

@@ -10,12 +10,12 @@
content: ''
mode: '0700'
loop:
- "{{ output_dir }}/broken"
- "{{ output_dir }}/broken.pub"
- "{{ remote_tmp_dir }}/broken"
- "{{ remote_tmp_dir }}/broken.pub"
- name: "({{ backend }}) Regenerate key - broken"
openssh_keypair:
path: "{{ output_dir }}/broken"
path: "{{ remote_tmp_dir }}/broken"
backend: "{{ backend }}"
register: broken_output
ignore_errors: true
@@ -28,7 +28,7 @@
- name: "({{ backend }}) Regenerate key with force - broken"
openssh_keypair:
path: "{{ output_dir }}/broken"
path: "{{ remote_tmp_dir }}/broken"
backend: "{{ backend }}"
force: true
register: force_broken_output
@@ -40,24 +40,24 @@
- name: "({{ backend }}) Remove key - broken"
openssh_keypair:
path: "{{ output_dir }}/broken"
path: "{{ remote_tmp_dir }}/broken"
backend: "{{ backend }}"
state: absent
- name: "({{ backend }}) Generate key - write-only"
openssh_keypair:
path: "{{ output_dir }}/write-only"
path: "{{ remote_tmp_dir }}/write-only"
mode: "0200"
backend: "{{ backend }}"
- name: "({{ backend }}) Check private key status - write-only"
stat:
path: '{{ output_dir }}/write-only'
path: '{{ remote_tmp_dir }}/write-only'
register: write_only_private_key
- name: "({{ backend }}) Check public key status - write-only"
stat:
path: '{{ output_dir }}/write-only.pub'
path: '{{ remote_tmp_dir }}/write-only.pub'
register: write_only_public_key
- name: "({{ backend }}) Assert that private and public keys match permissions - write-only"
@@ -68,14 +68,14 @@
- name: "({{ backend }}) Regenerate key with force - write-only"
openssh_keypair:
path: "{{ output_dir }}/write-only"
path: "{{ remote_tmp_dir }}/write-only"
backend: "{{ backend }}"
force: true
register: write_only_output
- name: "({{ backend }}) Check private key status after regeneration - write-only"
stat:
path: '{{ output_dir }}/write-only'
path: '{{ remote_tmp_dir }}/write-only'
register: write_only_private_key_after
- name: "({{ backend }}) Assert key is regenerated - write-only"
@@ -87,26 +87,19 @@
assert:
that:
- write_only_private_key_after.stat.mode == '0200'
when: backend == 'opensshbin'
- name: "({{ backend }}) Assert key permissions are not preserved with 'cryptography'"
assert:
that:
- write_only_private_key_after.stat.mode == '0600'
when: backend == 'cryptography'
- name: "({{ backend }}) Remove key - write-only"
openssh_keypair:
path: "{{ output_dir }}/write-only"
path: "{{ remote_tmp_dir }}/write-only"
backend: "{{ backend }}"
state: absent
- name: "({{ backend }}) Generate key with ssh-keygen - password_protected"
command: "ssh-keygen -f {{ output_dir }}/password_protected -N {{ passphrase }}"
command: "ssh-keygen -f {{ remote_tmp_dir }}/password_protected -N {{ passphrase }}"
- name: "({{ backend }}) Modify key - password_protected"
openssh_keypair:
path: "{{ output_dir }}/password_protected"
path: "{{ remote_tmp_dir }}/password_protected"
size: 2048
backend: "{{ backend }}"
register: password_protected_output
@@ -120,7 +113,7 @@
- name: "({{ backend }}) Modify key with 'force=true' - password_protected"
openssh_keypair:
path: "{{ output_dir }}/password_protected"
path: "{{ remote_tmp_dir }}/password_protected"
size: 2048
backend: "{{ backend }}"
force: true
@@ -133,6 +126,6 @@
- name: "({{ backend }}) Remove key - password_protected"
openssh_keypair:
path: "{{ output_dir }}/password_protected"
path: "{{ remote_tmp_dir }}/password_protected"
backend: "{{ backend }}"
state: absent

View File

@@ -12,13 +12,13 @@
- name: "({{ backend }}) Generate keys with default size - size"
openssh_keypair:
path: "{{ output_dir }}/default_size_{{ item }}"
path: "{{ remote_tmp_dir }}/default_size_{{ item }}"
type: "{{ item }}"
backend: "{{ backend }}"
loop: "{{ key_types }}"
- name: "({{ backend }}) Retrieve key size from 'ssh-keygen' - size"
shell: "ssh-keygen -lf {{ output_dir }}/default_size_{{ item }} | grep -o -E '^[0-9]+'"
shell: "ssh-keygen -lf {{ remote_tmp_dir }}/default_size_{{ item }} | grep -o -E '^[0-9]+'"
loop: "{{ key_types }}"
register: key_size_output
@@ -31,19 +31,19 @@
- name: "({{ backend }}) Remove keys - size"
openssh_keypair:
path: "{{ output_dir }}/default_size_{{ item }}"
path: "{{ remote_tmp_dir }}/default_size_{{ item }}"
state: absent
loop: "{{ key_types }}"
- block:
- name: "({{ backend }}) Generate ed25519 key with default size - size"
openssh_keypair:
path: "{{ output_dir }}/default_size_ed25519"
path: "{{ remote_tmp_dir }}/default_size_ed25519"
type: ed25519
backend: "{{ backend }}"
- name: "({{ backend }}) Retrieve ed25519 key size from 'ssh-keygen' - size"
shell: "ssh-keygen -lf {{ output_dir }}/default_size_ed25519 | grep -o -E '^[0-9]+'"
shell: "ssh-keygen -lf {{ remote_tmp_dir }}/default_size_ed25519 | grep -o -E '^[0-9]+'"
register: ed25519_key_size_output
- name: "({{ backend }}) Assert ed25519 key size matches default size - size"
@@ -53,19 +53,20 @@
- name: "({{ backend }}) Remove ed25519 key - size"
openssh_keypair:
path: "{{ output_dir }}/default_size_ed25519"
path: "{{ remote_tmp_dir }}/default_size_ed25519"
state: absent
when: not (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6')
# Support for ed25519 keys was added in OpenSSH 6.5
when: not (backend == 'opensshbin' and openssh_version is version('6.5', '<'))
- name: "({{ backend }}) Generate key - force"
openssh_keypair:
path: "{{ output_dir }}/force"
path: "{{ remote_tmp_dir }}/force"
type: rsa
backend: "{{ backend }}"
- name: "({{ backend }}) Regenerate key - force"
openssh_keypair:
path: "{{ output_dir }}/force"
path: "{{ remote_tmp_dir }}/force"
type: rsa
force: true
backend: "{{ backend }}"
@@ -78,33 +79,39 @@
- name: "({{ backend }}) Remove key - force"
openssh_keypair:
path: "{{ output_dir }}/force"
path: "{{ remote_tmp_dir }}/force"
state: absent
backend: "{{ backend }}"
- name: "({{ backend }}) Generate key - comment"
openssh_keypair:
path: "{{ output_dir }}/comment"
path: "{{ remote_tmp_dir }}/comment"
comment: "test@comment"
backend: "{{ backend }}"
register: comment_output
- name: "({{ backend }}) Modify comment - comment"
openssh_keypair:
path: "{{ output_dir }}/comment"
path: "{{ remote_tmp_dir }}/comment"
comment: "test_modified@comment"
backend: "{{ backend }}"
register: modified_comment_output
- name: "({{ backend }}) Assert only comment changed - comment"
- name: "({{ backend }}) Assert comment preserved public key - comment"
assert:
that:
- comment_output.public_key == modified_comment_output.public_key
- comment_output.comment == 'test@comment'
- name: "({{ backend }}) Assert comment changed - comment"
assert:
that:
- modified_comment_output.comment == 'test_modified@comment'
# Support for updating comments for key types other than rsa1 was added in OpenSSH 7.2
when: not (backend == 'opensshbin' and openssh_version is version('7.2', '<'))
- name: "({{ backend }}) Remove key - comment"
openssh_keypair:
path: "{{ output_dir }}/comment"
path: "{{ remote_tmp_dir }}/comment"
state: absent
backend: "{{ backend }}"

View File

@@ -10,22 +10,22 @@
path: "{{ item }}"
state: absent
with_fileglob:
- "{{ output_dir }}/regenerate*"
- "{{ remote_tmp_dir }}/regenerate*"
- name: "({{ backend }}) Regenerate - setup simple keys"
openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: rsa
size: 1024
backend: "{{ backend }}"
loop: "{{ regenerate_values }}"
- name: "({{ backend }}) Regenerate - setup password protected keys"
command: 'ssh-keygen -f {{ output_dir }}/regenerate-b-{{ item }} -N {{ passphrase }}'
command: 'ssh-keygen -f {{ remote_tmp_dir }}/regenerate-b-{{ item }} -N {{ passphrase }}'
loop: "{{ regenerate_values }}"
- name: "({{ backend }}) Regenerate - setup broken keys"
copy:
dest: '{{ output_dir }}/regenerate-c-{{ item.0 }}{{ item.1 }}'
dest: '{{ remote_tmp_dir }}/regenerate-c-{{ item.0 }}{{ item.1 }}'
content: 'broken key'
mode: '0700'
with_nested:
@@ -33,12 +33,12 @@
- [ '', '.pub' ]
- name: "({{ backend }}) Regenerate - setup password protected keys for passphrse test"
command: 'ssh-keygen -f {{ output_dir }}/regenerate-d-{{ item }} -N {{ passphrase }}'
command: 'ssh-keygen -f {{ remote_tmp_dir }}/regenerate-d-{{ item }} -N {{ passphrase }}'
loop: "{{ regenerate_values }}"
- name: "({{ backend }}) Regenerate - modify broken keys (check mode)"
openssh_keypair:
path: '{{ output_dir }}/regenerate-c-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-c-{{ item }}'
type: rsa
size: 1024
regenerate: '{{ item }}'
@@ -60,7 +60,7 @@
- name: "({{ backend }}) Regenerate - modify broken keys"
openssh_keypair:
path: '{{ output_dir }}/regenerate-c-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-c-{{ item }}'
type: rsa
size: 1024
regenerate: '{{ item }}'
@@ -81,7 +81,7 @@
- name: "({{ backend }}) Regenerate - modify password protected keys (check mode)"
openssh_keypair:
path: '{{ output_dir }}/regenerate-b-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-b-{{ item }}'
type: rsa
size: 1024
regenerate: '{{ item }}'
@@ -103,7 +103,7 @@
- name: "({{ backend }}) Regenerate - modify password protected keys with passphrase (check mode)"
openssh_keypair:
path: '{{ output_dir }}/regenerate-b-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-b-{{ item }}'
type: rsa
size: 1024
passphrase: "{{ passphrase }}"
@@ -127,7 +127,7 @@
- name: "({{ backend }}) Regenerate - modify password protected keys"
openssh_keypair:
path: '{{ output_dir }}/regenerate-b-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-b-{{ item }}'
type: rsa
size: 1024
regenerate: '{{ item }}'
@@ -148,7 +148,7 @@
- name: "({{ backend }}) Regenerate - modify password protected keys with passphrase"
openssh_keypair:
path: '{{ output_dir }}/regenerate-d-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-d-{{ item }}'
type: rsa
size: 1024
passphrase: "{{ passphrase }}"
@@ -171,7 +171,7 @@
- name: "({{ backend }}) Regenerate - not modify regular keys (check mode)"
openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: rsa
size: 1024
regenerate: '{{ item }}'
@@ -189,7 +189,7 @@
- name: "({{ backend }}) Regenerate - not modify regular keys"
openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: rsa
size: 1024
regenerate: '{{ item }}'
@@ -206,7 +206,7 @@
- name: "({{ backend }}) Regenerate - adjust key size (check mode)"
openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: rsa
size: 1048
regenerate: '{{ item }}'
@@ -226,7 +226,7 @@
- name: "({{ backend }}) Regenerate - adjust key size"
openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: rsa
size: 1048
regenerate: '{{ item }}'
@@ -245,8 +245,8 @@
- name: "({{ backend }}) Regenerate - redistribute keys"
copy:
src: '{{ output_dir }}/regenerate-a-always{{ item.1 }}'
dest: '{{ output_dir }}/regenerate-a-{{ item.0 }}{{ item.1 }}'
src: '{{ remote_tmp_dir }}/regenerate-a-always{{ item.1 }}'
dest: '{{ remote_tmp_dir }}/regenerate-a-{{ item.0 }}{{ item.1 }}'
remote_src: true
with_nested:
- "{{ regenerate_values }}"
@@ -255,7 +255,7 @@
- name: "({{ backend }}) Regenerate - adjust key type (check mode)"
openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: dsa
size: 1024
regenerate: '{{ item }}'
@@ -275,7 +275,7 @@
- name: "({{ backend }}) Regenerate - adjust key type"
openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: dsa
size: 1024
regenerate: '{{ item }}'
@@ -294,8 +294,8 @@
- name: "({{ backend }}) Regenerate - redistribute keys"
copy:
src: '{{ output_dir }}/regenerate-a-always{{ item.1 }}'
dest: '{{ output_dir }}/regenerate-a-{{ item.0 }}{{ item.1 }}'
src: '{{ remote_tmp_dir }}/regenerate-a-always{{ item.1 }}'
dest: '{{ remote_tmp_dir }}/regenerate-a-{{ item.0 }}{{ item.1 }}'
remote_src: true
with_nested:
- "{{ regenerate_values }}"
@@ -304,7 +304,7 @@
- name: "({{ backend }}) Regenerate - adjust comment (check mode)"
openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: dsa
size: 1024
comment: test comment
@@ -320,7 +320,7 @@
- name: "({{ backend }}) Regenerate - adjust comment"
openssh_keypair:
path: '{{ output_dir }}/regenerate-a-{{ item }}'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}'
type: dsa
size: 1024
comment: test comment

View File

@@ -6,36 +6,36 @@
- name: "({{ backend }}) Generate key"
openssh_keypair:
path: '{{ output_dir }}/removed'
path: '{{ remote_tmp_dir }}/removed'
backend: "{{ backend }}"
state: present
- name: "({{ backend }}) Generate key (idempotency)"
openssh_keypair:
path: '{{ output_dir }}/removed'
path: '{{ remote_tmp_dir }}/removed'
backend: "{{ backend }}"
state: present
- name: "({{ backend }}) Remove key"
openssh_keypair:
state: absent
path: '{{ output_dir }}/removed'
path: '{{ remote_tmp_dir }}/removed'
backend: "{{ backend }}"
- name: "({{ backend }}) Remove key (idempotency)"
openssh_keypair:
state: absent
path: '{{ output_dir }}/removed'
path: '{{ remote_tmp_dir }}/removed'
backend: "{{ backend }}"
- name: "({{ backend }}) Check private key status"
stat:
path: '{{ output_dir }}/removed'
path: '{{ remote_tmp_dir }}/removed'
register: removed_private_key
- name: "({{ backend }}) Check public key status"
stat:
path: '{{ output_dir }}/removed.pub'
path: '{{ remote_tmp_dir }}/removed.pub'
register: removed_public_key
- name: "({{ backend }}) Assert key pair files are removed"

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -1,13 +1,13 @@
---
- name: "({{ select_crypto_backend }}) Generate privatekey"
openssl_privatekey:
path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/privatekey.pem'
size: '{{ default_rsa_key_size }}'
- name: "({{ select_crypto_backend }}) Generate CSR (check mode)"
openssl_csr:
path: '{{ output_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -17,8 +17,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR"
openssl_csr:
path: '{{ output_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -27,8 +27,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent)"
openssl_csr:
path: '{{ output_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -37,8 +37,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent, check mode)"
openssl_csr:
path: '{{ output_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -48,8 +48,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR without SAN (check mode)"
openssl_csr:
path: '{{ output_dir }}/csr-nosan.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr-nosan.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
useCommonNameForSAN: no
@@ -59,8 +59,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR without SAN"
openssl_csr:
path: '{{ output_dir }}/csr-nosan.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr-nosan.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
useCommonNameForSAN: no
@@ -69,8 +69,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR without SAN (idempotent)"
openssl_csr:
path: '{{ output_dir }}/csr-nosan.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr-nosan.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
useCommonNameForSAN: no
@@ -79,8 +79,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR without SAN (idempotent, check mode)"
openssl_csr:
path: '{{ output_dir }}/csr-nosan.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr-nosan.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
useCommonNameForSAN: no
@@ -94,8 +94,8 @@
# and vice-versa for biometricInfo
- name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU"
openssl_csr:
path: '{{ output_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
CN: www.ansible.com
keyUsage:
@@ -110,8 +110,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU (test idempotency)"
openssl_csr:
path: '{{ output_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: 'www.ansible.com'
keyUsage:
@@ -127,8 +127,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU (test XKU change)"
openssl_csr:
path: '{{ output_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: 'www.ansible.com'
keyUsage:
@@ -143,8 +143,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with KU and XKU (test KU change)"
openssl_csr:
path: '{{ output_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: 'www.ansible.com'
keyUsage:
@@ -158,15 +158,15 @@
- name: "({{ select_crypto_backend }}) Generate CSR with old API"
openssl_csr:
path: '{{ output_dir }}/csr_oldapi.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_oldapi.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate CSR with invalid SAN (1/2)"
openssl_csr:
path: '{{ output_dir }}/csrinvsan.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csrinvsan.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject_alt_name: invalid-san.example.com
select_crypto_backend: '{{ select_crypto_backend }}'
register: generate_csr_invalid_san
@@ -174,8 +174,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with invalid SAN (2/2)"
openssl_csr:
path: '{{ output_dir }}/csrinvsan2.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csrinvsan2.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject_alt_name: "DNS:system:kube-controller-manager"
select_crypto_backend: '{{ select_crypto_backend }}'
register: generate_csr_invalid_san_2
@@ -183,16 +183,16 @@
- name: "({{ select_crypto_backend }}) Generate CSR with OCSP Must Staple"
openssl_csr:
path: '{{ output_dir }}/csr_ocsp.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ocsp.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject_alt_name: "DNS:www.ansible.com"
ocsp_must_staple: true
select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate CSR with OCSP Must Staple (test idempotency)"
openssl_csr:
path: '{{ output_dir }}/csr_ocsp.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ocsp.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject_alt_name: "DNS:www.ansible.com"
ocsp_must_staple: true
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -200,22 +200,22 @@
- name: "({{ select_crypto_backend }}) Generate ECC privatekey"
openssl_privatekey:
path: '{{ output_dir }}/privatekey2.pem'
path: '{{ remote_tmp_dir }}/privatekey2.pem'
type: ECC
curve: secp384r1
- name: "({{ select_crypto_backend }}) Generate CSR with ECC privatekey"
openssl_csr:
path: '{{ output_dir }}/csr2.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem'
path: '{{ remote_tmp_dir }}/csr2.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate CSR with text common name"
openssl_csr:
path: '{{ output_dir }}/csr3.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem'
path: '{{ remote_tmp_dir }}/csr3.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
subject:
commonName: This is for Ansible
useCommonNameForSAN: no
@@ -223,24 +223,24 @@
- name: "({{ select_crypto_backend }}) Generate CSR with country name"
openssl_csr:
path: '{{ output_dir }}/csr4.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem'
path: '{{ remote_tmp_dir }}/csr4.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
country_name: de
select_crypto_backend: '{{ select_crypto_backend }}'
register: country_idempotent_1
- name: "({{ select_crypto_backend }}) Generate CSR with country name (idempotent)"
openssl_csr:
path: '{{ output_dir }}/csr4.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem'
path: '{{ remote_tmp_dir }}/csr4.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
country_name: de
select_crypto_backend: '{{ select_crypto_backend }}'
register: country_idempotent_2
- name: "({{ select_crypto_backend }}) Generate CSR with country name (idempotent 2)"
openssl_csr:
path: '{{ output_dir }}/csr4.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem'
path: '{{ remote_tmp_dir }}/csr4.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
subject:
C: de
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -248,8 +248,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with country name (bad country name)"
openssl_csr:
path: '{{ output_dir }}/csr4.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem'
path: '{{ remote_tmp_dir }}/csr4.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
subject:
C: dex
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -258,7 +258,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey with password"
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: auto
select_crypto_backend: cryptography
@@ -266,16 +266,16 @@
- name: "({{ select_crypto_backend }}) Generate CSR with privatekey passphrase"
openssl_csr:
path: '{{ output_dir }}/csr_pw.csr'
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/csr_pw.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: hunter2
select_crypto_backend: '{{ select_crypto_backend }}'
register: passphrase_1
- name: "({{ select_crypto_backend }}) Generate CSR (failed passphrase 1)"
openssl_csr:
path: '{{ output_dir }}/csr_pw1.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_pw1.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
privatekey_passphrase: hunter2
select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes
@@ -283,8 +283,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR (failed passphrase 2)"
openssl_csr:
path: '{{ output_dir }}/csr_pw2.csr'
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/csr_pw2.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: wrong_password
select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes
@@ -292,20 +292,20 @@
- name: "({{ select_crypto_backend }}) Generate CSR (failed passphrase 3)"
openssl_csr:
path: '{{ output_dir }}/csr_pw3.csr'
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/csr_pw3.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes
register: passphrase_error_3
- name: "({{ select_crypto_backend }}) Create broken CSR"
copy:
dest: "{{ output_dir }}/csrbroken.csr"
dest: "{{ remote_tmp_dir }}/csrbroken.csr"
content: "broken"
- name: "({{ select_crypto_backend }}) Regenerate broken CSR"
openssl_csr:
path: '{{ output_dir }}/csrbroken.csr'
privatekey_path: '{{ output_dir }}/privatekey2.pem'
path: '{{ remote_tmp_dir }}/csrbroken.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey2.pem'
subject:
commonName: This is for Ansible
useCommonNameForSAN: no
@@ -314,8 +314,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR"
openssl_csr:
path: '{{ output_dir }}/csr_backup.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_backup.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
backup: yes
@@ -323,8 +323,8 @@
register: csr_backup_1
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent)"
openssl_csr:
path: '{{ output_dir }}/csr_backup.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_backup.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
backup: yes
@@ -332,8 +332,8 @@
register: csr_backup_2
- name: "({{ select_crypto_backend }}) Generate CSR (change)"
openssl_csr:
path: '{{ output_dir }}/csr_backup.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_backup.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: ansible.com
backup: yes
@@ -341,7 +341,7 @@
register: csr_backup_3
- name: "({{ select_crypto_backend }}) Generate CSR (remove)"
openssl_csr:
path: '{{ output_dir }}/csr_backup.csr'
path: '{{ remote_tmp_dir }}/csr_backup.csr'
state: absent
backup: yes
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -349,7 +349,7 @@
register: csr_backup_4
- name: "({{ select_crypto_backend }}) Generate CSR (remove, idempotent)"
openssl_csr:
path: '{{ output_dir }}/csr_backup.csr'
path: '{{ remote_tmp_dir }}/csr_backup.csr'
state: absent
backup: yes
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -357,8 +357,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier"
openssl_csr:
path: '{{ output_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
subject_key_identifier: "00:11:22:33"
@@ -368,8 +368,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (idempotency)"
openssl_csr:
path: '{{ output_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
subject_key_identifier: "00:11:22:33"
@@ -379,8 +379,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (change)"
openssl_csr:
path: '{{ output_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
subject_key_identifier: "44:55:66:77:88"
@@ -390,8 +390,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (auto-create)"
openssl_csr:
path: '{{ output_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
create_subject_key_identifier: yes
@@ -401,8 +401,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (auto-create idempotency)"
openssl_csr:
path: '{{ output_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
create_subject_key_identifier: yes
@@ -412,8 +412,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with subject key identifier (remove)"
openssl_csr:
path: '{{ output_dir }}/csr_ski.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_ski.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -422,8 +422,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier"
openssl_csr:
path: '{{ output_dir }}/csr_aki.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_aki.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
authority_key_identifier: "00:11:22:33"
@@ -433,8 +433,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier (idempotency)"
openssl_csr:
path: '{{ output_dir }}/csr_aki.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_aki.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
authority_key_identifier: "00:11:22:33"
@@ -444,8 +444,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier (change)"
openssl_csr:
path: '{{ output_dir }}/csr_aki.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_aki.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
authority_key_identifier: "44:55:66:77:88"
@@ -455,8 +455,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority key identifier (remove)"
openssl_csr:
path: '{{ output_dir }}/csr_aki.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_aki.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -465,8 +465,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number"
openssl_csr:
path: '{{ output_dir }}/csr_acisn.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_acisn.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
authority_cert_issuer:
@@ -479,8 +479,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (idempotency)"
openssl_csr:
path: '{{ output_dir }}/csr_acisn.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_acisn.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
authority_cert_issuer:
@@ -493,8 +493,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (change issuer)"
openssl_csr:
path: '{{ output_dir }}/csr_acisn.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_acisn.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
authority_cert_issuer:
@@ -507,8 +507,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (change serial number)"
openssl_csr:
path: '{{ output_dir }}/csr_acisn.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_acisn.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
authority_cert_issuer:
@@ -521,8 +521,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR with authority cert issuer / serial number (remove)"
openssl_csr:
path: '{{ output_dir }}/csr_acisn.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_acisn.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
when: select_crypto_backend != 'pyopenssl'
@@ -530,20 +530,20 @@
- name: "({{ select_crypto_backend }}) Generate CSR with everything"
openssl_csr:
path: '{{ output_dir }}/csr_everything.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_everything.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.example.com
C: de
L: Somewhere
ST: Zurich
streetAddress: Welcome Street
O: Ansible
organizationalUnitName: Crypto Department
ST: Zürich
streetAddress: Welcome Street N° 5
O: Ansiblé
organizationalUnitName: Crÿpto Depârtment
serialNumber: "1234"
SN: Last Name
SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
GN: First Name
title: Chief
title: Chïeff
pseudonym: test
UID: asdf
emailAddress: test@example.com
@@ -638,20 +638,20 @@
- name: "({{ select_crypto_backend }}) Generate CSR with everything (idempotent, check mode)"
openssl_csr:
path: '{{ output_dir }}/csr_everything.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_everything.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.example.com
C: de
CN: www.example.com
countryName: de
L: Somewhere
ST: Zurich
streetAddress: Welcome Street
O: Ansible
organizationalUnitName: Crypto Department
ST: Zürich
streetAddress: Welcome Street N° 5
organizationName: Ansiblé
organizationalUnitName: Crÿpto Depârtment
serialNumber: "1234"
SN: Last Name
SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
GN: First Name
title: Chief
title: Chïeff
pseudonym: test
UID: asdf
emailAddress: test@example.com
@@ -747,20 +747,20 @@
- name: "({{ select_crypto_backend }}) Generate CSR with everything (idempotent)"
openssl_csr:
path: '{{ output_dir }}/csr_everything.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_everything.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.example.com
C: de
CN: www.example.com
countryName: de
L: Somewhere
ST: Zurich
streetAddress: Welcome Street
O: Ansible
organizationalUnitName: Crypto Department
ST: Zürich
streetAddress: Welcome Street N° 5
organizationName: Ansiblé
organizationalUnitName: Crÿpto Depârtment
serialNumber: "1234"
SN: Last Name
SN: Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr.
GN: First Name
title: Chief
title: Chïeff
pseudonym: test
UID: asdf
emailAddress: test@example.com
@@ -855,7 +855,7 @@
- name: "({{ select_crypto_backend }}) Get info from CSR with everything"
community.crypto.openssl_csr_info:
path: '{{ output_dir }}/csr_everything.csr'
path: '{{ remote_tmp_dir }}/csr_everything.csr'
select_crypto_backend: '{{ select_crypto_backend }}'
register: everything_info
@@ -863,7 +863,7 @@
block:
- name: "({{ select_crypto_backend }}) Generate privatekeys"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_{{ item }}.pem'
path: '{{ remote_tmp_dir }}/privatekey_{{ item }}.pem'
type: '{{ item }}'
loop:
- Ed25519
@@ -877,8 +877,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR"
openssl_csr:
path: '{{ output_dir }}/csr_{{ item }}.csr'
privatekey_path: '{{ output_dir }}/privatekey_{{ item }}.pem'
path: '{{ remote_tmp_dir }}/csr_{{ item }}.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey_{{ item }}.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -890,8 +890,8 @@
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent)"
openssl_csr:
path: '{{ output_dir }}/csr_{{ item }}.csr'
privatekey_path: '{{ output_dir }}/privatekey_{{ item }}.pem'
path: '{{ remote_tmp_dir }}/csr_{{ item }}.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey_{{ item }}.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -907,8 +907,8 @@
block:
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints"
openssl_csr:
path: '{{ output_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
crl_distribution_points:
@@ -930,8 +930,8 @@
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints (idempotence)"
openssl_csr:
path: '{{ output_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
crl_distribution_points:
@@ -953,8 +953,8 @@
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints (change)"
openssl_csr:
path: '{{ output_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
crl_distribution_points:
@@ -975,8 +975,8 @@
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints (no endpoints)"
openssl_csr:
path: '{{ output_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -984,8 +984,8 @@
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints"
openssl_csr:
path: '{{ output_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_crl_d_e.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
crl_distribution_points:

View File

@@ -6,12 +6,12 @@
- name: Prepare private key for backend autodetection test
openssl_privatekey:
path: '{{ output_dir }}/privatekey_backend_selection.pem'
path: '{{ remote_tmp_dir }}/privatekey_backend_selection.pem'
size: '{{ default_rsa_key_size }}'
- name: Run module with backend autodetection
openssl_csr:
path: '{{ output_dir }}/csr_backend_selection.csr'
privatekey_path: '{{ output_dir }}/privatekey_backend_selection.pem'
path: '{{ remote_tmp_dir }}/csr_backend_selection.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey_backend_selection.pem'
subject:
commonName: www.ansible.com
@@ -29,12 +29,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:

View File

@@ -1,14 +1,14 @@
---
- name: "({{ select_crypto_backend }}) Validate CSR (test - privatekey modulus)"
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ output_dir }}/privatekey.pem'
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ remote_tmp_dir }}/privatekey.pem'
register: privatekey_modulus
- name: "({{ select_crypto_backend }}) Validate CSR (test - Common Name)"
shell: "{{ openssl_binary }} req -noout -subject -in {{ output_dir }}/csr.csr -nameopt oneline,-space_eq"
shell: "{{ openssl_binary }} req -noout -subject -in {{ remote_tmp_dir }}/csr.csr -nameopt oneline,-space_eq"
register: csr_cn
- name: "({{ select_crypto_backend }}) Validate CSR (test - csr modulus)"
shell: '{{ openssl_binary }} req -noout -modulus -in {{ output_dir }}/csr.csr'
shell: '{{ openssl_binary }} req -noout -modulus -in {{ remote_tmp_dir }}/csr.csr'
register: csr_modulus
- name: "({{ select_crypto_backend }}) Validate CSR (assert)"
@@ -25,11 +25,16 @@
- generate_csr_idempotent is not changed
- generate_csr_idempotent_check is not changed
- name: "({{ select_crypto_backend }}) Read CSR"
slurp:
src: '{{ remote_tmp_dir }}/csr.csr'
register: slurp
- name: "({{ select_crypto_backend }}) Validate CSR (data retrieval)"
assert:
that:
- generate_csr_check.csr is none
- generate_csr.csr == lookup('file', output_dir ~ '/csr.csr', rstrip=False)
- generate_csr.csr == (slurp.content | b64decode)
- generate_csr.csr == generate_csr_idempotent.csr
- generate_csr.csr == generate_csr_idempotent_check.csr
@@ -49,11 +54,11 @@
- csr_ku_xku_change_2 is changed
- name: "({{ select_crypto_backend }}) Validate old_API CSR (test - Common Name)"
shell: "{{ openssl_binary }} req -noout -subject -in {{ output_dir }}/csr_oldapi.csr -nameopt oneline,-space_eq"
shell: "{{ openssl_binary }} req -noout -subject -in {{ remote_tmp_dir }}/csr_oldapi.csr -nameopt oneline,-space_eq"
register: csr_oldapi_cn
- name: "({{ select_crypto_backend }}) Validate old_API CSR (test - csr modulus)"
shell: '{{ openssl_binary }} req -noout -modulus -in {{ output_dir }}/csr_oldapi.csr'
shell: '{{ openssl_binary }} req -noout -modulus -in {{ remote_tmp_dir }}/csr_oldapi.csr'
register: csr_oldapi_modulus
- name: "({{ select_crypto_backend }}) Validate old_API CSR (assert)"
@@ -78,7 +83,7 @@
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.0', '<')
- name: "({{ select_crypto_backend }}) Validate OCSP Must Staple CSR (test - everything)"
shell: "{{ openssl_binary }} req -noout -in {{ output_dir }}/csr_ocsp.csr -text"
shell: "{{ openssl_binary }} req -noout -in {{ remote_tmp_dir }}/csr_ocsp.csr -text"
register: csr_ocsp
- name: "({{ select_crypto_backend }}) Validate OCSP Must Staple CSR (assert)"
@@ -93,15 +98,15 @@
- csr_ocsp_idempotency is not changed
- name: "({{ select_crypto_backend }}) Validate ECC CSR (test - privatekey's public key)"
shell: '{{ openssl_binary }} ec -pubout -in {{ output_dir }}/privatekey2.pem'
shell: '{{ openssl_binary }} ec -pubout -in {{ remote_tmp_dir }}/privatekey2.pem'
register: privatekey_ecc_key
- name: "({{ select_crypto_backend }}) Validate ECC CSR (test - Common Name)"
shell: "{{ openssl_binary }} req -noout -subject -in {{ output_dir }}/csr2.csr -nameopt oneline,-space_eq"
shell: "{{ openssl_binary }} req -noout -subject -in {{ remote_tmp_dir }}/csr2.csr -nameopt oneline,-space_eq"
register: csr_ecc_cn
- name: "({{ select_crypto_backend }}) Validate ECC CSR (test - CSR pubkey)"
shell: '{{ openssl_binary }} req -noout -pubkey -in {{ output_dir }}/csr2.csr'
shell: '{{ openssl_binary }} req -noout -pubkey -in {{ remote_tmp_dir }}/csr2.csr'
register: csr_ecc_pubkey
- name: "({{ select_crypto_backend }}) Validate ECC CSR (assert)"
@@ -111,7 +116,7 @@
- csr_ecc_pubkey.stdout == privatekey_ecc_key.stdout
- name: "({{ select_crypto_backend }}) Validate CSR (text common name - Common Name)"
shell: "{{ openssl_binary }} req -noout -subject -in {{ output_dir }}/csr3.csr -nameopt oneline,-space_eq"
shell: "{{ openssl_binary }} req -noout -subject -in {{ remote_tmp_dir }}/csr3.csr -nameopt oneline,-space_eq"
register: csr3_cn
- name: "({{ select_crypto_backend }}) Validate CSR (assert)"
@@ -219,16 +224,16 @@
- everything_info.subject.emailAddress == "test@example.com"
- everything_info.subject.givenName == "First Name"
- everything_info.subject.localityName == "Somewhere"
- everything_info.subject.organizationName == "Ansible"
- everything_info.subject.organizationalUnitName == "Crypto Department"
- everything_info.subject.organizationName == "Ansiblé"
- everything_info.subject.organizationalUnitName == "Crÿpto Depârtment"
- everything_info.subject.postalAddress == "1234 Somewhere"
- everything_info.subject.postalCode == "1234"
- everything_info.subject.pseudonym == "test"
- everything_info.subject.serialNumber == "1234"
- everything_info.subject.stateOrProvinceName == "Zurich"
- everything_info.subject.streetAddress == "Welcome Street"
- everything_info.subject.surname == "Last Name"
- everything_info.subject.title == "Chief"
- everything_info.subject.stateOrProvinceName == "Zürich"
- everything_info.subject.streetAddress == "Welcome Street N° 5"
- everything_info.subject.surname == "Last Name Which Happens To Be A Very Løng String With A Lot Of Spaces, Jr."
- everything_info.subject.title == "Chïeff"
- everything_info.subject.userId == "asdf"
- everything_info.subject | length == 16
- everything_info.subject_alt_name_critical == false

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -4,7 +4,7 @@
- name: "({{ select_crypto_backend }}) Get CSR info"
openssl_csr_info:
path: '{{ output_dir }}/csr_1.csr'
path: '{{ remote_tmp_dir }}/csr_1.csr'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result
@@ -34,9 +34,14 @@
set_fact:
info_results: "{{ info_results + [result] }}"
- name: "({{ select_crypto_backend }}) Read CSR"
slurp:
src: '{{ remote_tmp_dir }}/csr_1.csr'
register: slurp
- name: "({{ select_crypto_backend }}) Get CSR info directly"
openssl_csr_info:
content: '{{ lookup("file", output_dir ~ "/csr_1.csr") }}'
content: '{{ slurp.content | b64decode }}'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result_direct
@@ -47,7 +52,7 @@
- name: "({{ select_crypto_backend }}) Get CSR info"
openssl_csr_info:
path: '{{ output_dir }}/csr_2.csr'
path: '{{ remote_tmp_dir }}/csr_2.csr'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result
@@ -57,7 +62,7 @@
- name: "({{ select_crypto_backend }}) Get CSR info"
openssl_csr_info:
path: '{{ output_dir }}/csr_3.csr'
path: '{{ remote_tmp_dir }}/csr_3.csr'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result
@@ -79,7 +84,7 @@
- name: "({{ select_crypto_backend }}) Get CSR info"
openssl_csr_info:
path: '{{ output_dir }}/csr_4.csr'
path: '{{ remote_tmp_dir }}/csr_4.csr'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result

View File

@@ -6,12 +6,12 @@
- name: Generate privatekey
openssl_privatekey:
path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/privatekey.pem'
size: '{{ default_rsa_key_size }}'
- name: Generate privatekey with password
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: auto
select_crypto_backend: cryptography
@@ -19,8 +19,8 @@
- name: Generate CSR 1
openssl_csr:
path: '{{ output_dir }}/csr_1.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_1.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.example.com
C: de
@@ -87,8 +87,8 @@
- name: Generate CSR 2
openssl_csr:
path: '{{ output_dir }}/csr_2.csr'
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/csr_2.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: hunter2
useCommonNameForSAN: no
basic_constraints:
@@ -96,8 +96,8 @@
- name: Generate CSR 3
openssl_csr:
path: '{{ output_dir }}/csr_3.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_3.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
useCommonNameForSAN: no
subject_alt_name:
- "DNS:*.ansible.com"
@@ -114,8 +114,8 @@
- name: Generate CSR 4
openssl_csr:
path: '{{ output_dir }}/csr_4.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_4.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
useCommonNameForSAN: no
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}'

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -1,12 +1,12 @@
---
- name: "({{ select_crypto_backend }}) Generate privatekey"
openssl_privatekey:
path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/privatekey.pem'
size: '{{ default_rsa_key_size }}'
- name: "({{ select_crypto_backend }}) Generate CSR (check mode)"
openssl_csr_pipe:
privatekey_path: '{{ output_dir }}/privatekey.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -15,7 +15,7 @@
- name: "({{ select_crypto_backend }}) Generate CSR"
openssl_csr_pipe:
privatekey_path: '{{ output_dir }}/privatekey.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -24,7 +24,7 @@
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent)"
openssl_csr_pipe:
content: "{{ generate_csr.csr }}"
privatekey_path: '{{ output_dir }}/privatekey.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -33,7 +33,7 @@
- name: "({{ select_crypto_backend }}) Generate CSR (idempotent, check mode)"
openssl_csr_pipe:
content: "{{ generate_csr.csr }}"
privatekey_path: '{{ output_dir }}/privatekey.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -43,7 +43,7 @@
- name: "({{ select_crypto_backend }}) Generate CSR (changed)"
openssl_csr_pipe:
content: "{{ generate_csr.csr }}"
privatekey_path: '{{ output_dir }}/privatekey.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -52,7 +52,7 @@
- name: "({{ select_crypto_backend }}) Generate CSR (changed, check mode)"
openssl_csr_pipe:
content: "{{ generate_csr.csr }}"
privatekey_path: '{{ output_dir }}/privatekey.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: ansible.com
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -60,7 +60,7 @@
register: generate_csr_changed_check
- name: "({{ select_crypto_backend }}) Validate CSR (test - privatekey modulus)"
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ output_dir }}/privatekey.pem'
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ remote_tmp_dir }}/privatekey.pem'
register: privatekey_modulus
- name: "({{ select_crypto_backend }}) Validate CSR (test - Common Name)"

View File

@@ -6,11 +6,11 @@
- name: Prepare private key for backend autodetection test
openssl_privatekey:
path: '{{ output_dir }}/privatekey_backend_selection.pem'
path: '{{ remote_tmp_dir }}/privatekey_backend_selection.pem'
size: '{{ default_rsa_key_size }}'
- name: Run module with backend autodetection
openssl_csr_pipe:
privatekey_path: '{{ output_dir }}/privatekey_backend_selection.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekey_backend_selection.pem'
subject:
commonName: www.ansible.com
@@ -24,12 +24,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:

View File

@@ -1,2 +1,3 @@
dependencies:
- setup_openssl
- setup_remote_tmp_dir

View File

@@ -4,7 +4,7 @@
- name: "[{{ select_crypto_backend }}] Generate parameter (check mode)"
openssl_dhparam:
size: 768
path: '{{ output_dir }}/dh768.pem'
path: '{{ remote_tmp_dir }}/dh768.pem'
select_crypto_backend: "{{ select_crypto_backend }}"
return_content: yes
check_mode: true
@@ -13,7 +13,7 @@
- name: "[{{ select_crypto_backend }}] Generate parameter"
openssl_dhparam:
size: 768
path: '{{ output_dir }}/dh768.pem'
path: '{{ remote_tmp_dir }}/dh768.pem'
select_crypto_backend: "{{ select_crypto_backend }}"
return_content: yes
register: dhparam
@@ -21,7 +21,7 @@
- name: "[{{ select_crypto_backend }}] Don't regenerate parameters with no change (check mode)"
openssl_dhparam:
size: 768
path: '{{ output_dir }}/dh768.pem'
path: '{{ remote_tmp_dir }}/dh768.pem'
select_crypto_backend: "{{ select_crypto_backend }}"
return_content: yes
check_mode: true
@@ -30,39 +30,39 @@
- name: "[{{ select_crypto_backend }}] Don't regenerate parameters with no change"
openssl_dhparam:
size: 768
path: '{{ output_dir }}/dh768.pem'
path: '{{ remote_tmp_dir }}/dh768.pem'
select_crypto_backend: "{{ select_crypto_backend }}"
return_content: yes
register: dhparam_changed
- name: "[{{ select_crypto_backend }}] Generate parameters with size option"
openssl_dhparam:
path: '{{ output_dir }}/dh512.pem'
path: '{{ remote_tmp_dir }}/dh512.pem'
size: 512
select_crypto_backend: "{{ select_crypto_backend }}"
- name: "[{{ select_crypto_backend }}] Don't regenerate parameters with size option and no change"
openssl_dhparam:
path: '{{ output_dir }}/dh512.pem'
path: '{{ remote_tmp_dir }}/dh512.pem'
size: 512
select_crypto_backend: "{{ select_crypto_backend }}"
register: dhparam_changed_512
- copy:
src: '{{ output_dir }}/dh768.pem'
src: '{{ remote_tmp_dir }}/dh768.pem'
remote_src: yes
dest: '{{ output_dir }}/dh512.pem'
dest: '{{ remote_tmp_dir }}/dh512.pem'
- name: "[{{ select_crypto_backend }}] Re-generate if size is different"
openssl_dhparam:
path: '{{ output_dir }}/dh512.pem'
path: '{{ remote_tmp_dir }}/dh512.pem'
size: 512
select_crypto_backend: "{{ select_crypto_backend }}"
register: dhparam_changed_to_512
- name: "[{{ select_crypto_backend }}] Force re-generate parameters with size option"
openssl_dhparam:
path: '{{ output_dir }}/dh512.pem'
path: '{{ remote_tmp_dir }}/dh512.pem'
size: 512
force: yes
select_crypto_backend: "{{ select_crypto_backend }}"
@@ -70,11 +70,11 @@
- name: "[{{ select_crypto_backend }}] Create broken params"
copy:
dest: "{{ output_dir }}/dhbroken.pem"
dest: "{{ remote_tmp_dir }}/dhbroken.pem"
content: "broken"
- name: "[{{ select_crypto_backend }}] Regenerate broken params"
openssl_dhparam:
path: '{{ output_dir }}/dhbroken.pem'
path: '{{ remote_tmp_dir }}/dhbroken.pem'
size: 512
force: yes
select_crypto_backend: "{{ select_crypto_backend }}"
@@ -82,21 +82,21 @@
- name: "[{{ select_crypto_backend }}] Generate params"
openssl_dhparam:
path: '{{ output_dir }}/dh_backup.pem'
path: '{{ remote_tmp_dir }}/dh_backup.pem'
size: 512
backup: yes
select_crypto_backend: "{{ select_crypto_backend }}"
register: dhparam_backup_1
- name: "[{{ select_crypto_backend }}] Generate params (idempotent)"
openssl_dhparam:
path: '{{ output_dir }}/dh_backup.pem'
path: '{{ remote_tmp_dir }}/dh_backup.pem'
size: 512
backup: yes
select_crypto_backend: "{{ select_crypto_backend }}"
register: dhparam_backup_2
- name: "[{{ select_crypto_backend }}] Generate params (change)"
openssl_dhparam:
path: '{{ output_dir }}/dh_backup.pem'
path: '{{ remote_tmp_dir }}/dh_backup.pem'
size: 512
force: yes
backup: yes
@@ -104,7 +104,7 @@
register: dhparam_backup_3
- name: "[{{ select_crypto_backend }}] Generate params (remove)"
openssl_dhparam:
path: '{{ output_dir }}/dh_backup.pem'
path: '{{ remote_tmp_dir }}/dh_backup.pem'
state: absent
backup: yes
select_crypto_backend: "{{ select_crypto_backend }}"
@@ -112,7 +112,7 @@
register: dhparam_backup_4
- name: "[{{ select_crypto_backend }}] Generate params (remove, idempotent)"
openssl_dhparam:
path: '{{ output_dir }}/dh_backup.pem'
path: '{{ remote_tmp_dir }}/dh_backup.pem'
state: absent
backup: yes
select_crypto_backend: "{{ select_crypto_backend }}"

View File

@@ -9,7 +9,7 @@
- name: Run module with backend autodetection
openssl_dhparam:
path: '{{ output_dir }}/dh_backend_selection.pem'
path: '{{ remote_tmp_dir }}/dh_backend_selection.pem'
size: 512
- block:
@@ -24,12 +24,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:

View File

@@ -1,12 +1,12 @@
---
- name: "[{{ select_crypto_backend }}] Validate generated params"
shell: '{{ openssl_binary }} dhparam -in {{ output_dir }}/{{ item }}.pem -noout -check'
shell: '{{ openssl_binary }} dhparam -in {{ remote_tmp_dir }}/{{ item }}.pem -noout -check'
with_items:
- dh768
- dh512
- name: "[{{ select_crypto_backend }}] Get bit size of 768"
shell: '{{ openssl_binary }} dhparam -noout -in {{ output_dir }}/dh768.pem -text | head -n1 | sed -ne "s@.*(\\([[:digit:]]\{1,\}\\) bit).*@\\1@p"'
shell: '{{ openssl_binary }} dhparam -noout -in {{ remote_tmp_dir }}/dh768.pem -text | head -n1 | sed -ne "s@.*(\\([[:digit:]]\{1,\}\\) bit).*@\\1@p"'
register: bit_size_dhparam
- name: "[{{ select_crypto_backend }}] Check bit size of default"
@@ -15,7 +15,7 @@
- bit_size_dhparam.stdout == "768"
- name: "[{{ select_crypto_backend }}] Get bit size of 512"
shell: '{{ openssl_binary }} dhparam -noout -in {{ output_dir }}/dh512.pem -text | head -n1 | sed -ne "s@.*(\\([[:digit:]]\{1,\}\\) bit).*@\\1@p"'
shell: '{{ openssl_binary }} dhparam -noout -in {{ remote_tmp_dir }}/dh512.pem -text | head -n1 | sed -ne "s@.*(\\([[:digit:]]\{1,\}\\) bit).*@\\1@p"'
register: bit_size_dhparam_512
- name: "[{{ select_crypto_backend }}] Check bit size of default"
@@ -34,10 +34,15 @@
- dhparam_changed_to_512 is changed
- dhparam_changed_force is changed
- name: "[{{ select_crypto_backend }}] Read result"
slurp:
src: '{{ remote_tmp_dir }}/dh768.pem'
register: slurp
- name: "[{{ select_crypto_backend }}] Make sure correct values are returned"
assert:
that:
- dhparam.dhparams == lookup('file', output_dir ~ '/dh768.pem', rstrip=False)
- dhparam.dhparams == (slurp.content | b64decode)
- dhparam.dhparams == dhparam_changed.dhparams
- name: "[{{ select_crypto_backend }}] Verify that broken params will be regenerated"

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -2,10 +2,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (check mode)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
return_content: true
check_mode: true
@@ -14,10 +14,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
return_content: true
register: p12_standard
@@ -25,10 +25,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file again, idempotency (check mode)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
return_content: true
check_mode: true
@@ -37,17 +37,17 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file again, idempotency"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
return_content: true
register: p12_standard_idempotency
- name: "({{ select_crypto_backend }}) Read ansible.p12"
slurp:
src: '{{ output_dir }}/ansible.p12'
src: '{{ remote_tmp_dir }}/ansible.p12'
register: ansible_p12_content
- name: "({{ select_crypto_backend }}) Validate PKCS#12"
@@ -59,10 +59,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (force)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
force: true
register: p12_force
@@ -70,10 +70,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (force + change mode)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
force: true
mode: '0644'
@@ -82,8 +82,8 @@
- name: "({{ select_crypto_backend }}) Dump PKCS#12"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
src: '{{ output_dir }}/ansible.p12'
path: '{{ output_dir }}/ansible_parse.pem'
src: '{{ remote_tmp_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible_parse.pem'
action: parse
state: present
register: p12_dumped
@@ -91,8 +91,8 @@
- name: "({{ select_crypto_backend }}) Dump PKCS#12 file again, idempotency"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
src: '{{ output_dir }}/ansible.p12'
path: '{{ output_dir }}/ansible_parse.pem'
src: '{{ remote_tmp_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible_parse.pem'
action: parse
state: present
register: p12_dumped_idempotency
@@ -100,8 +100,8 @@
- name: "({{ select_crypto_backend }}) Dump PKCS#12, check mode"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
src: '{{ output_dir }}/ansible.p12'
path: '{{ output_dir }}/ansible_parse.pem'
src: '{{ remote_tmp_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible_parse.pem'
action: parse
state: present
check_mode: true
@@ -110,36 +110,36 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file with multiple certs and passphrase"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_multi_certs.p12'
path: '{{ remote_tmp_dir }}/ansible_multi_certs.p12'
friendly_name: abracadabra
passphrase: hunter3
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
other_certificates:
- '{{ output_dir }}/ansible2.crt'
- '{{ output_dir }}/ansible3.crt'
- '{{ remote_tmp_dir }}/ansible2.crt'
- '{{ remote_tmp_dir }}/ansible3.crt'
state: present
register: p12_multiple_certs
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file with multiple certs and passphrase, again (idempotency)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_multi_certs.p12'
path: '{{ remote_tmp_dir }}/ansible_multi_certs.p12'
friendly_name: abracadabra
passphrase: hunter3
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
other_certificates:
- '{{ output_dir }}/ansible2.crt'
- '{{ output_dir }}/ansible3.crt'
- '{{ remote_tmp_dir }}/ansible2.crt'
- '{{ remote_tmp_dir }}/ansible3.crt'
state: present
register: p12_multiple_certs_idempotency
- name: "({{ select_crypto_backend }}) Dump PKCS#12 with multiple certs and passphrase"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
src: '{{ output_dir }}/ansible_multi_certs.p12'
path: '{{ output_dir }}/ansible_parse_multi_certs.pem'
src: '{{ remote_tmp_dir }}/ansible_multi_certs.p12'
path: '{{ remote_tmp_dir }}/ansible_parse_multi_certs.pem'
passphrase: hunter3
action: parse
state: present
@@ -147,11 +147,11 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (password fail 1)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_pw1.p12'
path: '{{ remote_tmp_dir }}/ansible_pw1.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
privatekey_passphrase: hunter2
certificate_path: '{{ output_dir }}/ansible1.crt'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
ignore_errors: true
register: passphrase_error_1
@@ -159,11 +159,11 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (password fail 2)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_pw2.p12'
path: '{{ remote_tmp_dir }}/ansible_pw2.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: wrong_password
certificate_path: '{{ output_dir }}/ansible1.crt'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
ignore_errors: true
register: passphrase_error_2
@@ -171,10 +171,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (password fail 3)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_pw3.p12'
path: '{{ remote_tmp_dir }}/ansible_pw3.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
ignore_errors: true
register: passphrase_error_3
@@ -182,24 +182,24 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file, no privatekey"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_no_pkey.p12'
path: '{{ remote_tmp_dir }}/ansible_no_pkey.p12'
friendly_name: abracadabra
certificate_path: '{{ output_dir }}/ansible1.crt'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
register: p12_no_pkey
- name: "({{ select_crypto_backend }}) Create broken PKCS#12"
copy:
dest: '{{ output_dir }}/broken.p12'
dest: '{{ remote_tmp_dir }}/broken.p12'
content: broken
- name: "({{ select_crypto_backend }}) Regenerate broken PKCS#12"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/broken.p12'
path: '{{ remote_tmp_dir }}/broken.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
force: true
mode: '0644'
@@ -208,10 +208,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_backup.p12'
path: '{{ remote_tmp_dir }}/ansible_backup.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
backup: true
register: p12_backup_1
@@ -219,10 +219,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (idempotent)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_backup.p12'
path: '{{ remote_tmp_dir }}/ansible_backup.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
backup: true
register: p12_backup_2
@@ -230,10 +230,10 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (change)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_backup.p12'
path: '{{ remote_tmp_dir }}/ansible_backup.p12'
friendly_name: abra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
force: true
backup: true
@@ -242,7 +242,7 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (remove)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_backup.p12'
path: '{{ remote_tmp_dir }}/ansible_backup.p12'
state: absent
backup: true
return_content: true
@@ -251,7 +251,7 @@
- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (remove, idempotent)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_backup.p12'
path: '{{ remote_tmp_dir }}/ansible_backup.p12'
state: absent
backup: true
register: p12_backup_5
@@ -259,11 +259,11 @@
- name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_empty.p12'
path: '{{ remote_tmp_dir }}/ansible_empty.p12'
friendly_name: abracadabra
other_certificates:
- '{{ output_dir }}/ansible2.crt'
- '{{ output_dir }}/ansible3.crt'
- '{{ remote_tmp_dir }}/ansible2.crt'
- '{{ remote_tmp_dir }}/ansible3.crt'
state: present
register: p12_empty
@@ -271,21 +271,21 @@
- name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file (idempotent)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_empty.p12'
path: '{{ remote_tmp_dir }}/ansible_empty.p12'
friendly_name: abracadabra
other_certificates:
- '{{ output_dir }}/ansible3.crt'
- '{{ output_dir }}/ansible2.crt'
- '{{ remote_tmp_dir }}/ansible3.crt'
- '{{ remote_tmp_dir }}/ansible2.crt'
state: present
register: p12_empty_idem
- name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file (idempotent, concatenated other certificates)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ output_dir }}/ansible_empty.p12'
path: '{{ remote_tmp_dir }}/ansible_empty.p12'
friendly_name: abracadabra
other_certificates:
- '{{ output_dir }}/ansible23.crt'
- '{{ remote_tmp_dir }}/ansible23.crt'
other_certificates_parse_all: true
state: present
register: p12_empty_concat_idem
@@ -293,8 +293,8 @@
- name: "({{ select_crypto_backend }}) Generate 'empty' PKCS#12 file (parse)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
src: '{{ output_dir }}/ansible_empty.p12'
path: '{{ output_dir }}/ansible_empty.pem'
src: '{{ remote_tmp_dir }}/ansible_empty.p12'
path: '{{ remote_tmp_dir }}/ansible_empty.pem'
action: parse
- import_tasks: ../tests/validate.yml
@@ -303,7 +303,7 @@
- name: "({{ select_crypto_backend }}) Delete PKCS#12 file"
openssl_pkcs12:
state: absent
path: '{{ output_dir }}/{{ item }}.p12'
path: '{{ remote_tmp_dir }}/{{ item }}.p12'
loop:
- ansible
- ansible_no_pkey

View File

@@ -7,50 +7,56 @@
- block:
- name: Generate private keys
openssl_privatekey:
path: '{{ output_dir }}/ansible_pkey{{ item }}.pem'
path: '{{ remote_tmp_dir }}/ansible_pkey{{ item }}.pem'
size: '{{ default_rsa_key_size_certifiates }}'
loop: "{{ range(1, 4) | list }}"
- name: Generate privatekey with password
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: auto
size: '{{ default_rsa_key_size }}'
- name: Generate CSRs
openssl_csr:
path: '{{ output_dir }}/ansible{{ item }}.csr'
privatekey_path: '{{ output_dir }}/ansible_pkey{{ item }}.pem'
path: '{{ remote_tmp_dir }}/ansible{{ item }}.csr'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey{{ item }}.pem'
commonName: www{{ item }}.ansible.com
loop: "{{ range(1, 4) | list }}"
- name: Generate certificate
x509_certificate:
path: '{{ output_dir }}/ansible{{ item }}.crt'
privatekey_path: '{{ output_dir }}/ansible_pkey{{ item }}.pem'
csr_path: '{{ output_dir }}/ansible{{ item }}.csr'
path: '{{ remote_tmp_dir }}/ansible{{ item }}.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey{{ item }}.pem'
csr_path: '{{ remote_tmp_dir }}/ansible{{ item }}.csr'
provider: selfsigned
loop: "{{ range(1, 4) | list }}"
- name: Read files
slurp:
src: '{{ item }}'
loop:
- "{{ remote_tmp_dir ~ '/ansible2.crt' }}"
- "{{ remote_tmp_dir ~ '/ansible3.crt' }}"
register: slurp
- name: Generate concatenated PEM file
copy:
dest: '{{ output_dir }}/ansible23.crt'
content: |
{{ lookup("file", output_dir ~ "/ansible2.crt") }}
{{ lookup("file", output_dir ~ "/ansible3.crt") }}
dest: '{{ remote_tmp_dir }}/ansible23.crt'
content: '{{ slurp.results[0].content | b64decode }}{{ slurp.results[1].content | b64decode }}'
- name: Generate PKCS#12 file with backend autodetection
openssl_pkcs12:
path: '{{ output_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra
privatekey_path: '{{ output_dir }}/ansible_pkey1.pem'
certificate_path: '{{ output_dir }}/ansible1.crt'
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
state: present
- name: Delete result
file:
path: '{{ output_dir }}/ansible.p12'
path: '{{ remote_tmp_dir }}/ansible.p12'
state: absent
- block:

View File

@@ -1,14 +1,14 @@
---
- name: '({{ select_crypto_backend }}) Validate PKCS#12'
command: "{{ openssl_binary }} pkcs12 -info -in {{ output_dir }}/ansible.p12 -nodes -passin pass:''"
command: "{{ openssl_binary }} pkcs12 -info -in {{ remote_tmp_dir }}/ansible.p12 -nodes -passin pass:''"
register: p12
- name: '({{ select_crypto_backend }}) Validate PKCS#12 with no private key'
command: "{{ openssl_binary }} pkcs12 -info -in {{ output_dir }}/ansible_no_pkey.p12 -nodes -passin pass:''"
command: "{{ openssl_binary }} pkcs12 -info -in {{ remote_tmp_dir }}/ansible_no_pkey.p12 -nodes -passin pass:''"
register: p12_validate_no_pkey
- name: '({{ select_crypto_backend }}) Validate PKCS#12 with multiple certs'
shell: "{{ openssl_binary }} pkcs12 -info -in {{ output_dir }}/ansible_multi_certs.p12 -nodes -passin pass:'hunter3' | grep subject"
shell: "{{ openssl_binary }} pkcs12 -info -in {{ remote_tmp_dir }}/ansible_multi_certs.p12 -nodes -passin pass:'hunter3' | grep subject"
register: p12_validate_multi_certs
- name: '({{ select_crypto_backend }}) Validate PKCS#12 (assert)'
@@ -62,11 +62,20 @@
- p12_backup_5.backup_file is undefined
- p12_backup_4.pkcs12 is none
- name: '({{ select_crypto_backend }}) Read files'
slurp:
src: '{{ item }}'
loop:
- "{{ remote_tmp_dir ~ '/ansible_empty.pem' }}"
- "{{ remote_tmp_dir ~ '/ansible2.crt' }}"
- "{{ remote_tmp_dir ~ '/ansible3.crt' }}"
register: slurp
- name: '({{ select_crypto_backend }}) Load "empty" file'
set_fact:
empty_contents: "{{ lookup('file', output_dir ~ '/ansible_empty.pem') }}"
empty_expected_pyopenssl: "{{ lookup('file', output_dir ~ '/ansible3.crt') ~ '\n' ~ lookup('file', output_dir ~ '/ansible2.crt') }}"
empty_expected_cryptography: "{{ lookup('file', output_dir ~ '/ansible2.crt') ~ '\n' ~ lookup('file', output_dir ~ '/ansible3.crt') }}"
empty_contents: "{{ slurp.results[0].content | b64decode }}"
empty_expected_pyopenssl: "{{ (slurp.results[2].content | b64decode) ~ (slurp.results[1].content | b64decode) }}"
empty_expected_cryptography: "{{ (slurp.results[1].content | b64decode) ~ (slurp.results[2].content | b64decode) }}"
- name: '({{ select_crypto_backend }}) Check "empty" file'
assert:

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -1,7 +1,7 @@
---
- name: "({{ select_crypto_backend }}) Generate privatekey1 - standard (check mode)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey1.pem'
path: '{{ remote_tmp_dir }}/privatekey1.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
return_content: yes
check_mode: true
@@ -9,14 +9,14 @@
- name: "({{ select_crypto_backend }}) Generate privatekey1 - standard"
openssl_privatekey:
path: '{{ output_dir }}/privatekey1.pem'
path: '{{ remote_tmp_dir }}/privatekey1.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
return_content: yes
register: privatekey1
- name: "({{ select_crypto_backend }}) Generate privatekey1 - standard (idempotence, check mode)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey1.pem'
path: '{{ remote_tmp_dir }}/privatekey1.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
return_content: yes
check_mode: true
@@ -24,34 +24,34 @@
- name: "({{ select_crypto_backend }}) Generate privatekey1 - standard (idempotence)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey1.pem'
path: '{{ remote_tmp_dir }}/privatekey1.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
return_content: yes
register: privatekey1_idempotence
- name: "({{ select_crypto_backend }}) Generate privatekey2 - size 2048"
openssl_privatekey:
path: '{{ output_dir }}/privatekey2.pem'
path: '{{ remote_tmp_dir }}/privatekey2.pem'
size: 2048
select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate privatekey3 - type DSA"
openssl_privatekey:
path: '{{ output_dir }}/privatekey3.pem'
path: '{{ remote_tmp_dir }}/privatekey3.pem'
type: DSA
size: 3072
select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate privatekey4 - standard"
openssl_privatekey:
path: '{{ output_dir }}/privatekey4.pem'
path: '{{ remote_tmp_dir }}/privatekey4.pem'
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Delete privatekey4 - standard"
openssl_privatekey:
state: absent
path: '{{ output_dir }}/privatekey4.pem'
path: '{{ remote_tmp_dir }}/privatekey4.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
return_content: yes
register: privatekey4_delete
@@ -59,13 +59,13 @@
- name: "({{ select_crypto_backend }}) Delete privatekey4 - standard (idempotence)"
openssl_privatekey:
state: absent
path: '{{ output_dir }}/privatekey4.pem'
path: '{{ remote_tmp_dir }}/privatekey4.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
register: privatekey4_delete_idempotence
- name: "({{ select_crypto_backend }}) Generate privatekey5 - standard - with passphrase"
openssl_privatekey:
path: '{{ output_dir }}/privatekey5.pem'
path: '{{ remote_tmp_dir }}/privatekey5.pem'
passphrase: ansible
cipher: "{{ 'aes256' if select_crypto_backend == 'pyopenssl' else 'auto' }}"
size: '{{ default_rsa_key_size }}'
@@ -73,7 +73,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey5 - standard - idempotence"
openssl_privatekey:
path: '{{ output_dir }}/privatekey5.pem'
path: '{{ remote_tmp_dir }}/privatekey5.pem'
passphrase: ansible
cipher: "{{ 'aes256' if select_crypto_backend == 'pyopenssl' else 'auto' }}"
size: '{{ default_rsa_key_size }}'
@@ -82,7 +82,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey6 - standard - with non-ASCII passphrase"
openssl_privatekey:
path: '{{ output_dir }}/privatekey6.pem'
path: '{{ remote_tmp_dir }}/privatekey6.pem'
passphrase: ànsïblé
cipher: "{{ 'aes256' if select_crypto_backend == 'pyopenssl' else 'auto' }}"
size: '{{ default_rsa_key_size }}'
@@ -154,7 +154,7 @@
- name: "({{ select_crypto_backend }}) Test ECC key generation"
openssl_privatekey:
path: '{{ output_dir }}/privatekey-{{ item.curve }}.pem'
path: '{{ remote_tmp_dir }}/privatekey-{{ item.curve }}.pem'
type: ECC
curve: "{{ item.curve }}"
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -168,7 +168,7 @@
- name: "({{ select_crypto_backend }}) Test ECC key generation (idempotency)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey-{{ item.curve }}.pem'
path: '{{ remote_tmp_dir }}/privatekey-{{ item.curve }}.pem'
type: ECC
curve: "{{ item.curve }}"
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -183,7 +183,7 @@
- block:
- name: "({{ select_crypto_backend }}) Test other type generation"
openssl_privatekey:
path: '{{ output_dir }}/privatekey-{{ item.type }}.pem'
path: '{{ remote_tmp_dir }}/privatekey-{{ item.type }}.pem'
type: "{{ item.type }}"
select_crypto_backend: '{{ select_crypto_backend }}'
when: cryptography_version.stdout is version(item.min_version, '>=')
@@ -195,7 +195,7 @@
- name: "({{ select_crypto_backend }}) Test other type generation (idempotency)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey-{{ item.type }}.pem'
path: '{{ remote_tmp_dir }}/privatekey-{{ item.type }}.pem'
type: "{{ item.type }}"
select_crypto_backend: '{{ select_crypto_backend }}'
when: cryptography_version.stdout is version(item.min_version, '>=')
@@ -219,7 +219,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey with passphrase"
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: "{{ 'aes256' if select_crypto_backend == 'pyopenssl' else 'auto' }}"
size: '{{ default_rsa_key_size }}'
@@ -229,7 +229,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey with passphrase (idempotent)"
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: "{{ 'aes256' if select_crypto_backend == 'pyopenssl' else 'auto' }}"
size: '{{ default_rsa_key_size }}'
@@ -239,7 +239,7 @@
- name: "({{ select_crypto_backend }}) Regenerate privatekey without passphrase"
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
backup: yes
@@ -247,7 +247,7 @@
- name: "({{ select_crypto_backend }}) Regenerate privatekey without passphrase (idempotent)"
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
backup: yes
@@ -255,7 +255,7 @@
- name: "({{ select_crypto_backend }}) Regenerate privatekey with passphrase"
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: "{{ 'aes256' if select_crypto_backend == 'pyopenssl' else 'auto' }}"
size: '{{ default_rsa_key_size }}'
@@ -265,18 +265,18 @@
- name: "({{ select_crypto_backend }}) Create broken key"
copy:
dest: "{{ output_dir }}/broken"
dest: "{{ remote_tmp_dir }}/broken"
content: "broken"
- name: "({{ select_crypto_backend }}) Regenerate broken key"
openssl_privatekey:
path: '{{ output_dir }}/broken.pem'
path: '{{ remote_tmp_dir }}/broken.pem'
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
register: output_broken
- name: "({{ select_crypto_backend }}) Remove module"
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: "{{ 'aes256' if select_crypto_backend == 'pyopenssl' else 'auto' }}"
size: '{{ default_rsa_key_size }}'
@@ -287,7 +287,7 @@
- name: "({{ select_crypto_backend }}) Remove module (idempotent)"
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: "{{ 'aes256' if select_crypto_backend == 'pyopenssl' else 'auto' }}"
size: '{{ default_rsa_key_size }}'
@@ -298,19 +298,19 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_mode (mode 0400)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_mode.pem'
path: '{{ remote_tmp_dir }}/privatekey_mode.pem'
mode: '0400'
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
register: privatekey_mode_1
- name: "({{ select_crypto_backend }}) Stat for privatekey_mode"
stat:
path: '{{ output_dir }}/privatekey_mode.pem'
path: '{{ remote_tmp_dir }}/privatekey_mode.pem'
register: privatekey_mode_1_stat
- name: "({{ select_crypto_backend }}) Generate privatekey_mode (mode 0400, idempotency)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_mode.pem'
path: '{{ remote_tmp_dir }}/privatekey_mode.pem'
mode: '0400'
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -325,7 +325,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_mode (mode 0400, force)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_mode.pem'
path: '{{ remote_tmp_dir }}/privatekey_mode.pem'
mode: '0400'
force: yes
size: '{{ default_rsa_key_size }}'
@@ -333,13 +333,13 @@
register: privatekey_mode_3
- name: "({{ select_crypto_backend }}) Stat for privatekey_mode"
stat:
path: '{{ output_dir }}/privatekey_mode.pem'
path: '{{ remote_tmp_dir }}/privatekey_mode.pem'
register: privatekey_mode_3_stat
- block:
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - auto format"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
format: auto
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -347,7 +347,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - auto format (idempotent)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
format: auto
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -355,7 +355,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - PKCS1 format"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
format: pkcs1
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -363,7 +363,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - PKCS8 format"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
format: pkcs8
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -371,7 +371,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - PKCS8 format (idempotent)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
format: pkcs8
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -379,7 +379,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - auto format (ignore)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
format: auto_ignore
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -387,7 +387,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - auto format (no ignore)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
format: auto
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -395,7 +395,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - raw format (fail)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
format: raw
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -404,13 +404,13 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - PKCS8 format (convert)"
openssl_privatekey_info:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
register: privatekey_fmt_1_step_9_before
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - PKCS8 format (convert)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
format: pkcs8
format_mismatch: convert
size: '{{ default_rsa_key_size }}'
@@ -419,7 +419,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_1 - PKCS8 format (convert)"
openssl_privatekey_info:
path: '{{ output_dir }}/privatekey_fmt_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_1.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
register: privatekey_fmt_1_step_9_after
@@ -428,7 +428,7 @@
- block:
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_2 - PKCS8 format"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_2.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_2.pem'
type: X448
format: pkcs8
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -437,7 +437,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_2 - PKCS8 format (idempotent)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_2.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_2.pem'
type: X448
format: pkcs8
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -446,7 +446,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_2 - raw format"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_2.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_2.pem'
type: X448
format: raw
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -456,7 +456,7 @@
- name: "({{ select_crypto_backend }}) Read privatekey_fmt_2.pem"
slurp:
src: "{{ output_dir }}/privatekey_fmt_2.pem"
src: "{{ remote_tmp_dir }}/privatekey_fmt_2.pem"
ignore_errors: yes
register: content
@@ -468,7 +468,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_2 - raw format (idempotent)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_2.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_2.pem'
type: X448
format: raw
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -478,7 +478,7 @@
- name: "({{ select_crypto_backend }}) Read privatekey_fmt_2.pem"
slurp:
src: "{{ output_dir }}/privatekey_fmt_2.pem"
src: "{{ remote_tmp_dir }}/privatekey_fmt_2.pem"
ignore_errors: yes
register: content
@@ -490,7 +490,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_2 - auto format (ignore)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_2.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_2.pem'
type: X448
format: auto_ignore
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -500,7 +500,7 @@
- name: "({{ select_crypto_backend }}) Read privatekey_fmt_2.pem"
slurp:
src: "{{ output_dir }}/privatekey_fmt_2.pem"
src: "{{ remote_tmp_dir }}/privatekey_fmt_2.pem"
ignore_errors: yes
register: content
@@ -512,7 +512,7 @@
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_2 - auto format (no ignore)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey_fmt_2.pem'
path: '{{ remote_tmp_dir }}/privatekey_fmt_2.pem'
type: X448
format: auto
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -520,10 +520,16 @@
ignore_errors: yes
register: privatekey_fmt_2_step_6
- name: "({{ select_crypto_backend }}) Read private key"
slurp:
src: '{{ remote_tmp_dir }}/privatekey_fmt_2.pem'
register: slurp
when: privatekey_fmt_2_step_1 is not failed
- name: "({{ select_crypto_backend }}) Generate privatekey_fmt_2 - verify that returned content is not base64 encoded"
assert:
that:
- privatekey_fmt_2_step_6.privatekey == lookup('file', output_dir ~ '/privatekey_fmt_2.pem', rstrip=False)
- privatekey_fmt_2_step_6.privatekey == (slurp.content | b64decode)
when: privatekey_fmt_2_step_1 is not failed
when: 'select_crypto_backend == "cryptography" and cryptography_version.stdout is version("2.6", ">=")'
@@ -534,14 +540,14 @@
- name: "({{ select_crypto_backend }}) Regenerate - setup simple keys"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: RSA
size: '{{ default_rsa_key_size }}'
select_crypto_backend: '{{ select_crypto_backend }}'
loop: "{{ regenerate_values }}"
- name: "({{ select_crypto_backend }}) Regenerate - setup password protected keys"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-b-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-b-{{ item }}.pem'
type: RSA
size: '{{ default_rsa_key_size }}'
passphrase: hunter2
@@ -550,14 +556,14 @@
loop: "{{ regenerate_values }}"
- name: "({{ select_crypto_backend }}) Regenerate - setup broken keys"
copy:
dest: '{{ output_dir }}/regenerate-c-{{ item }}.pem'
dest: '{{ remote_tmp_dir }}/regenerate-c-{{ item }}.pem'
content: 'broken key'
mode: '0700'
loop: "{{ regenerate_values }}"
- name: "({{ select_crypto_backend }}) Regenerate - modify broken keys (check mode)"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-c-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-c-{{ item }}.pem'
type: RSA
size: '{{ default_rsa_key_size }}'
regenerate: '{{ item }}'
@@ -579,7 +585,7 @@
- name: "({{ select_crypto_backend }}) Regenerate - modify broken keys"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-c-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-c-{{ item }}.pem'
type: RSA
size: '{{ default_rsa_key_size }}'
regenerate: '{{ item }}'
@@ -600,7 +606,7 @@
- name: "({{ select_crypto_backend }}) Regenerate - modify password protected keys (check mode)"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-b-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-b-{{ item }}.pem'
type: RSA
size: '{{ default_rsa_key_size }}'
regenerate: '{{ item }}'
@@ -622,7 +628,7 @@
- name: "({{ select_crypto_backend }}) Regenerate - modify password protected keys"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-b-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-b-{{ item }}.pem'
type: RSA
size: '{{ default_rsa_key_size }}'
regenerate: '{{ item }}'
@@ -643,7 +649,7 @@
- name: "({{ select_crypto_backend }}) Regenerate - not modify regular keys (check mode)"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: RSA
size: '{{ default_rsa_key_size }}'
regenerate: '{{ item }}'
@@ -661,7 +667,7 @@
- name: "({{ select_crypto_backend }}) Regenerate - not modify regular keys"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: RSA
size: '{{ default_rsa_key_size }}'
regenerate: '{{ item }}'
@@ -678,7 +684,7 @@
- name: "({{ select_crypto_backend }}) Regenerate - adjust key size (check mode)"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: RSA
size: '{{ default_rsa_key_size + 20 }}'
regenerate: '{{ item }}'
@@ -698,7 +704,7 @@
- name: "({{ select_crypto_backend }}) Regenerate - adjust key size"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: RSA
size: '{{ default_rsa_key_size + 20 }}'
regenerate: '{{ item }}'
@@ -717,15 +723,15 @@
- name: "({{ select_crypto_backend }}) Regenerate - redistribute keys"
copy:
src: '{{ output_dir }}/regenerate-a-always.pem'
dest: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
src: '{{ remote_tmp_dir }}/regenerate-a-always.pem'
dest: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
remote_src: true
loop: "{{ regenerate_values }}"
when: "item != 'always'"
- name: "({{ select_crypto_backend }}) Regenerate - adjust key type (check mode)"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: DSA
size: '{{ default_rsa_key_size }}'
regenerate: '{{ item }}'
@@ -745,7 +751,7 @@
- name: "({{ select_crypto_backend }}) Regenerate - adjust key type"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: DSA
size: '{{ default_rsa_key_size }}'
regenerate: '{{ item }}'
@@ -765,15 +771,15 @@
- block:
- name: "({{ select_crypto_backend }}) Regenerate - redistribute keys"
copy:
src: '{{ output_dir }}/regenerate-a-always.pem'
dest: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
src: '{{ remote_tmp_dir }}/regenerate-a-always.pem'
dest: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
remote_src: true
loop: "{{ regenerate_values }}"
when: "item != 'always'"
- name: "({{ select_crypto_backend }}) Regenerate - format mismatch (check mode)"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: DSA
size: '{{ default_rsa_key_size }}'
format: pkcs8
@@ -794,7 +800,7 @@
- name: "({{ select_crypto_backend }}) Regenerate - format mismatch"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: DSA
size: '{{ default_rsa_key_size }}'
format: pkcs8
@@ -814,15 +820,15 @@
- name: "({{ select_crypto_backend }}) Regenerate - redistribute keys"
copy:
src: '{{ output_dir }}/regenerate-a-always.pem'
dest: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
src: '{{ remote_tmp_dir }}/regenerate-a-always.pem'
dest: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
remote_src: true
loop: "{{ regenerate_values }}"
when: "item != 'always'"
- name: "({{ select_crypto_backend }}) Regenerate - convert format (check mode)"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: DSA
size: '{{ default_rsa_key_size }}'
format: pkcs1
@@ -842,7 +848,7 @@
- name: "({{ select_crypto_backend }}) Regenerate - convert format"
openssl_privatekey:
path: '{{ output_dir }}/regenerate-a-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/regenerate-a-{{ item }}.pem'
type: DSA
size: '{{ default_rsa_key_size }}'
format: pkcs1

View File

@@ -33,7 +33,7 @@
- name: Run module with backend autodetection
openssl_privatekey:
path: '{{ output_dir }}/privatekey_backend_selection.pem'
path: '{{ remote_tmp_dir }}/privatekey_backend_selection.pem'
size: '{{ default_rsa_key_size }}'
- block:
@@ -51,12 +51,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:
@@ -75,7 +75,7 @@
block:
- name: "Fingerprint comparison: pyOpenSSL"
openssl_privatekey:
path: '{{ output_dir }}/fingerprint-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/fingerprint-{{ item }}.pem'
type: "{{ item }}"
size: '{{ default_rsa_key_size }}'
select_crypto_backend: pyopenssl
@@ -86,7 +86,7 @@
- name: "Fingerprint comparison: cryptography"
openssl_privatekey:
path: '{{ output_dir }}/fingerprint-{{ item }}.pem'
path: '{{ remote_tmp_dir }}/fingerprint-{{ item }}.pem'
type: "{{ item }}"
size: '{{ default_rsa_key_size }}'
select_crypto_backend: cryptography

View File

@@ -2,6 +2,11 @@
- set_fact:
system_potentially_has_no_algorithm_support: "{{ ansible_os_family == 'FreeBSD' }}"
- name: "({{ select_crypto_backend }}) Read private key"
slurp:
src: '{{ remote_tmp_dir }}/privatekey1.pem'
register: slurp
- name: "({{ select_crypto_backend }}) Validate privatekey1 idempotency and content returned"
assert:
that:
@@ -9,12 +14,12 @@
- privatekey1 is changed
- privatekey1_idempotence_check is not changed
- privatekey1_idempotence is not changed
- privatekey1.privatekey == lookup('file', output_dir ~ '/privatekey1.pem', rstrip=False)
- privatekey1.privatekey == (slurp.content | b64decode)
- privatekey1.privatekey == privatekey1_idempotence.privatekey
- name: "({{ select_crypto_backend }}) Validate privatekey1 (test - RSA key with size 4096 bits)"
shell: "{{ openssl_binary }} rsa -noout -text -in {{ output_dir }}/privatekey1.pem | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
shell: "{{ openssl_binary }} rsa -noout -text -in {{ remote_tmp_dir }}/privatekey1.pem | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
register: privatekey1
- name: "({{ select_crypto_backend }}) Validate privatekey1 (assert - RSA key with size 4096 bits)"
@@ -24,7 +29,7 @@
- name: "({{ select_crypto_backend }}) Validate privatekey2 (test - RSA key with size 2048 bits)"
shell: "{{ openssl_binary }} rsa -noout -text -in {{ output_dir }}/privatekey2.pem | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
shell: "{{ openssl_binary }} rsa -noout -text -in {{ remote_tmp_dir }}/privatekey2.pem | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
register: privatekey2
- name: "({{ select_crypto_backend }}) Validate privatekey2 (assert - RSA key with size 2048 bits)"
@@ -34,7 +39,7 @@
- name: "({{ select_crypto_backend }}) Validate privatekey3 (test - DSA key with size 3072 bits)"
shell: "{{ openssl_binary }} dsa -noout -text -in {{ output_dir }}/privatekey3.pem | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
shell: "{{ openssl_binary }} dsa -noout -text -in {{ remote_tmp_dir }}/privatekey3.pem | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
register: privatekey3
- name: Validate privatekey3 (assert - DSA key with size 3072 bits)
@@ -45,7 +50,7 @@
- name: "({{ select_crypto_backend }}) Validate privatekey4 (test - Ensure key has been removed)"
stat:
path: '{{ output_dir }}/privatekey4.pem'
path: '{{ remote_tmp_dir }}/privatekey4.pem'
register: privatekey4
- name: "({{ select_crypto_backend }}) Validate privatekey4 (assert - Ensure key has been removed)"
@@ -62,7 +67,7 @@
- name: "({{ select_crypto_backend }}) Validate privatekey5 (test - Passphrase protected key + idempotence)"
shell: "{{ openssl_binary }} rsa -noout -text -in {{ output_dir }}/privatekey5.pem -passin pass:ansible | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
shell: "{{ openssl_binary }} rsa -noout -text -in {{ remote_tmp_dir }}/privatekey5.pem -passin pass:ansible | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
register: privatekey5
# Current version of OS/X that runs in the CI (10.11) does not have an up to date version of the OpenSSL library
# leading to this test to fail when run in the CI. However, this test has been run for 10.12 and has returned succesfully.
@@ -81,7 +86,7 @@
- name: "({{ select_crypto_backend }}) Validate privatekey6 (test - Passphrase protected key with non ascii character)"
shell: "{{ openssl_binary }} rsa -noout -text -in {{ output_dir }}/privatekey6.pem -passin pass:ànsïblé | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
shell: "{{ openssl_binary }} rsa -noout -text -in {{ remote_tmp_dir }}/privatekey6.pem -passin pass:ànsïblé | grep Private | sed 's/\\(RSA *\\)*Private-Key: (\\(.*\\) bit.*)/\\2/'"
register: privatekey6
when: openssl_version.stdout is version('0.9.8zh', '>=')
@@ -92,7 +97,7 @@
when: openssl_version.stdout is version('0.9.8zh', '>=')
- name: "({{ select_crypto_backend }}) Validate ECC generation (dump with OpenSSL)"
shell: "{{ openssl_binary }} ec -in {{ output_dir }}/privatekey-{{ item.item.curve }}.pem -noout -text | grep 'ASN1 OID: ' | sed 's/ASN1 OID: \\([^ ]*\\)/\\1/'"
shell: "{{ openssl_binary }} ec -in {{ remote_tmp_dir }}/privatekey-{{ item.item.curve }}.pem -noout -text | grep 'ASN1 OID: ' | sed 's/ASN1 OID: \\([^ ]*\\)/\\1/'"
loop: "{{ privatekey_ecc_generate.results }}"
register: privatekey_ecc_dump
when: openssl_version.stdout is version('0.9.8zh', '>=') and 'skip_reason' not in item

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -4,7 +4,7 @@
- name: ({{select_crypto_backend}}) Get key 1 info
openssl_privatekey_info:
path: '{{ output_dir }}/privatekey_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_1.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result
@@ -24,9 +24,14 @@
set_fact:
info_results: "{{ info_results | combine({'key1': result}) }}"
- name: ({{select_crypto_backend}}) Read private key
slurp:
src: '{{ remote_tmp_dir }}/privatekey_1.pem'
register: slurp
- name: ({{select_crypto_backend}}) Get key 1 info directly
openssl_privatekey_info:
content: '{{ lookup("file", output_dir ~ "/privatekey_1.pem") }}'
content: '{{ slurp.content | b64decode }}'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result_direct
@@ -37,7 +42,7 @@
- name: ({{select_crypto_backend}}) Get key 2 info
openssl_privatekey_info:
path: '{{ output_dir }}/privatekey_2.pem'
path: '{{ remote_tmp_dir }}/privatekey_2.pem'
return_private_key_data: yes
select_crypto_backend: '{{ select_crypto_backend }}'
register: result
@@ -63,7 +68,7 @@
- name: ({{select_crypto_backend}}) Get key 3 info (without passphrase)
openssl_privatekey_info:
path: '{{ output_dir }}/privatekey_3.pem'
path: '{{ remote_tmp_dir }}/privatekey_3.pem'
return_private_key_data: yes
select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes
@@ -88,7 +93,7 @@
- name: ({{select_crypto_backend}}) Get key 3 info (with passphrase)
openssl_privatekey_info:
path: '{{ output_dir }}/privatekey_3.pem'
path: '{{ remote_tmp_dir }}/privatekey_3.pem'
passphrase: hunter2
return_private_key_data: yes
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -114,7 +119,7 @@
- name: ({{select_crypto_backend}}) Get key 4 info
openssl_privatekey_info:
path: '{{ output_dir }}/privatekey_4.pem'
path: '{{ remote_tmp_dir }}/privatekey_4.pem'
return_private_key_data: yes
select_crypto_backend: '{{ select_crypto_backend }}'
register: result
@@ -153,7 +158,7 @@
- name: ({{select_crypto_backend}}) Get key 5 info
openssl_privatekey_info:
path: '{{ output_dir }}/privatekey_5.pem'
path: '{{ remote_tmp_dir }}/privatekey_5.pem'
return_private_key_data: yes
select_crypto_backend: '{{ select_crypto_backend }}'
register: result

View File

@@ -6,17 +6,17 @@
- name: Generate privatekey 1
openssl_privatekey:
path: '{{ output_dir }}/privatekey_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_1.pem'
- name: Generate privatekey 2 (less bits)
openssl_privatekey:
path: '{{ output_dir }}/privatekey_2.pem'
path: '{{ remote_tmp_dir }}/privatekey_2.pem'
type: RSA
size: '{{ default_rsa_key_size }}'
- name: Generate privatekey 3 (with password)
openssl_privatekey:
path: '{{ output_dir }}/privatekey_3.pem'
path: '{{ remote_tmp_dir }}/privatekey_3.pem'
passphrase: hunter2
cipher: auto
size: '{{ default_rsa_key_size }}'
@@ -24,7 +24,7 @@
- name: Generate privatekey 4 (ECC)
openssl_privatekey:
path: '{{ output_dir }}/privatekey_4.pem'
path: '{{ remote_tmp_dir }}/privatekey_4.pem'
type: ECC
curve: "{{ (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6') | ternary('secp521r1', 'secp256k1') }}"
# ^ cryptography on CentOS6 doesn't support secp256k1, so we use secp521r1 instead
@@ -32,7 +32,7 @@
- name: Generate privatekey 5 (DSA)
openssl_privatekey:
path: '{{ output_dir }}/privatekey_5.pem'
path: '{{ remote_tmp_dir }}/privatekey_5.pem'
type: DSA
size: 1024

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -19,12 +19,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -1,13 +1,13 @@
---
- name: "({{ select_crypto_backend }}) Generate privatekey"
openssl_privatekey:
path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/privatekey.pem'
size: '{{ default_rsa_key_size }}'
- name: "({{ select_crypto_backend }}) Generate publickey - PEM format (check mode)"
openssl_publickey:
path: '{{ output_dir }}/publickey.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
return_content: yes
check_mode: true
@@ -15,16 +15,16 @@
- name: "({{ select_crypto_backend }}) Generate publickey - PEM format"
openssl_publickey:
path: '{{ output_dir }}/publickey.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
return_content: yes
register: publickey
- name: "({{ select_crypto_backend }}) Generate publickey - PEM format (check mode, idempotence)"
openssl_publickey:
path: '{{ output_dir }}/publickey.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
return_content: yes
check_mode: true
@@ -32,8 +32,8 @@
- name: "({{ select_crypto_backend }}) Generate publickey - PEM format (idempotence)"
openssl_publickey:
path: '{{ output_dir }}/publickey.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
return_content: yes
register: publickey_idempotence
@@ -48,16 +48,16 @@
- name: "({{ select_crypto_backend }}) Generate publickey - OpenSSH format"
openssl_publickey:
path: '{{ output_dir }}/publickey-ssh.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey-ssh.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
format: OpenSSH
select_crypto_backend: '{{ select_crypto_backend }}'
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=')
- name: "({{ select_crypto_backend }}) Generate publickey - OpenSSH format - test idempotence (issue 33256)"
openssl_publickey:
path: '{{ output_dir }}/publickey-ssh.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey-ssh.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
format: OpenSSH
select_crypto_backend: '{{ select_crypto_backend }}'
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=')
@@ -65,15 +65,15 @@
- name: "({{ select_crypto_backend }}) Generate publickey2 - standard"
openssl_publickey:
path: '{{ output_dir }}/publickey2.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey2.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Delete publickey2 - standard"
openssl_publickey:
state: absent
path: '{{ output_dir }}/publickey2.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey2.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
return_content: yes
register: publickey2_absent
@@ -81,76 +81,76 @@
- name: "({{ select_crypto_backend }}) Delete publickey2 - standard (idempotence)"
openssl_publickey:
state: absent
path: '{{ output_dir }}/publickey2.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey2.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
register: publickey2_absent_idempotence
- name: "({{ select_crypto_backend }}) Generate privatekey3 - with passphrase"
openssl_privatekey:
path: '{{ output_dir }}/privatekey3.pem'
path: '{{ remote_tmp_dir }}/privatekey3.pem'
passphrase: ansible
cipher: aes256
size: '{{ default_rsa_key_size }}'
- name: "({{ select_crypto_backend }}) Generate publickey3 - with passphrase protected privatekey"
openssl_publickey:
path: '{{ output_dir }}/publickey3.pub'
privatekey_path: '{{ output_dir }}/privatekey3.pem'
path: '{{ remote_tmp_dir }}/publickey3.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey3.pem'
privatekey_passphrase: ansible
select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate publickey3 - with passphrase protected privatekey - idempotence"
openssl_publickey:
path: '{{ output_dir }}/publickey3.pub'
privatekey_path: '{{ output_dir }}/privatekey3.pem'
path: '{{ remote_tmp_dir }}/publickey3.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey3.pem'
privatekey_passphrase: ansible
select_crypto_backend: '{{ select_crypto_backend }}'
register: publickey3_idempotence
- name: "({{ select_crypto_backend }}) Generate empty file that will hold a public key (issue 33072)"
file:
path: '{{ output_dir }}/publickey4.pub'
path: '{{ remote_tmp_dir }}/publickey4.pub'
state: touch
- name: "({{ select_crypto_backend }}) Generate publickey in empty existing file (issue 33072)"
openssl_publickey:
path: '{{ output_dir }}/publickey4.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey4.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate privatekey 5 (ECC)"
openssl_privatekey:
path: '{{ output_dir }}/privatekey5.pem'
path: '{{ remote_tmp_dir }}/privatekey5.pem'
type: ECC
curve: secp256r1
size: '{{ default_rsa_key_size }}'
- name: "({{ select_crypto_backend }}) Generate publickey 5 - PEM format"
openssl_publickey:
path: '{{ output_dir }}/publickey5.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey5.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
backup: yes
select_crypto_backend: '{{ select_crypto_backend }}'
register: privatekey5_1
- name: "({{ select_crypto_backend }}) Generate publickey 5 - PEM format (idempotent)"
openssl_publickey:
path: '{{ output_dir }}/publickey5.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey5.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
backup: yes
select_crypto_backend: '{{ select_crypto_backend }}'
register: privatekey5_2
- name: "({{ select_crypto_backend }}) Generate publickey 5 - PEM format (different private key)"
openssl_publickey:
path: '{{ output_dir }}/publickey5.pub'
privatekey_path: '{{ output_dir }}/privatekey5.pem'
path: '{{ remote_tmp_dir }}/publickey5.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey5.pem'
backup: yes
select_crypto_backend: '{{ select_crypto_backend }}'
register: privatekey5_3
- name: "({{ select_crypto_backend }}) Generate privatekey with password"
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: auto
select_crypto_backend: cryptography
@@ -158,8 +158,8 @@
- name: "({{ select_crypto_backend }}) Generate publickey - PEM format (failed passphrase 1)"
openssl_publickey:
path: '{{ output_dir }}/publickey_pw1.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey_pw1.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
privatekey_passphrase: hunter2
select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes
@@ -167,8 +167,8 @@
- name: "({{ select_crypto_backend }}) Generate publickey - PEM format (failed passphrase 2)"
openssl_publickey:
path: '{{ output_dir }}/publickey_pw2.pub'
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/publickey_pw2.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: wrong_password
select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes
@@ -176,41 +176,41 @@
- name: "({{ select_crypto_backend }}) Generate publickey - PEM format (failed passphrase 3)"
openssl_publickey:
path: '{{ output_dir }}/publickey_pw3.pub'
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/publickey_pw3.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes
register: passphrase_error_3
- name: "({{ select_crypto_backend }}) Create broken key"
copy:
dest: "{{ output_dir }}/publickeybroken.pub"
dest: "{{ remote_tmp_dir }}/publickeybroken.pub"
content: "broken"
- name: "({{ select_crypto_backend }}) Regenerate broken key"
openssl_publickey:
path: '{{ output_dir }}/publickeybroken.pub'
privatekey_path: '{{ output_dir }}/privatekey5.pem'
path: '{{ remote_tmp_dir }}/publickeybroken.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey5.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
register: output_broken
- name: "({{ select_crypto_backend }}) Generate publickey - PEM format (for removal)"
openssl_publickey:
path: '{{ output_dir }}/publickey_removal.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey_removal.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
- name: "({{ select_crypto_backend }}) Generate publickey - PEM format (removal)"
openssl_publickey:
state: absent
path: '{{ output_dir }}/publickey_removal.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey_removal.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
backup: yes
select_crypto_backend: '{{ select_crypto_backend }}'
register: remove_1
- name: "({{ select_crypto_backend }}) Generate publickey - PEM format (removal, idempotent)"
openssl_publickey:
state: absent
path: '{{ output_dir }}/publickey_removal.pub'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/publickey_removal.pub'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
backup: yes
select_crypto_backend: '{{ select_crypto_backend }}'
register: remove_2

View File

@@ -7,13 +7,13 @@
- block:
- name: Generate privatekey1 - standard
openssl_privatekey:
path: '{{ output_dir }}/privatekey_autodetect.pem'
path: '{{ remote_tmp_dir }}/privatekey_autodetect.pem'
size: '{{ default_rsa_key_size }}'
- name: Run module with backend autodetection
openssl_publickey:
path: '{{ output_dir }}/privatekey_autodetect_public.pem'
privatekey_path: '{{ output_dir }}/privatekey_autodetect.pem'
path: '{{ remote_tmp_dir }}/privatekey_autodetect_public.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekey_autodetect.pem'
when: |
pyopenssl_version.stdout is version('16.0.0', '>=') or
@@ -33,12 +33,12 @@
- name: Remove output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: absent
- name: Re-create output directory
file:
path: "{{ output_dir }}"
path: "{{ remote_tmp_dir }}"
state: directory
- block:

View File

@@ -1,18 +1,23 @@
---
- name: "({{ select_crypto_backend }}) Read publickey 1"
slurp:
src: '{{ remote_tmp_dir }}/publickey.pub'
register: slurp
- name: "({{ select_crypto_backend }}) Validate publickey 1 idempotence and result behavior"
assert:
that:
- publickey is changed
- publickey_idempotence is not changed
- publickey.publickey == lookup('file', output_dir ~ '/publickey.pub', rstrip=False)
- publickey.publickey == (slurp.content | b64decode)
- publickey.publickey == publickey_idempotence.publickey
- name: "({{ select_crypto_backend }}) Validate public key (test - privatekey modulus)"
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ output_dir }}/privatekey.pem'
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ remote_tmp_dir }}/privatekey.pem'
register: privatekey_modulus
- name: "({{ select_crypto_backend }}) Validate public key (test - publickey modulus)"
shell: '{{ openssl_binary }} rsa -pubin -noout -modulus < {{ output_dir }}/publickey.pub'
shell: '{{ openssl_binary }} rsa -pubin -noout -modulus < {{ remote_tmp_dir }}/publickey.pub'
register: publickey_modulus
- name: "({{ select_crypto_backend }}) Validate public key (assert)"
@@ -21,13 +26,13 @@
- publickey_modulus.stdout == privatekey_modulus.stdout
- name: "({{ select_crypto_backend }}) Validate public key - OpenSSH format (test - privatekey's publickey)"
shell: 'ssh-keygen -y -f {{ output_dir }}/privatekey.pem'
shell: 'ssh-keygen -y -f {{ remote_tmp_dir }}/privatekey.pem'
register: privatekey_publickey
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=')
- name: "({{ select_crypto_backend }}) Validate public key - OpenSSH format (test - publickey)"
slurp:
src: '{{ output_dir }}/publickey-ssh.pub'
src: '{{ remote_tmp_dir }}/publickey-ssh.pub'
register: publickey
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=')
@@ -45,7 +50,7 @@
- name: "({{ select_crypto_backend }}) Validate publickey2 (test - Ensure key has been removed)"
stat:
path: '{{ output_dir }}/publickey2.pub'
path: '{{ remote_tmp_dir }}/publickey2.pub'
register: publickey2
- name: "({{ select_crypto_backend }}) Validate publickey2 (assert - Ensure key has been removed)"
@@ -62,12 +67,12 @@
- name: "({{ select_crypto_backend }}) Validate publickey3 (test - privatekey modulus)"
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ output_dir }}/privatekey3.pem -passin pass:ansible'
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ remote_tmp_dir }}/privatekey3.pem -passin pass:ansible'
register: privatekey3_modulus
when: openssl_version.stdout is version('0.9.8zh', '>=')
- name: "({{ select_crypto_backend }}) Validate publickey3 (test - publickey modulus)"
shell: '{{ openssl_binary }} rsa -pubin -noout -modulus < {{ output_dir }}/publickey3.pub'
shell: '{{ openssl_binary }} rsa -pubin -noout -modulus < {{ remote_tmp_dir }}/publickey3.pub'
register: publickey3_modulus
when: openssl_version.stdout is version('0.9.8zh', '>=')
@@ -83,12 +88,12 @@
- publickey3_idempotence is not changed
- name: "({{ select_crypto_backend }}) Validate publickey4 (test - privatekey modulus)"
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ output_dir }}/privatekey.pem'
shell: '{{ openssl_binary }} rsa -noout -modulus -in {{ remote_tmp_dir }}/privatekey.pem'
register: privatekey4_modulus
when: openssl_version.stdout is version('0.9.8zh', '>=')
- name: "({{ select_crypto_backend }}) Validate publickey4 (test - publickey modulus)"
shell: '{{ openssl_binary }} rsa -pubin -noout -modulus < {{ output_dir }}/publickey4.pub'
shell: '{{ openssl_binary }} rsa -pubin -noout -modulus < {{ remote_tmp_dir }}/publickey4.pub'
register: publickey4_modulus
when: openssl_version.stdout is version('0.9.8zh', '>=')
@@ -109,12 +114,12 @@
- privatekey5_3.backup_file is string
- name: "({{ select_crypto_backend }}) Validate public key 5 (test - privatekey's pubkey)"
command: '{{ openssl_binary }} ec -in {{ output_dir }}/privatekey5.pem -pubout'
command: '{{ openssl_binary }} ec -in {{ remote_tmp_dir }}/privatekey5.pem -pubout'
register: privatekey5_pubkey
- name: "({{ select_crypto_backend }}) Validate public key 5 (test - publickey pubkey)"
# Fancy way of writing "cat {{ output_dir }}/publickey5.pub"
command: '{{ openssl_binary }} ec -pubin -in {{ output_dir }}/publickey5.pub -pubout'
# Fancy way of writing "cat {{ remote_tmp_dir }}/publickey5.pub"
command: '{{ openssl_binary }} ec -pubin -in {{ remote_tmp_dir }}/publickey5.pub -pubout'
register: publickey5_pubkey
- name: "({{ select_crypto_backend }}) Validate public key 5 (assert)"

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -4,7 +4,7 @@
- name: ({{select_crypto_backend}}) Get key 1 info
openssl_publickey_info:
path: '{{ output_dir }}/publickey_1.pem'
path: '{{ remote_tmp_dir }}/publickey_1.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result
@@ -22,9 +22,14 @@
set_fact:
info_results: "{{ info_results | combine({'key1': result}) }}"
- name: ({{select_crypto_backend}}) Read file
slurp:
src: '{{ remote_tmp_dir }}/publickey_1.pem'
register: slurp
- name: ({{select_crypto_backend}}) Get key 1 info directly
openssl_publickey_info:
content: '{{ lookup("file", output_dir ~ "/publickey_1.pem") }}'
content: '{{ slurp.content | b64decode }}'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result_direct
@@ -35,7 +40,7 @@
- name: ({{select_crypto_backend}}) Get key 2 info
openssl_publickey_info:
path: '{{ output_dir }}/publickey_2.pem'
path: '{{ remote_tmp_dir }}/publickey_2.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result
@@ -56,7 +61,7 @@
- name: ({{select_crypto_backend}}) Get key 3 info
openssl_publickey_info:
path: '{{ output_dir }}/publickey_3.pem'
path: '{{ remote_tmp_dir }}/publickey_3.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result
@@ -89,7 +94,7 @@
- name: ({{select_crypto_backend}}) Get key 4 info
openssl_publickey_info:
path: '{{ output_dir }}/publickey_4.pem'
path: '{{ remote_tmp_dir }}/publickey_4.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
register: result

View File

@@ -6,17 +6,17 @@
- name: Generate privatekey 1
openssl_privatekey:
path: '{{ output_dir }}/privatekey_1.pem'
path: '{{ remote_tmp_dir }}/privatekey_1.pem'
- name: Generate privatekey 2 (less bits)
openssl_privatekey:
path: '{{ output_dir }}/privatekey_2.pem'
path: '{{ remote_tmp_dir }}/privatekey_2.pem'
type: RSA
size: '{{ default_rsa_key_size }}'
- name: Generate privatekey 3 (ECC)
openssl_privatekey:
path: '{{ output_dir }}/privatekey_3.pem'
path: '{{ remote_tmp_dir }}/privatekey_3.pem'
type: ECC
curve: "{{ (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6') | ternary('secp521r1', 'secp256k1') }}"
# ^ cryptography on CentOS6 doesn't support secp256k1, so we use secp521r1 instead
@@ -24,14 +24,14 @@
- name: Generate privatekey 4 (DSA)
openssl_privatekey:
path: '{{ output_dir }}/privatekey_4.pem'
path: '{{ remote_tmp_dir }}/privatekey_4.pem'
type: DSA
size: 1024
- name: Generate public keys
openssl_publickey:
privatekey_path: '{{ output_dir }}/privatekey_{{ item }}.pem'
path: '{{ output_dir }}/publickey_{{ item }}.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekey_{{ item }}.pem'
path: '{{ remote_tmp_dir }}/publickey_{{ item }}.pem'
loop:
- 1
- 2

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -2,9 +2,9 @@
# This file is intended to be included in a loop statement
- name: Sign statement with {{ item.type }} key - {{ item.passwd }} using {{ item.backend }}
openssl_signature:
privatekey_path: '{{ output_dir }}/{{item.backend}}_privatekey_{{ item.type }}_{{ item.passwd }}.pem'
privatekey_path: '{{ remote_tmp_dir }}/{{item.backend}}_privatekey_{{ item.type }}_{{ item.passwd }}.pem'
privatekey_passphrase: '{{ item.privatekey_passphrase | default(omit) }}'
path: '{{ output_dir }}/statement.txt'
path: '{{ remote_tmp_dir }}/statement.txt'
select_crypto_backend: '{{ item.backend }}'
register: sign_result
@@ -13,8 +13,8 @@
- name: Verify {{ item.type }} signature - {{ item.passwd }} using {{ item.backend }}
openssl_signature_info:
certificate_path: '{{ output_dir }}/{{item.backend}}_certificate_{{ item.type }}_{{ item.passwd }}.pem'
path: '{{ output_dir }}/statement.txt'
certificate_path: '{{ remote_tmp_dir }}/{{item.backend}}_certificate_{{ item.type }}_{{ item.passwd }}.pem'
path: '{{ remote_tmp_dir }}/statement.txt'
signature: '{{ sign_result.signature }}'
select_crypto_backend: '{{ item.backend }}'
register: verify_result

View File

@@ -71,7 +71,7 @@
- name: Generate private keys
openssl_privatekey:
path: '{{ output_dir }}/{{item.backend}}_privatekey_{{ item.type }}_{{ item.passwd }}.pem'
path: '{{ remote_tmp_dir }}/{{item.backend}}_privatekey_{{ item.type }}_{{ item.passwd }}.pem'
type: '{{ item.type }}'
curve: '{{ item.curve | default(omit) }}'
size: '{{ item.size | default(omit) }}'
@@ -82,31 +82,31 @@
- name: Generate public keys
openssl_publickey:
path: '{{ output_dir }}/{{item.backend}}_publickey_{{ item.type }}_{{ item.passwd }}.pem'
privatekey_path: '{{ output_dir }}/{{item.backend}}_privatekey_{{ item.type }}_{{ item.passwd }}.pem'
path: '{{ remote_tmp_dir }}/{{item.backend}}_publickey_{{ item.type }}_{{ item.passwd }}.pem'
privatekey_path: '{{ remote_tmp_dir }}/{{item.backend}}_privatekey_{{ item.type }}_{{ item.passwd }}.pem'
privatekey_passphrase: '{{ item.privatekey_passphrase | default(omit) }}'
loop: '{{ all_tests }}'
- name: Generate CSRs
openssl_csr:
path: '{{ output_dir }}/{{item.backend}}_{{ item.type }}_{{ item.passwd }}.csr'
privatekey_path: '{{ output_dir }}/{{item.backend}}_privatekey_{{ item.type }}_{{ item.passwd }}.pem'
path: '{{ remote_tmp_dir }}/{{item.backend}}_{{ item.type }}_{{ item.passwd }}.csr'
privatekey_path: '{{ remote_tmp_dir }}/{{item.backend}}_privatekey_{{ item.type }}_{{ item.passwd }}.pem'
privatekey_passphrase: '{{ item.privatekey_passphrase | default(omit) }}'
loop: '{{ all_tests }}'
- name: Generate selfsigned certificates
x509_certificate:
provider: selfsigned
path: '{{ output_dir }}/{{item.backend}}_certificate_{{ item.type }}_{{ item.passwd }}.pem'
privatekey_path: '{{ output_dir }}/{{item.backend}}_privatekey_{{ item.type }}_{{ item.passwd }}.pem'
path: '{{ remote_tmp_dir }}/{{item.backend}}_certificate_{{ item.type }}_{{ item.passwd }}.pem'
privatekey_path: '{{ remote_tmp_dir }}/{{item.backend}}_privatekey_{{ item.type }}_{{ item.passwd }}.pem'
privatekey_passphrase: '{{ item.privatekey_passphrase | default(omit) }}'
csr_path: '{{ output_dir }}/{{item.backend}}_{{ item.type }}_{{ item.passwd }}.csr'
csr_path: '{{ remote_tmp_dir }}/{{item.backend}}_{{ item.type }}_{{ item.passwd }}.csr'
loop: '{{ all_tests }}'
- name: Create statement to be signed
copy:
content: "Erst wenn der Subwoofer die Katze inhaliert, fickt der Bass richtig übel. -- W.A. Mozart"
dest: '{{ output_dir }}/statement.txt'
dest: '{{ remote_tmp_dir }}/statement.txt'
- name: Loop over all variants
include_tasks: loop.yml

View File

@@ -42,10 +42,16 @@
dest: "/tmp/ansible.pem"
when: ansible_os_family == 'FreeBSD'
- name: FreeBSD - Read test cacert
slurp:
src: "/tmp/ansible.pem"
register: slurp
when: ansible_os_family == 'FreeBSD'
- name: FreeBSD - Add cacert to root certificate store
blockinfile:
path: "/etc/ssl/cert.pem"
block: "{{ lookup('file', '/tmp/ansible.pem') }}"
block: "{{ slurp.content | b64decode }}"
when: ansible_os_family == 'FreeBSD'
- name: MacOS - Retrieve test cacert

View File

@@ -1,2 +1,3 @@
dependencies: []
dependencies:
# - setup_openssl
- setup_remote_tmp_dir

View File

@@ -2,7 +2,7 @@
## PRIVATE KEY ################################################################################
- name: ({{ certgen_title }}) Create cert private key
openssl_privatekey:
path: "{{ output_dir }}/{{ certificate_name }}.key"
path: "{{ remote_tmp_dir }}/{{ certificate_name }}.key"
type: "{{ 'RSA' if key_type == 'rsa' else 'ECC' }}"
size: "{{ rsa_bits if key_type == 'rsa' else omit }}"
curve: >-
@@ -17,8 +17,8 @@
## CSR ########################################################################################
- name: ({{ certgen_title }}) Create cert CSR
openssl_csr:
path: "{{ output_dir }}/{{ certificate_name }}.csr"
privatekey_path: "{{ output_dir }}/{{ certificate_name }}.key"
path: "{{ remote_tmp_dir }}/{{ certificate_name }}.csr"
privatekey_path: "{{ remote_tmp_dir }}/{{ certificate_name }}.key"
privatekey_passphrase: "{{ certificate_passphrase | default(omit, true) }}"
subject_alt_name: "{{ subject_alt_name }}"
subject_alt_name_critical: "{{ subject_alt_name_critical }}"
@@ -31,15 +31,15 @@
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
account_key: "{{ (output_dir ~ '/' ~ account_key ~ '.pem') if account_key_content is not defined else omit }}"
account_key: "{{ (remote_tmp_dir ~ '/' ~ account_key ~ '.pem') if account_key_content is not defined else omit }}"
account_key_content: "{{ account_key_content | default(omit) }}"
account_key_passphrase: "{{ account_key_passphrase | default(omit, true) }}"
modify_account: "{{ modify_account }}"
csr: "{{ omit if use_csr_content | default(false) else output_dir ~ '/' ~ certificate_name ~ '.csr' }}"
csr: "{{ omit if use_csr_content | default(false) else remote_tmp_dir ~ '/' ~ certificate_name ~ '.csr' }}"
csr_content: "{{ csr_result.csr if use_csr_content | default(false) else omit }}"
dest: "{{ output_dir }}/{{ certificate_name }}.pem"
fullchain_dest: "{{ output_dir }}/{{ certificate_name }}-fullchain.pem"
chain_dest: "{{ output_dir }}/{{ certificate_name }}-chain.pem"
dest: "{{ remote_tmp_dir }}/{{ certificate_name }}.pem"
fullchain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-fullchain.pem"
chain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-chain.pem"
challenge: "{{ challenge }}"
deactivate_authzs: "{{ deactivate_authzs }}"
force: "{{ force }}"
@@ -72,20 +72,25 @@
acme_challenge_cert_helper:
challenge: tls-alpn-01
challenge_data: "{{ item.value['tls-alpn-01'] }}"
private_key_src: "{{ output_dir }}/{{ certificate_name }}.key"
private_key_src: "{{ remote_tmp_dir }}/{{ certificate_name }}.key"
private_key_passphrase: "{{ certificate_passphrase | default(omit, true) }}"
with_dict: "{{ challenge_data.challenge_data }}"
with_dict: "{{ challenge_data.challenge_data if challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls is defined and challenge_alpn_tls == 'acme_challenge_cert_helper') else {} }}"
register: tls_alpn_challenges
when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls is defined and challenge_alpn_tls == 'acme_challenge_cert_helper')"
- name: ({{ certgen_title }}) Read private key
slurp:
src: '{{ remote_tmp_dir }}/{{ certificate_name }}.key'
register: slurp
when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls is defined and challenge_alpn_tls == 'acme_challenge_cert_helper')"
- name: ({{ certgen_title }}) Set TLS ALPN challenges (acm_challenge_cert_helper)
uri:
url: "http://{{ acme_host }}:5000/tls-alpn/{{ item.domain }}/{{ item.identifier }}/certificate-and-key"
method: PUT
body_format: raw
body: "{{ item.challenge_certificate }}\n{{ lookup('file', output_dir ~ '/' ~ certificate_name ~ '.key') }}"
body: "{{ item.challenge_certificate }}\n{{ slurp.content | b64decode }}"
headers:
content-type: "application/pem-certificate-chain"
with_items: "{{ tls_alpn_challenges.results }}"
with_items: "{{ tls_alpn_challenges.results if challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls is defined and challenge_alpn_tls == 'acme_challenge_cert_helper') else [] }}"
when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls is defined and challenge_alpn_tls == 'acme_challenge_cert_helper')"
- name: ({{ certgen_title }}) Create TLS ALPN challenges (der-value-b64)
uri:
@@ -95,7 +100,7 @@
body: "{{ item.value['tls-alpn-01'].resource_value }}"
headers:
content-type: "application/octet-stream"
with_dict: "{{ challenge_data.challenge_data }}"
with_dict: "{{ challenge_data.challenge_data if challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls is not defined or challenge_alpn_tls == 'der-value-b64') else [] }}"
when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls is not defined or challenge_alpn_tls == 'der-value-b64')"
## ACME STEP 2 ################################################################################
- name: ({{ certgen_title }}) Obtain cert, step 2
@@ -104,16 +109,16 @@
acme_version: 2
acme_directory: https://{{ acme_host }}:14000/dir
validate_certs: no
account_key: "{{ (output_dir ~ '/' ~ account_key ~ '.pem') if account_key_content is not defined else omit }}"
account_key: "{{ (remote_tmp_dir ~ '/' ~ account_key ~ '.pem') if account_key_content is not defined else omit }}"
account_key_content: "{{ account_key_content | default(omit) }}"
account_key_passphrase: "{{ account_key_passphrase | default(omit, true) }}"
account_uri: "{{ challenge_data.account_uri }}"
modify_account: "{{ modify_account }}"
csr: "{{ omit if use_csr_content | default(false) else output_dir ~ '/' ~ certificate_name ~ '.csr' }}"
csr: "{{ omit if use_csr_content | default(false) else remote_tmp_dir ~ '/' ~ certificate_name ~ '.csr' }}"
csr_content: "{{ csr_result.csr if use_csr_content | default(false) else omit }}"
dest: "{{ output_dir }}/{{ certificate_name }}.pem"
fullchain_dest: "{{ output_dir }}/{{ certificate_name }}-fullchain.pem"
chain_dest: "{{ output_dir }}/{{ certificate_name }}-chain.pem"
dest: "{{ remote_tmp_dir }}/{{ certificate_name }}.pem"
fullchain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-fullchain.pem"
chain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-chain.pem"
challenge: "{{ challenge }}"
deactivate_authzs: "{{ deactivate_authzs }}"
force: "{{ force }}"
@@ -146,5 +151,5 @@
- name: ({{ certgen_title }}) Get root certificate
get_url:
url: "http://{{ acme_host }}:5000/root-certificate-for-ca/{{ acme_expected_root_number | default(0) if select_crypto_backend == 'cryptography' else 0 }}"
dest: "{{ output_dir }}/{{ certificate_name }}-root.pem"
dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-root.pem"
###############################################################################################

View File

@@ -12,3 +12,12 @@
package:
name: '{{ openssh_client_package_name }}'
when: not ansible_os_family == "Darwin" and not ansible_os_family == "FreeBSD"
- name: Get ssh version
shell: ssh -Vq 2>&1|sed 's/^.*OpenSSH_\([0-9]\{1,\}\.[0-9]\{1,\}\).*$/\1/'
register:
rc_openssh_version_output
- name: Set ssh version facts
set_fact:
openssh_version: "{{ rc_openssh_version_output.stdout.strip() }}"

View File

@@ -1,2 +1,3 @@
dependencies:
- setup_acme
- setup_remote_tmp_dir

View File

@@ -1,18 +1,18 @@
---
- name: Generate account key
openssl_privatekey:
path: '{{ output_dir }}/account.key'
path: '{{ remote_tmp_dir }}/account.key'
size: '{{ default_rsa_key_size }}'
- name: Generate privatekey
openssl_privatekey:
path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/privatekey.pem'
size: '{{ default_rsa_key_size }}'
- name: Generate CSRs
openssl_csr:
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ output_dir }}/{{ item.name }}.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/{{ item.name }}.csr'
subject_alt_name: '{{ item.sans }}'
loop:
- name: cert-1
@@ -26,17 +26,17 @@
- name: Retrieve certificate 1
x509_certificate:
provider: acme
path: '{{ output_dir }}/cert-1.pem'
csr_path: '{{ output_dir }}/cert-1.csr'
acme_accountkey_path: '{{ output_dir }}/account.key'
acme_challenge_path: '{{ output_dir }}/challenges/'
path: '{{ remote_tmp_dir }}/cert-1.pem'
csr_path: '{{ remote_tmp_dir }}/cert-1.csr'
acme_accountkey_path: '{{ remote_tmp_dir }}/account.key'
acme_challenge_path: '{{ remote_tmp_dir }}/challenges/'
acme_directory: https://{{ acme_host }}:14000/dir
environment:
PATH: '{{ lookup("env", "PATH") }}:{{ output_dir }}'
PATH: '{{ lookup("env", "PATH") }}:{{ remote_tmp_dir }}'
- name: Get certificate information
x509_certificate_info:
path: '{{ output_dir }}/cert-1.pem'
path: '{{ remote_tmp_dir }}/cert-1.pem'
register: result
- name: Validate certificate information
@@ -48,17 +48,17 @@
- name: Retrieve certificate 2
x509_certificate:
provider: acme
path: '{{ output_dir }}/cert-2.pem'
csr_path: '{{ output_dir }}/cert-2.csr'
acme_accountkey_path: '{{ output_dir }}/account.key'
acme_challenge_path: '{{ output_dir }}/challenges/'
path: '{{ remote_tmp_dir }}/cert-2.pem'
csr_path: '{{ remote_tmp_dir }}/cert-2.csr'
acme_accountkey_path: '{{ remote_tmp_dir }}/account.key'
acme_challenge_path: '{{ remote_tmp_dir }}/challenges/'
acme_directory: https://{{ acme_host }}:14000/dir
environment:
PATH: '{{ lookup("env", "PATH") }}:{{ output_dir }}'
PATH: '{{ lookup("env", "PATH") }}:{{ remote_tmp_dir }}'
- name: Get certificate information
x509_certificate_info:
path: '{{ output_dir }}/cert-2.pem'
path: '{{ remote_tmp_dir }}/cert-2.pem'
register: result
- name: Validate certificate information

View File

@@ -8,38 +8,48 @@
- name: Obtain root and intermediate certificates
get_url:
url: "http://{{ acme_host }}:5000/{{ item.0 }}-certificate-for-ca/{{ item.1 }}"
dest: "{{ output_dir }}/acme-{{ item.0 }}-{{ item.1 }}.pem"
dest: "{{ remote_tmp_dir }}/acme-{{ item.0 }}-{{ item.1 }}.pem"
loop: "{{ query('nested', types, root_numbers) }}"
- name: Analyze root certificates
x509_certificate_info:
path: "{{ output_dir }}/acme-root-{{ item }}.pem"
path: "{{ remote_tmp_dir }}/acme-root-{{ item }}.pem"
loop: "{{ root_numbers }}"
register: acme_roots
- name: Analyze intermediate certificates
x509_certificate_info:
path: "{{ output_dir }}/acme-intermediate-{{ item }}.pem"
path: "{{ remote_tmp_dir }}/acme-intermediate-{{ item }}.pem"
loop: "{{ root_numbers }}"
register: acme_intermediates
- set_fact:
x__: "{{ item | dict2items | selectattr('key', 'in', interesting_keys) | list | items2dict }}"
y__: "{{ lookup('file', output_dir ~ '/acme-root-' ~ item.item ~ '.pem', rstrip=False) }}"
loop: "{{ acme_roots.results }}"
register: acme_roots_tmp
- name: Read root certificates
slurp:
src: "{{ remote_tmp_dir ~ '/acme-root-' ~ item ~ '.pem' }}"
loop: "{{ root_numbers }}"
register: slurp_roots
- set_fact:
x__: "{{ item | dict2items | selectattr('key', 'in', interesting_keys) | list | items2dict }}"
loop: "{{ acme_roots.results }}"
register: acme_roots_tmp
- name: Read intermediate certificates
slurp:
src: "{{ remote_tmp_dir ~ '/acme-intermediate-' ~ item ~ '.pem' }}"
loop: "{{ root_numbers }}"
register: slurp_intermediates
- set_fact:
x__: "{{ item | dict2items | selectattr('key', 'in', interesting_keys) | list | items2dict }}"
y__: "{{ lookup('file', output_dir ~ '/acme-intermediate-' ~ item.item ~ '.pem', rstrip=False) }}"
loop: "{{ acme_intermediates.results }}"
register: acme_intermediates_tmp
- set_fact:
acme_roots: "{{ acme_roots_tmp.results | map(attribute='ansible_facts.x__') | list }}"
acme_root_certs: "{{ acme_roots_tmp.results | map(attribute='ansible_facts.y__') | list }}"
acme_root_certs: "{{ slurp_roots.results | map(attribute='content') | map('b64decode') | list }}"
acme_intermediates: "{{ acme_intermediates_tmp.results | map(attribute='ansible_facts.x__') | list }}"
acme_intermediate_certs: "{{ acme_intermediates_tmp.results | map(attribute='ansible_facts.y__') | list }}"
acme_intermediate_certs: "{{ slurp_intermediates.results | map(attribute='content') | map('b64decode') | list }}"
vars:
types:
@@ -56,16 +66,16 @@
- name: Get hold of acme-tiny executable
get_url:
url: https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
dest: "{{ output_dir }}/acme-tiny"
dest: "{{ remote_tmp_dir }}/acme-tiny"
- name: Make sure acme-tiny is executable
file:
path: "{{ output_dir }}/acme-tiny"
path: "{{ remote_tmp_dir }}/acme-tiny"
mode: "0755"
- name: "Monkey-patch acme-tiny: Disable certificate validation"
blockinfile:
path: "{{ output_dir }}/acme-tiny"
path: "{{ remote_tmp_dir }}/acme-tiny"
marker: "# {mark} ANSIBLE MANAGED BLOCK: DISABLE CERTIFICATE VALIDATION FOR HTTPS REQUESTS"
insertafter: '^#!.*'
block: |
@@ -83,36 +93,25 @@
- name: "Monkey-patch acme-tiny: Disable check that challenge file is reachable via HTTP"
replace:
path: "{{ output_dir }}/acme-tiny"
path: "{{ remote_tmp_dir }}/acme-tiny"
regexp: 'parser\.add_argument\("--disable-check", default=False,'
replace: 'parser.add_argument("--disable-check", default=True,'
- name: "Monkey-patch acme-tiny: Instead of writing challenge files to disk, post them to challenge server"
replace:
path: "{{ output_dir }}/acme-tiny"
path: "{{ remote_tmp_dir }}/acme-tiny"
regexp: 'with open\(wellknown_path, "w"\) as [^:]+:\n\s+[^. ]+\.write\(([^)]+)\)'
replace: 'r = Request(url="http://{{ acme_host }}:5000/http/" + domain + "/" + token, data=\1.encode("utf8"), headers={"content-type": "application/octet-stream"}) ; r.get_method = lambda: "PUT" ; urlopen(r).close()'
- name: "Monkey-patch acme-tiny: Remove file cleanup"
replace:
path: "{{ output_dir }}/acme-tiny"
path: "{{ remote_tmp_dir }}/acme-tiny"
regexp: 'os\.remove\(wellknown_path\)'
replace: 'pass'
- name: "Monkey-patch acme-tiny: Avoid crash on already valid challenges (https://github.com/diafygi/acme-tiny/pull/254)"
blockinfile:
path: "{{ output_dir }}/acme-tiny"
marker: "# {mark} ANSIBLE MANAGED BLOCK: AVOID CRASH ON ALREADY VALID CHALLENGES"
insertbefore: '# find the http-01 challenge and write the challenge file'
block: |2
# skip if already valid
if authorization['status'] == "valid":
log.info("{0} already verified. Skipping.".format(domain))
continue
- name: Create challenges directory
file:
path: '{{ output_dir }}/challenges'
path: '{{ remote_tmp_dir }}/challenges'
state: directory
- name: Running tests

View File

@@ -1,3 +1,4 @@
dependencies:
- setup_openssl
- setup_pyopenssl
- setup_remote_tmp_dir

View File

@@ -1,12 +1,12 @@
---
- name: (Assertonly, {{select_crypto_backend}}) - Generate privatekey
openssl_privatekey:
path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/privatekey.pem'
size: '{{ default_rsa_key_size_certifiates }}'
- name: (Assertonly, {{select_crypto_backend}}) - Generate privatekey with password
openssl_privatekey:
path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/privatekeypw.pem'
passphrase: hunter2
cipher: auto
select_crypto_backend: cryptography
@@ -14,16 +14,16 @@
- name: (Assertonly, {{select_crypto_backend}}) - Generate CSR (no extensions)
openssl_csr:
path: '{{ output_dir }}/csr_noext.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_noext.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.example.com
useCommonNameForSAN: no
- name: (Assertonly, {{select_crypto_backend}}) - Generate CSR (with SANs)
openssl_csr:
path: '{{ output_dir }}/csr_sans.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/csr_sans.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
subject:
commonName: www.example.com
subject_alt_name:
@@ -34,25 +34,25 @@
- name: (Assertonly, {{select_crypto_backend}}) - Generate selfsigned certificate (no extensions)
x509_certificate:
path: '{{ output_dir }}/cert_noext.pem'
csr_path: '{{ output_dir }}/csr_noext.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/cert_noext.pem'
csr_path: '{{ remote_tmp_dir }}/csr_noext.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
provider: selfsigned
selfsigned_digest: sha256
select_crypto_backend: '{{ select_crypto_backend }}'
- name: (Assertonly, {{select_crypto_backend}}) - Generate selfsigned certificate (with SANs)
x509_certificate:
path: '{{ output_dir }}/cert_sans.pem'
csr_path: '{{ output_dir }}/csr_sans.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/cert_sans.pem'
csr_path: '{{ remote_tmp_dir }}/csr_sans.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
provider: selfsigned
selfsigned_digest: sha256
select_crypto_backend: '{{ select_crypto_backend }}'
- name: (Assertonly, {{select_crypto_backend}}) - Assert that subject_alt_name is there (should fail)
x509_certificate:
path: '{{ output_dir }}/cert_noext.pem'
path: '{{ remote_tmp_dir }}/cert_noext.pem'
provider: assertonly
subject_alt_name:
- "DNS:example.com"
@@ -62,7 +62,7 @@
- name: (Assertonly, {{select_crypto_backend}}) - Assert that subject_alt_name is there
x509_certificate:
path: '{{ output_dir }}/cert_sans.pem'
path: '{{ remote_tmp_dir }}/cert_sans.pem'
provider: assertonly
subject_alt_name:
- "DNS:ansible.com"
@@ -73,7 +73,7 @@
- name: (Assertonly, {{select_crypto_backend}}) - Assert that subject_alt_name is there (strict)
x509_certificate:
path: '{{ output_dir }}/cert_sans.pem'
path: '{{ remote_tmp_dir }}/cert_sans.pem'
provider: assertonly
subject_alt_name:
- "DNS:ansible.com"
@@ -85,7 +85,7 @@
- name: (Assertonly, {{select_crypto_backend}}) - Assert that key_usage is there (should fail)
x509_certificate:
path: '{{ output_dir }}/cert_noext.pem'
path: '{{ remote_tmp_dir }}/cert_noext.pem'
provider: assertonly
key_usage:
- digitalSignature
@@ -95,7 +95,7 @@
- name: (Assertonly, {{select_crypto_backend}}) - Assert that extended_key_usage is there (should fail)
x509_certificate:
path: '{{ output_dir }}/cert_noext.pem'
path: '{{ remote_tmp_dir }}/cert_noext.pem'
provider: assertonly
extended_key_usage:
- biometricInfo
@@ -116,8 +116,8 @@
- name: (Assertonly, {{select_crypto_backend}}) - Check wrong key fail
x509_certificate:
path: '{{ output_dir }}/cert_noext.pem'
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/cert_noext.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: hunter2
provider: assertonly
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -126,8 +126,8 @@
- name: (Assertonly, {{select_crypto_backend}}) - Check private key passphrase fail 1
x509_certificate:
path: '{{ output_dir }}/cert_noext.pem'
privatekey_path: '{{ output_dir }}/privatekey.pem'
path: '{{ remote_tmp_dir }}/cert_noext.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
privatekey_passphrase: hunter2
provider: assertonly
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -136,8 +136,8 @@
- name: (Assertonly, {{select_crypto_backend}}) - Check private key passphrase fail 2
x509_certificate:
path: '{{ output_dir }}/cert_noext.pem'
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/cert_noext.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
privatekey_passphrase: wrong_password
provider: assertonly
select_crypto_backend: '{{ select_crypto_backend }}'
@@ -146,8 +146,8 @@
- name: (Assertonly, {{select_crypto_backend}}) - Check private key passphrase fail 3
x509_certificate:
path: '{{ output_dir }}/cert_noext.pem'
privatekey_path: '{{ output_dir }}/privatekeypw.pem'
path: '{{ remote_tmp_dir }}/cert_noext.pem'
privatekey_path: '{{ remote_tmp_dir }}/privatekeypw.pem'
provider: assertonly
select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: yes

View File

@@ -1,21 +1,21 @@
---
- name: (Expired, {{select_crypto_backend}}) Generate privatekey
openssl_privatekey:
path: '{{ output_dir }}/has_expired_privatekey.pem'
path: '{{ remote_tmp_dir }}/has_expired_privatekey.pem'
size: '{{ default_rsa_key_size_certifiates }}'
- name: (Expired, {{select_crypto_backend}}) Generate CSR
openssl_csr:
path: '{{ output_dir }}/has_expired_csr.csr'
privatekey_path: '{{ output_dir }}/has_expired_privatekey.pem'
path: '{{ remote_tmp_dir }}/has_expired_csr.csr'
privatekey_path: '{{ remote_tmp_dir }}/has_expired_privatekey.pem'
subject:
commonName: www.example.com
- name: (Expired, {{select_crypto_backend}}) Generate expired selfsigned certificate
x509_certificate:
path: '{{ output_dir }}/has_expired_cert.pem'
csr_path: '{{ output_dir }}/has_expired_csr.csr'
privatekey_path: '{{ output_dir }}/has_expired_privatekey.pem'
path: '{{ remote_tmp_dir }}/has_expired_cert.pem'
csr_path: '{{ remote_tmp_dir }}/has_expired_csr.csr'
privatekey_path: '{{ remote_tmp_dir }}/has_expired_privatekey.pem'
provider: selfsigned
selfsigned_digest: sha256
selfsigned_not_after: "-1s"
@@ -24,13 +24,13 @@
when: select_crypto_backend == 'pyopenssl' # cryptography won't allow creating expired certificates
- name: (Expired, {{select_crypto_backend}}) Generate expired selfsigned certificate
command: "{{ openssl_binary }} x509 -req -days -1 -in {{ output_dir }}/has_expired_csr.csr -signkey {{ output_dir }}/has_expired_privatekey.pem -out {{ output_dir }}/has_expired_cert.pem"
command: "{{ openssl_binary }} x509 -req -days -1 -in {{ remote_tmp_dir }}/has_expired_csr.csr -signkey {{ remote_tmp_dir }}/has_expired_privatekey.pem -out {{ remote_tmp_dir }}/has_expired_cert.pem"
when: select_crypto_backend == 'cryptography' # So we create it with 'command'
- name: "(Expired) Check task fails because cert is expired (has_expired: false)"
x509_certificate:
provider: assertonly
path: "{{ output_dir }}/has_expired_cert.pem"
path: "{{ remote_tmp_dir }}/has_expired_cert.pem"
has_expired: false
select_crypto_backend: '{{ select_crypto_backend }}'
ignore_errors: true
@@ -43,7 +43,7 @@
- name: "(Expired) Check expired cert check is ignored (has_expired: true)"
x509_certificate:
provider: assertonly
path: "{{ output_dir }}/has_expired_cert.pem"
path: "{{ remote_tmp_dir }}/has_expired_cert.pem"
has_expired: true
select_crypto_backend: '{{ select_crypto_backend }}'
register: expired_cert_skip

Some files were not shown because too many files have changed in this diff Show More