예제 #1
0
    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
예제 #2
0
def test_create_class_from_xml_string_nameid():
    kl = create_class_from_xml_string(NameID, ITEMS[NameID][0])
    assert kl != None
    assert kl.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
    assert kl.sp_provided_id == "sp provided id"
    assert kl.text.strip() == "*****@*****.**"
    assert _eq(kl.keyswv(), ['sp_provided_id', 'format', 'text'])
    assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID"
    assert _eq(kl.keys(), ['sp_provided_id', 'sp_name_qualifier',
                           'name_qualifier', 'format', 'text'])

    kl = create_class_from_xml_string(NameID, ITEMS[NameID][1])
    assert kl != None
    assert kl.format == "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
    assert kl.sp_name_qualifier == "https://foo.example.com/sp"
    assert kl.text.strip() == "_1632879f09d08ea5ede2dc667cbed7e429ebc4335c"
    assert _eq(kl.keyswv(), ['sp_name_qualifier', 'format', 'text'])
    assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID"

    kl = create_class_from_xml_string(NameID, ITEMS[NameID][2])
    assert kl != None
    assert kl.format == "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
    assert kl.name_qualifier == "http://authentic.example.com/saml/metadata"
    assert kl.sp_name_qualifier == "http://auth.example.com/saml/metadata"
    assert kl.text.strip() == "test"
    assert _eq(kl.keyswv(), ['sp_name_qualifier', 'format', 'name_qualifier',
                             'text'])
    assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID"
예제 #3
0
    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))
예제 #4
0
def test_create_class_from_xml_string_nameid():
    kl = create_class_from_xml_string(NameID, ITEMS[NameID][0])
    assert kl != None
    assert kl.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
    assert kl.sp_provided_id == "sp provided id"
    assert kl.text.strip() == "*****@*****.**"
    assert _eq(kl.keyswv(), ['sp_provided_id', 'format', 'text'])
    assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID"
    assert _eq(kl.keys(), [
        'sp_provided_id', 'sp_name_qualifier', 'name_qualifier', 'format',
        'text'
    ])

    kl = create_class_from_xml_string(NameID, ITEMS[NameID][1])
    assert kl != None
    assert kl.format == "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
    assert kl.sp_name_qualifier == "https://foo.example.com/sp"
    assert kl.text.strip() == "_1632879f09d08ea5ede2dc667cbed7e429ebc4335c"
    assert _eq(kl.keyswv(), ['sp_name_qualifier', 'format', 'text'])
    assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID"

    kl = create_class_from_xml_string(NameID, ITEMS[NameID][2])
    assert kl != None
    assert kl.format == "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
    assert kl.name_qualifier == "http://authentic.example.com/saml/metadata"
    assert kl.sp_name_qualifier == "http://auth.example.com/saml/metadata"
    assert kl.text.strip() == "test"
    assert _eq(kl.keyswv(),
               ['sp_name_qualifier', 'format', 'name_qualifier', 'text'])
    assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID"
예제 #5
0
    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"
예제 #6
0
    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
예제 #7
0
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)
예제 #8
0
    def use_soap(self, request, destination="", soap_headers=None, sign=False,
                 **kwargs):
        """
        Construct the necessary information for using SOAP+POST

        :param request:
        :param destination:
        :param soap_headers:
        :param sign:
        :return: dictionary
        """
        headers = [("content-type", "application/soap+xml")]

        soap_message = make_soap_enveloped_saml_thingy(request, soap_headers)

        logger.debug("SOAP message: %s", soap_message)

        if sign and self.sec:
            _signed = self.sec.sign_statement(soap_message,
                                              class_name=class_name(request),
                                              node_id=request.id)
            soap_message = _signed

        return {"url": destination, "method": "POST",
                "data": soap_message, "headers": headers}
예제 #9
0
    def test_SAML_sign_with_pkcs11(self):
        """
        Test signing a SAML assertion using PKCS#11 and then verifying it.
        """
        os.environ['SOFTHSM_CONF'] = self.softhsm_conf

        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)

        print("Test PASSED")
예제 #10
0
    def test_SAML_sign_with_pkcs11(self):
        """
        Test signing a SAML assertion using PKCS#11 and then verifying it.
        """
        os.environ['SOFTHSM_CONF'] = self.softhsm_conf

        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)

        print("Test PASSED")
예제 #11
0
def entities_descriptor(eds, valid_for, name, ident, sign, secc, sign_alg=None,
                        digest_alg=None):
    entities = md.EntitiesDescriptor(entity_descriptor=eds)
    if valid_for:
        entities.valid_until = in_a_while(hours=valid_for)
    if name:
        entities.name = name
    if ident:
        entities.id = ident

    if sign:
        if not ident:
            ident = sid()

        if not secc.key_file:
            raise SAMLError("If you want to do signing you should define " +
                            "a key to sign with")

        if not secc.my_cert:
            raise SAMLError("If you want to do signing you should define " +
                            "where your public key are")

        entities.signature = pre_signature_part(ident, secc.my_cert, 1,
                                                sign_alg=sign_alg,
                                                digest_alg=digest_alg)
        entities.id = ident
        xmldoc = secc.sign_statement("%s" % entities, class_name(entities))
        entities = md.entities_descriptor_from_string(xmldoc)
    else:
        xmldoc = None

    return entities, xmldoc
예제 #12
0
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
예제 #13
0
    def decrypt_assertions(self, encrypted_assertions, decr_txt, issuer=None,
            verified=False):
        """ Moves the decrypted assertion from the encrypted assertion to a
        list.

        :param encrypted_assertions: A list of encrypted assertions.
        :param decr_txt: The string representation containing the decrypted
        data. Used when verifying signatures.
        :param issuer: The issuer of the response.
        :param verified: If True do not verify signatures, otherwise verify
        the signature if it exists.
        :return: A list of decrypted assertions.
        """
        res = []
        for encrypted_assertion in encrypted_assertions:
            if encrypted_assertion.extension_elements:
                assertions = extension_elements_to_elements(
                    encrypted_assertion.extension_elements, [saml, samlp])
                for assertion in assertions:
                    if assertion.signature and not verified:
                        if not self.sec.check_signature(
                                assertion, origdoc=decr_txt,
                                node_name=class_name(assertion), issuer=issuer):
                            logger.error("Failed to verify signature on '%s'",
                                         assertion)
                            raise SignatureError()
                    res.append(assertion)
        return res
예제 #14
0
    def parse_authn_request_response(self, xmlstr, binding, outstanding=None,
                                     outstanding_certs=None, conv_info=None):
        """ Deal with an AuthnResponse

        :param xmlstr: The reply as a xml string
        :param binding: Which binding that was used for the transport
        :param outstanding: A dictionary with session IDs as keys and
            the original web request from the user before redirection
            as values.
        :param outstanding_certs:
        :param conv_info: Information about the conversation.
        :return: An response.AuthnResponse or None
        """

        if not getattr(self.config, 'entityid', None):
            raise SAMLError("Missing entity_id specification")

        if not xmlstr:
            return None

        kwargs = {
            "outstanding_queries": outstanding,
            "outstanding_certs": outstanding_certs,
            "allow_unsolicited": self.allow_unsolicited,
            "want_assertions_signed": self.want_assertions_signed,
            "want_assertions_or_response_signed": self.want_assertions_or_response_signed,
            "want_response_signed": self.want_response_signed,
            "return_addrs": self.service_urls(binding=binding),
            "entity_id": self.config.entityid,
            "attribute_converters": self.config.attribute_converters,
            "allow_unknown_attributes":
                self.config.allow_unknown_attributes,
            'conv_info': conv_info,
            "valid_destination_regex": self.valid_destination_regex,
        }

        try:
            resp = self._parse_response(xmlstr, AuthnResponse,
                                        "assertion_consumer_service",
                                        binding, **kwargs)
        except StatusError as err:
            logger.error("SAML status error: %s", err)
            raise
        except UnravelError:
            return None
        except Exception as err:
            logger.error("XML parse error: %s", err)
            raise

        if not isinstance(resp, AuthnResponse):
            logger.error("Response type not supported: %s",
                         saml2_tophat.class_name(resp))
            return None

        if (resp.assertion and len(resp.response.encrypted_assertion) == 0 and
                resp.assertion.subject.name_id):
            self.users.add_information_about_person(resp.session_info())
            logger.info("--- ADDED person info ----")

        return resp
예제 #15
0
def test_create_class_from_xml_string_subject_locality():
    kl = create_class_from_xml_string(SubjectLocality, ITEMS[SubjectLocality])
    assert kl != None
    assert _eq(kl.keyswv(), ['address', "dns_name"])
    assert kl.address == "127.0.0.1"
    assert kl.dns_name == "localhost"
    assert class_name(
        kl) == "urn:oasis:names:tc:SAML:2.0:assertion:SubjectLocality"
