Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ Changelog
curve's order, matching
:func:`~cryptography.hazmat.primitives.asymmetric.ec.derive_private_key` and
the private key loading functions.
* :func:`~cryptography.hazmat.primitives.serialization.load_pem_private_key`
now raises ``ValueError`` for an encrypted traditional PEM whose
``DEK-Info`` IV does not match the cipher's IV length. Previously, some
lengths raised ``PanicException``.
* Added
:class:`~cryptography.hazmat.primitives.serialization.MLDSA44Ed25519PrivateKey`
and
Expand Down
8 changes: 4 additions & 4 deletions src/rust/cryptography-key-parsing/src/pem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ pub fn decrypt_pem<'a>(

let iv = cryptography_crypto::encoding::hex_decode(iv)
.ok_or(KeyParsingError::PemInvalidIv)?;
if Some(iv.len()) != cipher.iv_len() {
return Err(KeyParsingError::PemInvalidIv);
}

let key = cryptography_crypto::pbkdf1::openssl_kdf(
openssl::hash::MessageDigest::md5(),
password,
iv.get(..8)
.ok_or(KeyParsingError::PemInvalidIv)?
.try_into()
.unwrap(),
iv[..8].try_into().unwrap(),
cipher.key_len(),
)
.map_err(|_| KeyParsingError::PemUnableToDeriveKey)?;
Expand Down
8 changes: 5 additions & 3 deletions src/rust/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,11 @@ impl From<cryptography_key_parsing::KeyParsingError> for CryptographyError {
"Encrypted PEM's DEK-Info header is not valid.",
))
}
cryptography_key_parsing::KeyParsingError::PemInvalidIv => CryptographyError::Py(
pyo3::exceptions::PyValueError::new_err("DEK-Info IV is not valid hex"),
),
cryptography_key_parsing::KeyParsingError::PemInvalidIv => {
CryptographyError::Py(pyo3::exceptions::PyValueError::new_err(
"DEK-Info IV is not valid hex or has the wrong length",
))
}
cryptography_key_parsing::KeyParsingError::PemUnableToDeriveKey => {
CryptographyError::Py(pyo3::exceptions::PyValueError::new_err(
"Unable to derive key from password (are you in FIPS mode?)",
Expand Down
21 changes: 21 additions & 0 deletions tests/hazmat/primitives/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,27 @@ def test_pem_encryption_short_iv(self):
with pytest.raises(ValueError):
load_pem_private_key(data, password=b"password")

@pytest.mark.parametrize(
("cipher", "iv_len"),
[
("AES-128-CBC", 8),
("AES-128-CBC", 15),
("AES-256-CBC", 17),
("DES-EDE3-CBC", 9),
],
)
def test_pem_encryption_wrong_iv_length(self, cipher, iv_len):
data = textwrap.dedent(f"""\
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: {cipher},{"00" * iv_len}
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
-----END RSA PRIVATE KEY-----
""").encode()
with pytest.raises(ValueError):
load_pem_private_key(data, password=b"password")

def test_pkcs8_key_with_wrong_pem_delimiter(self):
data = load_vectors_from_file(
os.path.join(
Expand Down
Loading