From b6887ab1f4fb488fef5ee06be16d60861501fe4d Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Fri, 25 Jul 2025 17:08:45 +0200 Subject: [PATCH] Improve error message when lodaing corrupt private key or private key with wrong passphrase. (#939) (#940) (cherry picked from commit f219cac94c2c1b2ebb53f723f27b12c1f39ca530) --- .../fragments/939-private-key-errors.yml | 4 + plugins/module_utils/crypto/support.py | 9 ++- .../openssl_privatekey_info/tasks/impl.yml | 76 +++++++++++++++++++ 3 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/939-private-key-errors.yml diff --git a/changelogs/fragments/939-private-key-errors.yml b/changelogs/fragments/939-private-key-errors.yml new file mode 100644 index 00000000..6166e775 --- /dev/null +++ b/changelogs/fragments/939-private-key-errors.yml @@ -0,0 +1,4 @@ +bugfixes: + - "Improve error message when loading a private key fails due to correct private key files or wrong passwords. + Also include the original cryptography error since it likely contains more helpful information + (https://github.com/ansible-collections/community.crypto/issues/936, https://github.com/ansible-collections/community.crypto/pull/939)." diff --git a/plugins/module_utils/crypto/support.py b/plugins/module_utils/crypto/support.py index 931113c3..9eb75c33 100644 --- a/plugins/module_utils/crypto/support.py +++ b/plugins/module_utils/crypto/support.py @@ -40,6 +40,7 @@ except (ImportError, AttributeError): try: from cryptography import x509 + from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.backends import default_backend as cryptography_backend from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.serialization import load_pem_private_key @@ -213,12 +214,16 @@ def load_privatekey( None if passphrase is None else to_bytes(passphrase), cryptography_backend(), ) + except UnsupportedAlgorithm as exc: + raise OpenSSLBadPassphraseError("Unsupported private key type: {exc}".format(exc=exc)) except TypeError: raise OpenSSLBadPassphraseError( "Wrong or empty passphrase provided for private key" ) - except ValueError: - raise OpenSSLBadPassphraseError("Wrong passphrase provided for private key") + except ValueError as exc: + raise OpenSSLBadPassphraseError( + "Wrong passphrase provided for private key, or private key cannot be parsed: {exc}".format(exc=exc) + ) return result diff --git a/tests/integration/targets/openssl_privatekey_info/tasks/impl.yml b/tests/integration/targets/openssl_privatekey_info/tasks/impl.yml index 740c5957..bf1e1cb8 100644 --- a/tests/integration/targets/openssl_privatekey_info/tasks/impl.yml +++ b/tests/integration/targets/openssl_privatekey_info/tasks/impl.yml @@ -90,6 +90,32 @@ - "'public_data' not in result" - "'private_data' not in result" +- name: ({{ select_crypto_backend }}) Get key 3 info (with wrong passphrase) + community.crypto.openssl_privatekey_info: + path: '{{ remote_tmp_dir }}/privatekey_3.pem' + return_private_key_data: true + select_crypto_backend: '{{ select_crypto_backend }}' + passphrase: blabla + ignore_errors: true + register: result + +- name: Check that loading passphrase protected key with wrong passphrase failed + ansible.builtin.assert: + that: + - result is failed + # Check that return values are there + - result.can_load_key is defined + - result.can_parse_key is defined + # Check that return values are correct + - result.can_load_key + - not result.can_parse_key + # Check that additional data isn't there + - "'pulic_key' not in result" + - "'pulic_key_fingerprints' not in result" + - "'type' not in result" + - "'public_data' not in result" + - "'private_data' not in result" + - name: ({{ select_crypto_backend }}) Get key 3 info (with passphrase) community.crypto.openssl_privatekey_info: path: '{{ remote_tmp_dir }}/privatekey_3.pem' @@ -155,3 +181,53 @@ - "result.public_data.y > 2" - "'private_data' in result" - "result.private_data.x > 2" + +- name: ({{ select_crypto_backend }}) Get empty key info + community.crypto.openssl_privatekey_info: + content: '' + return_private_key_data: true + select_crypto_backend: '{{ select_crypto_backend }}' + register: result + ignore_errors: true + +- name: Check that empty key loading failed + ansible.builtin.assert: + that: + - result is failed + # Check that return values are there + - result.can_load_key is defined + - result.can_parse_key is defined + # Check that return values are correct + - result.can_load_key + - not result.can_parse_key + # Check that additional data isn't there + - "'pulic_key' not in result" + - "'pulic_key_fingerprints' not in result" + - "'type' not in result" + - "'public_data' not in result" + - "'private_data' not in result" + +- name: ({{ select_crypto_backend }}) Get corrupt key info + community.crypto.openssl_privatekey_info: + content: C0RRUPT + return_private_key_data: true + select_crypto_backend: '{{ select_crypto_backend }}' + register: result + ignore_errors: true + +- name: Check that corrupt key loading failed + ansible.builtin.assert: + that: + - result is failed + # Check that return values are there + - result.can_load_key is defined + - result.can_parse_key is defined + # Check that return values are correct + - result.can_load_key + - not result.can_parse_key + # Check that additional data isn't there + - "'pulic_key' not in result" + - "'pulic_key_fingerprints' not in result" + - "'type' not in result" + - "'public_data' not in result" + - "'private_data' not in result"