예제 #16
0
def test_create_class_from_xml_string_subject_locality():
    kl = create_class_from_xml_string(SubjectLocality, ITEMS[SubjectLocality])
    assert kl != None
    assert _eq(kl.keyswv(), ['address', "dns_name"])
    assert kl.address == "127.0.0.1"
    assert kl.dns_name == "localhost"
    assert class_name(
        kl) == "urn:oasis:names:tc:SAML:2.0:assertion:SubjectLocality"
예제 #17
0
    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
예제 #18
0
def test_create_class_from_xml_string_subject_confirmation_data():
    kl = create_class_from_xml_string(SubjectConfirmationData,
                                      ITEMS[SubjectConfirmationData])
    assert kl != None
    assert _eq(kl.keyswv(), ['in_response_to', 'not_on_or_after',
                             'not_before', 'recipient'])
    assert kl.in_response_to == "_1683146e27983964fbe7bf8f08961108d166a652e5"
    assert kl.not_on_or_after == "2010-02-18T13:52:13.959Z"
    assert kl.not_before == "2010-01-16T12:00:00Z"
    assert kl.recipient == "http://192.168.0.10/saml/sp"
    assert class_name(kl) == \
           "urn:oasis:names:tc:SAML:2.0:assertion:SubjectConfirmationData"
예제 #19
0
    def _assertion(self, assertion, verified=False):
        """
        Check the assertion
        :param assertion:
        :return: True/False depending on if the assertion is sane or not
        """

        if not hasattr(assertion, 'signature') or not assertion.signature:
            logger.debug("unsigned")
            if self.require_signature:
                raise SignatureError("Signature missing for assertion")
        else:
            logger.debug("signed")
            if not verified and self.do_not_verify is False:
                try:
                    self.sec.check_signature(assertion, class_name(assertion),
                                             self.xmlstr)
                except Exception as exc:
                    logger.error("correctly_signed_response: %s", exc)
                    raise

        self.assertion = assertion
        logger.debug("assertion context: %s", self.context)
        logger.debug("assertion keys: %s", assertion.keyswv())
        logger.debug("outstanding_queries: %s", self.outstanding_queries)

        # if self.context == "AuthnReq" or self.context == "AttrQuery":
        if self.context == "AuthnReq":
            self.authn_statement_ok()
        # elif self.context == "AttrQuery":
        #            self.authn_statement_ok(True)

        if not self.condition_ok():
            raise VerificationError("Condition not OK")

        logger.debug("--- Getting Identity ---")

        # if self.context == "AuthnReq" or self.context == "AttrQuery":
        #    self.ava = self.get_identity()
        #    logger.debug("--- AVA: %s", self.ava)

        try:
            self.get_subject()
            if self.asynchop:
                if self.allow_unsolicited:
                    pass
                elif self.came_from is None:
                    raise VerificationError("Came from")
            return True
        except Exception:
            logger.exception("get subject")
            raise
예제 #20
0
def test_create_class_from_xml_string_subject_confirmation_data():
    kl = create_class_from_xml_string(SubjectConfirmationData,
                                      ITEMS[SubjectConfirmationData])
    assert kl != None
    assert _eq(
        kl.keyswv(),
        ['in_response_to', 'not_on_or_after', 'not_before', 'recipient'])
    assert kl.in_response_to == "_1683146e27983964fbe7bf8f08961108d166a652e5"
    assert kl.not_on_or_after == "2010-02-18T13:52:13.959Z"
    assert kl.not_before == "2010-01-16T12:00:00Z"
    assert kl.recipient == "http://192.168.0.10/saml/sp"
    assert class_name(kl) == \
           "urn:oasis:names:tc:SAML:2.0:assertion:SubjectConfirmationData"
예제 #21
0
    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)
예제 #22
0
def test_nameid_with_extension():
    kl = create_class_from_xml_string(NameID, NAMEID_WITH_ATTRIBUTE_EXTENSION)
    assert kl != None
    print(kl.__dict__)
    assert kl.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
    assert kl.sp_provided_id == "sp provided id"
    assert kl.text.strip() == "*****@*****.**"
    assert _eq(kl.keyswv(), ['sp_provided_id', 'format',
                             'extension_attributes', 'text'])
    assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID"
    assert _eq(kl.keys(), ['sp_provided_id', 'sp_name_qualifier',
                           'name_qualifier', 'format', 'text'])
    assert kl.extension_attributes == {
        '{urn:mace:example.com:saml:assertion}Foo': 'BAR'}
예제 #23
0
    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'])
