From 6a786d0d93edcf033d32347f8aca73c1f825bee5 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Sat, 17 Aug 2019 18:52:14 +0200 Subject: [PATCH] openssl_publickey: add cryptography backend (#60387) * Add cryptography backend. * Add changelog. * Make sure requirements are satisfied. * Use more compatible elliptic curve. * Decrease required version numbers. * PyOpenSSL >= 16.0.0 is really needed. * Update lib/ansible/modules/crypto/openssl_publickey.py Co-Authored-By: MarkusTeufelberger --- ...openssl_publickey-cryptography-backend.yml | 2 + .../modules/crypto/openssl_publickey.py | 169 +++++++++++----- .../targets/openssl_publickey/tasks/impl.yml | 166 ++++++++++++++++ .../targets/openssl_publickey/tasks/main.yml | 180 ++++-------------- .../openssl_publickey/tests/validate.yml | 8 +- 5 files changed, 329 insertions(+), 196 deletions(-) create mode 100644 changelogs/fragments/60387-openssl_publickey-cryptography-backend.yml create mode 100644 test/integration/targets/openssl_publickey/tasks/impl.yml diff --git a/changelogs/fragments/60387-openssl_publickey-cryptography-backend.yml b/changelogs/fragments/60387-openssl_publickey-cryptography-backend.yml new file mode 100644 index 00000000000..36116161ddd --- /dev/null +++ b/changelogs/fragments/60387-openssl_publickey-cryptography-backend.yml @@ -0,0 +1,2 @@ +minor_changes: +- "openssl_publickey - now works with both PyOpenSSL and cryptography Python libraries. Autodetection can be overridden with ``select_crypto_backend`` option." diff --git a/lib/ansible/modules/crypto/openssl_publickey.py b/lib/ansible/modules/crypto/openssl_publickey.py index 2b5fe6f9345..ee08e9e44c7 100644 --- a/lib/ansible/modules/crypto/openssl_publickey.py +++ b/lib/ansible/modules/crypto/openssl_publickey.py @@ -18,14 +18,18 @@ version_added: "2.3" short_description: Generate an OpenSSL public key from its private key. description: - This module allows one to (re)generate OpenSSL public keys from their private keys. - - It uses the pyOpenSSL python library to interact with openssl. - - Keys are generated in PEM format. - - This module works only if the version of PyOpenSSL is recent enough (> 16.0.0). + - Keys are generated in PEM or OpenSSH format. + - The module can use the cryptography Python library, or the pyOpenSSL Python + library. By default, it tries to detect which one is available. This can be + overridden with the I(select_crypto_backend) option. When I(format) is C(OpenSSH), + the C(cryptography) backend has to be used." requirements: - - pyOpenSSL - - cryptography (if I(format) is C(OpenSSH)) + - Either cryptography >= 1.2.3 (older versions might work as well) + - Or pyOpenSSL >= 16.0.0 + - Needs cryptography >= 1.4 if I(format) is C(OpenSSH) author: -- Yanis Guenane (@Spredzy) + - Yanis Guenane (@Spredzy) + - Felix Fontein (@felixfontein) options: state: description: @@ -67,6 +71,16 @@ options: type: bool default: no version_added: "2.8" + select_crypto_backend: + description: + - Determines which crypto backend to use. + - The default choice is C(auto), which tries to use C(cryptography) if available, and falls back to C(pyopenssl). + - If set to C(pyopenssl), will try to use the L(pyOpenSSL,https://pypi.org/project/pyOpenSSL/) library. + - If set to C(cryptography), will try to use the L(cryptography,https://cryptography.io/) library. + type: str + default: auto + choices: [ auto, cryptography, pyopenssl ] + version_added: "2.9" extends_documentation_fragment: - files seealso: @@ -146,25 +160,34 @@ backup_file: import os import traceback +from distutils.version import LooseVersion + +MINIMAL_PYOPENSSL_VERSION = '16.0.0' +MINIMAL_CRYPTOGRAPHY_VERSION = '1.2.3' +MINIMAL_CRYPTOGRAPHY_VERSION_OPENSSH = '1.4' PYOPENSSL_IMP_ERR = None try: + import OpenSSL from OpenSSL import crypto + PYOPENSSL_VERSION = LooseVersion(OpenSSL.__version__) except ImportError: PYOPENSSL_IMP_ERR = traceback.format_exc() - pyopenssl_found = False + PYOPENSSL_FOUND = False else: - pyopenssl_found = True + PYOPENSSL_FOUND = True CRYPTOGRAPHY_IMP_ERR = None try: + import cryptography from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization as crypto_serialization + CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__) except ImportError: CRYPTOGRAPHY_IMP_ERR = traceback.format_exc() - cryptography_found = False + CRYPTOGRAPHY_FOUND = False else: - cryptography_found = True + CRYPTOGRAPHY_FOUND = True from ansible.module_utils import crypto as crypto_utils from ansible.module_utils._text import to_native, to_bytes @@ -177,7 +200,7 @@ class PublicKeyError(crypto_utils.OpenSSLObjectError): class PublicKey(crypto_utils.OpenSSLObject): - def __init__(self, module): + def __init__(self, module, backend): super(PublicKey, self).__init__( module.params['path'], module.params['state'], @@ -189,10 +212,34 @@ class PublicKey(crypto_utils.OpenSSLObject): self.privatekey_passphrase = module.params['privatekey_passphrase'] self.privatekey = None self.fingerprint = {} + self.backend = backend self.backup = module.params['backup'] self.backup_file = None + def _create_publickey(self, module): + self.privatekey = crypto_utils.load_privatekey( + self.privatekey_path, + self.privatekey_passphrase, + backend=self.backend + ) + if self.backend == 'cryptography': + if self.format == 'OpenSSH': + return self.privatekey.public_key().public_bytes( + crypto_serialization.Encoding.OpenSSH, + crypto_serialization.PublicFormat.OpenSSH + ) + else: + return self.privatekey.public_key().public_bytes( + crypto_serialization.Encoding.PEM, + crypto_serialization.PublicFormat.SubjectPublicKeyInfo + ) + else: + try: + return crypto.dump_publickey(crypto.FILETYPE_PEM, self.privatekey) + except AttributeError as exc: + raise PublicKeyError('You need to have PyOpenSSL>=16.0.0 to generate public keys') + def generate(self, module): """Generate the public key.""" @@ -203,23 +250,7 @@ class PublicKey(crypto_utils.OpenSSLObject): if not self.check(module, perms_required=False) or self.force: try: - if self.format == 'OpenSSH': - with open(self.privatekey_path, 'rb') as private_key_fh: - privatekey_content = private_key_fh.read() - key = crypto_serialization.load_pem_private_key( - privatekey_content, - password=None if self.privatekey_passphrase is None else to_bytes(self.privatekey_passphrase), - backend=default_backend() - ) - publickey_content = key.public_key().public_bytes( - crypto_serialization.Encoding.OpenSSH, - crypto_serialization.PublicFormat.OpenSSH - ) - else: - self.privatekey = crypto_utils.load_privatekey( - self.privatekey_path, self.privatekey_passphrase - ) - publickey_content = crypto.dump_publickey(crypto.FILETYPE_PEM, self.privatekey) + publickey_content = self._create_publickey(module) if self.backup: self.backup_file = module.backup_local(self.path) @@ -230,8 +261,6 @@ class PublicKey(crypto_utils.OpenSSLObject): raise PublicKeyError(exc) except (IOError, OSError) as exc: raise PublicKeyError(exc) - except AttributeError as exc: - raise PublicKeyError('You need to have PyOpenSSL>=16.0.0 to generate public keys') self.fingerprint = crypto_utils.get_fingerprint( self.privatekey_path, @@ -253,26 +282,34 @@ class PublicKey(crypto_utils.OpenSSLObject): try: with open(self.path, 'rb') as public_key_fh: publickey_content = public_key_fh.read() - if self.format == 'OpenSSH': - current_publickey = crypto_serialization.load_ssh_public_key(publickey_content, backend=default_backend()) - publickey_content = current_publickey.public_bytes(crypto_serialization.Encoding.PEM, - crypto_serialization.PublicFormat.SubjectPublicKeyInfo) - current_publickey = crypto.dump_publickey( - crypto.FILETYPE_ASN1, - crypto.load_publickey(crypto.FILETYPE_PEM, publickey_content) - ) + if self.backend == 'cryptography': + if self.format == 'OpenSSH': + # Read and dump public key. Makes sure that the comment is stripped off. + current_publickey = crypto_serialization.load_ssh_public_key(publickey_content, backend=default_backend()) + publickey_content = current_publickey.public_bytes( + crypto_serialization.Encoding.OpenSSH, + crypto_serialization.PublicFormat.OpenSSH + ) + else: + current_publickey = crypto_serialization.load_pem_public_key(publickey_content, backend=default_backend()) + publickey_content = current_publickey.public_bytes( + crypto_serialization.Encoding.PEM, + crypto_serialization.PublicFormat.SubjectPublicKeyInfo + ) + else: + publickey_content = crypto.dump_publickey( + crypto.FILETYPE_PEM, + crypto.load_publickey(crypto.FILETYPE_PEM, publickey_content) + ) except Exception as dummy: return False try: - desired_publickey = crypto.dump_publickey( - crypto.FILETYPE_ASN1, - crypto_utils.load_privatekey(self.privatekey_path, self.privatekey_passphrase) - ) + desired_publickey = self._create_publickey(module) except crypto_utils.OpenSSLBadPassphraseError as exc: raise PublicKeyError(exc) - return current_publickey == desired_publickey + return publickey_content == desired_publickey if not state_and_perms: return state_and_perms @@ -311,16 +348,52 @@ def main(): format=dict(type='str', default='PEM', choices=['OpenSSH', 'PEM']), privatekey_passphrase=dict(type='str', no_log=True), backup=dict(type='bool', default=False), + select_crypto_backend=dict(type='str', choices=['auto', 'pyopenssl', 'cryptography'], default='auto'), ), supports_check_mode=True, add_file_common_args=True, required_if=[('state', 'present', ['privatekey_path'])], ) - if not pyopenssl_found: - module.fail_json(msg=missing_required_lib('pyOpenSSL'), exception=PYOPENSSL_IMP_ERR) - if module.params['format'] == 'OpenSSH' and not cryptography_found: - module.fail_json(msg=missing_required_lib('cryptography'), exception=CRYPTOGRAPHY_IMP_ERR) + minimal_cryptography_version = MINIMAL_CRYPTOGRAPHY_VERSION + if module.params['format'] == 'OpenSSH': + minimal_cryptography_version = MINIMAL_CRYPTOGRAPHY_VERSION_OPENSSH + + backend = module.params['select_crypto_backend'] + if backend == 'auto': + # Detection what is possible + can_use_cryptography = CRYPTOGRAPHY_FOUND and CRYPTOGRAPHY_VERSION >= LooseVersion(minimal_cryptography_version) + can_use_pyopenssl = PYOPENSSL_FOUND and PYOPENSSL_VERSION >= LooseVersion(MINIMAL_PYOPENSSL_VERSION) + + # Decision + if can_use_cryptography: + backend = 'cryptography' + elif can_use_pyopenssl: + if module.params['format'] == 'OpenSSH': + module.fail_json( + msg=missing_required_lib('cryptography >= {0}'.format(MINIMAL_CRYPTOGRAPHY_VERSION_OPENSSH)), + exception=CRYPTOGRAPHY_IMP_ERR + ) + backend = 'pyopenssl' + + # Success? + if backend == 'auto': + module.fail_json(msg=("Can't detect any of the required Python libraries " + "cryptography (>= {0}) or PyOpenSSL (>= {1})").format( + minimal_cryptography_version, + MINIMAL_PYOPENSSL_VERSION)) + + if module.params['format'] == 'OpenSSH' and backend != 'cryptography': + module.fail_json(msg="Format OpenSSH requires the cryptography backend.") + + if backend == 'pyopenssl': + if not PYOPENSSL_FOUND: + module.fail_json(msg=missing_required_lib('pyOpenSSL >= {0}'.format(MINIMAL_PYOPENSSL_VERSION)), + exception=PYOPENSSL_IMP_ERR) + elif backend == 'cryptography': + if not CRYPTOGRAPHY_FOUND: + module.fail_json(msg=missing_required_lib('cryptography >= {0}'.format(minimal_cryptography_version)), + exception=CRYPTOGRAPHY_IMP_ERR) base_dir = os.path.dirname(module.params['path']) or '.' if not os.path.isdir(base_dir): @@ -330,7 +403,7 @@ def main(): ) try: - public_key = PublicKey(module) + public_key = PublicKey(module, backend) if public_key.state == 'present': if module.check_mode: diff --git a/test/integration/targets/openssl_publickey/tasks/impl.yml b/test/integration/targets/openssl_publickey/tasks/impl.yml new file mode 100644 index 00000000000..8885cf8e56b --- /dev/null +++ b/test/integration/targets/openssl_publickey/tasks/impl.yml @@ -0,0 +1,166 @@ +--- +- name: Generate privatekey + openssl_privatekey: + path: '{{ output_dir }}/privatekey.pem' + +- name: Generate publickey - PEM format + openssl_publickey: + path: '{{ output_dir }}/publickey.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + select_crypto_backend: '{{ select_crypto_backend }}' + +- name: Generate publickey - OpenSSH format + openssl_publickey: + path: '{{ output_dir }}/publickey-ssh.pub' + privatekey_path: '{{ output_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: Generate publickey - OpenSSH format - test idempotence (issue 33256) + openssl_publickey: + path: '{{ output_dir }}/publickey-ssh.pub' + privatekey_path: '{{ output_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', '>=') + register: publickey_ssh_idempotence + +- name: Generate publickey2 - standard + openssl_publickey: + path: '{{ output_dir }}/publickey2.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + select_crypto_backend: '{{ select_crypto_backend }}' + +- name: Delete publickey2 - standard + openssl_publickey: + state: absent + path: '{{ output_dir }}/publickey2.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + select_crypto_backend: '{{ select_crypto_backend }}' + +- name: Generate privatekey3 - with passphrase + openssl_privatekey: + path: '{{ output_dir }}/privatekey3.pem' + passphrase: ansible + cipher: aes256 + +- name: Generate publickey3 - with passphrase protected privatekey + openssl_publickey: + path: '{{ output_dir }}/publickey3.pub' + privatekey_path: '{{ output_dir }}/privatekey3.pem' + privatekey_passphrase: ansible + select_crypto_backend: '{{ select_crypto_backend }}' + +- name: Generate publickey3 - with passphrase protected privatekey - idempotence + openssl_publickey: + path: '{{ output_dir }}/publickey3.pub' + privatekey_path: '{{ output_dir }}/privatekey3.pem' + privatekey_passphrase: ansible + select_crypto_backend: '{{ select_crypto_backend }}' + register: publickey3_idempotence + +- name: Generate empty file that will hold a public key (issue 33072) + file: + path: '{{ output_dir }}/publickey4.pub' + state: touch + +- name: Generate publickey in empty existing file (issue 33072) + openssl_publickey: + path: '{{ output_dir }}/publickey4.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + select_crypto_backend: '{{ select_crypto_backend }}' + +- name: Generate privatekey 5 (ECC) + openssl_privatekey: + path: '{{ output_dir }}/privatekey5.pem' + type: ECC + curve: secp256r1 + +- name: Generate publickey 5 - PEM format + openssl_publickey: + path: '{{ output_dir }}/publickey5.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + backup: yes + select_crypto_backend: '{{ select_crypto_backend }}' + register: privatekey5_1 +- name: Generate publickey 5 - PEM format (idempotent) + openssl_publickey: + path: '{{ output_dir }}/publickey5.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + backup: yes + select_crypto_backend: '{{ select_crypto_backend }}' + register: privatekey5_2 +- name: Generate publickey 5 - PEM format (different private key) + openssl_publickey: + path: '{{ output_dir }}/publickey5.pub' + privatekey_path: '{{ output_dir }}/privatekey5.pem' + backup: yes + select_crypto_backend: '{{ select_crypto_backend }}' + register: privatekey5_3 + +- name: Generate privatekey with password + openssl_privatekey: + path: '{{ output_dir }}/privatekeypw.pem' + passphrase: hunter2 + cipher: auto + select_crypto_backend: cryptography + +- name: Generate publickey - PEM format (failed passphrase 1) + openssl_publickey: + path: '{{ output_dir }}/publickey_pw1.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + privatekey_passphrase: hunter2 + select_crypto_backend: '{{ select_crypto_backend }}' + ignore_errors: yes + register: passphrase_error_1 + +- name: Generate publickey - PEM format (failed passphrase 2) + openssl_publickey: + path: '{{ output_dir }}/publickey_pw2.pub' + privatekey_path: '{{ output_dir }}/privatekeypw.pem' + privatekey_passphrase: wrong_password + select_crypto_backend: '{{ select_crypto_backend }}' + ignore_errors: yes + register: passphrase_error_2 + +- name: Generate publickey - PEM format (failed passphrase 3) + openssl_publickey: + path: '{{ output_dir }}/publickey_pw3.pub' + privatekey_path: '{{ output_dir }}/privatekeypw.pem' + select_crypto_backend: '{{ select_crypto_backend }}' + ignore_errors: yes + register: passphrase_error_3 + +- name: Create broken key + copy: + dest: "{{ output_dir }}/publickeybroken.pub" + content: "broken" +- name: Regenerate broken key + openssl_publickey: + path: '{{ output_dir }}/publickeybroken.pub' + privatekey_path: '{{ output_dir }}/privatekey5.pem' + select_crypto_backend: '{{ select_crypto_backend }}' + register: output_broken + +- name: Generate publickey - PEM format (for removal) + openssl_publickey: + path: '{{ output_dir }}/publickey_removal.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + select_crypto_backend: '{{ select_crypto_backend }}' +- name: Generate publickey - PEM format (removal) + openssl_publickey: + state: absent + path: '{{ output_dir }}/publickey_removal.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + backup: yes + select_crypto_backend: '{{ select_crypto_backend }}' + register: remove_1 +- name: Generate publickey - PEM format (removal, idempotent) + openssl_publickey: + state: absent + path: '{{ output_dir }}/publickey_removal.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + backup: yes + select_crypto_backend: '{{ select_crypto_backend }}' + register: remove_2 diff --git a/test/integration/targets/openssl_publickey/tasks/main.yml b/test/integration/targets/openssl_publickey/tasks/main.yml index c83c3971cbd..b7369c03d70 100644 --- a/test/integration/targets/openssl_publickey/tasks/main.yml +++ b/test/integration/targets/openssl_publickey/tasks/main.yml @@ -1,156 +1,48 @@ --- - block: - - name: Generate privatekey - openssl_privatekey: - path: '{{ output_dir }}/privatekey.pem' + - name: Generate privatekey1 - standard + openssl_privatekey: + path: '{{ output_dir }}/privatekey_autodetect.pem' - - name: Generate publickey - PEM format - openssl_publickey: - path: '{{ output_dir }}/publickey.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' + - name: Run module with backend autodetection + openssl_publickey: + path: '{{ output_dir }}/privatekey_autodetect_public.pem' + privatekey_path: '{{ output_dir }}/privatekey_autodetect.pem' - - name: Generate publickey - OpenSSH format - openssl_publickey: - path: '{{ output_dir }}/publickey-ssh.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - format: OpenSSH - # cryptography.hazmat.primitives import serialization.Encoding.OpenSSH and - # cryptography.hazmat.primitives import serialization.PublicFormat.OpenSSH constants - # appeared in version 1.4 of cryptography - when: cryptography_version.stdout is version('1.4.0', '>=') + when: | + pyopenssl_version.stdout is version('16.0.0', '>=') or + cryptography_version.stdout is version('1.2.3', '>=') - - name: Generate publickey - OpenSSH format - test idempotence (issue 33256) - openssl_publickey: - path: '{{ output_dir }}/publickey-ssh.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - format: OpenSSH - when: cryptography_version.stdout is version('1.4.0', '>=') - register: publickey_ssh_idempotence - - - name: Generate publickey2 - standard - openssl_publickey: - path: '{{ output_dir }}/publickey2.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - - - name: Delete publickey2 - standard - openssl_publickey: - state: absent - path: '{{ output_dir }}/publickey2.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - - - name: Generate privatekey3 - with passphrase - openssl_privatekey: - path: '{{ output_dir }}/privatekey3.pem' - passphrase: ansible - cipher: aes256 - - - name: Generate publickey3 - with passphrase protected privatekey - openssl_publickey: - path: '{{ output_dir }}/publickey3.pub' - privatekey_path: '{{ output_dir }}/privatekey3.pem' - privatekey_passphrase: ansible - - - name: Generate publickey3 - with passphrase protected privatekey - idempotence - openssl_publickey: - path: '{{ output_dir }}/publickey3.pub' - privatekey_path: '{{ output_dir }}/privatekey3.pem' - privatekey_passphrase: ansible - register: publickey3_idempotence - - - name: Generate empty file that will hold a public key (issue 33072) - file: - path: '{{ output_dir }}/publickey4.pub' - state: touch - - - name: Generate publickey in empty existing file (issue 33072) - openssl_publickey: - path: '{{ output_dir }}/publickey4.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - - - name: Generate privatekey 5 (ECC) - openssl_privatekey: - path: '{{ output_dir }}/privatekey5.pem' - type: ECC - curve: secp256k1 - - - name: Generate publickey 5 - PEM format - openssl_publickey: - path: '{{ output_dir }}/publickey5.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - backup: yes - register: privatekey5_1 - - name: Generate publickey 5 - PEM format (idempotent) - openssl_publickey: - path: '{{ output_dir }}/publickey5.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - backup: yes - register: privatekey5_2 - - name: Generate publickey 5 - PEM format (different private key) - openssl_publickey: - path: '{{ output_dir }}/publickey5.pub' - privatekey_path: '{{ output_dir }}/privatekey5.pem' - backup: yes - register: privatekey5_3 - - - name: Generate privatekey with password - openssl_privatekey: - path: '{{ output_dir }}/privatekeypw.pem' - passphrase: hunter2 - cipher: auto - select_crypto_backend: cryptography +- block: + - name: Running tests with pyOpenSSL backend + include_tasks: impl.yml + vars: + select_crypto_backend: pyopenssl - - name: Generate publickey - PEM format (failed passphrase 1) - openssl_publickey: - path: '{{ output_dir }}/publickey_pw1.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - privatekey_passphrase: hunter2 - ignore_errors: yes - register: passphrase_error_1 + - import_tasks: ../tests/validate.yml + vars: + select_crypto_backend: pyopenssl - - name: Generate publickey - PEM format (failed passphrase 2) - openssl_publickey: - path: '{{ output_dir }}/publickey_pw2.pub' - privatekey_path: '{{ output_dir }}/privatekeypw.pem' - privatekey_passphrase: wrong_password - ignore_errors: yes - register: passphrase_error_2 + when: pyopenssl_version.stdout is version('16.0.0', '>=') - - name: Generate publickey - PEM format (failed passphrase 3) - openssl_publickey: - path: '{{ output_dir }}/publickey_pw3.pub' - privatekey_path: '{{ output_dir }}/privatekeypw.pem' - ignore_errors: yes - register: passphrase_error_3 +- name: Remove output directory + file: + path: "{{ output_dir }}" + state: absent - - name: Create broken key - copy: - dest: "{{ output_dir }}/publickeybroken.pub" - content: "broken" - - name: Regenerate broken key - openssl_publickey: - path: '{{ output_dir }}/publickeybroken.pub' - privatekey_path: '{{ output_dir }}/privatekey5.pem' - register: output_broken +- name: Re-create output directory + file: + path: "{{ output_dir }}" + state: directory - - name: Generate publickey - PEM format (for removal) - openssl_publickey: - path: '{{ output_dir }}/publickey_removal.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - - name: Generate publickey - PEM format (removal) - openssl_publickey: - state: absent - path: '{{ output_dir }}/publickey_removal.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - backup: yes - register: remove_1 - - name: Generate publickey - PEM format (removal, idempotent) - openssl_publickey: - state: absent - path: '{{ output_dir }}/publickey_removal.pub' - privatekey_path: '{{ output_dir }}/privatekey.pem' - backup: yes - register: remove_2 +- block: + - name: Running tests with cryptography backend + include_tasks: impl.yml + vars: + select_crypto_backend: cryptography - - import_tasks: ../tests/validate.yml + - import_tasks: ../tests/validate.yml + vars: + select_crypto_backend: cryptography - when: pyopenssl_version.stdout is version('16.0.0', '>=') + when: cryptography_version.stdout is version('1.2.3', '>=') diff --git a/test/integration/targets/openssl_publickey/tests/validate.yml b/test/integration/targets/openssl_publickey/tests/validate.yml index 83011b210ca..a07b7b0499b 100644 --- a/test/integration/targets/openssl_publickey/tests/validate.yml +++ b/test/integration/targets/openssl_publickey/tests/validate.yml @@ -15,25 +15,25 @@ - name: Validate public key - OpenSSH format (test - privatekey's publickey) shell: 'ssh-keygen -y -f {{ output_dir }}/privatekey.pem' register: privatekey_publickey - when: cryptography_version.stdout is version('1.4.0', '>=') + when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=') - name: Validate public key - OpenSSH format (test - publickey) slurp: src: '{{ output_dir }}/publickey-ssh.pub' register: publickey - when: cryptography_version.stdout is version('1.4.0', '>=') + when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=') - name: Validate public key - OpenSSH format (assert) assert: that: - privatekey_publickey.stdout == '{{ publickey.content|b64decode }}' - when: cryptography_version.stdout is version('1.4.0', '>=') + when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=') - name: Validate public key - OpenSSH format - test idempotence (issue 33256) assert: that: - publickey_ssh_idempotence is not changed - when: cryptography_version.stdout is version('1.4.0', '>=') + when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=') - name: Validate publickey2 (test - Ensure key has been removed) stat: