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 ):
@@ -80,7 +81,7 @@ def check_xmlsec_import():
80
81
)
81
82
82
83
83
- def sign_envelope (envelope , keyfile , certfile , password = None ):
84
+ def sign_envelope (envelope , keyfile , certfile , password = None , signatures = None ):
84
85
"""Sign given SOAP envelope with WSSE sig using given key and cert.
85
86
86
87
Sign the wsu:Timestamp node in the wsse:Security header and the soap:Body;
@@ -170,10 +171,10 @@ def sign_envelope(envelope, keyfile, certfile, password=None):
170
171
"""
171
172
# Load the signing key and certificate.
172
173
key = _make_sign_key (_read_file (keyfile ), _read_file (certfile ), password )
173
- return _sign_envelope_with_key (envelope , key )
174
+ return _sign_envelope_with_key (envelope , key , signatures )
174
175
175
176
176
- def _sign_envelope_with_key (envelope , key ):
177
+ def _sign_envelope_with_key (envelope , key , signatures = None ):
177
178
soap_env = detect_soap_env (envelope )
178
179
179
180
# Create the Signature node.
@@ -198,8 +199,20 @@ def _sign_envelope_with_key(envelope, key):
198
199
# Perform the actual signing.
199
200
ctx = xmlsec .SignatureContext ()
200
201
ctx .key = key
201
- _sign_node ( ctx , signature , envelope . find ( QName ( soap_env , 'Body' )))
202
+ # Sign default elements
202
203
_sign_node (ctx , signature , security .find (QName (ns .WSU , 'Timestamp' )))
204
+
205
+ # Sign extra elements defined in WSDL
206
+ if signatures is not None :
207
+ if signatures ['body' ] or signatures ['everything' ]:
208
+ _sign_node (ctx , signature , envelope .find (QName (soap_env , 'Body' )))
209
+ header = get_or_create_header (envelope )
210
+ if signatures ['everything' ]:
211
+ for node in header .iterchildren ():
212
+ _sign_node (ctx , signature , node )
213
+ else :
214
+ for node in signatures ['header' ]:
215
+ _sign_node (ctx , signature , header .find (QName (node ['Namespace' ], node ['Name' ])))
203
216
ctx .sign (signature )
204
217
205
218
# Place the X509 data inside a WSSE SecurityTokenReference within
0 commit comments