diff --git a/cl_sii/libs/xml_utils.py b/cl_sii/libs/xml_utils.py index 20e4e2f0..677a40b7 100644 --- a/cl_sii/libs/xml_utils.py +++ b/cl_sii/libs/xml_utils.py @@ -431,8 +431,24 @@ def verify_xml_signature( try: # note: by passing 'x509_cert' we override any X.509 certificate information supplied # by the signature itself. + + # note: when an X509Data element is present in the signature and used for verification, but + # a KeyValue element is also present, there is an ambiguity and a security hazard because + # the public key used to sign the document is already encoded in the certificate (which is + # in X509Data), so the verifier must either ignore KeyValue or ensure that it matches what + # is in the certificate. SignXML does not perform that validation and throws an + # 'InvalidInput' error instead. + # + # SII's schema for XML signatures requires both elements to be present, which forces us to + # enable 'ignore_ambiguous_key_info' to bypass the error and validate the signature using + # X509Data only. + # + # Source: + # https://github.com/XML-Security/signxml/commit/ef15da8dbb904f1dedfdd210ae3e0df5da535612 result: signxml.VerifyResult = xml_verifier.verify( - data=tmp_bytes, require_x509=True, x509_cert=trusted_x509_cert_open_ssl) + data=tmp_bytes, require_x509=True, x509_cert=trusted_x509_cert_open_ssl, + ignore_ambiguous_key_info=True, + ) except signxml.exceptions.InvalidDigest as exc: # warning: catch before 'InvalidSignature' (it is the parent of 'InvalidDigest'). diff --git a/requirements/base.txt b/requirements/base.txt index f82eca83..b26ffd96 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -9,7 +9,7 @@ lxml==4.5.0 marshmallow==2.19.5 pyOpenSSL==18.0.0 pytz==2019.3 -signxml==2.6.0 +signxml==2.8.0 # Packages dependencies: # - cryptography: @@ -24,16 +24,13 @@ signxml==2.6.0 # - setuptools # - six # - signxml: -# - asn1crypto # - certifi # - cryptography -# - defusedxml # - eight # - future # - lxml # - pyOpenSSL # - six -asn1crypto==1.3.0 attrs==19.3.0 certifi==2020.4.5.1 cffi==1.14.0 diff --git a/setup.py b/setup.py index f5094afb..36f65e71 100755 --- a/setup.py +++ b/setup.py @@ -27,10 +27,10 @@ def get_version(*file_paths: Sequence[str]) -> str: 'jsonschema>=3.1.1', 'lxml>=4.5.0,<5', 'marshmallow>=2.19.2,<3', - # TODO: remove upper-bound after a new release of 'signxml' drops the requirement 'pyOpenSSL<19' - 'pyOpenSSL>=18.0.0,<19', + # TODO: remove upper-bound after a new release of 'signxml' drops the requirement 'pyOpenSSL<20' + 'pyOpenSSL>=18.0.0,<20', 'pytz>=2019.3', - 'signxml>=2.6.0', + 'signxml>=2.8.0', ] extras_requirements = {