예제 #24
0
def test_nameid_with_extension():
    kl = create_class_from_xml_string(NameID, NAMEID_WITH_ATTRIBUTE_EXTENSION)
    assert kl != None
    print(kl.__dict__)
    assert kl.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
    assert kl.sp_provided_id == "sp provided id"
    assert kl.text.strip() == "*****@*****.**"
    assert _eq(kl.keyswv(),
               ['sp_provided_id', 'format', 'extension_attributes', 'text'])
    assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID"
    assert _eq(kl.keys(), [
        'sp_provided_id', 'sp_name_qualifier', 'name_qualifier', 'format',
        'text'
    ])
    assert kl.extension_attributes == {
        '{urn:mace:example.com:saml:assertion}Foo': 'BAR'
    }
예제 #25
0
def sign_entity_descriptor(edesc, ident, secc, sign_alg=None, digest_alg=None):
    """

    :param edesc: EntityDescriptor instance
    :param ident: EntityDescriptor identifier
    :param secc: Security context
    :return: Tuple with EntityDescriptor instance and Signed XML document
    """

    if not ident:
        ident = sid()

    edesc.signature = pre_signature_part(ident, secc.my_cert, 1, sign_alg=sign_alg, digest_alg=digest_alg)
    edesc.id = ident
    xmldoc = secc.sign_statement("%s" % edesc, class_name(edesc))
    edesc = md.entity_descriptor_from_string(xmldoc)
    return edesc, xmldoc
예제 #26
0
    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)
예제 #27
0
    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)
예제 #28
0
def sign_entity_descriptor(edesc, ident, secc, sign_alg=None, digest_alg=None):
    """

    :param edesc: EntityDescriptor instance
    :param ident: EntityDescriptor identifier
    :param secc: Security context
    :return: Tuple with EntityDescriptor instance and Signed XML document
    """

    if not ident:
        ident = sid()

    edesc.signature = pre_signature_part(ident,
                                         secc.my_cert,
                                         1,
                                         sign_alg=sign_alg,
                                         digest_alg=digest_alg)
    edesc.id = ident
    xmldoc = secc.sign_statement("%s" % edesc, class_name(edesc))
    edesc = md.entity_descriptor_from_string(xmldoc)
    return edesc, xmldoc
예제 #29
0
def test_create_class_from_xml_string_subject_confirmation():
    kl = create_class_from_xml_string(SubjectConfirmation,
                                      ITEMS[SubjectConfirmation])
    assert kl != None
    assert _eq(kl.keyswv(), ['method', 'name_id', 'subject_confirmation_data'])
    assert kl.method == "urn:oasis:names:tc:SAML:2.0:cm:bearer"
    name_id = kl.name_id
    assert _eq(name_id.keyswv(), ['format', 'name_qualifier', 'text'])
    assert name_id.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
    assert name_id.name_qualifier == "http://authentic.example.com/saml/metadata"
    assert name_id.text.strip() == "*****@*****.**"
    subject_confirmation_data = kl.subject_confirmation_data
    assert _eq(subject_confirmation_data.keyswv(),
               ['not_on_or_after', 'recipient', 'in_response_to'])
    assert subject_confirmation_data.recipient == \
           "http://auth.example.com/saml/proxySingleSignOnRedirect"
    assert subject_confirmation_data.not_on_or_after == "2010-02-17T17:02:38Z"
    assert subject_confirmation_data.in_response_to == \
           "_59B3A01B03334032C31E434C63F89E3E"
    assert class_name(kl) == \
           "urn:oasis:names:tc:SAML:2.0:assertion:SubjectConfirmation"
예제 #30
0
def entities_descriptor(eds,
                        valid_for,
                        name,
                        ident,
                        sign,
                        secc,
                        sign_alg=None,
                        digest_alg=None):
    entities = md.EntitiesDescriptor(entity_descriptor=eds)
    if valid_for:
        entities.valid_until = in_a_while(hours=valid_for)
    if name:
        entities.name = name
    if ident:
        entities.id = ident

    if sign:
        if not ident:
            ident = sid()

        if not secc.key_file:
            raise SAMLError("If you want to do signing you should define " +
                            "a key to sign with")

        if not secc.my_cert:
            raise SAMLError("If you want to do signing you should define " +
                            "where your public key are")

        entities.signature = pre_signature_part(ident,
                                                secc.my_cert,
                                                1,
                                                sign_alg=sign_alg,
                                                digest_alg=digest_alg)
        entities.id = ident
        xmldoc = secc.sign_statement("%s" % entities, class_name(entities))
        entities = md.entities_descriptor_from_string(xmldoc)
    else:
        xmldoc = None

    return entities, xmldoc
