1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
from datetime import datetime
from unittest.mock import Mock
from unittest.mock import patch
from saml2.config import config_factory
from saml2.response import authn_response
from saml2.sigver import SignatureError
from dateutil import parser
from pytest import raises
from pathutils import dotname
from pathutils import full_path
SIGNED_XSW_ASSERTION_WRAPPER = full_path("xsw/signed-xsw-assertion-wrapper.xml")
SIGNED_XSW_ASSERTION_EXTENSIONS = full_path("xsw/signed-xsw-assertion-extensions.xml")
SIGNED_XSW_ASSERTION_ASSERTION = full_path("xsw/signed-xsw-assertion-assertion.xml")
SIGNED_ASSERTION_FIRST_SIG = full_path("xsw/signed-xsw-assertion-in-assertion-first-sig.xml")
SIGNED_REPONSE_FIRST_SIG = full_path("xsw/signed-xsw-response-in-response-first-sig.xml")
class TestXSW:
def setup_class(self):
self.conf = config_factory("sp", dotname("server_conf"))
self.ar = authn_response(self.conf, return_addrs="https://example.org/acs/post")
@patch('saml2.response.validate_on_or_after', return_value=True)
def test_signed_xsw_assertion_wrapper_should_fail(self, mock_validate_on_or_after):
self.ar.issue_instant_ok = Mock(return_value=True)
with open(SIGNED_XSW_ASSERTION_WRAPPER) as fp:
xml_response = fp.read()
self.ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"}
self.ar.timeslack = 10000
self.ar.loads(xml_response, decode=False)
assert self.ar.came_from == 'http://localhost:8088/sso'
assert self.ar.session_id() == "id-abc"
assert self.ar.issuer() == 'urn:mace:example.com:saml:roland:idp'
with raises(SignatureError):
self.ar.verify()
assert self.ar.ava is None
assert self.ar.name_id is None
@patch('saml2.response.validate_on_or_after', return_value=True)
def test_signed_xsw_assertion_extensions_should_fail(self, mock_validate_on_or_after):
self.ar.issue_instant_ok = Mock(return_value=True)
with open(SIGNED_XSW_ASSERTION_EXTENSIONS) as fp:
xml_response = fp.read()
self.ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"}
self.ar.timeslack = 10000
self.ar.loads(xml_response, decode=False)
assert self.ar.came_from == 'http://localhost:8088/sso'
assert self.ar.session_id() == "id-abc"
assert self.ar.issuer() == 'urn:mace:example.com:saml:roland:idp'
with raises(SignatureError):
self.ar.verify()
assert self.ar.ava is None
assert self.ar.name_id is None
@patch('saml2.response.validate_on_or_after', return_value=True)
def test_signed_xsw_assertion_assertion_should_fail(self, mock_validate_on_or_after):
self.ar.issue_instant_ok = Mock(return_value=True)
with open(SIGNED_XSW_ASSERTION_ASSERTION) as fp:
xml_response = fp.read()
self.ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"}
self.ar.timeslack = 10000
self.ar.loads(xml_response, decode=False)
assert self.ar.came_from == 'http://localhost:8088/sso'
assert self.ar.session_id() == "id-abc"
assert self.ar.issuer() == 'urn:mace:example.com:saml:roland:idp'
with raises(SignatureError):
self.ar.verify()
assert self.ar.ava is None
assert self.ar.name_id is None
class TestInvalidDepthFirstSig:
def setup_class(self):
self.conf = config_factory("sp", dotname("server_conf"))
self.ar = authn_response(self.conf, return_addrs="https://example.org/acs/post")
@patch('saml2.response.validate_on_or_after', return_value=True)
def test_signed_assertion_first_sig_should_fail(self, mock_validate_on_or_after):
self.ar.issue_instant_ok = Mock(return_value=True)
with open(SIGNED_ASSERTION_FIRST_SIG) as fp:
xml_response = fp.read()
self.ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"}
self.ar.timeslack = 10000
self.ar.loads(xml_response, decode=False)
assert self.ar.came_from == 'http://localhost:8088/sso'
assert self.ar.session_id() == "id-abc"
assert self.ar.issuer() == 'urn:mace:example.com:saml:roland:idp'
with raises(SignatureError):
self.ar.verify()
assert self.ar.ava is None
assert self.ar.name_id is None
@patch('saml2.response.validate_on_or_after', return_value=True)
def test_signed_response_first_sig_should_fail(self, mock_validate_on_or_after):
self.ar.issue_instant_ok = Mock(return_value=True)
with open(SIGNED_REPONSE_FIRST_SIG) as fp:
xml_response = fp.read()
self.ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"}
self.ar.timeslack = 10000
with raises(SignatureError):
self.ar.loads(xml_response, decode=False)
|