diff options
Diffstat (limited to 'tests/test_40_sigver.py')
-rw-r--r-- | tests/test_40_sigver.py | 424 |
1 files changed, 424 insertions, 0 deletions
diff --git a/tests/test_40_sigver.py b/tests/test_40_sigver.py index f975b5ea..ba5cf639 100644 --- a/tests/test_40_sigver.py +++ b/tests/test_40_sigver.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- import base64 from saml2.xmldsig import SIG_RSA_SHA256 @@ -420,6 +421,300 @@ class TestSecurity(): s_response, response2, class_name(response2)) +class TestSecurityNonAsciiAva(): + def setup_class(self): + # This would be one way to initialize the security context : + # + # conf = config.SPConfig() + # conf.load_file("server_conf") + # conf.only_use_keys_in_metadata = False + # + # but instead, FakeConfig() is used to really only use the minimal + # set of parameters needed for these test cases. Other test cases + # (TestSecurityMetadata below) excersise the SPConfig() mechanism. + # + conf = FakeConfig() + self.sec = sigver.security_context(conf) + + self._assertion = factory( + saml.Assertion, + version="2.0", + id="11111", + issue_instant="2009-10-30T13:20:28Z", + signature=sigver.pre_signature_part("11111", self.sec.my_cert, 1), + attribute_statement=do_attribute_statement({ + ("", "", "surName"): ("Föö", ""), + ("", "", "givenName"): ("Bär", ""), + }) + ) + + def test_verify_1(self): + with open(SIGNED) as fp: + xml_response = fp.read() + response = self.sec.correctly_signed_response(xml_response) + assert response + + def test_non_verify_1(self): + """ unsigned is OK """ + with open(UNSIGNED) as fp: + xml_response = fp.read() + response = self.sec.correctly_signed_response(xml_response) + assert response + + def test_sign_assertion(self): + ass = self._assertion + print(ass) + sign_ass = self.sec.sign_assertion("%s" % ass, node_id=ass.id) + #print(sign_ass) + sass = saml.assertion_from_string(sign_ass) + #print(sass) + assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant', + 'version', 'signature', 'id']) + assert sass.version == "2.0" + assert sass.id == "11111" + assert time_util.str_to_time(sass.issue_instant) + + print("Crypto version : %s" % (self.sec.crypto.version())) + + item = self.sec.check_signature(sass, class_name(sass), sign_ass) + + assert isinstance(item, saml.Assertion) + + def test_multiple_signatures_assertion(self): + ass = self._assertion + # basic test with two of the same + to_sign = [(ass, ass.id, ''), + (ass, ass.id, '') + ] + sign_ass = self.sec.multiple_signatures("%s" % ass, to_sign) + sass = saml.assertion_from_string(sign_ass) + assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant', + 'version', 'signature', 'id']) + assert sass.version == "2.0" + assert sass.id == "11111" + assert time_util.str_to_time(sass.issue_instant) + + print("Crypto version : %s" % (self.sec.crypto.version())) + + item = self.sec.check_signature(sass, class_name(sass), + sign_ass, must=True) + + assert isinstance(item, saml.Assertion) + + def test_multiple_signatures_response(self): + response = factory(samlp.Response, + assertion=self._assertion, + id="22222", + signature=sigver.pre_signature_part( + "22222", self.sec.my_cert)) + + # order is important, we can't validate if the signatures are made + # in the reverse order + to_sign = [(self._assertion, self._assertion.id, ''), + (response, response.id, '')] + + s_response = self.sec.multiple_signatures("%s" % response, to_sign) + assert s_response is not None + response = response_from_string(s_response) + + item = self.sec.check_signature(response, class_name(response), + s_response, must=True) + assert item == response + assert item.id == "22222" + + s_assertion = item.assertion[0] + assert isinstance(s_assertion, saml.Assertion) + # make sure the assertion was modified when we supposedly signed it + assert s_assertion != self._assertion + + ci = "".join(sigver.cert_from_instance(s_assertion)[0].split()) + assert ci == self.sec.my_cert + + res = self.sec.check_signature(s_assertion, class_name(s_assertion), + s_response, must=True) + assert res == s_assertion + assert s_assertion.id == "11111" + assert s_assertion.version == "2.0" + assert _eq(s_assertion.keyswv(), ['attribute_statement', + 'issue_instant', + 'version', 'signature', 'id']) + + def test_sign_response(self): + response = factory(samlp.Response, + assertion=self._assertion, + id="22222", + signature=sigver.pre_signature_part("22222", + self.sec + .my_cert)) + + to_sign = [(class_name(self._assertion), self._assertion.id), + (class_name(response), response.id)] + s_response = sigver.signed_instance_factory(response, self.sec, to_sign) + + assert s_response is not None + print(s_response) + response = response_from_string(s_response) + sass = response.assertion[0] + + print(sass) + assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant', + 'version', 'signature', 'id']) + assert sass.version == "2.0" + assert sass.id == "11111" + + item = self.sec.check_signature(response, class_name(response), + s_response) + assert isinstance(item, samlp.Response) + assert item.id == "22222" + + def test_sign_response_2(self): + assertion2 = factory(saml.Assertion, + version="2.0", + id="11122", + issue_instant="2009-10-30T13:20:28Z", + signature=sigver.pre_signature_part("11122", + self.sec + .my_cert), + attribute_statement=do_attribute_statement({ + ("", "", "surName"): ("Räv", ""), + ("", "", "givenName"): ("Björn", ""), + }) + ) + response = factory(samlp.Response, + assertion=assertion2, + id="22233", + signature=sigver.pre_signature_part("22233", + self.sec + .my_cert)) + + to_sign = [(class_name(assertion2), assertion2.id), + (class_name(response), response.id)] + + s_response = sigver.signed_instance_factory(response, self.sec, to_sign) + + assert s_response is not None + response2 = response_from_string(s_response) + + sass = response2.assertion[0] + assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant', + 'version', 'signature', 'id']) + assert sass.version == "2.0" + assert sass.id == "11122" + + item = self.sec.check_signature(response2, class_name(response), + s_response) + + assert isinstance(item, samlp.Response) + + def test_sign_verify(self): + response = factory(samlp.Response, + assertion=self._assertion, + id="22233", + signature=sigver.pre_signature_part("22233", + self.sec + .my_cert)) + + to_sign = [(class_name(self._assertion), self._assertion.id), + (class_name(response), response.id)] + + s_response = sigver.signed_instance_factory(response, self.sec, + to_sign) + + print(s_response) + res = self.sec.verify_signature(s_response, + node_name=class_name(samlp.Response())) + + print(res) + assert res + + def test_sign_verify_with_cert_from_instance(self): + response = factory(samlp.Response, + assertion=self._assertion, + id="22222", + signature=sigver.pre_signature_part("22222", + self.sec + .my_cert)) + + to_sign = [(class_name(self._assertion), self._assertion.id), + (class_name(response), response.id)] + + s_response = sigver.signed_instance_factory(response, self.sec, to_sign) + + response2 = response_from_string(s_response) + + ci = "".join(sigver.cert_from_instance(response2)[0].split()) + + assert ci == self.sec.my_cert + + res = self.sec.verify_signature(s_response, + node_name=class_name(samlp.Response())) + + assert res + + res = self.sec._check_signature(s_response, response2, + class_name(response2), s_response) + assert res == response2 + + def test_sign_verify_assertion_with_cert_from_instance(self): + assertion = factory(saml.Assertion, + version="2.0", + id="11100", + issue_instant="2009-10-30T13:20:28Z", + signature=sigver.pre_signature_part("11100", + self.sec + .my_cert), + attribute_statement=do_attribute_statement({ + ("", "", "surName"): ("Räv", ""), + ("", "", "givenName"): ("Björn", ""), + }) + ) + + to_sign = [(class_name(assertion), assertion.id)] + s_assertion = sigver.signed_instance_factory(assertion, self.sec, + to_sign) + print(s_assertion) + ass = assertion_from_string(s_assertion) + ci = "".join(sigver.cert_from_instance(ass)[0].split()) + assert ci == self.sec.my_cert + + res = self.sec.verify_signature(s_assertion, + node_name=class_name(ass)) + assert res + + res = self.sec._check_signature(s_assertion, ass, class_name(ass)) + + assert res + + def test_exception_sign_verify_with_cert_from_instance(self): + assertion = factory(saml.Assertion, + version="2.0", + id="11100", + issue_instant="2009-10-30T13:20:28Z", + #signature= sigver.pre_signature_part("11100", + # self.sec.my_cert), + attribute_statement=do_attribute_statement({ + ("", "", "surName"): ("Föö", ""), + ("", "", "givenName"): ("Bär", ""), + }) + ) + + response = factory(samlp.Response, + assertion=assertion, + id="22222", + signature=sigver.pre_signature_part("22222", + self.sec + .my_cert)) + + to_sign = [(class_name(response), response.id)] + + s_response = sigver.signed_instance_factory(response, self.sec, to_sign) + + response2 = response_from_string(s_response) + # Change something that should make everything fail + response2.id = "23456" + raises(sigver.SignatureError, self.sec._check_signature, + s_response, response2, class_name(response2)) + class TestSecurityMetadata(): def setup_class(self): @@ -442,6 +737,27 @@ class TestSecurityMetadata(): ) +class TestSecurityMetadataNonAsciiAva(): + def setup_class(self): + conf = config.SPConfig() + conf.load_file("server_conf") + md = MetadataStore([saml, samlp], None, conf) + md.load("local", full_path("metadata_cert.xml")) + + conf.metadata = md + conf.only_use_keys_in_metadata = False + self.sec = sigver.security_context(conf) + + assertion = factory( + saml.Assertion, version="2.0", id="11111", + issue_instant="2009-10-30T13:20:28Z", + signature=sigver.pre_signature_part("11111", self.sec.my_cert, 1), + attribute_statement=do_attribute_statement( + {("", "", "surName"): ("Föö", ""), + ("", "", "givenName"): ("Bär", ""), }) + ) + + def test_xbox(): conf = config.SPConfig() conf.load_file("server_conf") @@ -495,6 +811,59 @@ def test_xbox(): print(assertions) +def test_xbox_non_ascii_ava(): + conf = config.SPConfig() + conf.load_file("server_conf") + md = MetadataStore([saml, samlp], None, conf) + md.load("local", full_path("idp_example.xml")) + + conf.metadata = md + conf.only_use_keys_in_metadata = False + sec = sigver.security_context(conf) + + assertion = factory( + saml.Assertion, version="2.0", id="11111", + issue_instant="2009-10-30T13:20:28Z", + signature=sigver.pre_signature_part("11111", sec.my_cert, 1), + attribute_statement=do_attribute_statement( + {("", "", "surName"): ("Föö", ""), + ("", "", "givenName"): ("Bär", ""), }) + ) + + sigass = sec.sign_statement(assertion, class_name(assertion), + key_file=full_path("test.key"), + node_id=assertion.id) + + _ass0 = saml.assertion_from_string(sigass) + + encrypted_assertion = EncryptedAssertion() + encrypted_assertion.add_extension_element(_ass0) + + _, pre = make_temp(str(pre_encryption_part()).encode('utf-8'), decode=False) + enctext = sec.crypto.encrypt( + str(encrypted_assertion), conf.cert_file, pre, "des-192", + '/*[local-name()="EncryptedAssertion"]/*[local-name()="Assertion"]') + + decr_text = sec.decrypt(enctext) + _seass = saml.encrypted_assertion_from_string(decr_text) + assertions = [] + assers = extension_elements_to_elements(_seass.extension_elements, + [saml, samlp]) + + sign_cert_file = full_path("test.pem") + + for ass in assers: + _ass = "%s" % ass + #_ass = _ass.replace('xsi:nil="true" ', '') + #assert sigass == _ass + _txt = sec.verify_signature(_ass, sign_cert_file, + node_name=class_name(assertion)) + if _txt: + assertions.append(ass) + + print(assertions) + + def test_okta(): conf = config.Config() conf.load_file("server_conf") @@ -548,6 +917,35 @@ def test_xmlsec_err(): assert False +def test_xmlsec_err_non_ascii_ava(): + conf = config.SPConfig() + conf.load_file("server_conf") + md = MetadataStore([saml, samlp], None, conf) + md.load("local", full_path("idp_example.xml")) + + conf.metadata = md + conf.only_use_keys_in_metadata = False + sec = sigver.security_context(conf) + + assertion = factory( + saml.Assertion, version="2.0", id="11111", + issue_instant="2009-10-30T13:20:28Z", + signature=sigver.pre_signature_part("11111", sec.my_cert, 1), + attribute_statement=do_attribute_statement( + {("", "", "surName"): ("Föö", ""), + ("", "", "givenName"): ("Bär", ""), }) + ) + + try: + sec.sign_statement(assertion, class_name(assertion), + key_file=full_path("tes.key"), + node_id=assertion.id) + except (XmlsecError, SigverError) as err: # should throw an exception + pass + else: + assert False + + def test_sha256_signing(): conf = config.SPConfig() conf.load_file("server_conf") @@ -574,6 +972,32 @@ def test_sha256_signing(): assert s +def test_sha256_signing_non_ascii_ava(): + conf = config.SPConfig() + conf.load_file("server_conf") + md = MetadataStore([saml, samlp], None, conf) + md.load("local", full_path("idp_example.xml")) + + conf.metadata = md + conf.only_use_keys_in_metadata = False + sec = sigver.security_context(conf) + + assertion = factory( + saml.Assertion, version="2.0", id="11111", + issue_instant="2009-10-30T13:20:28Z", + signature=sigver.pre_signature_part("11111", sec.my_cert, 1, + sign_alg=SIG_RSA_SHA256), + attribute_statement=do_attribute_statement( + {("", "", "surName"): ("Föö", ""), + ("", "", "givenName"): ("Bär", ""), }) + ) + + s = sec.sign_statement(assertion, class_name(assertion), + key_file=full_path("test.key"), + node_id=assertion.id) + assert s + + def test_xmlsec_output_line_parsing(): output1 = "prefix\nOK\npostfix" assert sigver.parse_xmlsec_output(output1) |