예제 #31
0
def test_create_class_from_xml_string_subject_confirmation():
    kl = create_class_from_xml_string(SubjectConfirmation,
                                      ITEMS[SubjectConfirmation])
    assert kl != None
    assert _eq(kl.keyswv(), ['method', 'name_id',
                             'subject_confirmation_data'])
    assert kl.method == "urn:oasis:names:tc:SAML:2.0:cm:bearer"
    name_id = kl.name_id
    assert _eq(name_id.keyswv(), ['format', 'name_qualifier', 'text'])
    assert name_id.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
    assert name_id.name_qualifier == "http://authentic.example.com/saml/metadata"
    assert name_id.text.strip() == "*****@*****.**"
    subject_confirmation_data = kl.subject_confirmation_data
    assert _eq(subject_confirmation_data.keyswv(), ['not_on_or_after',
                                                    'recipient',
                                                    'in_response_to'])
    assert subject_confirmation_data.recipient == \
           "http://auth.example.com/saml/proxySingleSignOnRedirect"
    assert subject_confirmation_data.not_on_or_after == "2010-02-17T17:02:38Z"
    assert subject_confirmation_data.in_response_to == \
           "_59B3A01B03334032C31E434C63F89E3E"
    assert class_name(kl) == \
           "urn:oasis:names:tc:SAML:2.0:assertion:SubjectConfirmation"
예제 #32
0
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
예제 #33
0
def test_create_class_from_xml_string_issuer():
    kl = create_class_from_xml_string(Issuer, ITEMS[Issuer])
    assert kl != None
    assert kl.text.strip() == "http://www.example.com/test"
    assert _eq(kl.keyswv(), ['text'])
    assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:Issuer"
예제 #34
0
    def parse_authn_request_response(self,
                                     xmlstr,
                                     binding,
                                     outstanding=None,
                                     outstanding_certs=None,
                                     conv_info=None):
        """ Deal with an AuthnResponse

        :param xmlstr: The reply as a xml string
        :param binding: Which binding that was used for the transport
        :param outstanding: A dictionary with session IDs as keys and
            the original web request from the user before redirection
            as values.
        :param outstanding_certs:
        :param conv_info: Information about the conversation.
        :return: An response.AuthnResponse or None
        """

        if not getattr(self.config, 'entityid', None):
            raise SAMLError("Missing entity_id specification")

        if not xmlstr:
            return None

        kwargs = {
            "outstanding_queries": outstanding,
            "outstanding_certs": outstanding_certs,
            "allow_unsolicited": self.allow_unsolicited,
            "want_assertions_signed": self.want_assertions_signed,
            "want_assertions_or_response_signed":
            self.want_assertions_or_response_signed,
            "want_response_signed": self.want_response_signed,
            "return_addrs": self.service_urls(binding=binding),
            "entity_id": self.config.entityid,
            "attribute_converters": self.config.attribute_converters,
            "allow_unknown_attributes": self.config.allow_unknown_attributes,
            'conv_info': conv_info,
            "valid_destination_regex": self.valid_destination_regex,
        }

        try:
            resp = self._parse_response(xmlstr, AuthnResponse,
                                        "assertion_consumer_service", binding,
                                        **kwargs)
        except StatusError as err:
            logger.error("SAML status error: %s", err)
            raise
        except UnravelError:
            return None
        except Exception as err:
            logger.error("XML parse error: %s", err)
            raise

        if not isinstance(resp, AuthnResponse):
            logger.error("Response type not supported: %s",
                         saml2_tophat.class_name(resp))
            return None

        if (resp.assertion and len(resp.response.encrypted_assertion) == 0
                and resp.assertion.subject.name_id):
            self.users.add_information_about_person(resp.session_info())
            logger.info("--- ADDED person info ----")

        return resp
예제 #35
0
def test_create_class_from_xml_string_issuer():
    kl = create_class_from_xml_string(Issuer, ITEMS[Issuer])
    assert kl != None
    assert kl.text.strip() == "http://www.example.com/test"
    assert _eq(kl.keyswv(), ['text'])
    assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:Issuer"
