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 8e473ffe..51c85881 100644 --- a/plugins/module_utils/_crypto/support.py +++ b/plugins/module_utils/_crypto/support.py @@ -25,6 +25,7 @@ from ansible_collections.community.crypto.plugins.module_utils._crypto.pem impor try: from cryptography import x509 + from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.serialization import load_pem_private_key except ImportError: @@ -168,13 +169,15 @@ def load_privatekey( priv_key_detail, None if passphrase is None else to_bytes(passphrase), ) + except UnsupportedAlgorithm as exc: + raise OpenSSLBadPassphraseError(f"Unsupported private key type: {exc}") from exc except TypeError as exc: raise OpenSSLBadPassphraseError( "Wrong or empty passphrase provided for private key" ) from exc except ValueError as exc: raise OpenSSLBadPassphraseError( - "Wrong passphrase provided for private key" + f"Wrong passphrase provided for private key, or private key cannot be parsed: {exc}" ) from exc 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"