Skip to content

Commit dfdd4a1

Browse files
committed
Add docs for SHA1 deprecation; reject empty configs
1 parent 9c827a9 commit dfdd4a1

File tree

3 files changed

+22
-27
lines changed

3 files changed

+22
-27
lines changed

signxml/algorithms.py

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,7 @@ class DigestAlgorithm(FragmentLookupMixin, InvalidInputErrorMixin, Enum):
7070
SHA3_512 = "http://www.w3.org/2007/05/xmldsig-more#sha3-512"
7171

7272
SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1"
73-
"""
74-
SHA1 based algorithms are not secure for use in digital signatures. They are included for legacy compatibility only.
75-
Support for their algorithm identifiers is deprecated and will be removed in a future release.
76-
"""
73+
"See `SHA1 deprecation`_."
7774

7875
@property
7976
def implementation(self) -> Callable:
@@ -123,29 +120,24 @@ class SignatureMethod(FragmentLookupMixin, InvalidInputErrorMixin, Enum):
123120

124121
DSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#dsa-sha1"
125122
"""
126-
SHA1 based algorithms are not secure for use in digital signatures. They are included for legacy compatibility only.
127-
Support for their algorithm identifiers is deprecated and will be removed in a future release.
123+
_`SHA1 deprecation`: SHA1 based algorithms are not secure for use in digital signatures. They are included for
124+
legacy compatibility only and disabled by default. To verify SHA1 based signatures, use::
125+
126+
XMLVerifier().verify(
127+
expect_config=SignatureConfiguration(
128+
signature_methods=...,
129+
digest_algorithms=...
130+
)
131+
)
128132
"""
129133
HMAC_SHA1 = "http://www.w3.org/2000/09/xmldsig#hmac-sha1"
130-
"""
131-
SHA1 based algorithms are not secure for use in digital signatures. They are included for legacy compatibility only.
132-
Support for their algorithm identifiers is deprecated and will be removed in a future release.
133-
"""
134+
"See `SHA1 deprecation`_."
134135
RSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
135-
"""
136-
SHA1 based algorithms are not secure for use in digital signatures. They are included for legacy compatibility only.
137-
Support for their algorithm identifiers is deprecated and will be removed in a future release.
138-
"""
136+
"See `SHA1 deprecation`_."
139137
ECDSA_SHA1 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"
140-
"""
141-
SHA1 based algorithms are not secure for use in digital signatures. They are included for legacy compatibility only.
142-
Support for their algorithm identifiers is deprecated and will be removed in a future release.
143-
"""
138+
"See `SHA1 deprecation`_."
144139
SHA1_RSA_MGF1 = "http://www.w3.org/2007/05/xmldsig-more#sha1-rsa-MGF1"
145-
"""
146-
SHA1 based algorithms are not secure for use in digital signatures. They are included for legacy compatibility only.
147-
Support for their algorithm identifiers is deprecated and will be removed in a future release.
148-
"""
140+
"See `SHA1 deprecation`_."
149141

150142

151143
class CanonicalizationMethod(InvalidInputErrorMixin, Enum):

signxml/verifier.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ class SignatureConfiguration:
6363
signature_methods: FrozenSet[SignatureMethod] = frozenset(sm for sm in SignatureMethod if "SHA1" not in sm.name)
6464
"""
6565
Set of acceptable signature methods (signature algorithms). Any signature generated using an algorithm not listed
66-
here will fail verification (but if this set is left empty, then all supported algorithms are accepted).
66+
here will fail verification.
6767
"""
6868

6969
digest_algorithms: FrozenSet[DigestAlgorithm] = frozenset(da for da in DigestAlgorithm if "SHA1" not in da.name)
7070
"""
7171
Set of acceptable digest algorithms. Any signature or reference transform generated using an algorithm not listed
72-
here will cause verification to fail (but if this set is left empty, then all supported algorithms are accepted).
72+
here will cause verification to fail.
7373
"""
7474

7575
ignore_ambiguous_key_info: bool = False
@@ -338,7 +338,7 @@ def verify(
338338
signature_method = self._find(signed_info, "SignatureMethod")
339339
signature_value = self._find(signature, "SignatureValue")
340340
signature_alg = SignatureMethod(signature_method.get("Algorithm"))
341-
if self.config.signature_methods and signature_alg not in self.config.signature_methods:
341+
if signature_alg not in self.config.signature_methods:
342342
raise InvalidInput(f"Signature method {signature_alg.name} forbidden by configuration")
343343
raw_signature = b64decode(signature_value.text)
344344
x509_data = signature.find("ds:KeyInfo/ds:X509Data", namespaces=namespaces)
@@ -467,7 +467,7 @@ def _verify_reference(self, reference, index, root, uri_resolver, c14n_algorithm
467467
# TODO: payload-specific c14n alg
468468
payload_c14n = self._apply_transforms(payload, transforms, copied_signature_ref, c14n_algorithm)
469469
digest_alg = DigestAlgorithm(digest_method_alg_name)
470-
if self.config.digest_algorithms and digest_alg not in self.config.digest_algorithms:
470+
if digest_alg not in self.config.digest_algorithms:
471471
raise InvalidInput(f"Digest algorithm {digest_alg.name} forbidden by configuration")
472472

473473
if b64decode(digest_value.text) != self._get_digest(payload_c14n, digest_alg):

test/test.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,12 +630,15 @@ def test_verify_config(self):
630630
config = SignatureConfiguration(location="./foo/bar/")
631631
with self.assertRaisesRegex(InvalidInput, "Expected to find XML element Signature in data"):
632632
verifier.verify(signed, x509_cert=cert, expect_config=config)
633-
config = SignatureConfiguration(signature_methods=[SignatureMethod.ECDSA_SHA384])
633+
config = SignatureConfiguration(signature_methods=[])
634634
with self.assertRaisesRegex(InvalidInput, "Signature method RSA_SHA256 forbidden by configuration"):
635635
verifier.verify(signed, x509_cert=cert, expect_config=config)
636636
config = SignatureConfiguration(digest_algorithms=[DigestAlgorithm.SHA3_512])
637637
with self.assertRaisesRegex(InvalidInput, "Digest algorithm SHA256 forbidden by configuration"):
638638
verifier.verify(signed, x509_cert=cert, expect_config=config)
639+
config = SignatureConfiguration(digest_algorithms=[])
640+
with self.assertRaisesRegex(InvalidInput, "Digest algorithm SHA256 forbidden by configuration"):
641+
verifier.verify(signed, x509_cert=cert, expect_config=config)
639642

640643
def test_sha1_policy(self):
641644
data = etree.parse(self.example_xml_files[0]).getroot()

0 commit comments

Comments
 (0)