From e58db0c224abd62348a0ae96d0ee9ed07e70d976 Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Thu, 23 Apr 2026 17:50:22 -0700 Subject: [PATCH] Update to 0.6.3 Update License to BSD-2-Clause to match upstream SPDX identifier Added nesting depth limit to ASN.1 decoder (CVE-2026-30922) Fixed continuation octet limits in OID/RELATIVE-OID decoder (CVE-2026-23490) Resolves: RHEL-170862 --- .gitignore | 29 +--- 0001-Backport-commit-be353d7.patch | 122 -------------- ...ackage-pyasn1-with-pyproject.toml-90.patch | 158 ++++++++++++++++++ python-pyasn1.spec | 32 ++-- sources | 4 +- tests/tests.yml | 14 +- 6 files changed, 190 insertions(+), 169 deletions(-) delete mode 100644 0001-Backport-commit-be353d7.patch create mode 100644 0001-Revert-Package-pyasn1-with-pyproject.toml-90.patch diff --git a/.gitignore b/.gitignore index e2fbe6c..95f9450 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,3 @@ -pyasn1-0.0.9a.tar.gz -/pyasn1-0.0.12a.tar.gz -/pyasn1-0.1.2.tar.gz -/pyasn1-modules-0.0.2.tar.gz -/pyasn1-0.1.6.tar.gz -/pyasn1-modules-0.0.4.tar.gz -/pyasn1-0.1.7.tar.gz -/pyasn1-modules-0.0.5.tar.gz -/pyasn1-0.1.8.tar.gz -/pyasn1-modules-0.0.6.tar.gz -/pyasn1-modules-0.0.8.tar.gz -/pyasn1-0.1.9.tar.gz -/v0.2.1.tar.gz -/v0.2.3.tar.gz -/v0.3.2.tar.gz -/v0.0.11.tar.gz -/v0.3.4.tar.gz -/v0.1.2.tar.gz -/v0.1.5.tar.gz -/v0.3.7.tar.gz -/v0.4.4.tar.gz -/v0.2.2.tar.gz -/v0.2.6.tar.gz -/v0.4.6.tar.gz -/v0.4.8.tar.gz -/v0.2.8.tar.gz +/pyasn1-*.tar.gz +/pyasn1-modules-*.tar.gz +/v*.tar.gz diff --git a/0001-Backport-commit-be353d7.patch b/0001-Backport-commit-be353d7.patch deleted file mode 100644 index f15dc8e..0000000 --- a/0001-Backport-commit-be353d7.patch +++ /dev/null @@ -1,122 +0,0 @@ -From eb5017870dd6c96c1994a1b94150237e68edb179 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Thu, 12 Feb 2026 23:18:56 +0100 -Subject: [PATCH] Backport commit be353d7 - -Add limit of 20 continuation octets per OID arc to prevent a potential memory -exhaustion from excessive continuation bytes input. ---- - pyasn1/codec/ber/decoder.py | 11 ++++++ - tests/codec/ber/test_decoder.py | 66 +++++++++++++++++++++++++++++++++ - 2 files changed, 77 insertions(+) - -diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py -index 5ff485fbeb0cc7d761dd398134cf39a6258a109e..adfd7501a52421748b3143935a0ec95bdd1d42e6 100644 ---- a/pyasn1/codec/ber/decoder.py -+++ b/pyasn1/codec/ber/decoder.py -@@ -22,6 +22,10 @@ LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_DECODER) - - noValue = base.noValue - -+# Maximum number of continuation octets (high-bit set) allowed per OID arc. -+# 20 octets allows up to 140-bit integers, supporting UUID-based OIDs -+MAX_OID_ARC_CONTINUATION_OCTETS = 20 -+ - - class AbstractDecoder(object): - protoComponent = None -@@ -342,7 +346,14 @@ class ObjectIdentifierDecoder(AbstractSimpleDecoder): - # Construct subid from a number of octets - nextSubId = subId - subId = 0 -+ continuationOctetCount = 0 - while nextSubId >= 128: -+ continuationOctetCount += 1 -+ if continuationOctetCount > MAX_OID_ARC_CONTINUATION_OCTETS: -+ raise error.PyAsn1Error( -+ 'OID arc exceeds maximum continuation octets limit (%d) ' -+ 'at position %d' % (MAX_OID_ARC_CONTINUATION_OCTETS, index) -+ ) - subId = (subId << 7) + (nextSubId & 0x7F) - if index >= substrateLen: - raise error.SubstrateUnderrunError( -diff --git a/tests/codec/ber/test_decoder.py b/tests/codec/ber/test_decoder.py -index e3b74dfd203923157cb6a26215e9d03c971a5b41..f9bf381b1da339611d974673420248e1a1014421 100644 ---- a/tests/codec/ber/test_decoder.py -+++ b/tests/codec/ber/test_decoder.py -@@ -407,6 +407,72 @@ class ObjectIdentifierDecoderTestCase(BaseTestCase): - ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, 0xB8, 0xCB, 0xE2, 0xB6, 0x47)) - ) == ((2, 999, 18446744073709551535184467440737095), null) - -+ def testExcessiveContinuationOctets(self): -+ """Test that OID arcs with excessive continuation octets are rejected.""" -+ # Create a payload with 25 continuation octets (exceeds 20 limit) -+ # 0x81 bytes are continuation octets, 0x01 terminates -+ malicious_payload = bytes([0x06, 26]) + bytes([0x81] * 25) + bytes([0x01]) -+ try: -+ decoder.decode(malicious_payload) -+ except PyAsn1Error: -+ pass -+ else: -+ assert 0, 'Excessive continuation octets tolerated' -+ -+ def testMaxAllowedContinuationOctets(self): -+ """Test that OID arcs at the maximum continuation octets limit work.""" -+ # Create a payload with exactly 20 continuation octets (at limit) -+ # This should succeed -+ payload = bytes([0x06, 21]) + bytes([0x81] * 20) + bytes([0x01]) -+ try: -+ decoder.decode(payload) -+ except PyAsn1Error: -+ assert 0, 'Valid OID with 20 continuation octets rejected' -+ -+ def testOneOverContinuationLimit(self): -+ """Test boundary: 21 continuation octets (one over limit) is rejected.""" -+ payload = bytes([0x06, 22]) + bytes([0x81] * 21) + bytes([0x01]) -+ try: -+ decoder.decode(payload) -+ except PyAsn1Error: -+ pass -+ else: -+ assert 0, '21 continuation octets tolerated (should be rejected)' -+ -+ def testExcessiveContinuationInSecondArc(self): -+ """Test that limit applies to subsequent arcs, not just the first.""" -+ # First arc: valid simple byte (0x55 = 85, decodes to arc 2.5) -+ # Second arc: excessive continuation octets -+ payload = bytes([0x06, 27]) + bytes([0x55]) + bytes([0x81] * 25) + bytes([0x01]) -+ try: -+ decoder.decode(payload) -+ except PyAsn1Error: -+ pass -+ else: -+ assert 0, 'Excessive continuation in second arc tolerated' -+ -+ def testMultipleArcsAtLimit(self): -+ """Test multiple arcs each at the continuation limit work correctly.""" -+ # Two arcs, each with 20 continuation octets (both at limit) -+ arc1 = bytes([0x81] * 20) + bytes([0x01]) # 21 bytes -+ arc2 = bytes([0x81] * 20) + bytes([0x01]) # 21 bytes -+ payload = bytes([0x06, 42]) + arc1 + arc2 -+ try: -+ decoder.decode(payload) -+ except PyAsn1Error: -+ assert 0, 'Multiple valid arcs at limit rejected' -+ -+ def testExcessiveContinuationWithMaxBytes(self): -+ """Test with 0xFF continuation bytes (maximum value, not just 0x81).""" -+ # 0xFF bytes are also continuation octets (high bit set) -+ malicious_payload = bytes([0x06, 26]) + bytes([0xFF] * 25) + bytes([0x01]) -+ try: -+ decoder.decode(malicious_payload) -+ except PyAsn1Error: -+ pass -+ else: -+ assert 0, 'Excessive 0xFF continuation octets tolerated' -+ - - class RealDecoderTestCase(BaseTestCase): - def testChar(self): --- -2.52.0 - diff --git a/0001-Revert-Package-pyasn1-with-pyproject.toml-90.patch b/0001-Revert-Package-pyasn1-with-pyproject.toml-90.patch new file mode 100644 index 0000000..e710b65 --- /dev/null +++ b/0001-Revert-Package-pyasn1-with-pyproject.toml-90.patch @@ -0,0 +1,158 @@ +From 66bcd08ebf586742ca3dd857ec29f490eac2b242 Mon Sep 17 00:00:00 2001 +From: Simon Pichugin +Date: Mon, 27 Apr 2026 20:34:28 -0700 +Subject: [PATCH] Revert "Package pyasn1 with pyproject.toml (#90)" + +This reverts commit d2015ad04336944511ce7643914e8daf432ef2f9. + +It's a modified patch because the release tarball already contains a setup.cfg +with [egg_info] content; this patch prepends the full [metadata] and [options] +sections so that EL9's older setuptools can read the package name/version correctly +and produce a properly-named wheel instead of UNKNOWN-0.0.0. +--- + +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -4,68 +4,3 @@ + ] + build-backend = "setuptools.build_meta" + +-[project] +-name = "pyasn1" +-license.text = "BSD-2-Clause" # Replace with 'license' once Python 3.8 is dropped +-description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +-readme = "README.md" +-authors = [ +- {name = "Ilya Etingof", email = "etingof@gmail.com"} +-] +-maintainers = [ +- {name = "pyasn1 maintenance organization"}, +- {name = "Christian Heimes", email = "christian@python.org"} +-] +-requires-python = ">=3.8" +-classifiers = [ +- "Development Status :: 5 - Production/Stable", +- "Environment :: Console", +- "Intended Audience :: Developers", +- "Intended Audience :: Education", +- "Intended Audience :: Information Technology", +- "Intended Audience :: System Administrators", +- "Intended Audience :: Telecommunications Industry", +- "Natural Language :: English", +- "Operating System :: OS Independent", +- "Programming Language :: Python :: 3", +- "Programming Language :: Python :: 3.8", +- "Programming Language :: Python :: 3.9", +- "Programming Language :: Python :: 3.10", +- "Programming Language :: Python :: 3.11", +- "Programming Language :: Python :: 3.12", +- "Programming Language :: Python :: 3.13", +- "Programming Language :: Python :: 3.14", +- "Programming Language :: Python :: Implementation :: CPython", +- "Programming Language :: Python :: Implementation :: PyPy", +- "Topic :: Communications", +- "Topic :: Software Development :: Libraries :: Python Modules" +-] +-dynamic = ["version"] +- +-[project.urls] +-"Homepage" = "https://github.com/pyasn1/pyasn1" +-"Documentation" = "https://pyasn1.readthedocs.io" +-"Source" = "https://github.com/pyasn1/pyasn1" +-"Issues" = "https://github.com/pyasn1/pyasn1/issues" +-"Changelog" = "https://pyasn1.readthedocs.io/en/latest/changelog.html" +- +-[tool.setuptools] +-zip-safe = true +-platforms = ["any"] +-# Additional files to include in the distribution (replaces MANIFEST.in functionality) +-include-package-data = true +-license-files = ["LICENSE.rst"] # Replace with 'project.license-files' once Python 3.8 is dropped +- +-[tool.setuptools.dynamic] +-version = {attr = "pyasn1.__version__"} +- +-[tool.setuptools.packages.find] +-include = [ +- "pyasn1*" +-] +- +-[tool.setuptools.package-data] +-"*" = [ +- "*.rst", +- "*.md" +-] +--- a/setup.cfg ++++ b/setup.cfg +@@ -0,0 +1,56 @@ ++[metadata] ++name = pyasn1 ++version = attr: pyasn1.__version__ ++description = Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208) ++long_description = file: README.md ++long_description_content_type = text/markdown ++license = BSD-2-Clause ++license_files = LICENSE.rst ++url = https://github.com/pyasn1/pyasn1 ++author = Ilya Etingof ++author_email = etingof@gmail.com ++maintainer = pyasn1 maintenance organization ++maintainer_email = Christian Heimes ++project_urls = ++ Documentation=https://pyasn1.readthedocs.io ++ Source=https://github.com/pyasn1/pyasn1 ++ Issues=https://github.com/pyasn1/pyasn1/issues ++ Changelog=https://pyasn1.readthedocs.io/en/latest/changelog.html ++platforms = any ++classifiers = ++ Development Status :: 5 - Production/Stable ++ Environment :: Console ++ Intended Audience :: Developers ++ Intended Audience :: Education ++ Intended Audience :: Information Technology ++ Intended Audience :: System Administrators ++ Intended Audience :: Telecommunications Industry ++ License :: OSI Approved :: BSD License ++ Natural Language :: English ++ Operating System :: OS Independent ++ Programming Language :: Python :: 3 ++ Programming Language :: Python :: 3.8 ++ Programming Language :: Python :: 3.9 ++ Programming Language :: Python :: 3.10 ++ Programming Language :: Python :: 3.11 ++ Programming Language :: Python :: 3.12 ++ Programming Language :: Python :: 3.13 ++ Programming Language :: Python :: Implementation :: CPython ++ Programming Language :: Python :: Implementation :: PyPy ++ Topic :: Communications ++ Topic :: Software Development :: Libraries :: Python Modules ++ ++[options] ++python_requires = >=3.8 ++zip_safe = True ++setup_requires = setuptools ++packages = ++ pyasn1 ++ pyasn1.type ++ pyasn1.compat ++ pyasn1.codec ++ pyasn1.codec.ber ++ pyasn1.codec.cer ++ pyasn1.codec.der ++ pyasn1.codec.native ++ +--- a/setup.py ++++ b/setup.py +@@ -0,0 +1,10 @@ ++#!/usr/bin/env python ++# ++# This file is part of pyasn1 software. ++# ++# Copyright (c) 2005-2020, Ilya Etingof ++# License: https://pyasn1.readthedocs.io/en/latest/license.html ++# ++from setuptools import setup ++ ++setup() +-- +2.52.0 diff --git a/python-pyasn1.spec b/python-pyasn1.spec index 8892a67..6c2a5e7 100644 --- a/python-pyasn1.spec +++ b/python-pyasn1.spec @@ -1,18 +1,18 @@ %global module pyasn1 -%global modules_version 0.2.8 +%global modules_version 0.4.2 Name: python-pyasn1 -Version: 0.4.8 -Release: 7%{?dist} +Version: 0.6.3 +Release: 1%{?dist} Summary: ASN.1 tools for Python -License: BSD -Source0: https://github.com/etingof/pyasn1/archive/v%{version}.tar.gz -Source1: https://github.com/etingof/pyasn1-modules/archive/v%{modules_version}.tar.gz -URL: http://pyasn1.sourceforge.net/ +License: BSD-2-Clause +Source0: https://github.com/pyasn1/pyasn1/archive/v%{version}.tar.gz +Source1: https://github.com/pyasn1/pyasn1-modules/archive/v%{modules_version}.tar.gz +URL: https://github.com/pyasn1/pyasn1 BuildArch: noarch - -Patch1: 0001-Backport-commit-be353d7.patch - +# Revert upstream migration to pyproject.toml [project] metadata (PR#90); +# EL9 ships setuptools too old to handle it, producing an UNKNOWN-0.0.0 wheel. +Patch0: 0001-Revert-Package-pyasn1-with-pyproject.toml-90.patch %description This is an implementation of ASN.1 types and codecs in the Python programming @@ -58,7 +58,7 @@ pushd ../pyasn1-modules-%{modules_version} popd pushd docs -PYTHONPATH=%{buildroot}%{python3_sitelib} make SPHINXBUILD=sphinx-build-3 html +PYTHONPATH=.. make SPHINXBUILD=sphinx-build-3 html popd @@ -71,7 +71,8 @@ popd %check -PYTHONPATH=%{buildroot}%{python3_sitelib} %{__python3} setup.py test +cd %{_builddir}/%{module}-%{version} +PYTHONPATH=%{buildroot}%{python3_sitelib} %{__python3} -m tests %files -n python3-pyasn1 @@ -89,6 +90,13 @@ PYTHONPATH=%{buildroot}%{python3_sitelib} %{__python3} setup.py test %doc docs/build/html/* %changelog +* Fri Apr 24 2026 Simon Pichugin - 0.6.3-1 +- Update to 0.6.3 +- Update License to BSD-2-Clause to match upstream SPDX identifier +- Added nesting depth limit to ASN.1 decoder (CVE-2026-30922) +- Fixed continuation octet limits in OID/RELATIVE-OID decoder (CVE-2026-23490) +- Resolves: RHEL-170862 + * Fri Feb 13 2026 Florence Blanc-Renaud - 0.4.8-7 - Resolves: RHEL-148154 diff --git a/sources b/sources index 80953d0..d571d22 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (v0.4.8.tar.gz) = 3bd2f51c8f9f1f3ba48464622370bb7e7c9eda63d9cd2ef2fd6b6bbcd916a439c053febab2535f5fb6120d0ce87d7aa3c9c8756809db73502b5cf7c7a2048a6d -SHA512 (v0.2.8.tar.gz) = 7701f239c13e65d5a0979b0d3ac4a408e9493dfdbb2277d864a6c204ea8dc569cddbbaba2e9a601c86336a02af660a6dfeb734f70c6f73631443219b2e770047 +SHA512 (v0.6.3.tar.gz) = c58962b3f11f486da3e73c09dbe2aff7500879b29c4a7be4295878e4edbcaaa2680d608720ad5af86a2457de7da50471ab7a9e925f717db5c467553fc552e6d6 +SHA512 (v0.4.2.tar.gz) = 7c4feab23a8c5ab72549387586894d1d53a3ad8b9d12cc5774b1d1f5192873f87da2e3525059fdda5b5884a52908ce79df274e3b75ee1f42af32e83ceb3f9167 diff --git a/tests/tests.yml b/tests/tests.yml index b4db6f4..6d8632c 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -13,15 +13,15 @@ required_packages: - python3-pyasn1 - python3-pyasn1-modules - - python3-pytest tests: - unittests-pyasn1: - dir: "source/pyasn1-0.4.8" + # Must match the unpacked tarball directory name from this SRPM (see sources / spec Version). + dir: "source/pyasn1-0.6.3" run: >- - rm -rf pyasn1* && - pytest-3 tests/ + rm -rf pyasn1 && + python3 -m tests - unittests-pyasn1-modules: - dir: "source/pyasn1-modules-0.2.8" + dir: "source/pyasn1-modules-0.4.2" run: >- - rm -rf pyasn1_modules* && - pytest-3 tests/ + rm -rf pyasn1_modules && + python3 -m tests