diff --git a/lib/ansible/module_utils/crypto.py b/lib/ansible/module_utils/crypto.py index 4f2b770cd48..0ee1f67a151 100644 --- a/lib/ansible/module_utils/crypto.py +++ b/lib/ansible/module_utils/crypto.py @@ -35,15 +35,12 @@ class OpenSSLObjectError(Exception): pass -def get_fingerprint(path, passphrase): +def get_fingerprint(path, passphrase=None): """Generate the fingerprint of the public key. """ fingerprint = {} - privatekey = crypto.load_privatekey(crypto.FILETYPE_PEM, - open(path, 'rb').read(), - passphrase) - + privatekey = load_privatekey(path, passphrase) try: publickey = crypto.dump_publickey(crypto.FILETYPE_ASN1, privatekey) for algo in hashlib.algorithms: @@ -63,10 +60,14 @@ def load_privatekey(path, passphrase=None): """Load the specified OpenSSL private key.""" try: - privatekey_content = open(path, 'rb').read() - privatekey = crypto.load_privatekey(crypto.FILETYPE_PEM, - privatekey_content, - passphrase) + if passphrase: + privatekey = crypto.load_privatekey(crypto.FILETYPE_PEM, + open(path, 'rb').read(), + passphrase) + else: + privatekey = crypto.load_privatekey(crypto.FILETYPE_PEM, + open(path, 'rb').read()) + return privatekey except (IOError, OSError) as exc: raise OpenSSLObjectError(exc) diff --git a/lib/ansible/modules/crypto/openssl_csr.py b/lib/ansible/modules/crypto/openssl_csr.py index 217e40ce1dd..1a25c3cdc42 100644 --- a/lib/ansible/modules/crypto/openssl_csr.py +++ b/lib/ansible/modules/crypto/openssl_csr.py @@ -179,6 +179,7 @@ except ImportError: else: pyopenssl_found = True +from ansible.module_utils import crypto as crypto_utils from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_native @@ -231,10 +232,11 @@ class CertificateSigningRequest(object): if self.subjectAltName is not None: req.add_extensions([crypto.X509Extension(b"subjectAltName", False, self.subjectAltName.encode('ascii'))]) - privatekey_content = open(self.privatekey_path).read() - self.privatekey = crypto.load_privatekey(crypto.FILETYPE_PEM, - privatekey_content, - self.privatekey_passphrase) + self.privatekey = crypto_utils.load_privatekey( + self.privatekey_path, + self.privatekey_passphrase + ) + req.set_pubkey(self.privatekey) req.sign(self.privatekey, self.digest) self.request = req diff --git a/lib/ansible/modules/crypto/openssl_publickey.py b/lib/ansible/modules/crypto/openssl_publickey.py index fe7cfdd8352..b8d1bd2f118 100644 --- a/lib/ansible/modules/crypto/openssl_publickey.py +++ b/lib/ansible/modules/crypto/openssl_publickey.py @@ -187,7 +187,7 @@ class PublicKey(object): self.privatekey = crypto.load_privatekey(crypto.FILETYPE_PEM, privatekey_content) publickey_content = crypto.dump_publickey(crypto.FILETYPE_PEM, self.privatekey) - publickey_file = open(self.path, 'w') + publickey_file = open(self.path, 'wb') publickey_file.write(publickey_content) publickey_file.close() diff --git a/test/integration/targets/openssl_csr/aliases b/test/integration/targets/openssl_csr/aliases new file mode 100644 index 00000000000..4485d761629 --- /dev/null +++ b/test/integration/targets/openssl_csr/aliases @@ -0,0 +1 @@ +posix/ci/group1 diff --git a/test/integration/targets/openssl_csr/meta/main.yml b/test/integration/targets/openssl_csr/meta/main.yml new file mode 100644 index 00000000000..800aff64284 --- /dev/null +++ b/test/integration/targets/openssl_csr/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - setup_openssl diff --git a/test/integration/targets/openssl_csr/tasks/main.yml b/test/integration/targets/openssl_csr/tasks/main.yml new file mode 100644 index 00000000000..48f3a489efa --- /dev/null +++ b/test/integration/targets/openssl_csr/tasks/main.yml @@ -0,0 +1,11 @@ +- name: Generate privatekey + openssl_privatekey: + path: '{{ output_dir }}/privatekey.pem' + +- name: Generate CSR + openssl_csr: + path: '{{ output_dir }}/csr.csr' + privatekey_path: '{{ output_dir }}/privatekey.pem' + commonName: 'www.ansible.com' + +- import_tasks: ../tests/validate.yml diff --git a/test/integration/targets/openssl_csr/tests/validate.yml b/test/integration/targets/openssl_csr/tests/validate.yml new file mode 100644 index 00000000000..b24f61a2bbf --- /dev/null +++ b/test/integration/targets/openssl_csr/tests/validate.yml @@ -0,0 +1,17 @@ +- name: Validate CSR (test - privatekey modulus) + shell: 'openssl rsa -noout -modulus -in {{ output_dir }}/privatekey.pem | openssl md5' + register: privatekey_modulus + +- name: Validate CSR (test - Common Name) + shell: "openssl req -noout -subject -in {{ output_dir }}/csr.csr -nameopt oneline,-space_eq" + register: csr_cn + +- name: Validate CSR (test - csr modulus) + shell: 'openssl req -noout -modulus -in {{ output_dir }}/csr.csr | openssl md5' + register: csr_modulus + +- name: Validate CSR (assert) + assert: + that: + - csr_cn.stdout.split('=')[-1] == 'www.ansible.com' + - csr_modulus.stdout == privatekey_modulus.stdout diff --git a/test/integration/targets/openssl_privatekey/aliases b/test/integration/targets/openssl_privatekey/aliases new file mode 100644 index 00000000000..4485d761629 --- /dev/null +++ b/test/integration/targets/openssl_privatekey/aliases @@ -0,0 +1 @@ +posix/ci/group1 diff --git a/test/integration/targets/openssl_privatekey/meta/main.yml b/test/integration/targets/openssl_privatekey/meta/main.yml new file mode 100644 index 00000000000..800aff64284 --- /dev/null +++ b/test/integration/targets/openssl_privatekey/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - setup_openssl diff --git a/test/integration/targets/openssl_privatekey/tasks/main.yml b/test/integration/targets/openssl_privatekey/tasks/main.yml new file mode 100644 index 00000000000..464f56e17e3 --- /dev/null +++ b/test/integration/targets/openssl_privatekey/tasks/main.yml @@ -0,0 +1,15 @@ +- name: Generate privatekey1 - standard + openssl_privatekey: + path: '{{ output_dir }}/privatekey1.pem' + +- name: Generate privatekey2 - size 2048 + openssl_privatekey: + path: '{{ output_dir }}/privatekey2.pem' + size: 2048 + +- name: Generate privatekey3 - type DSA + openssl_privatekey: + path: '{{ output_dir }}/privatekey3.pem' + type: DSA + +- import_tasks: ../tests/validate.yml diff --git a/test/integration/targets/openssl_privatekey/tests/validate.yml b/test/integration/targets/openssl_privatekey/tests/validate.yml new file mode 100644 index 00000000000..ccbce924e55 --- /dev/null +++ b/test/integration/targets/openssl_privatekey/tests/validate.yml @@ -0,0 +1,28 @@ +- name: Validate privatekey1 (test) + shell: "openssl rsa -noout -text -in {{ output_dir }}/privatekey1.pem | grep Private | sed 's/Private-Key: (\\(.*\\) bit)/\\1/'" + register: privatekey1 + +- name: Validate privatekey1 (assert) + assert: + that: + - privatekey1.stdout == '4096' + + +- name: Validate privatekey2 (test) + shell: "openssl rsa -noout -text -in {{ output_dir }}/privatekey2.pem | grep Private | sed 's/Private-Key: (\\(.*\\) bit)/\\1/'" + register: privatekey2 + +- name: Validate privatekey2 (assert) + assert: + that: + - privatekey2.stdout == '2048' + + +- name: Validate privatekey3 (test) + shell: "openssl dsa -noout -text -in {{ output_dir }}/privatekey3.pem | grep Private | sed 's/Private-Key: (\\(.*\\) bit)/\\1/'" + register: privatekey3 + +- name: Validate privatekey3 (assert) + assert: + that: + - privatekey1.stdout == '4096' diff --git a/test/integration/targets/openssl_publickey/aliases b/test/integration/targets/openssl_publickey/aliases new file mode 100644 index 00000000000..4485d761629 --- /dev/null +++ b/test/integration/targets/openssl_publickey/aliases @@ -0,0 +1 @@ +posix/ci/group1 diff --git a/test/integration/targets/openssl_publickey/meta/main.yml b/test/integration/targets/openssl_publickey/meta/main.yml new file mode 100644 index 00000000000..800aff64284 --- /dev/null +++ b/test/integration/targets/openssl_publickey/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - setup_openssl diff --git a/test/integration/targets/openssl_publickey/tasks/main.yml b/test/integration/targets/openssl_publickey/tasks/main.yml new file mode 100644 index 00000000000..8f8a7a34526 --- /dev/null +++ b/test/integration/targets/openssl_publickey/tasks/main.yml @@ -0,0 +1,13 @@ +- block: + - name: Generate privatekey + openssl_privatekey: + path: '{{ output_dir }}/privatekey.pem' + + - name: Generate publickey + openssl_publickey: + path: '{{ output_dir }}/publickey.pub' + privatekey_path: '{{ output_dir }}/privatekey.pem' + + - import_tasks: ../tests/validate.yml + + when: pyopenssl_version.stdout|version_compare('16.0.0', '>=') diff --git a/test/integration/targets/openssl_publickey/tests/validate.yml b/test/integration/targets/openssl_publickey/tests/validate.yml new file mode 100644 index 00000000000..8bf34c6d138 --- /dev/null +++ b/test/integration/targets/openssl_publickey/tests/validate.yml @@ -0,0 +1,12 @@ +- name: Validate public key (test - privatekey modulus) + shell: 'openssl rsa -noout -modulus -in {{ output_dir }}/privatekey.pem | openssl md5' + register: privatekey_modulus + +- name: Validate public key (test - publickey modulus) + shell: 'openssl rsa -pubin -noout -modulus < {{ output_dir }}/publickey.pub | openssl md5' + register: publickey_modulus + +- name: Validate public key (assert) + assert: + that: + - publickey_modulus.stdout == privatekey_modulus.stdout diff --git a/test/integration/targets/setup_openssl/tasks/main.yml b/test/integration/targets/setup_openssl/tasks/main.yml new file mode 100644 index 00000000000..282ee43dd49 --- /dev/null +++ b/test/integration/targets/setup_openssl/tasks/main.yml @@ -0,0 +1,25 @@ +- name: Incluse OS-specific variables + include_vars: '{{ ansible_os_family }}.yml' + when: not ansible_os_family == "Darwin" + +- name: Install pyOpenSSL + become: True + package: + name: '{{ pyopenssl_package_name_python3 }}' + when: not ansible_os_family == 'Darwin' and ansible_python_version|version_compare('3.0', '>=') + +- name: Install pyOpenSSL + become: True + package: + name: '{{ pyopenssl_package_name }}' + when: not ansible_os_family == 'Darwin' and ansible_python_version|version_compare('3.0', '<') + +- name: Install pyOpenSSL + become: True + pip: + name: pyOpenSSL + when: ansible_os_family == 'Darwin' + +- name: register openssl version + command: python -c 'import OpenSSL; print(OpenSSL.__version__)' + register: pyopenssl_version diff --git a/test/integration/targets/setup_openssl/vars/Debian.yml b/test/integration/targets/setup_openssl/vars/Debian.yml new file mode 100644 index 00000000000..44d0aab0b3b --- /dev/null +++ b/test/integration/targets/setup_openssl/vars/Debian.yml @@ -0,0 +1,2 @@ +pyopenssl_package_name: python-openssl +pyopenssl_package_name_python3: python3-openssl diff --git a/test/integration/targets/setup_openssl/vars/FreeBSD.yml b/test/integration/targets/setup_openssl/vars/FreeBSD.yml new file mode 100644 index 00000000000..a2064a7d062 --- /dev/null +++ b/test/integration/targets/setup_openssl/vars/FreeBSD.yml @@ -0,0 +1 @@ +pyopenssl_package_name: py27-openssl diff --git a/test/integration/targets/setup_openssl/vars/RedHat.yml b/test/integration/targets/setup_openssl/vars/RedHat.yml new file mode 100644 index 00000000000..5631e74433d --- /dev/null +++ b/test/integration/targets/setup_openssl/vars/RedHat.yml @@ -0,0 +1 @@ +pyopenssl_package_name: pyOpenSSL diff --git a/test/integration/targets/setup_openssl/vars/Suse.yml b/test/integration/targets/setup_openssl/vars/Suse.yml new file mode 100644 index 00000000000..4816a9f645b --- /dev/null +++ b/test/integration/targets/setup_openssl/vars/Suse.yml @@ -0,0 +1 @@ +pyopenssl_package_name: python-pyOpenSSL