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'

Reply via email to