From 7417a8e0b955d47a33ff56a647d6874be3585bfd Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Tue, 28 Oct 2025 17:15:09 +0100 Subject: [PATCH 01/15] fix: add deep copy for rsa keys --- .../hazmat/primitives/asymmetric/rsa.py | 12 ++++++++++ src/rust/src/backend/rsa.rs | 23 ++++++++++++++++++- tests/hazmat/primitives/test_rsa.py | 22 ++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py index f94812e186f5..959db1594f26 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -69,6 +69,12 @@ def __copy__(self) -> RSAPrivateKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> RSAPrivateKey: + """ + Returns a deep copy. + """ + RSAPrivateKeyWithSerialization = RSAPrivateKey RSAPrivateKey.register(rust_openssl.rsa.RSAPrivateKey) @@ -139,6 +145,12 @@ def __copy__(self) -> RSAPublicKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> RSAPublicKey: + """ + Returns a deep copy. + """ + RSAPublicKeyWithSerialization = RSAPublicKey RSAPublicKey.register(rust_openssl.rsa.RSAPublicKey) diff --git a/src/rust/src/backend/rsa.rs b/src/rust/src/backend/rsa.rs index a8627e78ff75..a0fcfcb2de12 100644 --- a/src/rust/src/backend/rsa.rs +++ b/src/rust/src/backend/rsa.rs @@ -5,7 +5,7 @@ use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; -use pyo3::types::PyAnyMethods; +use pyo3::types::{PyAnyMethods, PyDict}; use crate::backend::{hashes, utils}; use crate::buf::CffiBuf; @@ -422,6 +422,17 @@ impl RsaPrivateKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + + Ok(new_key) + } } #[pyo3::pymethods] @@ -535,6 +546,16 @@ impl RsaPublicKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + Ok(new_key) + } } #[pyo3::pyclass( diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 2c595e7395c1..cbf87074e394 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -8,6 +8,7 @@ import itertools import os +from cryptography.hazmat.primitives.asymmetric.rsa import generate_private_key import pytest from cryptography.exceptions import InvalidSignature, _Reasons @@ -15,6 +16,7 @@ from cryptography.hazmat.primitives.asymmetric import padding, rsa from cryptography.hazmat.primitives.asymmetric import utils as asym_utils from cryptography.hazmat.primitives.asymmetric.rsa import ( + RSAPrivateKey, RSAPrivateNumbers, RSAPublicNumbers, ) @@ -2795,3 +2797,23 @@ def test_private_key_copy(self, rsa_key_2048: rsa.RSAPrivateKey): key2 = copy.copy(key1) assert key1 == key2 + + def test_public_key_deepcopy(self, rsa_key_2048: rsa.RSAPrivateKey): + key1 = rsa_key_2048.public_key() + key2 = copy.deepcopy(key1) + + assert key1.public_numbers() == key2.public_numbers() + + key1 = generate_private_key(public_exponent=65537, key_size=2048).public_key() + + assert key1.public_numbers() != key2.public_numbers() + + def test_private_key_deepcopy(self, rsa_key_2048: rsa.RSAPrivateKey): + key1 = rsa_key_2048 + key2 = copy.deepcopy(key1) + + assert key1.private_numbers() == key2.private_numbers() + + key1 = generate_private_key(public_exponent=65537, key_size=2048) + + assert key1.private_numbers() != key2.private_numbers() From 087b6f1f8adbcc9e446acb7d7296d5a30e2464b7 Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Wed, 29 Oct 2025 15:38:43 +0100 Subject: [PATCH 02/15] fix: add deep copy for dh keys --- .../hazmat/primitives/asymmetric/dh.py | 12 +++++ src/rust/src/backend/dh.rs | 22 +++++++++ tests/hazmat/primitives/test_dh.py | 45 +++++++++++++++++++ tests/hazmat/primitives/test_rsa.py | 7 +-- 4 files changed, 83 insertions(+), 3 deletions(-) diff --git a/src/cryptography/hazmat/primitives/asymmetric/dh.py b/src/cryptography/hazmat/primitives/asymmetric/dh.py index 1822e99dcda8..5aacb726f4d2 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dh.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dh.py @@ -87,6 +87,12 @@ def __copy__(self) -> DHPublicKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> DHPublicKey: + """ + Returns a deep copy. + """ + DHPublicKeyWithSerialization = DHPublicKey DHPublicKey.register(rust_openssl.dh.DHPublicKey) @@ -142,6 +148,12 @@ def __copy__(self) -> DHPrivateKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> DHPrivateKey: + """ + Returns a deep copy. + """ + DHPrivateKeyWithSerialization = DHPrivateKey DHPrivateKey.register(rust_openssl.dh.DHPrivateKey) diff --git a/src/rust/src/backend/dh.rs b/src/rust/src/backend/dh.rs index fb90847613a3..4ac05d46d822 100644 --- a/src/rust/src/backend/dh.rs +++ b/src/rust/src/backend/dh.rs @@ -247,6 +247,17 @@ impl DHPrivateKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + + Ok(new_key) + } } #[pyo3::pymethods] @@ -312,6 +323,17 @@ impl DHPublicKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + + Ok(new_key) + } } #[pyo3::pymethods] diff --git a/tests/hazmat/primitives/test_dh.py b/tests/hazmat/primitives/test_dh.py index 3fb563239f1d..02b1a0491a05 100644 --- a/tests/hazmat/primitives/test_dh.py +++ b/tests/hazmat/primitives/test_dh.py @@ -482,6 +482,27 @@ def test_public_key_copy(self): assert key1 == key2 + def test_public_key_deepcopy(self): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "DH", "dhpub.pem"), + lambda pemfile: pemfile.read(), + mode="rb", + ) + + key_bytes_2 = load_vectors_from_file( + os.path.join("asymmetric", "DH", "dhpub_rfc5114_2.pem"), + lambda pemfile: pemfile.read(), + mode="rb", + ) + + key1 = serialization.load_pem_public_key(key_bytes) + key2 = copy.deepcopy(key1) + + assert key1 == key2 + + key1 = serialization.load_pem_public_key(key_bytes_2) + assert key1 != key2 + @pytest.mark.skip_fips(reason="non-FIPS parameters") def test_private_key_copy(self, backend): key_bytes = load_vectors_from_file( @@ -494,6 +515,30 @@ def test_private_key_copy(self, backend): assert key1 == key2 + @pytest.mark.skip_fips(reason="non-FIPS parameters") + def test_private_key_deepcopy(self, backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "DH", "dhkey.pem"), + lambda pemfile: pemfile.read(), + mode="rb", + ) + + key_bytes_2 = load_vectors_from_file( + os.path.join("asymmetric", "DH", "dhkey_rfc5114_2.pem"), + lambda pemfile: pemfile.read(), + mode="rb", + ) + + key1 = serialization.load_pem_private_key(key_bytes, None, backend) + if not isinstance(key1, dh.DHPrivateKey): + raise ValueError("Expected a DHPrivateKey") + key2 = copy.deepcopy(key1) + + assert key1.parameters() != key2.parameters() + + key1 = serialization.load_pem_private_key(key_bytes_2, None, backend) + assert key1 != key2 + @pytest.mark.supported( only_if=lambda backend: backend.dh_supported(), diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index cbf87074e394..19917808a06d 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -8,7 +8,6 @@ import itertools import os -from cryptography.hazmat.primitives.asymmetric.rsa import generate_private_key import pytest from cryptography.exceptions import InvalidSignature, _Reasons @@ -16,9 +15,9 @@ from cryptography.hazmat.primitives.asymmetric import padding, rsa from cryptography.hazmat.primitives.asymmetric import utils as asym_utils from cryptography.hazmat.primitives.asymmetric.rsa import ( - RSAPrivateKey, RSAPrivateNumbers, RSAPublicNumbers, + generate_private_key, ) from ...doubles import ( @@ -2804,7 +2803,9 @@ def test_public_key_deepcopy(self, rsa_key_2048: rsa.RSAPrivateKey): assert key1.public_numbers() == key2.public_numbers() - key1 = generate_private_key(public_exponent=65537, key_size=2048).public_key() + key1 = generate_private_key( + public_exponent=65537, key_size=2048 + ).public_key() assert key1.public_numbers() != key2.public_numbers() From de8775e0f833eb33428585ba5f6bf8514257ffcb Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Wed, 29 Oct 2025 20:55:21 +0100 Subject: [PATCH 03/15] fix: add deep copy for ec keys --- .../hazmat/primitives/asymmetric/dsa.py | 18 ++++++++++ .../hazmat/primitives/asymmetric/ec.py | 12 +++++++ src/rust/src/backend/dsa.rs | 22 ++++++++++++ src/rust/src/backend/ec.rs | 28 +++++++++++++++ tests/hazmat/primitives/test_dsa.py | 29 +++++++++++++++ tests/hazmat/primitives/test_ec.py | 35 +++++++++++++++++++ tests/hazmat/primitives/test_rsa.py | 1 + 7 files changed, 145 insertions(+) diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py index 21d78ba95e03..1cb44076c7ef 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py @@ -78,12 +78,24 @@ def private_bytes( Returns the key serialized as bytes. """ + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + @abc.abstractmethod def __copy__(self) -> DSAPrivateKey: """ Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> DSAPrivateKey: + """ + Returns a deep copy. + """ + DSAPrivateKeyWithSerialization = DSAPrivateKey DSAPrivateKey.register(rust_openssl.dsa.DSAPrivateKey) @@ -142,6 +154,12 @@ def __copy__(self) -> DSAPublicKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> DSAPublicKey: + """ + Returns a deep copy. + """ + DSAPublicKeyWithSerialization = DSAPublicKey DSAPublicKey.register(rust_openssl.dsa.DSAPublicKey) diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py index 5f37077f781e..e98895256794 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -134,6 +134,12 @@ def __copy__(self) -> EllipticCurvePrivateKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> EllipticCurvePrivateKey: + """ + Returns a deep copy. + """ + EllipticCurvePrivateKeyWithSerialization = EllipticCurvePrivateKey EllipticCurvePrivateKey.register(rust_openssl.ec.ECPrivateKey) @@ -207,6 +213,12 @@ def __copy__(self) -> EllipticCurvePublicKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> EllipticCurvePublicKey: + """ + Returns a deep copy. + """ + EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey EllipticCurvePublicKey.register(rust_openssl.ec.ECPublicKey) diff --git a/src/rust/src/backend/dsa.rs b/src/rust/src/backend/dsa.rs index 0cf3170d7b2b..cb3deda1d10a 100644 --- a/src/rust/src/backend/dsa.rs +++ b/src/rust/src/backend/dsa.rs @@ -153,9 +153,22 @@ impl DsaPrivateKey { ) } + fn __eq__(&self, other: pyo3::PyRef<'_, Self>) -> bool { + self.pkey.public_eq(&other.pkey) + } + fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + Ok(Self { + pkey: slf.pkey.clone(), + }) + } } #[pyo3::pymethods] @@ -229,6 +242,15 @@ impl DsaPublicKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + Ok(Self { + pkey: slf.pkey.clone(), + }) + } } #[pyo3::pymethods] diff --git a/src/rust/src/backend/ec.rs b/src/rust/src/backend/ec.rs index 10c105bd3030..cafddde933ac 100644 --- a/src/rust/src/backend/ec.rs +++ b/src/rust/src/backend/ec.rs @@ -373,6 +373,20 @@ impl ECPrivateKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + py: pyo3::Python<'p>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let ec = slf.pkey.ec_key()?; + let curve = py_curve_from_curve(py, ec.group())?; + let new_key = Self { + pkey: slf.pkey.clone(), + curve: curve.clone().into(), + }; + Ok(new_key) + } } #[pyo3::pymethods] @@ -458,6 +472,20 @@ impl ECPublicKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + py: pyo3::Python<'p>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let ec = slf.pkey.ec_key()?; + let curve = py_curve_from_curve(py, ec.group())?; + let new_key = Self { + pkey: slf.pkey.clone(), + curve: curve.clone().into(), + }; + Ok(new_key) + } } #[pyo3::pyclass(frozen, module = "cryptography.hazmat.primitives.asymmetric.ec")] diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py index 844430389da2..ab88093bdb7d 100644 --- a/tests/hazmat/primitives/test_dsa.py +++ b/tests/hazmat/primitives/test_dsa.py @@ -409,6 +409,21 @@ def test_public_key_copy(self): assert key1 == key2 + def test_public_key_deepcopy(self): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "PKCS8", "unenc-dsa-pkcs8.pem"), + lambda pemfile: pemfile.read().encode(), + ) + key1 = serialization.load_pem_private_key(key_bytes, None).public_key() + if not isinstance(key1, dsa.DSAPublicKey): + raise ValueError("Expected a DSA public key") + key2 = copy.deepcopy(key1) + assert key1.public_numbers() == key2.public_numbers() + assert id(key1) != id(key2) + + key1 = dsa.generate_private_key(2048).public_key() + assert key1.public_numbers() != key2.public_numbers() + def test_private_key_copy(self): key_bytes = load_vectors_from_file( os.path.join("asymmetric", "PKCS8", "unenc-dsa-pkcs8.pem"), @@ -419,6 +434,20 @@ def test_private_key_copy(self): assert key1 == key2 + def test_private_key_deepcopy(self): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "PKCS8", "unenc-dsa-pkcs8.pem"), + lambda pemfile: pemfile.read().encode(), + ) + key1 = serialization.load_pem_private_key(key_bytes, None) + if not isinstance(key1, dsa.DSAPrivateKey): + raise ValueError("Expected a DSA private key") + key2 = copy.deepcopy(key1) + assert key1.private_numbers() == key2.private_numbers() + assert id(key1) != id(key2) + key1 = dsa.generate_private_key(2048) + assert key1.private_numbers() != key2.private_numbers() + @pytest.mark.supported( only_if=lambda backend: backend.dsa_supported(), diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index 29d73e14b781..7e12acefd253 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -769,6 +769,23 @@ def test_public_key_copy(self, backend): assert key1 == key2 + def test_public_key_deepcopy(self, backend): + _skip_curve_unsupported(backend, ec.SECP256R1()) + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "PKCS8", "ec_private_key.pem"), + lambda pemfile: pemfile.read().encode(), + ) + key1 = serialization.load_pem_private_key(key_bytes, None).public_key() + if not isinstance(key1, ec.EllipticCurvePublicKey): + raise ValueError("Expected an EllipticCurvePublicKey") + key2 = copy.deepcopy(key1) + + assert id(key1) != id(key2) + assert ( + key1.curve == key2.curve + and key1.public_numbers() == key2.public_numbers() + ) + def test_private_key_copy(self, backend): _skip_curve_unsupported(backend, ec.SECP256R1()) key_bytes = load_vectors_from_file( @@ -780,6 +797,24 @@ def test_private_key_copy(self, backend): assert key1 == key2 + def test_private_key_deepcopy(self, backend): + _skip_curve_unsupported(backend, ec.SECP256R1()) + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "PKCS8", "ec_private_key.pem"), + lambda pemfile: pemfile.read().encode(), + ) + key1 = serialization.load_pem_private_key(key_bytes, None) + if not isinstance(key1, ec.EllipticCurvePrivateKey): + raise ValueError("Expected an EllipticCurvePrivateKey") + + key2 = copy.deepcopy(key1) + + assert id(key1) != id(key2) + assert ( + key1.curve == key2.curve + and key1.private_numbers() == key2.private_numbers() + ) + class TestECSerialization: @pytest.mark.parametrize( diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 19917808a06d..062e7df880ae 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -2802,6 +2802,7 @@ def test_public_key_deepcopy(self, rsa_key_2048: rsa.RSAPrivateKey): key2 = copy.deepcopy(key1) assert key1.public_numbers() == key2.public_numbers() + assert id(key1) != id(key2) key1 = generate_private_key( public_exponent=65537, key_size=2048 From 1f952b5a545c72b9172b4c69b6ccdd7affb7ad7e Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Wed, 29 Oct 2025 21:35:28 +0100 Subject: [PATCH 04/15] fix: add deep copy for ed25519 keys --- .../hazmat/primitives/asymmetric/ed25519.py | 12 ++++++ src/rust/src/backend/ed25519.rs | 20 ++++++++++ tests/hazmat/primitives/test_ed25519.py | 39 +++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py index e576dc9f42f1..fea591b005f4 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed25519.py @@ -60,6 +60,12 @@ def __copy__(self) -> Ed25519PublicKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> Ed25519PublicKey: + """ + Returns a deep copy. + """ + Ed25519PublicKey.register(rust_openssl.ed25519.Ed25519PublicKey) @@ -125,5 +131,11 @@ def __copy__(self) -> Ed25519PrivateKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> Ed25519PrivateKey: + """ + Returns a deep copy. + """ + Ed25519PrivateKey.register(rust_openssl.ed25519.Ed25519PrivateKey) diff --git a/src/rust/src/backend/ed25519.rs b/src/rust/src/backend/ed25519.rs index 1158a1bc56c2..fd3b9da3972c 100644 --- a/src/rust/src/backend/ed25519.rs +++ b/src/rust/src/backend/ed25519.rs @@ -119,6 +119,16 @@ impl Ed25519PrivateKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'_, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + Ok(new_key) + } } #[pyo3::pymethods] @@ -161,6 +171,16 @@ impl Ed25519PublicKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'_, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + Ok(new_key) + } } #[pyo3::pymodule(gil_used = false)] diff --git a/tests/hazmat/primitives/test_ed25519.py b/tests/hazmat/primitives/test_ed25519.py index fddb39d0d6d5..6d19ba333823 100644 --- a/tests/hazmat/primitives/test_ed25519.py +++ b/tests/hazmat/primitives/test_ed25519.py @@ -12,6 +12,7 @@ from cryptography.exceptions import InvalidSignature, _Reasons from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ed25519 from cryptography.hazmat.primitives.asymmetric.ed25519 import ( Ed25519PrivateKey, Ed25519PublicKey, @@ -329,6 +330,25 @@ def test_public_key_copy(backend): assert key1 == key2 +@pytest.mark.supported( + only_if=lambda backend: backend.ed25519_supported(), + skip_message="Requires OpenSSL with Ed25519 support", +) +def test_public_key_deepcopy(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "Ed25519", "ed25519-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None).public_key() + if not isinstance(key1, ed25519.Ed25519PublicKey): + raise ValueError("Expected a Ed25519PublicKey") + key2 = copy.deepcopy(key1) + + assert id(key1) != id(key2) + assert key1.public_bytes_raw() == key2.public_bytes_raw() + + @pytest.mark.supported( only_if=lambda backend: backend.ed25519_supported(), skip_message="Requires OpenSSL with Ed25519 support", @@ -343,3 +363,22 @@ def test_private_key_copy(backend): key2 = copy.copy(key1) assert key1 == key2 + + +@pytest.mark.supported( + only_if=lambda backend: backend.ed25519_supported(), + skip_message="Requires OpenSSL with Ed25519 support", +) +def test_private_key_deepcopy(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "Ed25519", "ed25519-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None) + if not isinstance(key1, ed25519.Ed25519PrivateKey): + raise ValueError("Expected a Ed25519PrivateKey") + key2 = copy.deepcopy(key1) + + assert id(key1) != id(key2) + assert key1.private_bytes_raw() == key2.private_bytes_raw() From 0c86c733722b21008260ee34ee88ea3fa016740e Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Wed, 29 Oct 2025 22:35:52 +0100 Subject: [PATCH 05/15] fix: add deep copy for ed448 keys --- .../hazmat/primitives/asymmetric/ed448.py | 12 ++++++ src/rust/src/backend/ed25519.rs | 4 +- src/rust/src/backend/ed448.rs | 20 ++++++++++ tests/hazmat/primitives/test_ed448.py | 39 +++++++++++++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/cryptography/hazmat/primitives/asymmetric/ed448.py b/src/cryptography/hazmat/primitives/asymmetric/ed448.py index 89db20984fd6..ec6d607b86c0 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ed448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ed448.py @@ -60,6 +60,12 @@ def __copy__(self) -> Ed448PublicKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> Ed448PublicKey: + """ + Returns a deep copy. + """ + if hasattr(rust_openssl, "ed448"): Ed448PublicKey.register(rust_openssl.ed448.Ed448PublicKey) @@ -126,6 +132,12 @@ def __copy__(self) -> Ed448PrivateKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> Ed448PrivateKey: + """ + Returns a deep copy. + """ + if hasattr(rust_openssl, "x448"): Ed448PrivateKey.register(rust_openssl.ed448.Ed448PrivateKey) diff --git a/src/rust/src/backend/ed25519.rs b/src/rust/src/backend/ed25519.rs index fd3b9da3972c..a265a6294fe0 100644 --- a/src/rust/src/backend/ed25519.rs +++ b/src/rust/src/backend/ed25519.rs @@ -121,7 +121,7 @@ impl Ed25519PrivateKey { } fn __deepcopy__<'p>( - slf: pyo3::PyRef<'_, Self>, + slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, ) -> CryptographyResult { let new_key = Self { @@ -173,7 +173,7 @@ impl Ed25519PublicKey { } fn __deepcopy__<'p>( - slf: pyo3::PyRef<'_, Self>, + slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, ) -> CryptographyResult { let new_key = Self { diff --git a/src/rust/src/backend/ed448.rs b/src/rust/src/backend/ed448.rs index eac69b41ff4e..713f9024d9f1 100644 --- a/src/rust/src/backend/ed448.rs +++ b/src/rust/src/backend/ed448.rs @@ -117,6 +117,16 @@ impl Ed448PrivateKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + Ok(new_key) + } } #[pyo3::pymethods] @@ -158,6 +168,16 @@ impl Ed448PublicKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + Ok(new_key) + } } #[pyo3::pymodule(gil_used = false)] diff --git a/tests/hazmat/primitives/test_ed448.py b/tests/hazmat/primitives/test_ed448.py index de1e84fb7105..64948d8ab1bf 100644 --- a/tests/hazmat/primitives/test_ed448.py +++ b/tests/hazmat/primitives/test_ed448.py @@ -12,6 +12,7 @@ from cryptography.exceptions import InvalidSignature, _Reasons from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ed448 from cryptography.hazmat.primitives.asymmetric.ed448 import ( Ed448PrivateKey, Ed448PublicKey, @@ -323,6 +324,25 @@ def test_public_key_copy(backend): assert key1 == key2 +@pytest.mark.supported( + only_if=lambda backend: backend.ed448_supported(), + skip_message="Requires OpenSSL with Ed448 support", +) +def test_public_key_deepcopy(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "Ed448", "ed448-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None).public_key() + if not isinstance(key1, ed448.Ed448PublicKey): + raise ValueError("Expected Ed448PublicKey") + key2 = copy.deepcopy(key1) + + assert id(key1) != id(key2) + assert key1.public_bytes_raw() == key2.public_bytes_raw() + + @pytest.mark.supported( only_if=lambda backend: backend.ed448_supported(), skip_message="Requires OpenSSL with Ed448 support", @@ -337,3 +357,22 @@ def test_private_key_copy(backend): key2 = copy.copy(key1) assert key1 == key2 + + +@pytest.mark.supported( + only_if=lambda backend: backend.ed448_supported(), + skip_message="Requires OpenSSL with Ed448 support", +) +def test_private_key_deepcopy(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "Ed448", "ed448-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None) + if not isinstance(key1, ed448.Ed448PrivateKey): + raise ValueError("Expected Ed448PrivateKey") + key2 = copy.deepcopy(key1) + + assert id(key1) != id(key2) + assert key1.private_bytes_raw() == key2.private_bytes_raw() From 9659cf99da6114463416891f0f782cbcb350dd6d Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Wed, 29 Oct 2025 22:42:21 +0100 Subject: [PATCH 06/15] fix: add deep copy for x25519 keys --- .../hazmat/primitives/asymmetric/x25519.py | 12 ++++++ src/rust/src/backend/x25519.rs | 20 ++++++++++ tests/hazmat/primitives/test_x25519.py | 39 +++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/src/cryptography/hazmat/primitives/asymmetric/x25519.py b/src/cryptography/hazmat/primitives/asymmetric/x25519.py index a4993766b076..e73c20e6240c 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x25519.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x25519.py @@ -54,6 +54,12 @@ def __copy__(self) -> X25519PublicKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> X25519PublicKey: + """ + Returns a deep copy. + """ + X25519PublicKey.register(rust_openssl.x25519.X25519PublicKey) @@ -118,5 +124,11 @@ def __copy__(self) -> X25519PrivateKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> X25519PrivateKey: + """ + Returns a deep copy. + """ + X25519PrivateKey.register(rust_openssl.x25519.X25519PrivateKey) diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index ff0658a03779..f6d077ad00ff 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -119,6 +119,16 @@ impl X25519PrivateKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + Ok(new_key) + } } #[pyo3::pymethods] @@ -147,6 +157,16 @@ impl X25519PublicKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + Ok(new_key) + } } #[pyo3::pymodule(gil_used = false)] diff --git a/tests/hazmat/primitives/test_x25519.py b/tests/hazmat/primitives/test_x25519.py index f478e7cfcf76..833fb7847d21 100644 --- a/tests/hazmat/primitives/test_x25519.py +++ b/tests/hazmat/primitives/test_x25519.py @@ -12,6 +12,7 @@ from cryptography.exceptions import _Reasons from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import x25519 from cryptography.hazmat.primitives.asymmetric.x25519 import ( X25519PrivateKey, X25519PublicKey, @@ -379,6 +380,25 @@ def test_public_key_copy(backend): assert key1 == key2 +@pytest.mark.supported( + only_if=lambda backend: backend.x25519_supported(), + skip_message="Requires OpenSSL with X25519 support", +) +def test_public_key_deepcopy(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "X25519", "x25519-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None).public_key() + if not isinstance(key1, x25519.X25519PublicKey): + raise ValueError("Expected X25519PublicKey") + key2 = copy.deepcopy(key1) + + assert id(key1) != id(key2) + assert key1.public_bytes_raw() == key2.public_bytes_raw() + + @pytest.mark.supported( only_if=lambda backend: backend.x25519_supported(), skip_message="Requires OpenSSL with X25519 support", @@ -393,3 +413,22 @@ def test_private_key_copy(backend): key2 = copy.copy(key1) assert key1 == key2 + + +@pytest.mark.supported( + only_if=lambda backend: backend.x25519_supported(), + skip_message="Requires OpenSSL with X25519 support", +) +def test_private_key_deepcopy(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "X25519", "x25519-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None) + if not isinstance(key1, x25519.X25519PrivateKey): + raise ValueError("Expected X25519PrivateKey") + key2 = copy.deepcopy(key1) + + assert id(key1) != id(key2) + assert key1.private_bytes_raw() == key2.private_bytes_raw() From 0d652a51da5f96e42849c69eebac76b9e8aece35 Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Wed, 29 Oct 2025 22:49:46 +0100 Subject: [PATCH 07/15] fix: add deep copy for x448 keys --- .../hazmat/primitives/asymmetric/x448.py | 12 +++++++ src/rust/src/backend/x448.rs | 20 +++++++++++ tests/hazmat/primitives/test_x448.py | 35 +++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/cryptography/hazmat/primitives/asymmetric/x448.py b/src/cryptography/hazmat/primitives/asymmetric/x448.py index c6fd71ba5003..748bcd58a0c6 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/x448.py +++ b/src/cryptography/hazmat/primitives/asymmetric/x448.py @@ -54,6 +54,12 @@ def __copy__(self) -> X448PublicKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> X448PublicKey: + """ + Returns a deep copy. + """ + if hasattr(rust_openssl, "x448"): X448PublicKey.register(rust_openssl.x448.X448PublicKey) @@ -120,6 +126,12 @@ def __copy__(self) -> X448PrivateKey: Returns a copy. """ + @abc.abstractmethod + def __deepcopy__(self) -> X448PrivateKey: + """ + Returns a deep copy. + """ + if hasattr(rust_openssl, "x448"): X448PrivateKey.register(rust_openssl.x448.X448PrivateKey) diff --git a/src/rust/src/backend/x448.rs b/src/rust/src/backend/x448.rs index 8e04307b3dcf..527eb4d2dc66 100644 --- a/src/rust/src/backend/x448.rs +++ b/src/rust/src/backend/x448.rs @@ -118,6 +118,16 @@ impl X448PrivateKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + Ok(new_key) + } } #[pyo3::pymethods] @@ -146,6 +156,16 @@ impl X448PublicKey { fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } + + fn __deepcopy__<'p>( + slf: pyo3::PyRef<'p, Self>, + _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + ) -> CryptographyResult { + let new_key = Self { + pkey: slf.pkey.clone(), + }; + Ok(new_key) + } } #[pyo3::pymodule(gil_used = false)] diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py index 75b9dd0b48c8..83585a0893d9 100644 --- a/tests/hazmat/primitives/test_x448.py +++ b/tests/hazmat/primitives/test_x448.py @@ -12,6 +12,7 @@ from cryptography.exceptions import _Reasons from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import x448 from cryptography.hazmat.primitives.asymmetric.x448 import ( X448PrivateKey, X448PublicKey, @@ -309,6 +310,21 @@ def test_public_key_copy(backend): assert key1 == key2 +def test_public_key_deepcopy(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "X448", "x448-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None).public_key() + if not isinstance(key1, x448.X448PublicKey): + raise ValueError("Expected X448PublicKey") + key2 = copy.deepcopy(key1) + + assert id(key1) != id(key2) + assert key1.public_bytes_raw() == key2.public_bytes_raw() + + @pytest.mark.supported( only_if=lambda backend: backend.x448_supported(), skip_message="Requires OpenSSL with X448 support", @@ -323,3 +339,22 @@ def test_private_key_copy(backend): key2 = copy.copy(key1) assert key1 == key2 + + +@pytest.mark.supported( + only_if=lambda backend: backend.x448_supported(), + skip_message="Requires OpenSSL with X448 support", +) +def test_private_key_deepcopy(backend): + key_bytes = load_vectors_from_file( + os.path.join("asymmetric", "X448", "x448-pkcs8.der"), + lambda derfile: derfile.read(), + mode="rb", + ) + key1 = serialization.load_der_private_key(key_bytes, None) + if not isinstance(key1, x448.X448PrivateKey): + raise ValueError("Expected X448PrivateKey") + key2 = copy.deepcopy(key1) + + assert id(key1) != id(key2) + assert key1.private_bytes_raw() == key2.private_bytes_raw() From 29630e2239f5d72e886b35baaca1955bc508f9f9 Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Wed, 29 Oct 2025 23:12:01 +0100 Subject: [PATCH 08/15] fix: forgot skip test when x448 not available --- tests/hazmat/primitives/test_x448.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py index 83585a0893d9..4098330da1f4 100644 --- a/tests/hazmat/primitives/test_x448.py +++ b/tests/hazmat/primitives/test_x448.py @@ -309,7 +309,10 @@ def test_public_key_copy(backend): assert key1 == key2 - +@pytest.mark.supported( + only_if=lambda backend: backend.x448_supported(), + skip_message="Requires OpenSSL with X448 support", +) def test_public_key_deepcopy(backend): key_bytes = load_vectors_from_file( os.path.join("asymmetric", "X448", "x448-pkcs8.der"), From 1e2523975b66f22688413a0d46c935bfde970290 Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Thu, 30 Oct 2025 11:55:19 +0100 Subject: [PATCH 09/15] chore: removed __eq__ from dsa because unrelated + fmt on x448 + added deepcopy on example clouhsm --- docs/hazmat/primitives/asymmetric/cloudhsm.rst | 3 +++ src/cryptography/hazmat/primitives/asymmetric/dsa.py | 6 ------ src/rust/src/backend/dsa.rs | 4 ---- tests/hazmat/primitives/test_x448.py | 1 + 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/docs/hazmat/primitives/asymmetric/cloudhsm.rst b/docs/hazmat/primitives/asymmetric/cloudhsm.rst index 8934133a228a..2f66a02ff6df 100644 --- a/docs/hazmat/primitives/asymmetric/cloudhsm.rst +++ b/docs/hazmat/primitives/asymmetric/cloudhsm.rst @@ -122,6 +122,9 @@ if you only need a subset of functionality. ... def __copy__(self) -> "CloudRSAPrivateKey": ... return self ... + ... def __deepcopy__(self, memodict: dict) -> "CloudRSAPrivateKey": + ... return self + ... >>> cloud_private_key = CloudRSAPrivateKey("creds", "key_id") >>> sig = cloud_private_key.sign(b"message", PKCS1v15(), hashes.SHA256()) >>> isinstance(sig, bytes) diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py index 1cb44076c7ef..8c736a2872ba 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py @@ -78,12 +78,6 @@ def private_bytes( Returns the key serialized as bytes. """ - @abc.abstractmethod - def __eq__(self, other: object) -> bool: - """ - Checks equality. - """ - @abc.abstractmethod def __copy__(self) -> DSAPrivateKey: """ diff --git a/src/rust/src/backend/dsa.rs b/src/rust/src/backend/dsa.rs index cb3deda1d10a..8b8a213cb4d5 100644 --- a/src/rust/src/backend/dsa.rs +++ b/src/rust/src/backend/dsa.rs @@ -153,10 +153,6 @@ impl DsaPrivateKey { ) } - fn __eq__(&self, other: pyo3::PyRef<'_, Self>) -> bool { - self.pkey.public_eq(&other.pkey) - } - fn __copy__(slf: pyo3::PyRef<'_, Self>) -> pyo3::PyRef<'_, Self> { slf } diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py index 4098330da1f4..9b4c46e8729e 100644 --- a/tests/hazmat/primitives/test_x448.py +++ b/tests/hazmat/primitives/test_x448.py @@ -309,6 +309,7 @@ def test_public_key_copy(backend): assert key1 == key2 + @pytest.mark.supported( only_if=lambda backend: backend.x448_supported(), skip_message="Requires OpenSSL with X448 support", From 828c95a04a41047d970a35f289d457058215ec4b Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Thu, 30 Oct 2025 13:39:52 +0100 Subject: [PATCH 10/15] fix: replaced all deepcopy implementations by self --- src/rust/src/backend/dh.rs | 16 ++++------------ src/rust/src/backend/dsa.rs | 12 ++++-------- src/rust/src/backend/ec.rs | 22 ++++------------------ src/rust/src/backend/ed25519.rs | 14 ++++---------- src/rust/src/backend/ed448.rs | 14 ++++---------- src/rust/src/backend/rsa.rs | 15 ++++----------- src/rust/src/backend/x25519.rs | 14 ++++---------- src/rust/src/backend/x448.rs | 14 ++++---------- tests/hazmat/primitives/test_dsa.py | 2 -- tests/hazmat/primitives/test_ec.py | 2 -- tests/hazmat/primitives/test_ed25519.py | 2 -- tests/hazmat/primitives/test_ed448.py | 2 -- tests/hazmat/primitives/test_rsa.py | 1 - tests/hazmat/primitives/test_x25519.py | 2 -- tests/hazmat/primitives/test_x448.py | 2 -- 15 files changed, 32 insertions(+), 102 deletions(-) diff --git a/src/rust/src/backend/dh.rs b/src/rust/src/backend/dh.rs index 4ac05d46d822..969901ab5436 100644 --- a/src/rust/src/backend/dh.rs +++ b/src/rust/src/backend/dh.rs @@ -251,12 +251,8 @@ impl DHPrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } @@ -327,12 +323,8 @@ impl DHPublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } diff --git a/src/rust/src/backend/dsa.rs b/src/rust/src/backend/dsa.rs index 8b8a213cb4d5..1e675035eff8 100644 --- a/src/rust/src/backend/dsa.rs +++ b/src/rust/src/backend/dsa.rs @@ -160,10 +160,8 @@ impl DsaPrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - Ok(Self { - pkey: slf.pkey.clone(), - }) + ) -> pyo3::PyRef<'p, Self> { + slf } } @@ -242,10 +240,8 @@ impl DsaPublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - Ok(Self { - pkey: slf.pkey.clone(), - }) + ) -> pyo3::PyRef<'p, Self> { + slf } } diff --git a/src/rust/src/backend/ec.rs b/src/rust/src/backend/ec.rs index cafddde933ac..ffc593a9e5dc 100644 --- a/src/rust/src/backend/ec.rs +++ b/src/rust/src/backend/ec.rs @@ -376,16 +376,9 @@ impl ECPrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - py: pyo3::Python<'p>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let ec = slf.pkey.ec_key()?; - let curve = py_curve_from_curve(py, ec.group())?; - let new_key = Self { - pkey: slf.pkey.clone(), - curve: curve.clone().into(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } @@ -475,16 +468,9 @@ impl ECPublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - py: pyo3::Python<'p>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let ec = slf.pkey.ec_key()?; - let curve = py_curve_from_curve(py, ec.group())?; - let new_key = Self { - pkey: slf.pkey.clone(), - curve: curve.clone().into(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } diff --git a/src/rust/src/backend/ed25519.rs b/src/rust/src/backend/ed25519.rs index a265a6294fe0..fd2d05317532 100644 --- a/src/rust/src/backend/ed25519.rs +++ b/src/rust/src/backend/ed25519.rs @@ -123,11 +123,8 @@ impl Ed25519PrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } @@ -175,11 +172,8 @@ impl Ed25519PublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } diff --git a/src/rust/src/backend/ed448.rs b/src/rust/src/backend/ed448.rs index 713f9024d9f1..d53a0d1bc5eb 100644 --- a/src/rust/src/backend/ed448.rs +++ b/src/rust/src/backend/ed448.rs @@ -121,11 +121,8 @@ impl Ed448PrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } @@ -172,11 +169,8 @@ impl Ed448PublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } diff --git a/src/rust/src/backend/rsa.rs b/src/rust/src/backend/rsa.rs index a0fcfcb2de12..c43083bfeb27 100644 --- a/src/rust/src/backend/rsa.rs +++ b/src/rust/src/backend/rsa.rs @@ -426,12 +426,8 @@ impl RsaPrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } @@ -550,11 +546,8 @@ impl RsaPublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index f6d077ad00ff..e2f69b20e940 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -123,11 +123,8 @@ impl X25519PrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } @@ -161,11 +158,8 @@ impl X25519PublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } diff --git a/src/rust/src/backend/x448.rs b/src/rust/src/backend/x448.rs index 527eb4d2dc66..aefa7d5e4f27 100644 --- a/src/rust/src/backend/x448.rs +++ b/src/rust/src/backend/x448.rs @@ -122,11 +122,8 @@ impl X448PrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } @@ -160,11 +157,8 @@ impl X448PublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, - ) -> CryptographyResult { - let new_key = Self { - pkey: slf.pkey.clone(), - }; - Ok(new_key) + ) -> pyo3::PyRef<'p, Self> { + slf } } diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py index ab88093bdb7d..226a7357a7a8 100644 --- a/tests/hazmat/primitives/test_dsa.py +++ b/tests/hazmat/primitives/test_dsa.py @@ -419,7 +419,6 @@ def test_public_key_deepcopy(self): raise ValueError("Expected a DSA public key") key2 = copy.deepcopy(key1) assert key1.public_numbers() == key2.public_numbers() - assert id(key1) != id(key2) key1 = dsa.generate_private_key(2048).public_key() assert key1.public_numbers() != key2.public_numbers() @@ -444,7 +443,6 @@ def test_private_key_deepcopy(self): raise ValueError("Expected a DSA private key") key2 = copy.deepcopy(key1) assert key1.private_numbers() == key2.private_numbers() - assert id(key1) != id(key2) key1 = dsa.generate_private_key(2048) assert key1.private_numbers() != key2.private_numbers() diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index 7e12acefd253..bb5e39c36253 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -780,7 +780,6 @@ def test_public_key_deepcopy(self, backend): raise ValueError("Expected an EllipticCurvePublicKey") key2 = copy.deepcopy(key1) - assert id(key1) != id(key2) assert ( key1.curve == key2.curve and key1.public_numbers() == key2.public_numbers() @@ -809,7 +808,6 @@ def test_private_key_deepcopy(self, backend): key2 = copy.deepcopy(key1) - assert id(key1) != id(key2) assert ( key1.curve == key2.curve and key1.private_numbers() == key2.private_numbers() diff --git a/tests/hazmat/primitives/test_ed25519.py b/tests/hazmat/primitives/test_ed25519.py index 6d19ba333823..0ebb42ac54b0 100644 --- a/tests/hazmat/primitives/test_ed25519.py +++ b/tests/hazmat/primitives/test_ed25519.py @@ -345,7 +345,6 @@ def test_public_key_deepcopy(backend): raise ValueError("Expected a Ed25519PublicKey") key2 = copy.deepcopy(key1) - assert id(key1) != id(key2) assert key1.public_bytes_raw() == key2.public_bytes_raw() @@ -380,5 +379,4 @@ def test_private_key_deepcopy(backend): raise ValueError("Expected a Ed25519PrivateKey") key2 = copy.deepcopy(key1) - assert id(key1) != id(key2) assert key1.private_bytes_raw() == key2.private_bytes_raw() diff --git a/tests/hazmat/primitives/test_ed448.py b/tests/hazmat/primitives/test_ed448.py index 64948d8ab1bf..cc415d0f2136 100644 --- a/tests/hazmat/primitives/test_ed448.py +++ b/tests/hazmat/primitives/test_ed448.py @@ -339,7 +339,6 @@ def test_public_key_deepcopy(backend): raise ValueError("Expected Ed448PublicKey") key2 = copy.deepcopy(key1) - assert id(key1) != id(key2) assert key1.public_bytes_raw() == key2.public_bytes_raw() @@ -374,5 +373,4 @@ def test_private_key_deepcopy(backend): raise ValueError("Expected Ed448PrivateKey") key2 = copy.deepcopy(key1) - assert id(key1) != id(key2) assert key1.private_bytes_raw() == key2.private_bytes_raw() diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 062e7df880ae..19917808a06d 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -2802,7 +2802,6 @@ def test_public_key_deepcopy(self, rsa_key_2048: rsa.RSAPrivateKey): key2 = copy.deepcopy(key1) assert key1.public_numbers() == key2.public_numbers() - assert id(key1) != id(key2) key1 = generate_private_key( public_exponent=65537, key_size=2048 diff --git a/tests/hazmat/primitives/test_x25519.py b/tests/hazmat/primitives/test_x25519.py index 833fb7847d21..7594c1fdfc0b 100644 --- a/tests/hazmat/primitives/test_x25519.py +++ b/tests/hazmat/primitives/test_x25519.py @@ -395,7 +395,6 @@ def test_public_key_deepcopy(backend): raise ValueError("Expected X25519PublicKey") key2 = copy.deepcopy(key1) - assert id(key1) != id(key2) assert key1.public_bytes_raw() == key2.public_bytes_raw() @@ -430,5 +429,4 @@ def test_private_key_deepcopy(backend): raise ValueError("Expected X25519PrivateKey") key2 = copy.deepcopy(key1) - assert id(key1) != id(key2) assert key1.private_bytes_raw() == key2.private_bytes_raw() diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py index 9b4c46e8729e..aead958e19db 100644 --- a/tests/hazmat/primitives/test_x448.py +++ b/tests/hazmat/primitives/test_x448.py @@ -325,7 +325,6 @@ def test_public_key_deepcopy(backend): raise ValueError("Expected X448PublicKey") key2 = copy.deepcopy(key1) - assert id(key1) != id(key2) assert key1.public_bytes_raw() == key2.public_bytes_raw() @@ -360,5 +359,4 @@ def test_private_key_deepcopy(backend): raise ValueError("Expected X448PrivateKey") key2 = copy.deepcopy(key1) - assert id(key1) != id(key2) assert key1.private_bytes_raw() == key2.private_bytes_raw() From 71abca4416b23653c3e92658a19f882f66d8be69 Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Thu, 30 Oct 2025 13:52:31 +0100 Subject: [PATCH 11/15] fix: modified tests for coverage --- tests/hazmat/primitives/test_dh.py | 4 +--- tests/hazmat/primitives/test_dsa.py | 12 ++++-------- tests/hazmat/primitives/test_ed25519.py | 9 ++------- tests/hazmat/primitives/test_ed448.py | 9 ++------- tests/hazmat/primitives/test_x25519.py | 13 ++++++------- tests/hazmat/primitives/test_x448.py | 8 ++------ 6 files changed, 17 insertions(+), 38 deletions(-) diff --git a/tests/hazmat/primitives/test_dh.py b/tests/hazmat/primitives/test_dh.py index 02b1a0491a05..71aefa6214e4 100644 --- a/tests/hazmat/primitives/test_dh.py +++ b/tests/hazmat/primitives/test_dh.py @@ -530,11 +530,9 @@ def test_private_key_deepcopy(self, backend): ) key1 = serialization.load_pem_private_key(key_bytes, None, backend) - if not isinstance(key1, dh.DHPrivateKey): - raise ValueError("Expected a DHPrivateKey") key2 = copy.deepcopy(key1) - assert key1.parameters() != key2.parameters() + assert key1 == key2 key1 = serialization.load_pem_private_key(key_bytes_2, None, backend) assert key1 != key2 diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py index 226a7357a7a8..75c942ef6319 100644 --- a/tests/hazmat/primitives/test_dsa.py +++ b/tests/hazmat/primitives/test_dsa.py @@ -415,13 +415,11 @@ def test_public_key_deepcopy(self): lambda pemfile: pemfile.read().encode(), ) key1 = serialization.load_pem_private_key(key_bytes, None).public_key() - if not isinstance(key1, dsa.DSAPublicKey): - raise ValueError("Expected a DSA public key") key2 = copy.deepcopy(key1) - assert key1.public_numbers() == key2.public_numbers() + assert key1 == key2 key1 = dsa.generate_private_key(2048).public_key() - assert key1.public_numbers() != key2.public_numbers() + assert key1 != key2 def test_private_key_copy(self): key_bytes = load_vectors_from_file( @@ -439,12 +437,10 @@ def test_private_key_deepcopy(self): lambda pemfile: pemfile.read().encode(), ) key1 = serialization.load_pem_private_key(key_bytes, None) - if not isinstance(key1, dsa.DSAPrivateKey): - raise ValueError("Expected a DSA private key") key2 = copy.deepcopy(key1) - assert key1.private_numbers() == key2.private_numbers() + assert key1 == key2 key1 = dsa.generate_private_key(2048) - assert key1.private_numbers() != key2.private_numbers() + assert key1 != key2 @pytest.mark.supported( diff --git a/tests/hazmat/primitives/test_ed25519.py b/tests/hazmat/primitives/test_ed25519.py index 0ebb42ac54b0..18ad9792373d 100644 --- a/tests/hazmat/primitives/test_ed25519.py +++ b/tests/hazmat/primitives/test_ed25519.py @@ -12,7 +12,6 @@ from cryptography.exceptions import InvalidSignature, _Reasons from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric import ed25519 from cryptography.hazmat.primitives.asymmetric.ed25519 import ( Ed25519PrivateKey, Ed25519PublicKey, @@ -341,11 +340,9 @@ def test_public_key_deepcopy(backend): mode="rb", ) key1 = serialization.load_der_private_key(key_bytes, None).public_key() - if not isinstance(key1, ed25519.Ed25519PublicKey): - raise ValueError("Expected a Ed25519PublicKey") key2 = copy.deepcopy(key1) - assert key1.public_bytes_raw() == key2.public_bytes_raw() + assert key1 == key2 @pytest.mark.supported( @@ -375,8 +372,6 @@ def test_private_key_deepcopy(backend): mode="rb", ) key1 = serialization.load_der_private_key(key_bytes, None) - if not isinstance(key1, ed25519.Ed25519PrivateKey): - raise ValueError("Expected a Ed25519PrivateKey") key2 = copy.deepcopy(key1) - assert key1.private_bytes_raw() == key2.private_bytes_raw() + assert key1 == key2 diff --git a/tests/hazmat/primitives/test_ed448.py b/tests/hazmat/primitives/test_ed448.py index cc415d0f2136..d0edaba9f8b1 100644 --- a/tests/hazmat/primitives/test_ed448.py +++ b/tests/hazmat/primitives/test_ed448.py @@ -12,7 +12,6 @@ from cryptography.exceptions import InvalidSignature, _Reasons from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric import ed448 from cryptography.hazmat.primitives.asymmetric.ed448 import ( Ed448PrivateKey, Ed448PublicKey, @@ -335,11 +334,9 @@ def test_public_key_deepcopy(backend): mode="rb", ) key1 = serialization.load_der_private_key(key_bytes, None).public_key() - if not isinstance(key1, ed448.Ed448PublicKey): - raise ValueError("Expected Ed448PublicKey") key2 = copy.deepcopy(key1) - assert key1.public_bytes_raw() == key2.public_bytes_raw() + assert key1 == key2 @pytest.mark.supported( @@ -369,8 +366,6 @@ def test_private_key_deepcopy(backend): mode="rb", ) key1 = serialization.load_der_private_key(key_bytes, None) - if not isinstance(key1, ed448.Ed448PrivateKey): - raise ValueError("Expected Ed448PrivateKey") key2 = copy.deepcopy(key1) - assert key1.private_bytes_raw() == key2.private_bytes_raw() + assert key1 == key2 diff --git a/tests/hazmat/primitives/test_x25519.py b/tests/hazmat/primitives/test_x25519.py index 7594c1fdfc0b..10e740c3643f 100644 --- a/tests/hazmat/primitives/test_x25519.py +++ b/tests/hazmat/primitives/test_x25519.py @@ -390,12 +390,13 @@ def test_public_key_deepcopy(backend): lambda derfile: derfile.read(), mode="rb", ) - key1 = serialization.load_der_private_key(key_bytes, None).public_key() - if not isinstance(key1, x25519.X25519PublicKey): - raise ValueError("Expected X25519PublicKey") + key1 = ( + x25519.X25519PublicKey, + serialization.load_der_private_key(key_bytes, None).public_key(), + ) key2 = copy.deepcopy(key1) - assert key1.public_bytes_raw() == key2.public_bytes_raw() + assert key1 == key2 @pytest.mark.supported( @@ -425,8 +426,6 @@ def test_private_key_deepcopy(backend): mode="rb", ) key1 = serialization.load_der_private_key(key_bytes, None) - if not isinstance(key1, x25519.X25519PrivateKey): - raise ValueError("Expected X25519PrivateKey") key2 = copy.deepcopy(key1) - assert key1.private_bytes_raw() == key2.private_bytes_raw() + assert key1 == key2 diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py index aead958e19db..40c3ad750124 100644 --- a/tests/hazmat/primitives/test_x448.py +++ b/tests/hazmat/primitives/test_x448.py @@ -321,11 +321,9 @@ def test_public_key_deepcopy(backend): mode="rb", ) key1 = serialization.load_der_private_key(key_bytes, None).public_key() - if not isinstance(key1, x448.X448PublicKey): - raise ValueError("Expected X448PublicKey") key2 = copy.deepcopy(key1) - assert key1.public_bytes_raw() == key2.public_bytes_raw() + assert key1 == key2 @pytest.mark.supported( @@ -355,8 +353,6 @@ def test_private_key_deepcopy(backend): mode="rb", ) key1 = serialization.load_der_private_key(key_bytes, None) - if not isinstance(key1, x448.X448PrivateKey): - raise ValueError("Expected X448PrivateKey") key2 = copy.deepcopy(key1) - assert key1.private_bytes_raw() == key2.private_bytes_raw() + assert key1 == key2 From 4bbab093087a0133fc90eeae89a3219fef9337b0 Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Thu, 30 Oct 2025 13:55:26 +0100 Subject: [PATCH 12/15] chore: format test x448 --- tests/hazmat/primitives/test_x448.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py index 40c3ad750124..b2d3a4c88ff9 100644 --- a/tests/hazmat/primitives/test_x448.py +++ b/tests/hazmat/primitives/test_x448.py @@ -12,7 +12,6 @@ from cryptography.exceptions import _Reasons from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric import x448 from cryptography.hazmat.primitives.asymmetric.x448 import ( X448PrivateKey, X448PublicKey, From f1fea09d37839728d62a9e396041556eab061599 Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Thu, 30 Oct 2025 14:08:41 +0100 Subject: [PATCH 13/15] chore: removed cast for key in test_ec --- tests/hazmat/primitives/test_ec.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index bb5e39c36253..a9f70b2d7eec 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -776,14 +776,9 @@ def test_public_key_deepcopy(self, backend): lambda pemfile: pemfile.read().encode(), ) key1 = serialization.load_pem_private_key(key_bytes, None).public_key() - if not isinstance(key1, ec.EllipticCurvePublicKey): - raise ValueError("Expected an EllipticCurvePublicKey") key2 = copy.deepcopy(key1) - assert ( - key1.curve == key2.curve - and key1.public_numbers() == key2.public_numbers() - ) + assert key1 == key2 def test_private_key_copy(self, backend): _skip_curve_unsupported(backend, ec.SECP256R1()) @@ -803,15 +798,9 @@ def test_private_key_deepcopy(self, backend): lambda pemfile: pemfile.read().encode(), ) key1 = serialization.load_pem_private_key(key_bytes, None) - if not isinstance(key1, ec.EllipticCurvePrivateKey): - raise ValueError("Expected an EllipticCurvePrivateKey") - key2 = copy.deepcopy(key1) - assert ( - key1.curve == key2.curve - and key1.private_numbers() == key2.private_numbers() - ) + assert key1 == key2 class TestECSerialization: From b830922dcdb728b0dc76cbdd85bb9f19974bc684 Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Mon, 3 Nov 2025 12:49:22 +0100 Subject: [PATCH 14/15] chore: replaced key generation in tests by pre generated keys Signed-off-by: Courtcircuits --- tests/hazmat/primitives/test_dsa.py | 20 ++++++++++++++++++-- tests/hazmat/primitives/test_rsa.py | 15 ++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py index 75c942ef6319..551e873f8776 100644 --- a/tests/hazmat/primitives/test_dsa.py +++ b/tests/hazmat/primitives/test_dsa.py @@ -418,7 +418,15 @@ def test_public_key_deepcopy(self): key2 = copy.deepcopy(key1) assert key1 == key2 - key1 = dsa.generate_private_key(2048).public_key() + key_bytes = load_vectors_from_file( + os.path.join( + "asymmetric", + "Traditional_OpenSSL_Serialization", + "dsa.1024.pem", + ), + lambda pemfile: pemfile.read().encode(), + ) + key1 = serialization.load_pem_private_key(key_bytes, None).public_key() assert key1 != key2 def test_private_key_copy(self): @@ -439,7 +447,15 @@ def test_private_key_deepcopy(self): key1 = serialization.load_pem_private_key(key_bytes, None) key2 = copy.deepcopy(key1) assert key1 == key2 - key1 = dsa.generate_private_key(2048) + key_bytes = load_vectors_from_file( + os.path.join( + "asymmetric", + "Traditional_OpenSSL_Serialization", + "dsa.1024.pem", + ), + lambda pemfile: pemfile.read().encode(), + ) + key1 = serialization.load_pem_private_key(key_bytes, None) assert key1 != key2 diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 19917808a06d..04472fb2394d 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -17,7 +17,6 @@ from cryptography.hazmat.primitives.asymmetric.rsa import ( RSAPrivateNumbers, RSAPublicNumbers, - generate_private_key, ) from ...doubles import ( @@ -2797,24 +2796,26 @@ def test_private_key_copy(self, rsa_key_2048: rsa.RSAPrivateKey): assert key1 == key2 - def test_public_key_deepcopy(self, rsa_key_2048: rsa.RSAPrivateKey): + def test_public_key_deepcopy( + self, rsa_key_2048: rsa.RSAPrivateKey, rsa_key_512: rsa.RSAPrivateKey + ): key1 = rsa_key_2048.public_key() key2 = copy.deepcopy(key1) assert key1.public_numbers() == key2.public_numbers() - key1 = generate_private_key( - public_exponent=65537, key_size=2048 - ).public_key() + key1 = rsa_key_512.public_key() assert key1.public_numbers() != key2.public_numbers() - def test_private_key_deepcopy(self, rsa_key_2048: rsa.RSAPrivateKey): + def test_private_key_deepcopy( + self, rsa_key_2048: rsa.RSAPrivateKey, rsa_key_512: rsa.RSAPrivateKey + ): key1 = rsa_key_2048 key2 = copy.deepcopy(key1) assert key1.private_numbers() == key2.private_numbers() - key1 = generate_private_key(public_exponent=65537, key_size=2048) + key1 = rsa_key_512 assert key1.private_numbers() != key2.private_numbers() From 7fa39b8fed2c0a6cbf0a56a5cc797c01f41a1b79 Mon Sep 17 00:00:00 2001 From: Courtcircuits Date: Mon, 3 Nov 2025 12:55:10 +0100 Subject: [PATCH 15/15] chore: replaced PyDict by PyAny in backend files for deepcopy Signed-off-by: Courtcircuits --- src/rust/src/backend/dh.rs | 4 ++-- src/rust/src/backend/dsa.rs | 4 ++-- src/rust/src/backend/ec.rs | 4 ++-- src/rust/src/backend/ed25519.rs | 4 ++-- src/rust/src/backend/ed448.rs | 4 ++-- src/rust/src/backend/rsa.rs | 6 +++--- src/rust/src/backend/x25519.rs | 4 ++-- src/rust/src/backend/x448.rs | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/rust/src/backend/dh.rs b/src/rust/src/backend/dh.rs index 969901ab5436..d9b60266a7e5 100644 --- a/src/rust/src/backend/dh.rs +++ b/src/rust/src/backend/dh.rs @@ -250,7 +250,7 @@ impl DHPrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } @@ -322,7 +322,7 @@ impl DHPublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::types::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } diff --git a/src/rust/src/backend/dsa.rs b/src/rust/src/backend/dsa.rs index 1e675035eff8..3b5706c39eac 100644 --- a/src/rust/src/backend/dsa.rs +++ b/src/rust/src/backend/dsa.rs @@ -159,7 +159,7 @@ impl DsaPrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } @@ -239,7 +239,7 @@ impl DsaPublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } diff --git a/src/rust/src/backend/ec.rs b/src/rust/src/backend/ec.rs index ffc593a9e5dc..64a8cabb6b82 100644 --- a/src/rust/src/backend/ec.rs +++ b/src/rust/src/backend/ec.rs @@ -376,7 +376,7 @@ impl ECPrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } @@ -468,7 +468,7 @@ impl ECPublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } diff --git a/src/rust/src/backend/ed25519.rs b/src/rust/src/backend/ed25519.rs index fd2d05317532..6b5ec52af28f 100644 --- a/src/rust/src/backend/ed25519.rs +++ b/src/rust/src/backend/ed25519.rs @@ -122,7 +122,7 @@ impl Ed25519PrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } @@ -171,7 +171,7 @@ impl Ed25519PublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } diff --git a/src/rust/src/backend/ed448.rs b/src/rust/src/backend/ed448.rs index d53a0d1bc5eb..e22486081a24 100644 --- a/src/rust/src/backend/ed448.rs +++ b/src/rust/src/backend/ed448.rs @@ -120,7 +120,7 @@ impl Ed448PrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } @@ -168,7 +168,7 @@ impl Ed448PublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } diff --git a/src/rust/src/backend/rsa.rs b/src/rust/src/backend/rsa.rs index c43083bfeb27..9c5ccc26a7cb 100644 --- a/src/rust/src/backend/rsa.rs +++ b/src/rust/src/backend/rsa.rs @@ -5,7 +5,7 @@ use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; -use pyo3::types::{PyAnyMethods, PyDict}; +use pyo3::types::PyAnyMethods; use crate::backend::{hashes, utils}; use crate::buf::CffiBuf; @@ -425,7 +425,7 @@ impl RsaPrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } @@ -545,7 +545,7 @@ impl RsaPublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } diff --git a/src/rust/src/backend/x25519.rs b/src/rust/src/backend/x25519.rs index e2f69b20e940..9ee092725aec 100644 --- a/src/rust/src/backend/x25519.rs +++ b/src/rust/src/backend/x25519.rs @@ -122,7 +122,7 @@ impl X25519PrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } @@ -157,7 +157,7 @@ impl X25519PublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } diff --git a/src/rust/src/backend/x448.rs b/src/rust/src/backend/x448.rs index aefa7d5e4f27..2b079160ff92 100644 --- a/src/rust/src/backend/x448.rs +++ b/src/rust/src/backend/x448.rs @@ -121,7 +121,7 @@ impl X448PrivateKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf } @@ -156,7 +156,7 @@ impl X448PublicKey { fn __deepcopy__<'p>( slf: pyo3::PyRef<'p, Self>, - _memo: &pyo3::Bound<'p, pyo3::types::PyDict>, + _memo: &pyo3::Bound<'p, pyo3::PyAny>, ) -> pyo3::PyRef<'p, Self> { slf }