diff --git a/src/saml2/entity.py b/src/saml2/entity.py index 9a92e84..5140d63 100644 --- a/src/saml2/entity.py +++ b/src/saml2/entity.py @@ -579,6 +579,12 @@ class Entity(HTTPBase): encrypt_advice = False if encrypted_advice_attributes and response.assertion.advice is not None \ and len(response.assertion.advice.assertion) == 1: + to_sign_advice = [] + if sign_assertion is not None and sign_assertion: + if response.assertion.advice and response.assertion.advice.assertion: + for tmp_assertion in response.assertion.advice.assertion: + tmp_assertion.signature = pre_signature_part(tmp_assertion.id, self.sec.my_cert, 1) + to_sign_advice.append((class_name(tmp_assertion), tmp_assertion.id)) tmp_assertion = response.assertion.advice.assertion[0] response.assertion.advice.encrypted_assertion = [] response.assertion.advice.encrypted_assertion.append(EncryptedAssertion()) @@ -587,12 +593,6 @@ class Entity(HTTPBase): else: response.assertion.advice.encrypted_assertion[0].add_extension_element(tmp_assertion) response.assertion.advice.assertion = [] - to_sign_advice = [] - if sign_assertion is not None and sign_assertion: - if response.assertion.advice and response.assertion.advice.assertion: - for tmp_assertion in response.assertion.advice.assertion: - tmp_assertion.signature = pre_signature_part(tmp_assertion.id, self.sec.my_cert, 1) - to_sign_advice.append((class_name(tmp_assertion), tmp_assertion.id)) if encrypt_assertion_self_contained: advice_tag = response.assertion.advice._to_element_tree().tag assertion_tag = tmp_assertion._to_element_tree().tag @@ -608,6 +608,14 @@ class Entity(HTTPBase): if encrypt_assertion: response = response_from_string(response) if encrypt_assertion: + to_sign_assertion = [] + if sign_assertion is not None and sign_assertion: + _assertions = response.assertion + if not isinstance(response.assertion, list): + _assertions = [response.assertion] + for _assertion in _assertions: + _assertion.signature = pre_signature_part(_assertion.id, self.sec.my_cert, 1) + to_sign_assertion.append((class_name(_assertion), _assertion.id)) if encrypt_assertion_self_contained: try: assertion_tag = response.assertion._to_element_tree().tag @@ -618,13 +626,12 @@ class Entity(HTTPBase): assertion_tag) else: response = pre_encrypt_assertion(response) - to_sign_assertion = [] - if sign_assertion is not None and sign_assertion: - response.assertion.signature = pre_signature_part(response.assertion.id, self.sec.my_cert, 1) - to_sign_assertion.append((class_name(response.assertion), response.assertion.id)) if to_sign_assertion: response = signed_instance_factory(response, self.sec, to_sign_assertion) response = self._encrypt_assertion(encrypt_cert_assertion, sp_entity_id, response) + else: + if to_sign: + response = signed_instance_factory(response, self.sec, to_sign) if sign: return signed_instance_factory(response, self.sec, sign_class) else: diff --git a/src/saml2/server.py b/src/saml2/server.py index e33d012..c7778b1 100644 --- a/src/saml2/server.py +++ b/src/saml2/server.py @@ -380,12 +380,12 @@ class Server(Entity): assertion.signature = pre_signature_part(assertion.id, self.sec.my_cert, 1) to_sign.append((class_name(assertion), assertion.id)) - if not encrypted_advice_attributes: - if sign_assertion: - if assertion.advice and assertion.advice.assertion: - for tmp_assertion in assertion.advice.assertion: - tmp_assertion.signature = pre_signature_part(tmp_assertion.id, self.sec.my_cert, 1) - to_sign.append((class_name(tmp_assertion), tmp_assertion.id)) + #if not encrypted_advice_attributes: + # if sign_assertion: + # if assertion.advice and assertion.advice.assertion: + # for tmp_assertion in assertion.advice.assertion: + # tmp_assertion.signature = pre_signature_part(tmp_assertion.id, self.sec.my_cert, 1) + # to_sign.append((class_name(tmp_assertion), tmp_assertion.id)) # Store which assertion that has been sent to which SP about which # subject. diff --git a/tests/test_50_server.py b/tests/test_50_server.py index f294cdb..e13944b 100644 --- a/tests/test_50_server.py +++ b/tests/test_50_server.py @@ -498,8 +498,32 @@ class TestServer1(): assert sresponse.assertion[0].signature == None + def test_signed_response_3(self): + signed_resp = self.server.create_authn_response( + self.ava, + "id12", # in_response_to + "http://lingon.catalogix.se:8087/", # consumer_url + "urn:mace:example.com:saml:roland:sp", # sp_entity_id + name_id=self.name_id, + sign_response=False, + sign_assertion=True, + ) + + sresponse = response_from_string(signed_resp) + + assert sresponse.signature == None + + valid = self.server.sec.verify_signature(signed_resp, + self.server.config.cert_file, + node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', + node_id=sresponse.assertion[0].id, + id_attr="") + assert valid + + self.verify_assertion(sresponse.assertion) + def test_encrypted_signed_response_1(self): cert_str, cert_key_str = generate_cert() @@ -512,10 +536,10 @@ class TestServer1(): name_id=self.name_id, sign_response=True, sign_assertion=True, - encrypt_assertion=True, + encrypt_assertion=False, encrypt_assertion_self_contained=True, encrypted_advice_attributes=True, - encrypt_cert=cert_str, + encrypt_cert_advice=cert_str, ) sresponse = response_from_string(signed_resp) @@ -527,34 +551,26 @@ class TestServer1(): id_attr="") assert valid + valid = self.server.sec.verify_signature(signed_resp, + self.server.config.cert_file, + node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', + node_id=sresponse.assertion[0].id, + id_attr="") + + assert valid + _, key_file = make_temp("%s" % cert_key_str, decode=False) decr_text = self.server.sec.decrypt(signed_resp, key_file) resp = samlp.response_from_string(decr_text) - valid = self.server.sec.verify_signature(decr_text, - self.server.config.cert_file, - node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', - node_id=resp.assertion[0].id, - id_attr="") - assert valid - assert resp.assertion[0].advice.encrypted_assertion[0].extension_elements assertion = extension_elements_to_elements(resp.assertion[0].advice.encrypted_assertion[0].extension_elements, [saml, samlp]) - assert assertion - assert assertion[0].attribute_statement - ava = ava = get_ava(assertion[0]) - - assert ava ==\ - {'mail': ['derek@nyy.mlb.com'], 'givenname': ['Derek'], 'surname': ['Jeter'], 'title': ['The man']} - - assert 'EncryptedAssertion>