예제 #36
0
    def _authn_response(self, in_response_to, consumer_url,
                        sp_entity_id, identity=None, name_id=None,
                        status=None, authn=None, issuer=None, policy=None,
                        sign_assertion=False, sign_response=False,
                        best_effort=False, encrypt_assertion=False,
                        encrypt_cert_advice=None, encrypt_cert_assertion=None,
                        authn_statement=None,
                        encrypt_assertion_self_contained=False,
                        encrypted_advice_attributes=False,
                        pefim=False, sign_alg=None, digest_alg=None,
                        farg=None, session_not_on_or_after=None):
        """ Create a response. A layer of indirection.

        :param in_response_to: The session identifier of the request
        :param consumer_url: The URL which should receive the response
        :param sp_entity_id: The entity identifier of the SP
        :param identity: A dictionary with attributes and values that are
            expected to be the bases for the assertion in the response.
        :param name_id: The identifier of the subject
        :param status: The status of the response
        :param authn: A dictionary containing information about the
            authn context.
        :param issuer: The issuer of the response
        :param policy:
        :param sign_assertion: Whether the assertion should be signed or not
        :param sign_response: Whether the response should be signed or not
        :param best_effort: Even if not the SPs demands can be met send a
            response.
        :param encrypt_assertion: True if assertions should be encrypted.
        :param encrypt_assertion_self_contained: True if all encrypted
        assertions should have alla namespaces
        selfcontained.
        :param encrypted_advice_attributes: True if assertions in the advice
        element should be encrypted.
        :param encrypt_cert_advice: Certificate to be used for encryption of
        assertions in the advice element.
        :param encrypt_cert_assertion: Certificate to be used for encryption
        of assertions.
        :param authn_statement: Authentication statement.
        :param sign_assertion: True if assertions should be signed.
        :param pefim: True if a response according to the PEFIM profile
        should be created.
        :param farg: Argument to pass on to the assertion constructor
        :return: A response instance
        """

        if farg is None:
            assertion_args = {}

        args = {}
        # if identity:
        _issuer = self._issuer(issuer)

        # if encrypt_assertion and show_nameid:
        #    tmp_name_id = name_id
        #    name_id = None
        #    name_id = None
        #    tmp_authn = authn
        #    authn = None
        #    tmp_authn_statement = authn_statement
        #    authn_statement = None

        if pefim:
            encrypted_advice_attributes = True
            encrypt_assertion_self_contained = True
            assertion_attributes = self.setup_assertion(
                None, sp_entity_id, None, None, None, policy, None, None,
                identity, best_effort, sign_response, farg=farg)
            assertion = self.setup_assertion(
                authn, sp_entity_id, in_response_to, consumer_url, name_id,
                policy, _issuer, authn_statement, [], True, sign_response,
                farg=farg, session_not_on_or_after=session_not_on_or_after)
            assertion.advice = saml.Advice()

            # assertion.advice.assertion_id_ref.append(saml.AssertionIDRef())
            # assertion.advice.assertion_uri_ref.append(saml.AssertionURIRef())
            assertion.advice.assertion.append(assertion_attributes)
        else:
            assertion = self.setup_assertion(
                authn, sp_entity_id, in_response_to, consumer_url, name_id,
                policy, _issuer, authn_statement, identity, True,
                sign_response, farg=farg,
                session_not_on_or_after=session_not_on_or_after)

        to_sign = []
        if not encrypt_assertion:
            if sign_assertion:
                assertion.signature = pre_signature_part(assertion.id,
                                                         self.sec.my_cert, 2,
                                                         sign_alg=sign_alg,
                                                         digest_alg=digest_alg)
                to_sign.append((class_name(assertion), assertion.id))

        args["assertion"] = assertion

        if (self.support_AssertionIDRequest() or self.support_AuthnQuery()):
            self.session_db.store_assertion(assertion, to_sign)

        return self._response(
            in_response_to, consumer_url, status, issuer, sign_response,
            to_sign, sp_entity_id=sp_entity_id,
            encrypt_assertion=encrypt_assertion,
            encrypt_cert_advice=encrypt_cert_advice,
            encrypt_cert_assertion=encrypt_cert_assertion,
            encrypt_assertion_self_contained=encrypt_assertion_self_contained,
            encrypted_advice_attributes=encrypted_advice_attributes,
            sign_assertion=sign_assertion,
            pefim=pefim, sign_alg=sign_alg, digest_alg=digest_alg, **args)
