Skip to content

Commit 84973ab

Browse files
committed
Omitt WSSE header elements from signature
1 parent c99354e commit 84973ab

File tree

2 files changed

+126
-2
lines changed

2 files changed

+126
-2
lines changed

src/zeep/wsse/signature.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
# SOAP envelope
2727
SOAP_NS = "http://schemas.xmlsoap.org/soap/envelope/"
28+
# Namespaces omitted from signing
29+
OMITTED_HEADERS = [ns.WSSE]
2830

2931

3032
def _read_file(f_name):
@@ -259,7 +261,9 @@ def _signature_prepare(envelope, key, signature_method, digest_method, signature
259261
header = get_or_create_header(envelope)
260262
if signatures["everything"]:
261263
for node in header.iterchildren():
262-
_sign_node(ctx, signature, node, digest_method)
264+
# Everything doesn't mean everything ...
265+
if node.nsmap.get(node.prefix) not in OMITTED_HEADERS:
266+
_sign_node(ctx, signature, node, digest_method)
263267
else:
264268
for node in signatures["header"]:
265269
_sign_node(

tests/test_wsse_signature.py

+121-1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,124 @@ def test_sign(
114114
assert sig.get("Algorithm") == expected_signature_href
115115

116116

117+
@skip_if_no_xmlsec
118+
@pytest.mark.parametrize("digest_method,expected_digest_href", DIGEST_METHODS_TESTDATA)
119+
@pytest.mark.parametrize(
120+
"signature_method,expected_signature_href", SIGNATURE_METHODS_TESTDATA
121+
)
122+
def test_sign_element(
123+
digest_method, signature_method, expected_digest_href, expected_signature_href
124+
):
125+
envelope = load_xml(
126+
"""
127+
<soapenv:Envelope
128+
xmlns:tns="http://tests.python-zeep.org/"
129+
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
130+
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
131+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
132+
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
133+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
134+
<soapenv:Header>
135+
<wsse:Security mustUnderstand="true">
136+
<wsu:Timestamp>
137+
<wsu:Created>2015-06-25T21:53:25.246276+00:00</wsu:Created>
138+
<wsu:Expires>2015-06-25T21:58:25.246276+00:00</wsu:Expires>
139+
</wsu:Timestamp>
140+
</wsse:Security>
141+
<tns:Some>OK</tns:Some>
142+
</soapenv:Header>
143+
<soapenv:Body>
144+
<tns:Function>
145+
<tns:Argument>OK</tns:Argument>
146+
</tns:Function>
147+
</soapenv:Body>
148+
</soapenv:Envelope>
149+
"""
150+
)
151+
152+
# Force header element and body signature
153+
signatures = {
154+
"everything": False,
155+
"body": True,
156+
"header": [{"Namespace": "http://tests.python-zeep.org/", "Name": "Some"}],
157+
}
158+
signature.sign_envelope(
159+
envelope,
160+
KEY_FILE,
161+
KEY_FILE,
162+
signature_method=getattr(xmlsec_installed.Transform, signature_method),
163+
digest_method=getattr(xmlsec_installed.Transform, digest_method),
164+
signatures=signatures,
165+
)
166+
signature.verify_envelope(envelope, KEY_FILE)
167+
168+
digests = envelope.xpath("//ds:DigestMethod", namespaces={"ds": ns.DS})
169+
assert len(digests)
170+
for digest in digests:
171+
assert digest.get("Algorithm") == expected_digest_href
172+
signatures = envelope.xpath("//ds:SignatureMethod", namespaces={"ds": ns.DS})
173+
assert len(signatures)
174+
for sig in signatures:
175+
assert sig.get("Algorithm") == expected_signature_href
176+
177+
178+
@skip_if_no_xmlsec
179+
@pytest.mark.parametrize("digest_method,expected_digest_href", DIGEST_METHODS_TESTDATA)
180+
@pytest.mark.parametrize(
181+
"signature_method,expected_signature_href", SIGNATURE_METHODS_TESTDATA
182+
)
183+
def test_sign_everything(
184+
digest_method, signature_method, expected_digest_href, expected_signature_href
185+
):
186+
envelope = load_xml(
187+
"""
188+
<soapenv:Envelope
189+
xmlns:tns="http://tests.python-zeep.org/"
190+
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
191+
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
192+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
193+
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
194+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
195+
<soapenv:Header>
196+
<wsse:Security mustUnderstand="true">
197+
<wsu:Timestamp>
198+
<wsu:Created>2015-06-25T21:53:25.246276+00:00</wsu:Created>
199+
<wsu:Expires>2015-06-25T21:58:25.246276+00:00</wsu:Expires>
200+
</wsu:Timestamp>
201+
</wsse:Security>
202+
<tns:Some>OK</tns:Some>
203+
</soapenv:Header>
204+
<soapenv:Body>
205+
<tns:Function>
206+
<tns:Argument>OK</tns:Argument>
207+
</tns:Function>
208+
</soapenv:Body>
209+
</soapenv:Envelope>
210+
"""
211+
)
212+
213+
# Force header element and body signature
214+
signatures = {"everything": True, "body": True, "header": []}
215+
signature.sign_envelope(
216+
envelope,
217+
KEY_FILE,
218+
KEY_FILE,
219+
signature_method=getattr(xmlsec_installed.Transform, signature_method),
220+
digest_method=getattr(xmlsec_installed.Transform, digest_method),
221+
signatures=signatures,
222+
)
223+
signature.verify_envelope(envelope, KEY_FILE)
224+
225+
digests = envelope.xpath("//ds:DigestMethod", namespaces={"ds": ns.DS})
226+
assert len(digests)
227+
for digest in digests:
228+
assert digest.get("Algorithm") == expected_digest_href
229+
signatures = envelope.xpath("//ds:SignatureMethod", namespaces={"ds": ns.DS})
230+
assert len(signatures)
231+
for sig in signatures:
232+
assert sig.get("Algorithm") == expected_signature_href
233+
234+
117235
@skip_if_no_xmlsec
118236
def test_sign_pw():
119237
envelope = load_xml(
@@ -135,7 +253,9 @@ def test_sign_pw():
135253

136254
# Force body signature
137255
signatures = {"everything": False, "body": True, "header": []}
138-
signature.sign_envelope(envelope, KEY_FILE_PW, KEY_FILE_PW, "geheim", signatures=signatures)
256+
signature.sign_envelope(
257+
envelope, KEY_FILE_PW, KEY_FILE_PW, "geheim", signatures=signatures
258+
)
139259
signature.verify_envelope(envelope, KEY_FILE_PW)
140260

141261

0 commit comments

Comments
 (0)