1
1
from base64 import b64encode
2
- from typing import Union
2
+ from typing import List , Optional , Union
3
3
4
4
from cryptography .hazmat .primitives .asymmetric import ec , utils
5
5
from cryptography .hazmat .primitives .asymmetric .padding import PKCS1v15
6
6
from cryptography .hazmat .primitives .hmac import HMAC
7
7
from cryptography .hazmat .primitives .serialization import load_pem_private_key
8
- from lxml .etree import Element , SubElement
8
+ from lxml .etree import Element , SubElement , _Element
9
9
from OpenSSL .crypto import FILETYPE_PEM , dump_certificate
10
10
11
- from .algorithms import DigestAlgorithm , SignatureMethod , SignatureType , digest_algorithm_implementations
11
+ from .algorithms import (
12
+ CanonicalizationMethod ,
13
+ DigestAlgorithm ,
14
+ SignatureMethod ,
15
+ SignatureType ,
16
+ digest_algorithm_implementations ,
17
+ )
12
18
from .exceptions import InvalidInput
13
19
from .processor import XMLSignatureProcessor
14
20
from .util import (
@@ -50,10 +56,10 @@ def __init__(
50
56
method : SignatureType = SignatureType .enveloped ,
51
57
signature_algorithm : Union [SignatureMethod , str ] = SignatureMethod .RSA_SHA256 ,
52
58
digest_algorithm : Union [DigestAlgorithm , str ] = DigestAlgorithm .SHA256 ,
53
- c14n_algorithm = XMLSignatureProcessor . default_c14n_algorithm ,
59
+ c14n_algorithm = CanonicalizationMethod . CANONICAL_XML_1_1 ,
54
60
):
55
61
if method is None or method not in SignatureType :
56
- raise InvalidInput ("Unknown signature method {}" . format ( method ) )
62
+ raise InvalidInput (f "Unknown signature method { method } " )
57
63
self .signature_type = method
58
64
if isinstance (signature_algorithm , str ) and "#" not in signature_algorithm :
59
65
self .sign_alg = SignatureMethod .from_fragment (signature_algorithm )
@@ -63,8 +69,7 @@ def __init__(
63
69
self .digest_alg = DigestAlgorithm .from_fragment (digest_algorithm )
64
70
else :
65
71
self .digest_alg = DigestAlgorithm (digest_algorithm )
66
- assert c14n_algorithm in self .known_c14n_algorithms
67
- self .c14n_alg = c14n_algorithm
72
+ self .c14n_alg = CanonicalizationMethod (c14n_algorithm )
68
73
self .namespaces = dict (ds = namespaces .ds )
69
74
self ._parser = None
70
75
self .signature_annotators = [self ._add_key_info ]
@@ -73,15 +78,15 @@ def sign(
73
78
self ,
74
79
data ,
75
80
key = None ,
76
- passphrase = None ,
81
+ passphrase : Optional [ bytes ] = None ,
77
82
cert = None ,
78
- reference_uri = None ,
79
- key_name = None ,
80
- key_info = None ,
81
- id_attribute = None ,
82
- always_add_key_value = False ,
83
- payload_inclusive_ns_prefixes = frozenset () ,
84
- signature_inclusive_ns_prefixes = frozenset () ,
83
+ reference_uri : Optional [ Union [ str , List [ str ]]] = None ,
84
+ key_name : Optional [ str ] = None ,
85
+ key_info : Optional [ _Element ] = None ,
86
+ id_attribute : Optional [ str ] = None ,
87
+ always_add_key_value : bool = False ,
88
+ payload_inclusive_ns_prefixes : Optional [ List [ str ]] = None ,
89
+ signature_inclusive_ns_prefixes : Optional [ List [ str ]] = None ,
85
90
signature_properties = None ,
86
91
):
87
92
"""
@@ -100,7 +105,6 @@ def sign(
100
105
:py:class:`cryptography.hazmat.primitives.interfaces.DSAPrivateKey`, or
101
106
:py:class:`cryptography.hazmat.primitives.interfaces.EllipticCurvePrivateKey` object
102
107
:param passphrase: Passphrase to use to decrypt the key, if any.
103
- :type passphrase: string
104
108
:param cert:
105
109
X.509 certificate to use for signing. This should be a string containing a PEM-formatted certificate, or an
106
110
array of strings or OpenSSL.crypto.X509 objects containing the certificate and a chain of intermediate
@@ -110,30 +114,24 @@ def sign(
110
114
Custom reference URI or list of reference URIs to incorporate into the signature. When ``method`` is set to
111
115
``detached`` or ``enveloped``, reference URIs are set to this value and only the referenced elements are
112
116
signed.
113
- :type reference_uri: string or list
114
117
:param key_name: Add a KeyName element in the KeyInfo element that may be used by the signer to communicate a
115
118
key identifier to the recipient. Typically, KeyName contains an identifier related to the key pair used to
116
119
sign the message.
117
- :type key_name: string
118
120
:param key_info:
119
121
A custom KeyInfo element to insert in the signature. Use this to supply ``<wsse:SecurityTokenReference>``
120
122
or other custom key references. An example value can be found here:
121
123
https://github.com/XML-Security/signxml/blob/master/test/wsse_keyinfo.xml
122
- :type key_info: :py:class:`lxml.etree.Element`
123
124
:param id_attribute:
124
125
Name of the attribute whose value ``URI`` refers to. By default, SignXML will search for "Id", then "ID".
125
- :type id_attribute: string
126
126
:param always_add_key_value:
127
127
Write the key value to the KeyInfo element even if a X509 certificate is present. Use of this parameter
128
128
is discouraged, as it introduces an ambiguity and a security hazard. The public key used to sign the
129
129
document is already encoded in the certificate (which is in X509Data), so the verifier must either ignore
130
130
KeyValue or make sure it matches what's in the certificate. This parameter is provided for compatibility
131
131
purposes only.
132
- :type always_add_key_value: boolean
133
132
:param payload_inclusive_ns_prefixes:
134
133
Provide a list of XML namespace prefixes whose declarations should be preserved when canonicalizing the
135
134
content referenced by the signature (**InclusiveNamespaces PrefixList**).
136
- :type inclusive_ns_prefixes: list
137
135
:param signature_inclusive_ns_prefixes:
138
136
Provide a list of XML namespace prefixes whose declarations should be preserved when canonicalizing the
139
137
signature itself (**InclusiveNamespaces PrefixList**).
@@ -161,9 +159,9 @@ def sign(
161
159
cert_chain = cert
162
160
163
161
if isinstance (reference_uri , (str , bytes )):
164
- reference_uris = [reference_uri ]
162
+ input_reference_uris = [reference_uri ]
165
163
else :
166
- reference_uris = reference_uri
164
+ input_reference_uris = reference_uri # type: ignore
167
165
168
166
signing_settings = SigningSettings (
169
167
key = None ,
@@ -181,7 +179,7 @@ def sign(
181
179
else :
182
180
signing_settings .key = key
183
181
184
- sig_root , doc_root , c14n_inputs , reference_uris = self ._unpack (data , reference_uris )
182
+ sig_root , doc_root , c14n_inputs , reference_uris = self ._unpack (data , input_reference_uris )
185
183
186
184
if self .signature_type == SignatureType .detached and signature_properties is not None :
187
185
reference_uris .append ("#prop" )
@@ -324,7 +322,7 @@ def _unpack(self, data, reference_uris):
324
322
325
323
def _build_sig (self , sig_root , reference_uris , c14n_inputs , sig_insp , payload_insp ):
326
324
signed_info = SubElement (sig_root , ds_tag ("SignedInfo" ), nsmap = self .namespaces )
327
- sig_c14n_method = SubElement (signed_info , ds_tag ("CanonicalizationMethod" ), Algorithm = self .c14n_alg )
325
+ sig_c14n_method = SubElement (signed_info , ds_tag ("CanonicalizationMethod" ), Algorithm = self .c14n_alg . value )
328
326
if sig_insp :
329
327
SubElement (sig_c14n_method , ec_tag ("InclusiveNamespaces" ), PrefixList = " " .join (sig_insp ))
330
328
@@ -334,9 +332,9 @@ def _build_sig(self, sig_root, reference_uris, c14n_inputs, sig_insp, payload_in
334
332
transforms = SubElement (reference , ds_tag ("Transforms" ))
335
333
if self .signature_type == SignatureType .enveloped :
336
334
SubElement (transforms , ds_tag ("Transform" ), Algorithm = namespaces .ds + "enveloped-signature" )
337
- SubElement (transforms , ds_tag ("Transform" ), Algorithm = self .c14n_alg )
335
+ SubElement (transforms , ds_tag ("Transform" ), Algorithm = self .c14n_alg . value )
338
336
else :
339
- c14n_xform = SubElement (transforms , ds_tag ("Transform" ), Algorithm = self .c14n_alg )
337
+ c14n_xform = SubElement (transforms , ds_tag ("Transform" ), Algorithm = self .c14n_alg . value )
340
338
if payload_insp :
341
339
SubElement (c14n_xform , ec_tag ("InclusiveNamespaces" ), PrefixList = " " .join (payload_insp ))
342
340
@@ -356,8 +354,8 @@ def _build_signature_properties(self, signature_properties):
356
354
signature_property = Element (
357
355
ds_tag ("SignatureProperty" ),
358
356
attrib = {
359
- "Id" : el .attrib .pop ("Id" , "sigprop{}" . format ( i ) ),
360
- "Target" : el .attrib .pop ("Target" , "#sigproptarget{}" . format ( i ) ),
357
+ "Id" : el .attrib .pop ("Id" , f "sigprop{ i } " ),
358
+ "Target" : el .attrib .pop ("Target" , f "#sigproptarget{ i } " ),
361
359
},
362
360
)
363
361
signature_property .append (el )
0 commit comments