예제 #37
0
    def create_attribute_response(self,
                                  identity,
                                  in_response_to,
                                  destination,
                                  sp_entity_id,
                                  userid="",
                                  name_id=None,
                                  status=None,
                                  issuer=None,
                                  sign_assertion=False,
                                  sign_response=False,
                                  attributes=None,
                                  sign_alg=None,
                                  digest_alg=None,
                                  farg=None,
                                  **kwargs):
        """ Create an attribute assertion response.

        :param identity: A dictionary with attributes and values that are
            expected to be the bases for the assertion in the response.
        :param in_response_to: The session identifier of the request
        :param destination: The URL which should receive the response
        :param sp_entity_id: The entity identifier of the SP
        :param userid: A identifier of the user
        :param name_id: The identifier of the subject
        :param status: The status of the response
        :param issuer: The issuer of the response
        :param sign_assertion: Whether the assertion should be signed or not
        :param sign_response: Whether the whole response should be signed
        :param attributes:
        :param kwargs: To catch extra keyword arguments
        :return: A response instance
        """

        policy = self.config.getattr("policy", "aa")

        if not name_id and userid:
            try:
                name_id = self.ident.construct_nameid(userid, policy,
                                                      sp_entity_id)
                logger.warning("Unspecified NameID format")
            except Exception:
                pass

        to_sign = []

        if identity:
            farg = self.update_farg(in_response_to, sp_entity_id, farg=farg)

            _issuer = self._issuer(issuer)
            ast = Assertion(identity)
            if policy:
                ast.apply_policy(sp_entity_id, policy, self.metadata)
            else:
                policy = Policy()

            if attributes:
                restr = restriction_from_attribute_spec(attributes)
                ast = filter_attribute_value_assertions(ast)

            assertion = ast.construct(sp_entity_id,
                                      self.config.attribute_converters,
                                      policy,
                                      issuer=_issuer,
                                      name_id=name_id,
                                      farg=farg['assertion'])

            if sign_assertion:
                assertion.signature = pre_signature_part(assertion.id,
                                                         self.sec.my_cert,
                                                         1,
                                                         sign_alg=sign_alg,
                                                         digest_alg=digest_alg)
                # Just the assertion or the response and the assertion ?
                to_sign = [(class_name(assertion), assertion.id)]
                kwargs['sign_assertion'] = True

            kwargs["assertion"] = assertion

        if sp_entity_id:
            kwargs['sp_entity_id'] = sp_entity_id

        return self._response(in_response_to,
                              destination,
                              status,
                              issuer,
                              sign_response,
                              to_sign,
                              sign_alg=sign_alg,
                              digest_alg=digest_alg,
                              **kwargs)
예제 #38
0
    def _authn_response(self,
                        in_response_to,
                        consumer_url,
                        sp_entity_id,
                        identity=None,
                        name_id=None,
                        status=None,
                        authn=None,
                        issuer=None,
                        policy=None,
                        sign_assertion=False,
                        sign_response=False,
                        best_effort=False,
                        encrypt_assertion=False,
                        encrypt_cert_advice=None,
                        encrypt_cert_assertion=None,
                        authn_statement=None,
                        encrypt_assertion_self_contained=False,
                        encrypted_advice_attributes=False,
                        pefim=False,
                        sign_alg=None,
                        digest_alg=None,
                        farg=None,
                        session_not_on_or_after=None):
        """ Create a response. A layer of indirection.

        :param in_response_to: The session identifier of the request
        :param consumer_url: The URL which should receive the response
        :param sp_entity_id: The entity identifier of the SP
        :param identity: A dictionary with attributes and values that are
            expected to be the bases for the assertion in the response.
        :param name_id: The identifier of the subject
        :param status: The status of the response
        :param authn: A dictionary containing information about the
            authn context.
        :param issuer: The issuer of the response
        :param policy:
        :param sign_assertion: Whether the assertion should be signed or not
        :param sign_response: Whether the response should be signed or not
        :param best_effort: Even if not the SPs demands can be met send a
            response.
        :param encrypt_assertion: True if assertions should be encrypted.
        :param encrypt_assertion_self_contained: True if all encrypted
        assertions should have alla namespaces
        selfcontained.
        :param encrypted_advice_attributes: True if assertions in the advice
        element should be encrypted.
        :param encrypt_cert_advice: Certificate to be used for encryption of
        assertions in the advice element.
        :param encrypt_cert_assertion: Certificate to be used for encryption
        of assertions.
        :param authn_statement: Authentication statement.
        :param sign_assertion: True if assertions should be signed.
        :param pefim: True if a response according to the PEFIM profile
        should be created.
        :param farg: Argument to pass on to the assertion constructor
        :return: A response instance
        """

        if farg is None:
            assertion_args = {}

        args = {}
        # if identity:
        _issuer = self._issuer(issuer)

        # if encrypt_assertion and show_nameid:
        #    tmp_name_id = name_id
        #    name_id = None
        #    name_id = None
        #    tmp_authn = authn
        #    authn = None
        #    tmp_authn_statement = authn_statement
        #    authn_statement = None

        if pefim:
            encrypted_advice_attributes = True
            encrypt_assertion_self_contained = True
            assertion_attributes = self.setup_assertion(None,
                                                        sp_entity_id,
                                                        None,
                                                        None,
                                                        None,
                                                        policy,
                                                        None,
                                                        None,
                                                        identity,
                                                        best_effort,
                                                        sign_response,
                                                        farg=farg)
            assertion = self.setup_assertion(
                authn,
                sp_entity_id,
                in_response_to,
                consumer_url,
                name_id,
                policy,
                _issuer,
                authn_statement, [],
                True,
                sign_response,
                farg=farg,
                session_not_on_or_after=session_not_on_or_after)
            assertion.advice = saml.Advice()

            # assertion.advice.assertion_id_ref.append(saml.AssertionIDRef())
            # assertion.advice.assertion_uri_ref.append(saml.AssertionURIRef())
            assertion.advice.assertion.append(assertion_attributes)
        else:
            assertion = self.setup_assertion(
                authn,
                sp_entity_id,
                in_response_to,
                consumer_url,
                name_id,
                policy,
                _issuer,
                authn_statement,
                identity,
                True,
                sign_response,
                farg=farg,
                session_not_on_or_after=session_not_on_or_after)

        to_sign = []
        if not encrypt_assertion:
            if sign_assertion:
                assertion.signature = pre_signature_part(assertion.id,
                                                         self.sec.my_cert,
                                                         2,
                                                         sign_alg=sign_alg,
                                                         digest_alg=digest_alg)
                to_sign.append((class_name(assertion), assertion.id))

        args["assertion"] = assertion

        if (self.support_AssertionIDRequest() or self.support_AuthnQuery()):
            self.session_db.store_assertion(assertion, to_sign)

        return self._response(
            in_response_to,
            consumer_url,
            status,
            issuer,
            sign_response,
            to_sign,
            sp_entity_id=sp_entity_id,
            encrypt_assertion=encrypt_assertion,
            encrypt_cert_advice=encrypt_cert_advice,
            encrypt_cert_assertion=encrypt_cert_assertion,
            encrypt_assertion_self_contained=encrypt_assertion_self_contained,
            encrypted_advice_attributes=encrypted_advice_attributes,
            sign_assertion=sign_assertion,
            pefim=pefim,
            sign_alg=sign_alg,
            digest_alg=digest_alg,
            **args)
