diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fdb2d5ffb1e2..8f03e173bac1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,8 +10,15 @@ Changelog * Support for Python 3.7 is deprecated and will be removed in the next ``cryptography`` release. -* Added support for PKCS7 decryption & encryption using AES-256 as content algorithm, - in addition to AES-128. +* Added support for PKCS7 decryption & encryption using AES-256 as content algorithm, + in addition to AES-128. +* **BACKWARDS INCOMPATIBLE:** Made SSH private key loading more consistent with + other private key loading: + :func:`~cryptography.hazmat.primitives.serialization.load_ssh_private_key` + now raises a ``TypeError`` if the key is unencrypted but a password is + provided (previously no exception was raised), and raises a ``TypeError`` if + the key is encrypted but no password is provided (previously a ``ValueError`` + was raised). .. _v44-0-0: diff --git a/src/cryptography/hazmat/primitives/serialization/ssh.py b/src/cryptography/hazmat/primitives/serialization/ssh.py index 8be2811c6e93..4d5e704a72b8 100644 --- a/src/cryptography/hazmat/primitives/serialization/ssh.py +++ b/src/cryptography/hazmat/primitives/serialization/ssh.py @@ -196,7 +196,9 @@ def _init_cipher( ) -> Cipher[modes.CBC | modes.CTR | modes.GCM]: """Generate key + iv and return cipher.""" if not password: - raise ValueError("Key is password-protected.") + raise TypeError( + "Key is password-protected, but password was not provided." + ) ciph = _SSH_CIPHERS[ciphername] seed = _bcrypt_kdf( @@ -745,6 +747,10 @@ def load_ssh_private_key( # should be no output from finalize _check_empty(dec.finalize()) else: + if password: + raise TypeError( + "Password was given but private key is not encrypted." + ) # load secret data edata, data = _get_sshstr(data) _check_empty(data) diff --git a/tests/hazmat/primitives/test_ssh.py b/tests/hazmat/primitives/test_ssh.py index ec424a2bc2aa..610148594268 100644 --- a/tests/hazmat/primitives/test_ssh.py +++ b/tests/hazmat/primitives/test_ssh.py @@ -375,7 +375,7 @@ def test_bcrypt_encryption(self, backend): ) assert pub1 == pub2 - with pytest.raises(ValueError): + with pytest.raises(TypeError): decoded_key = load_ssh_private_key(encdata, None, backend) with pytest.raises(ValueError): decoded_key = load_ssh_private_key(encdata, b"wrong", backend) @@ -611,6 +611,15 @@ def test_ssh_errors_bad_secrets(self, backend): with pytest.raises(ValueError): load_ssh_private_key(data, None, backend) + def test_ssh_errors_unencrypted_with_password(self): + data = load_vectors_from_file( + os.path.join("asymmetric", "OpenSSH", "rsa-nopsw.key"), + lambda f: f.read(), + mode="rb", + ) + with pytest.raises(TypeError): + load_ssh_private_key(data, password=b"password") + @pytest.mark.supported( only_if=lambda backend: backend.elliptic_curve_supported( ec.SECP192R1()