Package: release.debian.org Severity: normal Tags: trixie X-Debbugs-Cc: [email protected] Control: affects -1 + src:python-cryptography User: [email protected] Usertags: pu
[ Reason ] Backport patch for CVE-2026-26007. Prior to 46.0.5, the public_key_from_numbers (or EllipticCurvePublicNumbers.public_key()), EllipticCurvePublicNumbers.public_key(), load_der_public_key() and load_pem_public_key() functions do not verify that the point belongs to the expected prime-order subgroup of the curve. This missing validation allows an attacker to provide a public key point P from a small-order subgroup. This can lead to security issues in various situations, such as the most commonly used signature verification (ECDSA) and shared key negotiation (ECDH). When the victim computes the shared secret as S = [victim_private_key]P via ECDH, this leaks information about victim_private_key mod (small_subgroup_order). For curves with cofactor > 1, this reveals the least significant bits of the private key. When these weak public keys are used in ECDSA , it's easy to forge signatures on the small subgroup. Only SECT curves are impacted by this. This vulnerability is fixed in 46.0.5. [ Impact ] Quoting from upstream changelog: An attacker could create a malicious public key that reveals portions of your private key when using certain uncommon elliptic curves (binary curves). . This issue only affects binary elliptic curves, which are rarely used in real-world applications. [ Tests ] I didn't come up with a test to confirm the fix, but the patch (that comes from upstream) applies rather cleany for trixie, and it comes with unit tests. [ Risks ] The patch is straightforward to understand. [ Checklist ] [*] *all* changes are documented in the d/changelog [*] I reviewed all changes and I approve them [*] attach debdiff against the package in (old)stable [*] the issue is verified as fixed in unstable [ Changes ] Backport patch for CVE-2026-26007 (missing validation in EC public key creation) (Closes: #1127926) [ Other info ] I contacted the maintainer of the package and got his approval for taking care of this upload, cf. #1127926.
diff -Nru python-cryptography-43.0.0/debian/changelog python-cryptography-43.0.0/debian/changelog --- python-cryptography-43.0.0/debian/changelog 2025-04-25 13:17:42.000000000 +0700 +++ python-cryptography-43.0.0/debian/changelog 2026-03-04 14:17:04.000000000 +0700 @@ -1,3 +1,11 @@ +python-cryptography (43.0.0-3+deb13u1) trixie; urgency=medium + + * Non-maintainer upload. + * CVE-2026-26007: Missing validation in EC public key creation. + (Closes: #1127926) + + -- Arnaud Rebillout <[email protected]> Wed, 04 Mar 2026 14:17:04 +0700 + python-cryptography (43.0.0-3) unstable; urgency=medium [ Peter Michael Green ] diff -Nru python-cryptography-43.0.0/debian/gbp.conf python-cryptography-43.0.0/debian/gbp.conf --- python-cryptography-43.0.0/debian/gbp.conf 2025-04-25 13:17:42.000000000 +0700 +++ python-cryptography-43.0.0/debian/gbp.conf 2026-03-04 13:59:32.000000000 +0700 @@ -1,2 +1,3 @@ [DEFAULT] +debian-branch = debian/trixie pristine-tar = True diff -Nru python-cryptography-43.0.0/debian/patches/0006-CVE-2026-26007.patch python-cryptography-43.0.0/debian/patches/0006-CVE-2026-26007.patch --- python-cryptography-43.0.0/debian/patches/0006-CVE-2026-26007.patch 1970-01-01 08:00:00.000000000 +0800 +++ python-cryptography-43.0.0/debian/patches/0006-CVE-2026-26007.patch 2026-03-04 14:16:35.000000000 +0700 @@ -0,0 +1,141 @@ +From: Paul Kehrer <[email protected]> +Date: Tue, 10 Feb 2026 12:32:06 -0600 +Subject: EC check key on cofactor > 1 + +An attacker could create a malicious public key that reveals portions of +your private key when using certain uncommon elliptic curves (binary +curves). This version now includes additional security checks to +prevent this attack. This issue only affects binary elliptic curves, +which are rarely used in real-world applications. Credit to **XlabAI +Team of Tencent Xuanwu Lab and Atuin Automated Vulnerability Discovery +Engine** for reporting the issue. **CVE-2026-26007** + +Debian note: this is a partial backport of upstream commit +0eebb9dbb6343d9bc1d91e5a2482ed4e054a6d8c, to only include what's +relevant for CVE-2026-26007. + +Origin: backport, https://github.com/pyca/cryptography/commit/0eebb9dbb6343d9bc1d91e5a2482ed4e054a6d8c +--- + src/rust/src/backend/ec.rs | 41 ++++++++++++++++++++++++++------------ + tests/hazmat/primitives/test_ec.py | 37 ++++++++++++++++++++++++++++++++++ + 2 files changed, 65 insertions(+), 13 deletions(-) + +diff --git a/src/rust/src/backend/ec.rs b/src/rust/src/backend/ec.rs +index 1573545..0ba36dc 100644 +--- a/src/rust/src/backend/ec.rs ++++ b/src/rust/src/backend/ec.rs +@@ -148,12 +148,10 @@ pub(crate) fn public_key_from_pkey( + ) -> CryptographyResult<ECPublicKey> { + let ec = pkey.ec_key()?; + let curve = py_curve_from_curve(py, ec.group())?; +- check_key_infinity(&ec)?; +- Ok(ECPublicKey { +- pkey: pkey.to_owned(), +- curve: curve.into(), +- }) ++ ++ ECPublicKey::new(pkey.to_owned(), curve.into()) + } ++ + #[pyo3::pyfunction] + #[pyo3(signature = (curve, backend=None))] + fn generate_private_key( +@@ -209,10 +207,7 @@ fn from_public_bytes( + let ec = openssl::ec::EcKey::from_public_key(&curve, &point)?; + let pkey = openssl::pkey::PKey::from_ec_key(ec)?; + +- Ok(ECPublicKey { +- pkey, +- curve: py_curve.into(), +- }) ++ ECPublicKey::new(pkey, py_curve.into()) + } + + #[pyo3::pymethods] +@@ -374,6 +369,29 @@ impl ECPrivateKey { + } + } + ++impl ECPublicKey { ++ fn new( ++ pkey: openssl::pkey::PKey<openssl::pkey::Public>, ++ curve: pyo3::Py<pyo3::PyAny>, ++ ) -> CryptographyResult<ECPublicKey> { ++ let ec = pkey.ec_key()?; ++ check_key_infinity(&ec)?; ++ let mut bn_ctx = openssl::bn::BigNumContext::new()?; ++ let mut cofactor = openssl::bn::BigNum::new()?; ++ ec.group().cofactor(&mut cofactor, &mut bn_ctx)?; ++ let one = openssl::bn::BigNum::from_u32(1)?; ++ if cofactor != one { ++ ec.check_key().map_err(|_| { ++ pyo3::exceptions::PyValueError::new_err( ++ "Invalid EC key (key out of range, infinity, etc.)", ++ ) ++ })?; ++ } ++ ++ Ok(ECPublicKey { pkey, curve }) ++ } ++} ++ + #[pyo3::pymethods] + impl ECPublicKey { + #[getter] +@@ -615,10 +633,7 @@ impl EllipticCurvePublicNumbers { + + let pkey = openssl::pkey::PKey::from_ec_key(public_key)?; + +- Ok(ECPublicKey { +- pkey, +- curve: self.curve.clone_ref(py), +- }) ++ ECPublicKey::new(pkey, self.curve.clone_ref(py)) + } + + fn __eq__( +diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py +index d33fd10..1689b8b 100644 +--- a/tests/hazmat/primitives/test_ec.py ++++ b/tests/hazmat/primitives/test_ec.py +@@ -1447,3 +1447,40 @@ class TestECDH: + + with pytest.raises(ValueError): + key.exchange(ec.ECDH(), public_key) ++ ++ ++def test_invalid_sect_public_keys(backend): ++ _skip_curve_unsupported(backend, ec.SECT571K1()) ++ public_numbers = ec.EllipticCurvePublicNumbers(1, 1, ec.SECT571K1()) ++ with pytest.raises(ValueError): ++ public_numbers.public_key() ++ ++ point = binascii.unhexlify( ++ b"0400000000000000000000000000000000000000000000000000000000000000000" ++ b"0000000000000000000000000000000000000000000000000000000000000000000" ++ b"0000000000010000000000000000000000000000000000000000000000000000000" ++ b"0000000000000000000000000000000000000000000000000000000000000000000" ++ b"0000000000000000000001" ++ ) ++ with pytest.raises(ValueError): ++ ec.EllipticCurvePublicKey.from_encoded_point(ec.SECT571K1(), point) ++ ++ der = binascii.unhexlify( ++ b"3081a7301006072a8648ce3d020106052b810400260381920004000000000000000" ++ b"0000000000000000000000000000000000000000000000000000000000000000000" ++ b"0000000000000000000000000000000000000000000000000000000000000100000" ++ b"0000000000000000000000000000000000000000000000000000000000000000000" ++ b"0000000000000000000000000000000000000000000000000000000000000000000" ++ b"00001" ++ ) ++ with pytest.raises(ValueError): ++ serialization.load_der_public_key(der) ++ ++ pem = textwrap.dedent("""-----BEGIN PUBLIC KEY----- ++ MIGnMBAGByqGSM49AgEGBSuBBAAmA4GSAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++ AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE= ++ -----END PUBLIC KEY-----""").encode() ++ with pytest.raises(ValueError): ++ serialization.load_pem_public_key(pem) diff -Nru python-cryptography-43.0.0/debian/patches/series python-cryptography-43.0.0/debian/patches/series --- python-cryptography-43.0.0/debian/patches/series 2025-04-25 13:17:42.000000000 +0700 +++ python-cryptography-43.0.0/debian/patches/series 2026-03-04 14:16:35.000000000 +0700 @@ -3,3 +3,4 @@ downgrade-deps.patch 0004-update-to-asn1-0.19-and-use-X509GeneralizedTime.patch 0005-Support-128-bit-OID-arcs-11820.patch +0006-CVE-2026-26007.patch diff -Nru python-cryptography-43.0.0/debian/salsa-ci.yml python-cryptography-43.0.0/debian/salsa-ci.yml --- python-cryptography-43.0.0/debian/salsa-ci.yml 1970-01-01 08:00:00.000000000 +0800 +++ python-cryptography-43.0.0/debian/salsa-ci.yml 2026-03-04 13:59:50.000000000 +0700 @@ -0,0 +1,6 @@ +--- +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml + +variables: + RELEASE: 'trixie'

