diff --git a/backport-cryptopolicies-add-enums-and-__ems-tri-state.patch b/backport-cryptopolicies-add-enums-and-__ems-tri-state.patch new file mode 100644 index 0000000000000000000000000000000000000000..c2dc3c83d4850edfcfaaf6aa07c79e96444d2a2b --- /dev/null +++ b/backport-cryptopolicies-add-enums-and-__ems-tri-state.patch @@ -0,0 +1,189 @@ +From 31a2f91f302472a2f0e131ea08d3b5b66c045f23 Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Fri, 21 Jul 2023 10:52:41 +0200 +Subject: [PATCH 006/196] cryptopolicies: add enums and __ems tri-state + +--- + python/cryptopolicies/cryptopolicies.py | 32 +++++++++++++++++++---- + python/cryptopolicies/validation/rules.py | 6 +++++ + tests/unit/test_cryptopolicy.py | 5 ++++ + tests/unit/test_parse_rhs.py | 7 +++++ + 4 files changed, 45 insertions(+), 5 deletions(-) + +diff --git a/python/cryptopolicies/cryptopolicies.py b/python/cryptopolicies/cryptopolicies.py +index 3db1071..e32c179 100644 +--- a/python/cryptopolicies/cryptopolicies.py ++++ b/python/cryptopolicies/cryptopolicies.py +@@ -30,6 +30,13 @@ INT_DEFAULTS = {k: 0 for k in ( + )} + + ++# For enum values, first value works as default, ++ ++ENUMS = { ++ '__ems': ('DEFAULT', 'ENFORCE', 'RELAX'), # FIPS/NO-ENFORCE-EMS ++} ++ ++ + # Scopes (`@!ipsec`) and matching them + + SCOPE_ANY = '*' +@@ -118,6 +125,7 @@ class Operation(enum.Enum): + APPEND = 3 # cipher = NULL+ + OMIT = 4 # cipher = -NULL + SET_INT = 5 # sha1_in_certs = 0; setting to something that's all digits ++ SET_ENUM = 6 # __ems = ENFORCE + + def __repr__(self): # to unify the output between Python versions + return f'Operation.{self.name}' +@@ -138,6 +146,8 @@ def parse_rhs(rhs, prop_name): + >>> parse_rhs('+*DES-CBC', 'cipher') + [(Operation.PREPEND, 'DES-CBC'), + (Operation.PREPEND, '3DES-CBC')] ++ >>> parse_rhs('ENFORCE', '__ems') ++ [(Operation.SET_ENUM, 'ENFORCE')] + """ + def differential(v): + return v.startswith('+') or v.endswith('+') or v.startswith('-') +@@ -145,15 +155,21 @@ def parse_rhs(rhs, prop_name): + if rhs.isdigit(): + if prop_name not in alg_lists.ALL and prop_name in INT_DEFAULTS: + return [(Operation.SET_INT, int(rhs))] +- elif prop_name in alg_lists.ALL: ++ elif prop_name in alg_lists.ALL or prop_name in ENUMS: + raise validation.rules.NonIntPropertyIntValueError(prop_name) + else: + assert prop_name not in alg_lists.ALL + assert prop_name not in INT_DEFAULTS ++ assert prop_name not in ENUMS + # pass for now, it's gonna be caught as non-existing algclass + else: + if prop_name in INT_DEFAULTS: + raise validation.rules.IntPropertyNonIntValueError(prop_name) ++ if prop_name in ENUMS: ++ if rhs not in ENUMS[prop_name]: ++ raise validation.rules.BadEnumValueError(prop_name, rhs, ++ ENUMS[prop_name]) ++ return [(Operation.SET_ENUM, rhs)] + + values = rhs.split() + +@@ -327,6 +343,7 @@ class ScopedPolicy: + def __init__(self, directives, relevant_scopes=None): + relevant_scopes = relevant_scopes or set() + self.integers = INT_DEFAULTS.copy() ++ self.enums = {k: v[0] for k, v in ENUMS.items()} + self.enabled = {prop_name: [] for prop_name in alg_lists.ALL} + + for directive in directives: +@@ -350,9 +367,11 @@ class ScopedPolicy: + e for e in self.enabled[directive.prop_name] + if e != directive.value + ] +- else: +- assert directive.operation == Operation.SET_INT ++ elif directive.operation == Operation.SET_INT: + self.integers[directive.prop_name] = directive.value ++ else: ++ assert directive.operation == Operation.SET_ENUM ++ self.enums[directive.prop_name] = directive.value + assert len(self.enabled) == len(set(self.enabled)) + + self.disabled = {prop_name: [e for e in alg_list +@@ -444,14 +463,17 @@ class UnscopedCryptoPolicy: + s += '# it is provided for review convenience only.\n' + s += '#\n' + s += '# Baseline values for all scopes:\n' +- generic_all = {**generic_scoped.enabled, **generic_scoped.integers} ++ generic_all = {**generic_scoped.enabled, ++ **generic_scoped.integers, ++ **generic_scoped.enums} + for prop_name, value in generic_all.items(): + s += fmt(prop_name, value) + anything_scope_specific = False + for scope_name, scope_set in DUMPABLE_SCOPES.items(): + specific_scoped = self.scoped(scopes=scope_set) + specific_all = {**specific_scoped.enabled, +- **specific_scoped.integers} ++ **specific_scoped.integers, ++ **specific_scoped.enums} + for prop_name, value in specific_all.items(): + if value != generic_all[prop_name]: + if not anything_scope_specific: +diff --git a/python/cryptopolicies/validation/rules.py b/python/cryptopolicies/validation/rules.py +index db0539f..637d6d2 100644 +--- a/python/cryptopolicies/validation/rules.py ++++ b/python/cryptopolicies/validation/rules.py +@@ -30,6 +30,12 @@ class NonIntPropertyIntValueError(PolicySyntaxError): + ' value must not be an integer') + + ++class BadEnumValueError(PolicySyntaxError): ++ def __init__(self, enum_name, value, acceptable_values): ++ super().__init__(f'Bad value of policy property `{enum_name}`:' ++ f' {value}; must be one of {acceptable_values}') ++ ++ + def count_equals_signs(line): + if line.count('=') != 1: + raise MalformedLine(line) +diff --git a/tests/unit/test_cryptopolicy.py b/tests/unit/test_cryptopolicy.py +index d1bb6e5..f4e5157 100644 +--- a/tests/unit/test_cryptopolicy.py ++++ b/tests/unit/test_cryptopolicy.py +@@ -264,6 +264,7 @@ def test_cryptopolicy_to_string_empty(tmpdir): + sha1_in_certs = 0 + ssh_certs = 0 + ssh_etm = 0 ++ __ems = DEFAULT + # No scope-specific properties found. + ''').lstrip() + cp = _policy(tmpdir, EMPTYPOL='', EMPTYSUBPOL1='\n', EMPTYSUBPOL2='\t') +@@ -295,12 +296,14 @@ def test_cryptopolicy_to_string_twisted(tmpdir): + sha1_in_certs = 0 + ssh_certs = 0 + ssh_etm = 0 ++ __ems = ENFORCE + # Scope-specific properties derived for select backends: + cipher@gnutls = DES-CBC + hash@gnutls = + sha1_in_certs@gnutls = 1 + cipher@java-tls = DES-CBC + cipher@nss = DES-CBC ++ __ems@nss = RELAX + cipher@openssl = NULL DES-CBC + ''').lstrip() + cp = _policy(tmpdir, +@@ -312,5 +315,7 @@ def test_cryptopolicy_to_string_twisted(tmpdir): + cipher@openssl = +NULL + sha1_in_certs@gnutls = 1 + hash@gnutls = -MD5 ++ __ems = ENFORCE ++ __ems@nss = RELAX + ''') + assert str(cp) == reference +diff --git a/tests/unit/test_parse_rhs.py b/tests/unit/test_parse_rhs.py +index f68d98c..1831619 100644 +--- a/tests/unit/test_parse_rhs.py ++++ b/tests/unit/test_parse_rhs.py +@@ -13,6 +13,7 @@ from python.cryptopolicies.validation.rules import ( + MixedDifferentialNonDifferentialError, + IntPropertyNonIntValueError, + NonIntPropertyIntValueError, ++ BadEnumValueError, + ) + + +@@ -39,3 +40,9 @@ def test_parse_rhs(): + parse_rhs('0', 'cipher') + with pytest.raises(AlgorithmClassUnknownError): + parse_rhs('0', 'nonex_algo_class') ++ ++ assert parse_rhs('RELAX', '__ems') == [(Operation.SET_ENUM, 'RELAX')] ++ with pytest.raises(NonIntPropertyIntValueError): ++ parse_rhs('0', '__ems') ++ with pytest.raises(BadEnumValueError): ++ parse_rhs('INVALID', '__ems') +-- +2.50.1 + diff --git a/crypto-policies.spec b/crypto-policies.spec index 9cc552de5861b5c7fa0fe016f1943a0548ecff07..86add3ea573c14aebf3cf2e9e0713da92dec2525 100644 --- a/crypto-policies.spec +++ b/crypto-policies.spec @@ -4,7 +4,7 @@ Name: crypto-policies Version: %{git_date} -Release: 4.git%{git_commit_hash} +Release: 5.git%{git_commit_hash} Summary: Crypto policies package for Fedora License: LGPLv2+ @@ -15,6 +15,7 @@ URL: https://gitlab.com/redhat-crypto/fedora-crypto-policies Source0: https://gitlab.com/redhat-crypto/fedora-crypto-policies/-/archive/%{git_commit_hash}/%{name}-git%{git_commit_hash}.tar.gz Patch1: backport-nss-retire-NSS_OLD-and-replace-with-NSS_LAX-3.80-che.patch +Patch2: backport-cryptopolicies-add-enums-and-__ems-tri-state.patch BuildArch: noarch BuildRequires: asciidoc @@ -183,6 +184,9 @@ make check %{?_smp_mflags} %license COPYING.LESSER %changelog +* Tue Dec 09 2025 YangengLiu - 20230614-5.git5f3458e +- cryptopolicies: add enums and __ems tri-state + * Fri Oct 31 2025 zhangfeilong - 20230614-4.git5f3458e - change sw64 build deps to jdk17