1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
|
from enum import Enum
from typing import Callable, Dict, Type, Union
from cryptography.hazmat.primitives import hashes
from .exceptions import InvalidInput
class SignatureConstructionMethod(Enum):
"""
An enumeration of signature construction methods supported by SignXML, used to specify the method when signing.
See the list of signature types under `XML Signature Syntax and Processing Version 2.0, Definitions
<http://www.w3.org/TR/xmldsig-core2/#sec-Definitions>`_.
"""
enveloped = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
"""
The signature is over the XML content that contains the signature as an element. The content provides the root
XML document element. This is the most common XML signature type in modern applications.
"""
enveloping = "enveloping-signature"
"""
The signature is over content found within an Object element of the signature itself. The Object (or its
content) is identified via a Reference (via a URI fragment identifier or transform).
"""
detached = "detached-signature"
"""
The signature is over content external to the Signature element, and can be identified via a URI or
transform. Consequently, the signature is "detached" from the content it signs. This definition typically applies to
separate data objects, but it also includes the instance where the Signature and data object reside within the same
XML document but are sibling elements.
"""
class FragmentLookupMixin:
@classmethod
def from_fragment(cls, fragment):
for i in cls: # type: ignore[attr-defined]
if i.value.endswith("#" + fragment):
return i
else:
raise InvalidInput(f"Unrecognized {cls.__name__} identifier fragment: {fragment}")
class InvalidInputErrorMixin:
@classmethod
def _missing_(cls, value):
raise InvalidInput(f"Unrecognized {cls.__name__}: {value}")
def __repr__(self):
return f"{self.__class__.__name__}.{self.name}" # type: ignore[attr-defined]
class DigestAlgorithm(FragmentLookupMixin, InvalidInputErrorMixin, Enum):
"""
An enumeration of digest algorithms supported by SignXML. See the
`Algorithm Identifiers and Implementation Requirements <http://www.w3.org/TR/xmldsig-core1/#sec-AlgID>`_ section of
the XML Signature 1.1 standard for details.
"""
SHA224 = "http://www.w3.org/2001/04/xmldsig-more#sha224"
SHA384 = "http://www.w3.org/2001/04/xmldsig-more#sha384"
SHA256 = "http://www.w3.org/2001/04/xmlenc#sha256"
SHA512 = "http://www.w3.org/2001/04/xmlenc#sha512"
SHA3_224 = "http://www.w3.org/2007/05/xmldsig-more#sha3-224"
SHA3_256 = "http://www.w3.org/2007/05/xmldsig-more#sha3-256"
SHA3_384 = "http://www.w3.org/2007/05/xmldsig-more#sha3-384"
SHA3_512 = "http://www.w3.org/2007/05/xmldsig-more#sha3-512"
SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1"
"See `SHA1 deprecation`_."
@property
def implementation(self) -> Callable:
"""
The cryptography callable that implements the specified algorithm.
"""
return digest_algorithm_implementations[self]
# TODO: check if padding errors are fixed by using padding=MGF1
class SignatureMethod(FragmentLookupMixin, InvalidInputErrorMixin, Enum):
"""
An enumeration of signature methods (also referred to as signature algorithms) supported by SignXML. See the
`Algorithm Identifiers and Implementation Requirements <http://www.w3.org/TR/xmldsig-core1/#sec-AlgID>`_ section of
the XML Signature 1.1 standard for details.
"""
RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
"""
The RSASSA-PKCS1-v1_5 algorithm described in RFC 3447. This is the default, most widely supported signature method.
"""
RSA_SHA224 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha224"
RSA_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
RSA_SHA512 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
ECDSA_SHA224 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"
ECDSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"
ECDSA_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"
ECDSA_SHA512 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"
ECDSA_SHA3_224 = "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-224"
ECDSA_SHA3_256 = "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-256"
ECDSA_SHA3_384 = "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-384"
ECDSA_SHA3_512 = "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-512"
DSA_SHA256 = "http://www.w3.org/2009/xmldsig11#dsa-sha256"
HMAC_SHA224 = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha224"
HMAC_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"
HMAC_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha384"
HMAC_SHA512 = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha512"
SHA3_224_RSA_MGF1 = "http://www.w3.org/2007/05/xmldsig-more#sha3-224-rsa-MGF1"
SHA3_256_RSA_MGF1 = "http://www.w3.org/2007/05/xmldsig-more#sha3-256-rsa-MGF1"
SHA3_384_RSA_MGF1 = "http://www.w3.org/2007/05/xmldsig-more#sha3-384-rsa-MGF1"
SHA3_512_RSA_MGF1 = "http://www.w3.org/2007/05/xmldsig-more#sha3-512-rsa-MGF1"
SHA224_RSA_MGF1 = "http://www.w3.org/2007/05/xmldsig-more#sha224-rsa-MGF1"
SHA256_RSA_MGF1 = "http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1"
SHA384_RSA_MGF1 = "http://www.w3.org/2007/05/xmldsig-more#sha384-rsa-MGF1"
SHA512_RSA_MGF1 = "http://www.w3.org/2007/05/xmldsig-more#sha512-rsa-MGF1"
DSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#dsa-sha1"
"""
_`SHA1 deprecation`: SHA1 based algorithms are not secure for use in digital signatures. They are included for
legacy compatibility only and disabled by default. To verify SHA1 based signatures, use::
XMLVerifier().verify(
expect_config=SignatureConfiguration(
signature_methods=...,
digest_algorithms=...
)
)
"""
HMAC_SHA1 = "http://www.w3.org/2000/09/xmldsig#hmac-sha1"
"See `SHA1 deprecation`_."
RSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
"See `SHA1 deprecation`_."
ECDSA_SHA1 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"
"See `SHA1 deprecation`_."
SHA1_RSA_MGF1 = "http://www.w3.org/2007/05/xmldsig-more#sha1-rsa-MGF1"
"See `SHA1 deprecation`_."
class CanonicalizationMethod(InvalidInputErrorMixin, Enum):
"""
An enumeration of XML canonicalization methods (also referred to as canonicalization algorithms) supported by
SignXML. See the `Algorithm Identifiers and Implementation Requirements
<http://www.w3.org/TR/xmldsig-core1/#sec-AlgID>`_ section of the XML Signature 1.1 standard for details.
"""
CANONICAL_XML_1_0 = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
CANONICAL_XML_1_0_WITH_COMMENTS = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"
CANONICAL_XML_1_1 = "http://www.w3.org/2006/12/xml-c14n11"
CANONICAL_XML_1_1_WITH_COMMENTS = "http://www.w3.org/2006/12/xml-c14n11#WithComments"
EXCLUSIVE_XML_CANONICALIZATION_1_0 = "http://www.w3.org/2001/10/xml-exc-c14n#"
EXCLUSIVE_XML_CANONICALIZATION_1_0_WITH_COMMENTS = "http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
# The identifier for Canonical XML 2.0 is "http://www.w3.org/2010/xml-c14n2", but it is not a W3C standard.
# While it is supported by lxml, it's not in general use and not supported by SignXML
digest_algorithm_implementations: Dict[Union[DigestAlgorithm, SignatureMethod], Type[hashes.HashAlgorithm]] = {
DigestAlgorithm.SHA1: hashes.SHA1,
DigestAlgorithm.SHA224: hashes.SHA224,
DigestAlgorithm.SHA384: hashes.SHA384,
DigestAlgorithm.SHA256: hashes.SHA256,
DigestAlgorithm.SHA512: hashes.SHA512,
DigestAlgorithm.SHA3_224: hashes.SHA3_224,
DigestAlgorithm.SHA3_256: hashes.SHA3_256,
DigestAlgorithm.SHA3_384: hashes.SHA3_384,
DigestAlgorithm.SHA3_512: hashes.SHA3_512,
SignatureMethod.DSA_SHA1: hashes.SHA1,
SignatureMethod.HMAC_SHA1: hashes.SHA1,
SignatureMethod.RSA_SHA1: hashes.SHA1,
SignatureMethod.ECDSA_SHA1: hashes.SHA1,
SignatureMethod.ECDSA_SHA224: hashes.SHA224,
SignatureMethod.ECDSA_SHA256: hashes.SHA256,
SignatureMethod.ECDSA_SHA384: hashes.SHA384,
SignatureMethod.ECDSA_SHA512: hashes.SHA512,
SignatureMethod.HMAC_SHA224: hashes.SHA224,
SignatureMethod.HMAC_SHA256: hashes.SHA256,
SignatureMethod.HMAC_SHA384: hashes.SHA384,
SignatureMethod.HMAC_SHA512: hashes.SHA512,
SignatureMethod.RSA_SHA224: hashes.SHA224,
SignatureMethod.RSA_SHA256: hashes.SHA256,
SignatureMethod.RSA_SHA384: hashes.SHA384,
SignatureMethod.RSA_SHA512: hashes.SHA512,
SignatureMethod.DSA_SHA256: hashes.SHA256,
SignatureMethod.ECDSA_SHA3_224: hashes.SHA3_224,
SignatureMethod.ECDSA_SHA3_256: hashes.SHA3_256,
SignatureMethod.ECDSA_SHA3_384: hashes.SHA3_384,
SignatureMethod.ECDSA_SHA3_512: hashes.SHA3_512,
SignatureMethod.SHA3_224_RSA_MGF1: hashes.SHA3_224,
SignatureMethod.SHA3_256_RSA_MGF1: hashes.SHA3_256,
SignatureMethod.SHA3_384_RSA_MGF1: hashes.SHA3_384,
SignatureMethod.SHA3_512_RSA_MGF1: hashes.SHA3_512,
SignatureMethod.SHA224_RSA_MGF1: hashes.SHA224,
SignatureMethod.SHA256_RSA_MGF1: hashes.SHA256,
SignatureMethod.SHA384_RSA_MGF1: hashes.SHA384,
SignatureMethod.SHA512_RSA_MGF1: hashes.SHA512,
SignatureMethod.SHA1_RSA_MGF1: hashes.SHA1,
}
|