From a0e5e2e4c597c8cf0fdd39c2df45fe33fd38eedb Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 3 Feb 2020 06:18:19 +0100 Subject: [PATCH] openssl_publickey: forgot to pass backend (#67036) * Forgot to pass backend. * Add changelog. * Pass on backend from get_fingerprint. * Handle cryptography backend in get_fingerprint. --- .../67036-openssl_publickey-backend.yml | 2 ++ lib/ansible/module_utils/crypto.py | 36 +++++++++++-------- .../modules/crypto/openssl_publickey.py | 3 +- 3 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 changelogs/fragments/67036-openssl_publickey-backend.yml diff --git a/changelogs/fragments/67036-openssl_publickey-backend.yml b/changelogs/fragments/67036-openssl_publickey-backend.yml new file mode 100644 index 00000000000..97093c20869 --- /dev/null +++ b/changelogs/fragments/67036-openssl_publickey-backend.yml @@ -0,0 +1,2 @@ +bugfixes: +- "openssl_publickey - fix a module crash caused when pyOpenSSL is not installed (https://github.com/ansible/ansible/issues/67035)." diff --git a/lib/ansible/module_utils/crypto.py b/lib/ansible/module_utils/crypto.py index 6d4f8aac78d..fef01f1ab23 100644 --- a/lib/ansible/module_utils/crypto.py +++ b/lib/ansible/module_utils/crypto.py @@ -166,24 +166,32 @@ def get_fingerprint_of_bytes(source): return fingerprint -def get_fingerprint(path, passphrase=None, content=None): +def get_fingerprint(path, passphrase=None, content=None, backend='pyopenssl'): """Generate the fingerprint of the public key. """ - privatekey = load_privatekey(path, passphrase=passphrase, content=content, check_passphrase=False) - try: - publickey = crypto.dump_publickey(crypto.FILETYPE_ASN1, privatekey) - except AttributeError: - # If PyOpenSSL < 16.0 crypto.dump_publickey() will fail. + privatekey = load_privatekey(path, passphrase=passphrase, content=content, check_passphrase=False, backend=backend) + + if backend == 'pyopenssl': try: - bio = crypto._new_mem_buf() - rc = crypto._lib.i2d_PUBKEY_bio(bio, privatekey._pkey) - if rc != 1: - crypto._raise_current_error() - publickey = crypto._bio_to_string(bio) + publickey = crypto.dump_publickey(crypto.FILETYPE_ASN1, privatekey) except AttributeError: - # By doing this we prevent the code from raising an error - # yet we return no value in the fingerprint hash. - return None + # If PyOpenSSL < 16.0 crypto.dump_publickey() will fail. + try: + bio = crypto._new_mem_buf() + rc = crypto._lib.i2d_PUBKEY_bio(bio, privatekey._pkey) + if rc != 1: + crypto._raise_current_error() + publickey = crypto._bio_to_string(bio) + except AttributeError: + # By doing this we prevent the code from raising an error + # yet we return no value in the fingerprint hash. + return None + elif backend == 'cryptography': + publickey = privatekey.public_key().public_bytes( + serialization.Encoding.DER, + serialization.PublicFormat.SubjectPublicKeyInfo + ) + return get_fingerprint_of_bytes(publickey) diff --git a/lib/ansible/modules/crypto/openssl_publickey.py b/lib/ansible/modules/crypto/openssl_publickey.py index 687490a2e50..6526b6fe93d 100644 --- a/lib/ansible/modules/crypto/openssl_publickey.py +++ b/lib/ansible/modules/crypto/openssl_publickey.py @@ -299,7 +299,8 @@ class PublicKey(crypto_utils.OpenSSLObject): self.fingerprint = crypto_utils.get_fingerprint( path=self.privatekey_path, content=self.privatekey_content, - passphrase=self.privatekey_passphrase + passphrase=self.privatekey_passphrase, + backend=self.backend, ) file_args = module.load_file_common_arguments(module.params) if module.set_fs_attributes_if_different(file_args, False):