14
14
from zeep import ns
15
15
from zeep .exceptions import SignatureVerificationFailed
16
16
from zeep .utils import detect_soap_env
17
+ from zeep .wsdl .utils import get_or_create_header
17
18
from zeep .wsse .utils import ensure_id , get_security_header
18
19
19
20
try :
@@ -52,9 +53,9 @@ def __init__(self, key_data, cert_data, password=None):
52
53
self .cert_data = cert_data
53
54
self .password = password
54
55
55
- def apply (self , envelope , headers ):
56
+ def apply (self , envelope , headers , signatures = None ):
56
57
key = _make_sign_key (self .key_data , self .cert_data , self .password )
57
- _sign_envelope_with_key (envelope , key )
58
+ _sign_envelope_with_key (envelope , key , signatures )
58
59
return envelope , headers
59
60
60
61
def verify (self , envelope ):
@@ -76,9 +77,9 @@ class BinarySignature(Signature):
76
77
77
78
Place the key information into BinarySecurityElement."""
78
79
79
- def apply (self , envelope , headers ):
80
+ def apply (self , envelope , headers , signatures = None ):
80
81
key = _make_sign_key (self .key_data , self .cert_data , self .password )
81
- _sign_envelope_with_key_binary (envelope , key )
82
+ _sign_envelope_with_key_binary (envelope , key , signatures )
82
83
return envelope , headers
83
84
84
85
@@ -91,7 +92,7 @@ def check_xmlsec_import():
91
92
)
92
93
93
94
94
- def sign_envelope (envelope , keyfile , certfile , password = None ):
95
+ def sign_envelope (envelope , keyfile , certfile , password = None , signatures = None ):
95
96
"""Sign given SOAP envelope with WSSE sig using given key and cert.
96
97
97
98
Sign the wsu:Timestamp node in the wsse:Security header and the soap:Body;
@@ -181,10 +182,10 @@ def sign_envelope(envelope, keyfile, certfile, password=None):
181
182
"""
182
183
# Load the signing key and certificate.
183
184
key = _make_sign_key (_read_file (keyfile ), _read_file (certfile ), password )
184
- return _sign_envelope_with_key (envelope , key )
185
+ return _sign_envelope_with_key (envelope , key , signatures )
185
186
186
187
187
- def _signature_prepare (envelope , key ):
188
+ def _signature_prepare (envelope , key , signatures = None ):
188
189
"""Prepare envelope and sign."""
189
190
soap_env = detect_soap_env (envelope )
190
191
@@ -210,8 +211,20 @@ def _signature_prepare(envelope, key):
210
211
# Perform the actual signing.
211
212
ctx = xmlsec .SignatureContext ()
212
213
ctx .key = key
213
- _sign_node ( ctx , signature , envelope . find ( QName ( soap_env , 'Body' )))
214
+ # Sign default elements
214
215
_sign_node (ctx , signature , security .find (QName (ns .WSU , 'Timestamp' )))
216
+
217
+ # Sign extra elements defined in WSDL
218
+ if signatures is not None :
219
+ if signatures ['body' ] or signatures ['everything' ]:
220
+ _sign_node (ctx , signature , envelope .find (QName (soap_env , 'Body' )))
221
+ header = get_or_create_header (envelope )
222
+ if signatures ['everything' ]:
223
+ for node in header .iterchildren ():
224
+ _sign_node (ctx , signature , node )
225
+ else :
226
+ for node in signatures ['header' ]:
227
+ _sign_node (ctx , signature , header .find (QName (node ['Namespace' ], node ['Name' ])))
215
228
ctx .sign (signature )
216
229
217
230
# Place the X509 data inside a WSSE SecurityTokenReference within
@@ -223,13 +236,13 @@ def _signature_prepare(envelope, key):
223
236
return security , sec_token_ref , x509_data
224
237
225
238
226
- def _sign_envelope_with_key (envelope , key ):
227
- _ , sec_token_ref , x509_data = _signature_prepare (envelope , key )
239
+ def _sign_envelope_with_key (envelope , key , signatures = None ):
240
+ _ , sec_token_ref , x509_data = _signature_prepare (envelope , key , signatures = signatures )
228
241
sec_token_ref .append (x509_data )
229
242
230
243
231
- def _sign_envelope_with_key_binary (envelope , key ):
232
- security , sec_token_ref , x509_data = _signature_prepare (envelope , key )
244
+ def _sign_envelope_with_key_binary (envelope , key , signatures = None ):
245
+ security , sec_token_ref , x509_data = _signature_prepare (envelope , key , signatures = signatures )
233
246
ref = etree .SubElement (sec_token_ref , QName (ns .WSSE , 'Reference' ),
234
247
{'ValueType' : 'http://docs.oasis-open.org/wss/2004/01/'
235
248
'oasis-200401-wss-x509-token-profile-1.0#X509v3' })
0 commit comments