1414from zeep import ns
1515from zeep .exceptions import SignatureVerificationFailed
1616from zeep .utils import detect_soap_env
17+ from zeep .wsdl .utils import get_or_create_header
1718from zeep .wsse .utils import ensure_id , get_security_header
1819
1920try :
@@ -52,9 +53,9 @@ def __init__(self, key_data, cert_data, password=None):
5253 self .cert_data = cert_data
5354 self .password = password
5455
55- def apply (self , envelope , headers ):
56+ def apply (self , envelope , headers , signatures = None ):
5657 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 )
5859 return envelope , headers
5960
6061 def verify (self , envelope ):
@@ -76,9 +77,9 @@ class BinarySignature(Signature):
7677
7778 Place the key information into BinarySecurityElement."""
7879
79- def apply (self , envelope , headers ):
80+ def apply (self , envelope , headers , signatures = None ):
8081 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 )
8283 return envelope , headers
8384
8485
@@ -91,7 +92,7 @@ def check_xmlsec_import():
9192 )
9293
9394
94- def sign_envelope (envelope , keyfile , certfile , password = None ):
95+ def sign_envelope (envelope , keyfile , certfile , password = None , signatures = None ):
9596 """Sign given SOAP envelope with WSSE sig using given key and cert.
9697
9798 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):
181182 """
182183 # Load the signing key and certificate.
183184 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 )
185186
186187
187- def _signature_prepare (envelope , key ):
188+ def _signature_prepare (envelope , key , signatures = None ):
188189 """Prepare envelope and sign."""
189190 soap_env = detect_soap_env (envelope )
190191
@@ -210,8 +211,20 @@ def _signature_prepare(envelope, key):
210211 # Perform the actual signing.
211212 ctx = xmlsec .SignatureContext ()
212213 ctx .key = key
213- _sign_node ( ctx , signature , envelope . find ( QName ( soap_env , 'Body' )))
214+ # Sign default elements
214215 _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' ])))
215228 ctx .sign (signature )
216229
217230 # Place the X509 data inside a WSSE SecurityTokenReference within
@@ -223,13 +236,13 @@ def _signature_prepare(envelope, key):
223236 return security , sec_token_ref , x509_data
224237
225238
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 )
228241 sec_token_ref .append (x509_data )
229242
230243
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 )
233246 ref = etree .SubElement (sec_token_ref , QName (ns .WSSE , 'Reference' ),
234247 {'ValueType' : 'http://docs.oasis-open.org/wss/2004/01/'
235248 'oasis-200401-wss-x509-token-profile-1.0#X509v3' })
0 commit comments