From 71cc291a42a5189f8605a66f0de3c7c667534e23 Mon Sep 17 00:00:00 2001 From: Mathias Ertl Date: Fri, 27 Dec 2024 16:49:52 +0100 Subject: [PATCH] remove code paths for cg<44 --- ca/django_ca/constants.py | 9 +- ca/django_ca/extensions/text.py | 8 +- ca/django_ca/management/base.py | 2 +- ca/django_ca/pydantic/extension_attributes.py | 30 +- ca/django_ca/pydantic/extensions.py | 4 +- ca/django_ca/templatetags/django_ca.py | 4 +- .../tests/extensions/test_admin_html.py | 22 +- .../tests/pydantic/test_extensions.py | 331 +++++++++--------- ca/django_ca/tests/test_constants.py | 11 - ca/django_ca/tests/test_typehints.py | 6 - ca/django_ca/typehints.py | 98 ++---- devscripts/commands/recreate_fixtures.py | 122 ++++--- 12 files changed, 276 insertions(+), 371 deletions(-) diff --git a/ca/django_ca/constants.py b/ca/django_ca/constants.py index 78d1c202f..7730ca467 100644 --- a/ca/django_ca/constants.py +++ b/ca/django_ca/constants.py @@ -62,10 +62,13 @@ class ExtensionOID(_ExtensionOID): - """Extend the ExtensionOID object with any OIDs not known to cryptography.""" + """Extend the ExtensionOID object with any OIDs not known to cryptography. - if CRYPTOGRAPHY_VERSION < (44, 0): # pragma: cryptography<44 branch - ADMISSIONS = x509.ObjectIdentifier("1.3.36.8.3.3") + This subclass is usually empty but can be used in cases where some ExtensionOIDs are not supported in all + currently supported versions of cryptography. + """ + + pass ACCESS_METHOD_TYPES: MappingProxyType[AccessMethods, x509.ObjectIdentifier] = MappingProxyType( diff --git a/ca/django_ca/extensions/text.py b/ca/django_ca/extensions/text.py index 14fb4fad8..d4359b886 100644 --- a/ca/django_ca/extensions/text.py +++ b/ca/django_ca/extensions/text.py @@ -24,7 +24,7 @@ from django_ca.utils import bytes_to_hex, format_general_name -def _naming_authority_as_text(value: "x509.NamingAuthority") -> str: # pragma: only cryptography>=44 +def _naming_authority_as_text(value: "x509.NamingAuthority") -> str: lines = ["* Naming Authority:"] if value.id is None: lines.append("* id: None") @@ -34,7 +34,7 @@ def _naming_authority_as_text(value: "x509.NamingAuthority") -> str: # pragma: return "\n".join(lines) -def _profession_info_as_text(value: "x509.ProfessionInfo") -> str: # pragma: only cryptography>=44 +def _profession_info_as_text(value: "x509.ProfessionInfo") -> str: lines = [] if value.naming_authority is not None: @@ -56,7 +56,7 @@ def _profession_info_as_text(value: "x509.ProfessionInfo") -> str: # pragma: on return "\n".join(lines) -def _admissions_as_text(value: "x509.Admissions") -> str: # pragma: only cryptography>=44 +def _admissions_as_text(value: "x509.Admissions") -> str: lines = [] if value.authority: lines.append(f"* Authority: {format_general_name(value.authority)}") @@ -239,7 +239,7 @@ def extension_as_text(value: x509.ExtensionType) -> str: # noqa: PLR0911 return _signed_certificate_timestamps_as_text(value) if isinstance(value, (x509.AuthorityInformationAccess, x509.SubjectInformationAccess)): return _authority_information_access_as_text(value) - if hasattr(x509, "Admissions") and isinstance(value, x509.Admissions): # pragma: only cryptography>=44 + if isinstance(value, x509.Admissions): return _admissions_as_text(value) if isinstance(value, x509.AuthorityKeyIdentifier): return _authority_key_identifier_as_text(value) diff --git a/ca/django_ca/management/base.py b/ca/django_ca/management/base.py index 4959e86b1..27d29234a 100644 --- a/ca/django_ca/management/base.py +++ b/ca/django_ca/management/base.py @@ -439,7 +439,7 @@ def parse_x509_name(self, value: str, name_format: SubjectFormats) -> x509.Name: if name_format == "rfc4514": try: return parse_name_rfc4514(value) - except ValueError as ex: # pragma: only cryptography>=43.0 + except ValueError as ex: raise CommandError(ex) from ex # COVERAGE NOTE: Already covered by argparse raise ValueError(f"{name_format}: Unknown subject format.") # pragma: no cover diff --git a/ca/django_ca/pydantic/extension_attributes.py b/ca/django_ca/pydantic/extension_attributes.py index 298ecde3c..803fdba2c 100644 --- a/ca/django_ca/pydantic/extension_attributes.py +++ b/ca/django_ca/pydantic/extension_attributes.py @@ -15,7 +15,7 @@ import base64 from datetime import datetime -from typing import TYPE_CHECKING, Annotated, Any, Literal, NoReturn, Optional, Union +from typing import Annotated, Any, Literal, NoReturn, Optional, Union from annotated_types import MaxLen, MinLen from pydantic import AfterValidator, Base64Bytes, BeforeValidator, ConfigDict, Field, model_validator @@ -32,25 +32,14 @@ from django_ca.pydantic.type_aliases import Base64EncodedBytes, NonEmptyOrderedSet, OIDType from django_ca.typehints import DistributionPointReasons, LogEntryTypes -if TYPE_CHECKING: # pragma: only cryptography<44 - # NOTE: we can use bases directly once instances are supported in every versoin - NamingAuthorityBase = CryptographyModel[x509.NamingAuthority] - ProfessionInfoBase = CryptographyModel[x509.ProfessionInfo] - AdmissionBase = CryptographyModel[x509.Admission] - AdmissionsValueModelBase = CryptographyModel[x509.Admissions] -else: - NamingAuthorityBase = ProfessionInfoBase = AdmissionBase = AdmissionsValueModelBase = CryptographyModel - _NOTICE_REFERENCE_DESCRIPTION = ( "A NoticeReferenceModel consists of an optional *organization* and an optional list of *notice_numbers*." ) -class NamingAuthorityModel(NamingAuthorityBase): # pragma: only cryptography>=44.0 +class NamingAuthorityModel(CryptographyModel[x509.NamingAuthority]): """Pydantic model wrapping :py:class:`~cg:cryptography.x509.NamingAuthority`. - .. NOTE:: This class will not be able to produce a cryptography instance when using ``cryptography<44``. - .. versionadded:: 2.1.0 """ @@ -69,11 +58,9 @@ def cryptography(self) -> "x509.NamingAuthority": return x509.NamingAuthority(id=oid, url=self.url, text=self.text) -class ProfessionInfoModel(ProfessionInfoBase): # pragma: only cryptography>=44.0 +class ProfessionInfoModel(CryptographyModel[x509.ProfessionInfo]): """Pydantic model wrapping :py:class:`~cg:cryptography.x509.ProfessionInfo`. - .. NOTE:: This class will not be able to produce a cryptography instance when using ``cryptography<44``. - .. versionadded:: 2.1.0 """ @@ -109,11 +96,9 @@ def check_consistency(self) -> "ProfessionInfoModel": return self -class AdmissionModel(AdmissionBase): # pragma: only cryptography>=44.0 +class AdmissionModel(CryptographyModel[x509.Admission]): """Pydantic model wrapping :py:class:`~cg:cryptography.x509.Admission`. - .. NOTE:: This class will not be able to produce a cryptography instance when using ``cryptography<44``. - .. versionadded:: 2.1.0 """ @@ -138,11 +123,9 @@ def cryptography(self) -> "x509.Admission": ) -class AdmissionsValueModel(AdmissionsValueModelBase): # pragma: only cryptography>=44.0 +class AdmissionsValueModel(CryptographyModel[x509.Admissions]): """Pydantic model wrapping :py:class:`~cg:cryptography.x509.Admissions`. - .. NOTE:: This class will not be able to produce a cryptography instance when using ``cryptography<44``. - .. versionadded:: 2.1.0 """ @@ -164,8 +147,7 @@ def cryptography(self) -> "x509.Admissions": @classmethod def parse_cryptography(cls, data: Any) -> Any: """Parse cryptography instance.""" - # pragma: only cryptography<44 # remove hasattr() call when cg<44 is dropped - if hasattr(x509, "Admissions") and isinstance(data, x509.Admissions): + if isinstance(data, x509.Admissions): return {"authority": data.authority, "admissions": data._admissions} # pylint: disable=protected-access return data diff --git a/ca/django_ca/pydantic/extensions.py b/ca/django_ca/pydantic/extensions.py index 8300b0207..89def28b4 100644 --- a/ca/django_ca/pydantic/extensions.py +++ b/ca/django_ca/pydantic/extensions.py @@ -323,11 +323,9 @@ def extension_type(self) -> NoReturn: # pragma: no cover ######################## -class AdmissionsModel(ExtensionModel["x509.Admissions"]): # pragma: only cryptography>=44.0 +class AdmissionsModel(ExtensionModel[x509.Admissions]): """Pydantic model for a :py:class:`~cg:cryptography.x509.Admissions` extension. - .. NOTE:: This class will not be able to produce a cryptography instance when using ``cryptography<44``. - .. versionadded:: 2.1.0 The `value` is a :py:class:`~django_ca.pydantic.extension_attributes.AdmissionsValueModel`: diff --git a/ca/django_ca/templatetags/django_ca.py b/ca/django_ca/templatetags/django_ca.py index a30c4c104..66735a33e 100644 --- a/ca/django_ca/templatetags/django_ca.py +++ b/ca/django_ca/templatetags/django_ca.py @@ -43,7 +43,7 @@ @register.filter -def admissions(value: "x509.Admissions") -> list["x509.Admission"]: # pragma: only cryptography>=44 +def admissions(value: "x509.Admissions") -> list["x509.Admission"]: """Return list of admissions (templates cannot contain underscores in variables).""" return value._admissions # pylint: disable=protected-access; only way to get admissions @@ -97,7 +97,7 @@ def enum(mod: Any, cls_name_and_member: str) -> Any: @register.filter -def format_general_name(value: x509.GeneralName) -> str: # pragma: only cryptography>=44 +def format_general_name(value: x509.GeneralName) -> str: """A template tag to format general name.""" return _format_general_name(value) diff --git a/ca/django_ca/tests/extensions/test_admin_html.py b/ca/django_ca/tests/extensions/test_admin_html.py index a63de355f..7019063b2 100644 --- a/ca/django_ca/tests/extensions/test_admin_html.py +++ b/ca/django_ca/tests/extensions/test_admin_html.py @@ -30,8 +30,7 @@ from django_ca.tests.base.mixins import TestCaseMixin from django_ca.utils import bytes_to_hex -if hasattr(x509, "Admissions"): # pragma: only cryptography<44.0 - ALL_EXTENSIONS_ADMISSIONS = """ +ALL_EXTENSIONS_ADMISSIONS = """ """ - ALT_EXTENSIONS_ADMISSIONS = """ +ALT_EXTENSIONS_ADMISSIONS = """ """ -else: - ALL_EXTENSIONS_ADMISSIONS = ( - "30:82:01:9B:86:30:68:74:74:70:73:3A:2F:2F:64:65:66:61:75:6C:74:2D:61:75:74:68:6F:72:69:74:79:2E:61:" - "64:6D:69:73:73:69:6F:6E:73:2E:65:78:61:6D:70:6C:65:2E:63:6F:6D:30:82:01:65:30:82:01:61:A0:2A:86:28:" - "68:74:74:70:73:3A:2F:2F:61:75:74:68:6F:72:69:74:79:2E:61:64:6D:69:73:73:69:6F:6E:73:2E:65:78:61:6D:" - "70:6C:65:2E:63:6F:6D:A1:5B:30:59:06:02:2A:03:16:2A:68:74:74:70:73:3A:2F:2F:6E:61:6D:69:6E:67:2D:61:" - "75:74:68:2E:61:64:6D:69:73:73:69:6F:6E:73:2E:65:78:61:6D:70:6C:65:2E:63:6F:6D:0C:27:6E:61:6D:69:6E:" - "67:2D:61:75:74:68:2E:61:64:6D:69:73:73:69:6F:6E:73:2E:65:78:61:6D:70:6C:65:2E:63:6F:6D:20:74:65:78:" - "74:30:81:D5:30:81:B7:A0:77:30:75:16:3A:68:74:74:70:73:3A:2F:2F:6E:61:6D:69:6E:67:2D:61:75:74:68:2E:" - "70:72:6F:66:65:73:73:69:6F:6E:2D:69:6E:66:6F:2E:61:64:6D:69:73:73:69:6F:6E:73:2E:65:78:61:6D:70:6C:" - "65:2E:63:6F:6D:0C:37:6E:61:6D:69:6E:67:2D:61:75:74:68:2E:70:72:6F:66:65:73:73:69:6F:6E:2D:69:6E:66:" - "6F:2E:61:64:6D:69:73:73:69:6F:6E:73:2E:65:78:61:6D:70:6C:65:2E:63:6F:6D:20:74:65:78:74:30:0B:0C:09:" - "70:72:6F:66:5F:69:74:65:6D:30:05:06:03:2A:03:05:13:13:72:65:67:69:73:74:72:61:74:69:6F:6E:2D:6E:75:" - "6D:62:65:72:04:13:61:64:64:2D:70:72:6F:66:65:73:73:69:6F:6E:2D:69:6E:66:6F:30:19:A0:02:30:00:30:13:" - "0C:11:70:72:6F:66:5F:69:74:65:6D:5F:6D:69:6E:69:6D:61:6C" - ) - ALT_EXTENSIONS_ADMISSIONS = "30:15:30:13:30:11:30:0F:30:0D:30:0B:0C:09:70:72:6F:66:5F:69:74:65:6D" class CertificateExtensionTestCase(TestCaseMixin, TestCase): diff --git a/ca/django_ca/tests/pydantic/test_extensions.py b/ca/django_ca/tests/pydantic/test_extensions.py index b59cfe886..22052cb3a 100644 --- a/ca/django_ca/tests/pydantic/test_extensions.py +++ b/ca/django_ca/tests/pydantic/test_extensions.py @@ -77,7 +77,7 @@ TLSFeatureModel, UnrecognizedExtensionModel, ) -from django_ca.tests.base.constants import CERT_DATA, CRYPTOGRAPHY_VERSION +from django_ca.tests.base.constants import CERT_DATA from django_ca.tests.base.doctest import doctest_module from django_ca.tests.base.utils import dns, key_usage, uri from django_ca.tests.pydantic.base import ( @@ -186,188 +186,190 @@ def test_critical_validation() -> None: assert model.critical is False -if CRYPTOGRAPHY_VERSION >= (44, 0): # pragma: only cryptography>=44.0 - - @pytest.mark.parametrize( - ("parameters", "expected"), +@pytest.mark.parametrize( + ("parameters", "expected"), + ( + ({}, x509.NamingAuthority(id=None, url=None, text=None)), ( - ({}, x509.NamingAuthority(id=None, url=None, text=None)), - ( - {"id": "1.2.3", "url": "https://example.com", "text": "example"}, - x509.NamingAuthority( - id=x509.ObjectIdentifier("1.2.3"), url="https://example.com", text="example" - ), + {"id": "1.2.3", "url": "https://example.com", "text": "example"}, + x509.NamingAuthority( + id=x509.ObjectIdentifier("1.2.3"), url="https://example.com", text="example" ), ), - ) - def test_naming_authority_model(parameters: dict[str, Any], expected: x509.NamingAuthority) -> None: - """Test the NamingAuthorityModel.""" - assert_cryptography_model(NamingAuthorityModel, parameters, expected) + ), +) +def test_naming_authority_model(parameters: dict[str, Any], expected: x509.NamingAuthority) -> None: + """Test the NamingAuthorityModel.""" + assert_cryptography_model(NamingAuthorityModel, parameters, expected) - @pytest.mark.parametrize( - ("parameters", "expected"), + +@pytest.mark.parametrize( + ("parameters", "expected"), + ( ( - ( - {"profession_items": ["example_profession_items"]}, - x509.ProfessionInfo( - naming_authority=None, - profession_items=["example_profession_items"], - profession_oids=None, - registration_number=None, - add_profession_info=None, - ), + {"profession_items": ["example_profession_items"]}, + x509.ProfessionInfo( + naming_authority=None, + profession_items=["example_profession_items"], + profession_oids=None, + registration_number=None, + add_profession_info=None, ), - ( - { - "naming_authority": {}, - "profession_items": ["example_profession_items"], - "profession_oids": ["1.2.3"], - "registration_number": "example_registration_number", - "add_profession_info": b"example_add_profession_info", - }, - x509.ProfessionInfo( - naming_authority=x509.NamingAuthority(id=None, url=None, text=None), - profession_items=["example_profession_items"], - profession_oids=[x509.ObjectIdentifier("1.2.3")], - registration_number="example_registration_number", - add_profession_info=b"example_add_profession_info", - ), + ), + ( + { + "naming_authority": {}, + "profession_items": ["example_profession_items"], + "profession_oids": ["1.2.3"], + "registration_number": "example_registration_number", + "add_profession_info": b"example_add_profession_info", + }, + x509.ProfessionInfo( + naming_authority=x509.NamingAuthority(id=None, url=None, text=None), + profession_items=["example_profession_items"], + profession_oids=[x509.ObjectIdentifier("1.2.3")], + registration_number="example_registration_number", + add_profession_info=b"example_add_profession_info", ), ), - ) - def test_profession_info_model(parameters: dict[str, Any], expected: x509.ProfessionInfo) -> None: - """Test the ProfessionInfoModel.""" - assert_cryptography_model(ProfessionInfoModel, parameters, expected) + ), +) +def test_profession_info_model(parameters: dict[str, Any], expected: x509.ProfessionInfo) -> None: + """Test the ProfessionInfoModel.""" + assert_cryptography_model(ProfessionInfoModel, parameters, expected) + - @pytest.mark.parametrize( - ("parameters", "expected_errors"), +@pytest.mark.parametrize( + ("parameters", "expected_errors"), + ( ( - ( - { - "naming_authority": {}, - "profession_items": ["example_profession_items"], - "profession_oids": ["1.2.3", "1.2.4"], - "registration_number": "example_registration_number", - "add_profession_info": b"example_add_profession_info", - }, - [ - ( - "value_error", - (), - "Value error, if present, profession_oids must have the same length as " - "profession_items.", + { + "naming_authority": {}, + "profession_items": ["example_profession_items"], + "profession_oids": ["1.2.3", "1.2.4"], + "registration_number": "example_registration_number", + "add_profession_info": b"example_add_profession_info", + }, + [ + ( + "value_error", + (), + "Value error, if present, profession_oids must have the same length as " + "profession_items.", + ) + ], + ), + ), +) +def test_profession_info_errors(parameters: dict[str, Any], expected_errors: ExpectedErrors) -> None: + """Test validation errors for the ProfessionInfoModel.""" + assert_validation_errors(ProfessionInfoModel, parameters, expected_errors) + + +@pytest.mark.parametrize( + ("parameters", "expected"), + ( + ( + {"profession_infos": [{"profession_items": ["example_profession_items"]}]}, + x509.Admission( + admission_authority=None, + naming_authority=None, + profession_infos=[ + x509.ProfessionInfo( + naming_authority=None, + profession_items=["example_profession_items"], + profession_oids=None, + registration_number=None, + add_profession_info=None, ) ], ), ), - ) - def test_profession_info_errors(parameters: dict[str, Any], expected_errors: ExpectedErrors) -> None: - """Test validation errors for the ProfessionInfoModel.""" - assert_validation_errors(ProfessionInfoModel, parameters, expected_errors) - - @pytest.mark.parametrize( - ("parameters", "expected"), ( - ( - {"profession_infos": [{"profession_items": ["example_profession_items"]}]}, - x509.Admission( - admission_authority=None, - naming_authority=None, - profession_infos=[ - x509.ProfessionInfo( - naming_authority=None, - profession_items=["example_profession_items"], - profession_oids=None, - registration_number=None, - add_profession_info=None, - ) - ], - ), - ), - ( - { - "admission_authority": {"type": "URI", "value": "https://example.com"}, - "naming_authority": {}, - "profession_infos": [ - {"profession_items": ["example_profession_items"]}, - { - "naming_authority": {}, - "profession_items": ["example_profession_items"], - "profession_oids": ["1.2.3"], - "registration_number": "example_registration_number", - "add_profession_info": b"example_add_profession_info", - }, - ], - }, - x509.Admission( - admission_authority=uri("https://example.com"), - naming_authority=x509.NamingAuthority(id=None, url=None, text=None), - profession_infos=[ - x509.ProfessionInfo( - naming_authority=None, - profession_items=["example_profession_items"], - profession_oids=None, - registration_number=None, - add_profession_info=None, - ), - x509.ProfessionInfo( - naming_authority=x509.NamingAuthority(id=None, url=None, text=None), - profession_items=["example_profession_items"], - profession_oids=[x509.ObjectIdentifier("1.2.3")], - registration_number="example_registration_number", - add_profession_info=b"example_add_profession_info", - ), - ], - ), + { + "admission_authority": {"type": "URI", "value": "https://example.com"}, + "naming_authority": {}, + "profession_infos": [ + {"profession_items": ["example_profession_items"]}, + { + "naming_authority": {}, + "profession_items": ["example_profession_items"], + "profession_oids": ["1.2.3"], + "registration_number": "example_registration_number", + "add_profession_info": b"example_add_profession_info", + }, + ], + }, + x509.Admission( + admission_authority=uri("https://example.com"), + naming_authority=x509.NamingAuthority(id=None, url=None, text=None), + profession_infos=[ + x509.ProfessionInfo( + naming_authority=None, + profession_items=["example_profession_items"], + profession_oids=None, + registration_number=None, + add_profession_info=None, + ), + x509.ProfessionInfo( + naming_authority=x509.NamingAuthority(id=None, url=None, text=None), + profession_items=["example_profession_items"], + profession_oids=[x509.ObjectIdentifier("1.2.3")], + registration_number="example_registration_number", + add_profession_info=b"example_add_profession_info", + ), + ], ), ), - ) - def test_admission_model(parameters: dict[str, Any], expected: x509.Admission) -> None: - """Test the AdmissionModel.""" - assert_cryptography_model(AdmissionModel, parameters, expected) + ), +) +def test_admission_model(parameters: dict[str, Any], expected: x509.Admission) -> None: + """Test the AdmissionModel.""" + assert_cryptography_model(AdmissionModel, parameters, expected) - @pytest.mark.parametrize("critical", (False, True, None)) - @pytest.mark.parametrize( - ("parameters", "admissions"), + +@pytest.mark.parametrize("critical", (False, True, None)) +@pytest.mark.parametrize( + ("parameters", "admissions"), + ( + ({}, x509.Admissions(authority=None, admissions=[])), ( - ({}, x509.Admissions(authority=None, admissions=[])), - ( - {"authority": {"type": "URI", "value": "https://example.com"}, "admissions": []}, - x509.Admissions(authority=uri("https://example.com"), admissions=[]), - ), - ( - { - "authority": {"type": "URI", "value": "https://example.com"}, - "admissions": [ - {"profession_infos": [{"profession_items": ["example_profession_items"]}]}, - ], - }, - x509.Admissions( - authority=uri("https://example.com"), - admissions=[ - x509.Admission( - admission_authority=None, - naming_authority=None, - profession_infos=[ - x509.ProfessionInfo( - naming_authority=None, - profession_items=["example_profession_items"], - profession_oids=None, - registration_number=None, - add_profession_info=None, - ) - ], - ) - ], - ), + {"authority": {"type": "URI", "value": "https://example.com"}, "admissions": []}, + x509.Admissions(authority=uri("https://example.com"), admissions=[]), + ), + ( + { + "authority": {"type": "URI", "value": "https://example.com"}, + "admissions": [ + {"profession_infos": [{"profession_items": ["example_profession_items"]}]}, + ], + }, + x509.Admissions( + authority=uri("https://example.com"), + admissions=[ + x509.Admission( + admission_authority=None, + naming_authority=None, + profession_infos=[ + x509.ProfessionInfo( + naming_authority=None, + profession_items=["example_profession_items"], + profession_oids=None, + registration_number=None, + add_profession_info=None, + ) + ], + ) + ], ), ), - ) - def test_admissions( - critical: Optional[bool], parameters: dict[str, Any], admissions: x509.Admissions - ) -> None: - """Test the Admissions extension.""" - assert_extension_model(AdmissionsModel, parameters, admissions, critical) + ), +) +def test_admissions( + critical: Optional[bool], parameters: dict[str, Any], admissions: x509.Admissions +) -> None: + """Test the Admissions extension.""" + assert_extension_model(AdmissionsModel, parameters, admissions, critical) @pytest.mark.parametrize( @@ -1730,11 +1732,6 @@ def test_fixture_certs(any_cert: str) -> None: serialized_extensions = CERT_DATA[any_cert][("extensions")] actual_extensions = list(public_key.extensions) - # Remove Admissions extension for older cryptography versions - if not hasattr(x509, "Admissions"): # pragma: only cryptography<44 - serialized_extensions = [ext for ext in serialized_extensions if ext["type"] != "admissions"] - actual_extensions = [ext for ext in actual_extensions if ext.oid != ExtensionOID.ADMISSIONS] - expected = CertificateExtensionModelList.validate_python( serialized_extensions, context={"validate_required_critical": False} ) diff --git a/ca/django_ca/tests/test_constants.py b/ca/django_ca/tests/test_constants.py index 46f816808..b99d62972 100644 --- a/ca/django_ca/tests/test_constants.py +++ b/ca/django_ca/tests/test_constants.py @@ -21,7 +21,6 @@ from django_ca import constants, typehints from django_ca.constants import ExtensionOID -from django_ca.tests.base.constants import CRYPTOGRAPHY_VERSION from django_ca.typehints import GeneralNames, HashAlgorithms @@ -71,11 +70,7 @@ def test_certificate_extension_keys_typehints() -> None: et for et in get_args(typehints.CertificateExtensionType) if et != x509.UnrecognizedExtension ] expected = sorted((ext.oid for ext in extension_types), key=oid_sorter) - actual = sorted(constants.CERTIFICATE_EXTENSION_KEYS, key=oid_sorter) - if CRYPTOGRAPHY_VERSION < (44, 0): # pragma: cryptography<44 branch - actual.remove(ExtensionOID.ADMISSIONS) - assert actual == expected @@ -87,10 +82,7 @@ def test_configurable_extension_keys_typehints() -> None: # check that all keys (=Object identifiers) occur in ConfigurableExtensionType expected = sorted((ext.oid for ext in get_args(typehints.ConfigurableExtensionType)), key=oid_sorter) - actual = sorted(constants.CONFIGURABLE_EXTENSION_KEYS, key=oid_sorter) - if CRYPTOGRAPHY_VERSION < (44, 0): # pragma: cryptography<44 branch - actual.remove(ExtensionOID.ADMISSIONS) assert actual == expected @@ -118,10 +110,7 @@ def test_end_entity_certificate_extension_keys_typehints() -> None: expected = sorted( (ext.oid for ext in get_args(typehints.EndEntityCertificateExtensionType)), key=oid_sorter ) - actual = sorted(constants.END_ENTITY_CERTIFICATE_EXTENSION_KEYS, key=oid_sorter) - if CRYPTOGRAPHY_VERSION < (44, 0): # pragma: cryptography<44 branch - actual.remove(ExtensionOID.ADMISSIONS) assert actual == expected diff --git a/ca/django_ca/tests/test_typehints.py b/ca/django_ca/tests/test_typehints.py index d182b7bcb..be1c6c0cb 100644 --- a/ca/django_ca/tests/test_typehints.py +++ b/ca/django_ca/tests/test_typehints.py @@ -20,8 +20,6 @@ import pytest from django_ca import constants, typehints -from django_ca.constants import ExtensionOID -from django_ca.tests.base.constants import CRYPTOGRAPHY_VERSION from django_ca.tests.test_constants import oid_sorter @@ -34,8 +32,6 @@ def test_configurable_extension_keys() -> None: keys = get_args(typehints.ConfigurableExtensionKeys) expected = sorted((ext.oid for ext in get_args(typehints.ConfigurableExtensionType)), key=oid_sorter) actual = sorted((constants.CONFIGURABLE_EXTENSION_KEY_OIDS[v] for v in keys), key=oid_sorter) - if CRYPTOGRAPHY_VERSION < (44, 0): # pragma: cryptography<44 branch - actual.remove(ExtensionOID.ADMISSIONS) assert actual == expected @@ -48,8 +44,6 @@ def test_end_entity_certificate_extension_keys() -> None: (get_args(ext)[0].oid for ext in get_args(typehints.EndEntityCertificateExtension)), key=oid_sorter ) actual = sorted((constants.END_ENTITY_CERTIFICATE_EXTENSION_KEY_OIDS[v] for v in keys), key=oid_sorter) - if CRYPTOGRAPHY_VERSION < (44, 0): # pragma: cryptography<44 branch - actual.remove(ExtensionOID.ADMISSIONS) assert actual == expected diff --git a/ca/django_ca/typehints.py b/ca/django_ca/typehints.py index 016f921f3..49f3a0ef9 100644 --- a/ca/django_ca/typehints.py +++ b/ca/django_ca/typehints.py @@ -326,41 +326,21 @@ class ParsableAuthorityKeyIdentifierDict(TypedDict, total=False): ################ # Type aliases # ################ -if TYPE_CHECKING: # pragma: only cryptography<44 # remove special handling once cg43 support is dropped - ConfigurableExtensionType = Union[ - x509.Admissions, - x509.AuthorityInformationAccess, - x509.CertificatePolicies, - x509.CRLDistributionPoints, - x509.ExtendedKeyUsage, - x509.FreshestCRL, - x509.IssuerAlternativeName, - x509.KeyUsage, - x509.MSCertificateTemplate, - x509.OCSPNoCheck, - x509.PrecertPoison, - x509.SubjectAlternativeName, - x509.TLSFeature, - ] -else: - #: :py:class:`~cg:cryptography.x509.ExtensionType` classes that can be configured by the user. - ConfigurableExtensionType = Union[ - x509.AuthorityInformationAccess, - x509.CertificatePolicies, - x509.CRLDistributionPoints, - x509.ExtendedKeyUsage, - x509.FreshestCRL, - x509.IssuerAlternativeName, - x509.KeyUsage, - x509.MSCertificateTemplate, - x509.OCSPNoCheck, - x509.PrecertPoison, - x509.SubjectAlternativeName, - x509.TLSFeature, - ] - - if CRYPTOGRAPHY_VERSION >= (44, 0): # pragma: cryptography>=44 branch - ConfigurableExtensionType = Union[ConfigurableExtensionType, x509.Admissions] # type: ignore[misc] +ConfigurableExtensionType = Union[ + x509.Admissions, + x509.AuthorityInformationAccess, + x509.CertificatePolicies, + x509.CRLDistributionPoints, + x509.ExtendedKeyUsage, + x509.FreshestCRL, + x509.IssuerAlternativeName, + x509.KeyUsage, + x509.MSCertificateTemplate, + x509.OCSPNoCheck, + x509.PrecertPoison, + x509.SubjectAlternativeName, + x509.TLSFeature, +] #: :py:class:`~cg:cryptography.x509.ExtensionType` classes that may appear in an end entity certificate. #: @@ -389,39 +369,21 @@ class ParsableAuthorityKeyIdentifierDict(TypedDict, total=False): x509.UnrecognizedExtension, ] -if TYPE_CHECKING: # pragma: only cryptography<44 # remove special handling once cg43 support is dropped - ConfigurableExtension = Union[ - x509.Extension[x509.Admissions], - x509.Extension[x509.AuthorityInformationAccess], - x509.Extension[x509.CertificatePolicies], - x509.Extension[x509.CRLDistributionPoints], - x509.Extension[x509.ExtendedKeyUsage], - x509.Extension[x509.FreshestCRL], - x509.Extension[x509.IssuerAlternativeName], - x509.Extension[x509.KeyUsage], - x509.Extension[x509.MSCertificateTemplate], - x509.Extension[x509.OCSPNoCheck], - x509.Extension[x509.PrecertPoison], - x509.Extension[x509.SubjectAlternativeName], - x509.Extension[x509.TLSFeature], - ] -else: - ConfigurableExtension = Union[ - x509.Extension[x509.AuthorityInformationAccess], - x509.Extension[x509.CertificatePolicies], - x509.Extension[x509.CRLDistributionPoints], - x509.Extension[x509.ExtendedKeyUsage], - x509.Extension[x509.FreshestCRL], - x509.Extension[x509.IssuerAlternativeName], - x509.Extension[x509.KeyUsage], - x509.Extension[x509.MSCertificateTemplate], - x509.Extension[x509.OCSPNoCheck], - x509.Extension[x509.PrecertPoison], - x509.Extension[x509.SubjectAlternativeName], - x509.Extension[x509.TLSFeature], - ] - if CRYPTOGRAPHY_VERSION >= (44, 0): # pragma: cryptography>=44 branch - ConfigurableExtension = Union[ConfigurableExtension, x509.Extension[x509.Admissions]] # type: ignore[misc] +ConfigurableExtension = Union[ + x509.Extension[x509.Admissions], + x509.Extension[x509.AuthorityInformationAccess], + x509.Extension[x509.CertificatePolicies], + x509.Extension[x509.CRLDistributionPoints], + x509.Extension[x509.ExtendedKeyUsage], + x509.Extension[x509.FreshestCRL], + x509.Extension[x509.IssuerAlternativeName], + x509.Extension[x509.KeyUsage], + x509.Extension[x509.MSCertificateTemplate], + x509.Extension[x509.OCSPNoCheck], + x509.Extension[x509.PrecertPoison], + x509.Extension[x509.SubjectAlternativeName], + x509.Extension[x509.TLSFeature], +] EndEntityCertificateExtension = Union[ ConfigurableExtension, diff --git a/devscripts/commands/recreate_fixtures.py b/devscripts/commands/recreate_fixtures.py index b11dcaf5e..17f8503aa 100644 --- a/devscripts/commands/recreate_fixtures.py +++ b/devscripts/commands/recreate_fixtures.py @@ -541,70 +541,68 @@ def recreate_fixtures( # pylint: disable=too-many-locals # noqa: PLR0915 }, } - # NOTE: always add Admissions extension once support for cryptography<44 is dropped. - if hasattr(ExtensionOID, "ADMISSIONS"): # pragma: only cryptography<44.0 - data["all-extensions"]["extensions"]["admissions"] = x509.Extension( - oid=ExtensionOID.ADMISSIONS, - critical=False, - value=x509.Admissions( - authority=x509.UniformResourceIdentifier("https://default-authority.admissions.example.com"), - admissions=[ - x509.Admission( - admission_authority=x509.UniformResourceIdentifier( - "https://authority.admissions.example.com" + data["all-extensions"]["extensions"]["admissions"] = x509.Extension( + oid=ExtensionOID.ADMISSIONS, + critical=False, + value=x509.Admissions( + authority=x509.UniformResourceIdentifier("https://default-authority.admissions.example.com"), + admissions=[ + x509.Admission( + admission_authority=x509.UniformResourceIdentifier( + "https://authority.admissions.example.com" + ), + naming_authority=x509.NamingAuthority( + id=x509.ObjectIdentifier("1.2.3"), + url="https://naming-auth.admissions.example.com", + text="naming-auth.admissions.example.com text", + ), + profession_infos=[ + x509.ProfessionInfo( + naming_authority=x509.NamingAuthority( + id=None, + url="https://naming-auth.profession-info.admissions.example.com", + text="naming-auth.profession-info.admissions.example.com text", + ), + profession_items=["prof_item"], + profession_oids=[x509.ObjectIdentifier("1.2.3.5")], + registration_number="registration-number", + add_profession_info=b"add-profession-info", ), - naming_authority=x509.NamingAuthority( - id=x509.ObjectIdentifier("1.2.3"), - url="https://naming-auth.admissions.example.com", - text="naming-auth.admissions.example.com text", + x509.ProfessionInfo( + naming_authority=x509.NamingAuthority(id=None, url=None, text=None), + profession_items=["prof_item_minimal"], + profession_oids=None, + registration_number=None, + add_profession_info=None, ), - profession_infos=[ - x509.ProfessionInfo( - naming_authority=x509.NamingAuthority( - id=None, - url="https://naming-auth.profession-info.admissions.example.com", - text="naming-auth.profession-info.admissions.example.com text", - ), - profession_items=["prof_item"], - profession_oids=[x509.ObjectIdentifier("1.2.3.5")], - registration_number="registration-number", - add_profession_info=b"add-profession-info", - ), - x509.ProfessionInfo( - naming_authority=x509.NamingAuthority(id=None, url=None, text=None), - profession_items=["prof_item_minimal"], - profession_oids=None, - registration_number=None, - add_profession_info=None, - ), - ], - ) - ], - ), - ) - data["alt-extensions"]["extensions"]["admissions"] = x509.Extension( - oid=ExtensionOID.ADMISSIONS, - critical=False, - value=x509.Admissions( - authority=None, - admissions=[ - # Add a minimal admission extension here - x509.Admission( - admission_authority=None, - naming_authority=None, - profession_infos=[ - x509.ProfessionInfo( - naming_authority=None, - profession_items=["prof_item"], - profession_oids=None, - registration_number=None, - add_profession_info=None, - ) - ], - ) - ], - ), - ) + ], + ) + ], + ), + ) + data["alt-extensions"]["extensions"]["admissions"] = x509.Extension( + oid=ExtensionOID.ADMISSIONS, + critical=False, + value=x509.Admissions( + authority=None, + admissions=[ + # Add a minimal admission extension here + x509.Admission( + admission_authority=None, + naming_authority=None, + profession_infos=[ + x509.ProfessionInfo( + naming_authority=None, + profession_items=["prof_item"], + profession_oids=None, + registration_number=None, + add_profession_info=None, + ) + ], + ) + ], + ), + ) # Auto-compute some values (name, filenames, ...) based on the dict key for cert_name, cert_values in data.items():