예제 #39
0
    def create_attribute_response(self, identity, in_response_to, destination,
                                  sp_entity_id, userid="", name_id=None,
                                  status=None, issuer=None,
                                  sign_assertion=False, sign_response=False,
                                  attributes=None, sign_alg=None,
                                  digest_alg=None, farg=None, **kwargs):
        """ Create an attribute assertion response.

        :param identity: A dictionary with attributes and values that are
            expected to be the bases for the assertion in the response.
        :param in_response_to: The session identifier of the request
        :param destination: The URL which should receive the response
        :param sp_entity_id: The entity identifier of the SP
        :param userid: A identifier of the user
        :param name_id: The identifier of the subject
        :param status: The status of the response
        :param issuer: The issuer of the response
        :param sign_assertion: Whether the assertion should be signed or not
        :param sign_response: Whether the whole response should be signed
        :param attributes:
        :param kwargs: To catch extra keyword arguments
        :return: A response instance
        """

        policy = self.config.getattr("policy", "aa")

        if not name_id and userid:
            try:
                name_id = self.ident.construct_nameid(userid, policy,
                                                      sp_entity_id)
                logger.warning("Unspecified NameID format")
            except Exception:
                pass

        to_sign = []

        if identity:
            farg = self.update_farg(in_response_to, sp_entity_id, farg=farg)

            _issuer = self._issuer(issuer)
            ast = Assertion(identity)
            if policy:
                ast.apply_policy(sp_entity_id, policy, self.metadata)
            else:
                policy = Policy()

            if attributes:
                restr = restriction_from_attribute_spec(attributes)
                ast = filter_attribute_value_assertions(ast)

            assertion = ast.construct(
                sp_entity_id, self.config.attribute_converters, policy,
                issuer=_issuer, name_id=name_id,
                farg=farg['assertion'])

            if sign_assertion:
                assertion.signature = pre_signature_part(assertion.id,
                                                         self.sec.my_cert, 1,
                                                         sign_alg=sign_alg,
                                                         digest_alg=digest_alg)
                # Just the assertion or the response and the assertion ?
                to_sign = [(class_name(assertion), assertion.id)]
                kwargs['sign_assertion'] = True

            kwargs["assertion"] = assertion

        if sp_entity_id:
            kwargs['sp_entity_id'] = sp_entity_id

        return self._response(in_response_to, destination, status, issuer,
                              sign_response, to_sign, sign_alg=sign_alg,
                              digest_alg=digest_alg, **kwargs)