Example #1
0
    def test_encrypted_signed_response_4(self):

        cert_str, cert_key_str = generate_cert()

        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=True,
            sign_assertion=True,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=True,
            pefim=True,
            encrypt_cert_advice=cert_str,
        )

        sresponse = response_from_string(signed_resp)

        valid = self.server.sec.verify_signature(signed_resp,
                                                 self.server.config.cert_file,
                                                 node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response',
                                                 node_id=sresponse.id,
                                                 id_attr="")
        assert valid

        decr_text = self.server.sec.decrypt(signed_resp, self.client.config.encryption_keypairs[1]["key_file"])

        resp = samlp.response_from_string(decr_text)

        resp.assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp])

        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

        _, key_file = make_temp(cert_key_str, decode=False)

        decr_text = self.server.sec.decrypt(decr_text, key_file)

        resp = samlp.response_from_string(decr_text)

        assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp])
        assertion = \
             extension_elements_to_elements(assertion[0].advice.encrypted_assertion[0].extension_elements,[saml, samlp])
        self.verify_assertion(assertion)

        #PEFIM never signs assertion in advice
        assert assertion[0].signature is None
        #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=assertion[0].id,
        #                                         id_attr="")
        assert valid
Example #2
0
    def test_encrypted_response_7(self):
        _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=False,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=True,
            pefim=True
        )

        sresponse = response_from_string(_resp)

        assert sresponse.signature is None

        decr_text_1 = self.server.sec.decrypt(_resp, self.client.config.encryption_keypairs[1]["key_file"])

        decr_text_2 = self.server.sec.decrypt(decr_text_1, self.client.config.encryption_keypairs[1]["key_file"])

        resp = samlp.response_from_string(decr_text_2)

        resp.assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp])

        self.verify_advice_assertion(resp, decr_text_2)
Example #3
0
    def test_encrypted_response_3(self):
        cert_str_assertion, cert_key_str_assertion = generate_cert()

        _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=False,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=True,
            encrypted_advice_attributes=False,
            encrypt_cert_assertion=cert_str_assertion
        )

        sresponse = response_from_string(_resp)

        assert sresponse.signature is None

        _, key_file = make_temp(cert_key_str_assertion, decode=False)

        decr_text = self.server.sec.decrypt(_resp, key_file)

        resp = samlp.response_from_string(decr_text)

        assert resp.encrypted_assertion[0].extension_elements

        assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp])

        self.verify_encrypted_assertion(assertion, decr_text)
Example #4
0
    def test_encrypted_signed_response_2(self):
        cert_str, cert_key_str = generate_cert()

        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=True,
            sign_assertion=False,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=True,
        )

        sresponse = response_from_string(signed_resp)

        valid = self.server.sec.verify_signature(signed_resp,
                                                 self.server.config.cert_file,
                                                 node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response',
                                                 node_id=sresponse.id,
                                                 id_attr="")
        assert valid

        decr_text = self.server.sec.decrypt(signed_resp, self.client.config.key_file)

        resp = samlp.response_from_string(decr_text)

        resp.assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp])

        assert resp.assertion[0].signature == None

        self.verify_assertion(resp.assertion)
Example #5
0
    def ava_from(self, attribute):
        try:
            attr = self._fro[attribute.name.strip()]
        except (AttributeError, KeyError):
            try:
                attr = attribute.friendly_name.strip()
            except AttributeError:
                attr = attribute.name.strip()

        val = []
        for value in attribute.attribute_value:
            if value.extension_elements:
                ext = extension_elements_to_elements(value.extension_elements, [saml])

                for ex in ext:
                    if isinstance(ex, NameID):
                        cval = ''
                        for key, (name, type, mul) in ex.c_attributes.items():
                            exv = getattr(ex, name)
                            if exv and name in ['text', 'value']:
                                cval = exv

                        if ex.text and not cval:
                            cval = ex.text.strip()
                        val.append(cval)
            elif not value.text:
                val.append('')
            else:
                val.append(value.text.strip())

        return attr, val
    def ava_from(self, attribute):
        try:
            attr = self._fro[attribute.name.strip().lower()]
        except (AttributeError, KeyError):
            try:
                attr = attribute.friendly_name.strip().lower()
            except AttributeError:
                attr = attribute.name.strip().lower()

        val = []
        for value in attribute.attribute_value:
            if value.extension_elements:
                ext = extension_elements_to_elements(value.extension_elements,
                                                     [saml])
                for ex in ext:
                    cval = {}
                    for key, (name, typ, mul) in ex.c_attributes.items():
                        exv = getattr(ex, name)
                        if exv:
                            cval[name] = exv
                    if ex.text:
                        cval["value"] = ex.text.strip()
                    val.append({ex.c_tag: cval})
            elif not value.text:
                val.append('')
            else:
                val.append(value.text.strip())

        return attr, val
Example #7
0
def authn_context_decl_from_extension_elements(extelems):
    res = extension_elements_to_elements(extelems, [ippword, mobiletwofactor,
                                                    ppt, pword, sslcert])
    try:
        return res[0]
    except IndexError:
        return None
Example #8
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
Example #9
0
def test_xbox_non_ascii_ava():
    conf = config.SPConfig()
    conf.load_file("server_conf")
    md = MetadataStore([saml, samlp], None, conf)
    md.load("local", IDP_EXAMPLE)

    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=PRIV_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, key_file=PRIV_KEY)
    _seass = saml.encrypted_assertion_from_string(decr_text)
    assertions = []
    assers = extension_elements_to_elements(
        _seass.extension_elements, [saml, samlp]
    )

    for ass in assers:
        _txt = sec.verify_signature(
            str(ass), PUB_KEY, node_name=class_name(assertion)
        )
        if _txt:
            assertions.append(ass)

    assert assertions
    print(assertions)
Example #10
0
File: mdie.py Project: GSA/pysaml2
def to_dict(_dict, onts):
    """
    Convert a pysaml2 SAML2 metadata format into a basic dictionary format
    The export interface.

    :param _dict: The pysaml2 metadata instance
    :param onts: Schemas to use for the conversion
    :return: The converted information
    """
    res = {}
    if isinstance(_dict, SamlBase):
        res["__class__"] = "%s&%s" % (_dict.c_namespace,_dict.c_tag)
        for key in _dict.keyswv():
            if key in IMP_SKIP:
                continue
            val = getattr(_dict, key)
            if key == "extension_elements":
                _eel = extension_elements_to_elements(val, onts)
                _val = [_eval(_v, onts) for _v in _eel]
            else:
                _val = _eval(val, onts)

            if _val:
                res[key] = _val
    else:
        for key, val in _dict.items():
            _val = _eval(val, onts)
            if _val:
                res[key] = _val
    return res
Example #11
0
    def verify_advice_assertion(self, resp, decr_text):
        assert resp.assertion[0].signature is None

        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])
        self.verify_encrypted_assertion(assertion, decr_text)
Example #12
0
    def test_encrypted_signed_response_2(self):
        name_id = self.server.ident.transient_nameid(
            "urn:mace:example.com:saml:roland:sp", "id12")
        ava = {"givenName": ["Derek"], "surName": ["Jeter"],
               "mail": ["*****@*****.**"], "title": "The man"}

        cert_str, cert_key_str = generate_cert()

        signed_resp = self.server.create_authn_response(
            ava,
            "id12",  # in_response_to
            "http://lingon.catalogix.se:8087/",  # consumer_url
            "urn:mace:example.com:saml:roland:sp",  # sp_entity_id
            name_id=name_id,
            sign_response=True,
            sign_assertion=True,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=True,
            encrypt_cert=cert_str,
        )

        sresponse = response_from_string(signed_resp)

        valid = self.server.sec.verify_signature(signed_resp,
                                                 self.server.config.cert_file,
                                                 node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response',
                                                 node_id=sresponse.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)

        assert resp.encrypted_assertion[0].extension_elements

        assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp])
        assert assertion
        assert assertion[0].attribute_statement

        ava = get_ava(assertion[0])

        assert ava ==\
               {'mail': ['*****@*****.**'], 'givenname': ['Derek'], 'surname': ['Jeter'], 'title': ['The man']}

        assert 'EncryptedAssertion><encas2:Assertion xmlns:encas0="http://www.w3.org/2000/09/xmldsig#" ' \
               'xmlns:encas1="http://www.w3.org/2001/XMLSchema-instance" ' \
               'xmlns:encas2="urn:oasis:names:tc:SAML:2.0:assertion"' in 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=assertion[0].id,
                                                 id_attr="")
        assert valid
Example #13
0
    def _holder_of_key_confirmed(self, data):
        if not data:
            return False

        has_keyinfo = False
        for element in extension_elements_to_elements(data, [samlp, saml, xenc, ds]):
            if isinstance(element, ds.KeyInfo):
                has_keyinfo = True

        return has_keyinfo
Example #14
0
    def parse_artifact_resolve_response(self, xmlstr):
        kwargs = {"entity_id": self.config.entityid,
                  "attribute_converters": self.config.attribute_converters}

        resp = self._parse_response(xmlstr, response.ArtifactResponse,
                                    "artifact_resolve", BINDING_SOAP,
                                    **kwargs)
        # should just be one
        elems = extension_elements_to_elements(resp.response.extension_elements,
                                               [samlp, saml])
        return elems[0]
Example #15
0
    def _holder_of_key_confirmed(self, data):
        if not data:
            return False

        has_keyinfo = False
        for element in extension_elements_to_elements(data,
                                                      [samlp, saml, xenc, ds]):
            if isinstance(element, ds.KeyInfo):
                has_keyinfo = True

        return has_keyinfo
Example #16
0
    def parse_artifact_resolve_response(self, xmlstr):
        kwargs = {"entity_id": self.config.entityid,
                  "attribute_converters": self.config.attribute_converters}

        resp = self._parse_response(xmlstr, saml_response.ArtifactResponse,
                                    "artifact_resolve", BINDING_SOAP,
                                    **kwargs)
        # should just be one
        elems = extension_elements_to_elements(resp.response.extension_elements,
                                               [samlp, saml])
        return elems[0]
Example #17
0
def to_dict(_dict, onts, mdb_safe=False):
    """
    Convert a pysaml2 SAML2 message class instance into a basic dictionary
    format.
    The export interface.

    :param _dict: The pysaml2 metadata instance
    :param onts: List of schemas to use for the conversion
    :return: The converted information
    """
    res = {}
    if isinstance(_dict, SamlBase):
        res["__class__"] = "%s&%s" % (_dict.c_namespace, _dict.c_tag)
        for key in _dict.keyswv():
            if key in IMP_SKIP:
                continue
            val = getattr(_dict, key)
            if key == "extension_elements":
                _eel = extension_elements_to_elements(
                    val, onts, keep_unmatched=True
                )
                _val = [_eval(_v, onts, mdb_safe) for _v in _eel]
            elif key == "extension_attributes":
                if mdb_safe:
                    _val = dict([(k.replace(".", "__"), v) for k, v in
                                 val.items()])
                    #_val = {k.replace(".", "__"): v for k, v in val.items()}
                else:
                    _val = val
            else:
                _val = _eval(val, onts, mdb_safe)

            if _val:
                if mdb_safe:
                    key = key.replace(".", "__")
                res[key] = _val
    elif isinstance(_dict, ExtensionElement):
        res = {
            key: _val
            for key, val in _dict.__dict__.items()
            if val and key not in IMP_SKIP
            for _val in [_eval(val, onts, mdb_safe)]
            if _val
        }
        res["__class__"] = "%s&%s" % (_dict.namespace, _dict.tag)
    else:
        for key, val in _dict.items():
            _val = _eval(val, onts, mdb_safe)
            if _val:
                if mdb_safe and "." in key:
                    key = key.replace(".", "__")
                res[key] = _val
    return res
Example #18
0
 def decrypt_assertions(self, encrypted_assertions, key_file=""):
     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:
                     if not self.sec.verify_signature("%s" % assertion, key_file, node_name=class_name(assertion)):
                         logger.error("Failed to verify signature on '%s'" % assertion)
                         raise SignatureError()
                 res.append(assertion)
     return res
Example #19
0
def test_xbox():
    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"): ("Foo", ""), ("", "", "givenName"): ("Bar", "")}
        ),
    )

    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)
Example #20
0
    def test_encrypted_response_2(self):
        name_id = self.server.ident.transient_nameid(
            "urn:mace:example.com:saml:roland:sp", "id12")
        ava = {
            "givenName": ["Derek"],
            "surName": ["Jeter"],
            "mail": ["*****@*****.**"],
            "title": "The man"
        }

        cert_str, cert_key_str = generate_cert()

        signed_resp = self.server.create_authn_response(
            ava,
            "id12",  # in_response_to
            "http://lingon.catalogix.se:8087/",  # consumer_url
            "urn:mace:example.com:saml:roland:sp",  # sp_entity_id
            name_id=name_id,
            sign_response=False,
            sign_assertion=False,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=True,
            encrypted_advice_attributes=False,
            encrypt_cert=cert_str,
        )

        sresponse = response_from_string(signed_resp)

        assert sresponse.signature is None

        _, 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)

        assert resp.encrypted_assertion[0].extension_elements

        assertion = extension_elements_to_elements(
            resp.encrypted_assertion[0].extension_elements, [saml, samlp])
        assert assertion
        assert assertion[0].attribute_statement

        ava = ava = get_ava(assertion[0])

        assert ava ==\
               {'mail': ['*****@*****.**'], 'givenname': ['Derek'], 'surname': ['Jeter'], 'title': ['The man']}

        assert 'EncryptedAssertion><encas1:Assertion xmlns:encas0="http://www.w3.org/2001/XMLSchema-instance" ' \
               'xmlns:encas1="urn:oasis:names:tc:SAML:2.0:assertion"' in decr_text

        assert assertion[0].signature is None
Example #21
0
def test_xbox():
    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"): ("Foo", ""),
             ("", "", "givenName"): ("Bar", ""), })
    )

    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)
Example #22
0
def test_do_idp_sso_descriptor():
    conf = IdPConfig().load(IDP)
    idpsso = metadata.do_idpsso_descriptor(conf)

    assert isinstance(idpsso, md.IDPSSODescriptor)
    assert _eq(idpsso.keyswv(), [
        'protocol_support_enumeration', 'single_sign_on_service',
        'want_authn_requests_signed', "extensions"
    ])
    exts = idpsso.extensions.extension_elements
    assert len(exts) == 2
    print(exts)
    inst = saml2.extension_element_to_element(exts[0],
                                              shibmd.ELEMENT_FROM_STRING,
                                              namespace=shibmd.NAMESPACE)
    assert isinstance(inst, shibmd.Scope)
    assert inst.text == "example.org"
    assert inst.regexp == "false"

    uiinfo = saml2.extension_element_to_element(exts[1],
                                                mdui.ELEMENT_FROM_STRING,
                                                namespace=mdui.NAMESPACE)

    assert uiinfo
    assert _eq(uiinfo.keyswv(), [
        'display_name', 'description', 'information_url',
        'privacy_statement_url', 'keywords', 'logo'
    ])

    assert len(uiinfo.privacy_statement_url) == 1
    assert uiinfo.privacy_statement_url[
        0].text == "http://example.com/saml2/privacyStatement.html"
    assert len(uiinfo.description) == 1
    assert uiinfo.description[0].text == "Exempel bolag"
    assert uiinfo.description[0].lang == "se"

    res = extension_elements_to_elements(exts, [shibmd, mdui])

    assert len(res) == 2
    # one is a shibmd.Scope instance and the other a mdui.UIInfo instance
    if isinstance(res[0], shibmd.Scope):
        assert isinstance(res[1], mdui.UIInfo)
    elif isinstance(res[1], shibmd.Scope):
        assert isinstance(res[0], mdui.UIInfo)

    found = idpsso.extensions.find_extensions(mdui.UIInfo.c_tag,
                                              mdui.NAMESPACE)
    assert len(found) == 1

    elem = idpsso.extensions.extensions_as_elements(mdui.UIInfo.c_tag, mdui)
    assert len(elem) == 1
    assert isinstance(elem[0], mdui.UIInfo)
Example #23
0
def test_do_idp_sso_descriptor():
    conf = IdPConfig().load(IDP, metadata_construction=True)
    idpsso = metadata.do_idpsso_descriptor(conf)

    assert isinstance(idpsso, md.IDPSSODescriptor)
    assert _eq(idpsso.keyswv(), ['protocol_support_enumeration', 
                                'single_sign_on_service', 
                                'want_authn_requests_signed',
                                "extensions"])
    exts = idpsso.extensions.extension_elements
    assert len(exts) == 2
    print exts
    inst = saml2.extension_element_to_element(exts[0],
                                              shibmd.ELEMENT_FROM_STRING,
                                              namespace=shibmd.NAMESPACE)
    assert isinstance(inst, shibmd.Scope)
    assert inst.text == "example.org"
    assert inst.regexp == "false"

    uiinfo = saml2.extension_element_to_element(exts[1],
                                              mdui.ELEMENT_FROM_STRING,
                                              namespace=mdui.NAMESPACE)

    assert uiinfo
    assert _eq(uiinfo.keyswv(), ['display_name', 'description',
                                 'information_url', 'privacy_statement_url',
                                 'keywords', 'logo'])

    assert len(uiinfo.privacy_statement_url) == 1
    assert uiinfo.privacy_statement_url[0].text == "http://example.com/saml2/privacyStatement.html"
    assert len(uiinfo.description) == 1
    assert uiinfo.description[0].text == "Exempel bolag"
    assert uiinfo.description[0].lang == "se"

    res = extension_elements_to_elements(exts,[shibmd, mdui])

    assert len(res) == 2
    # one is a shibmd.Scope instance and the other a mdui.UIInfo instance
    if isinstance(res[0], shibmd.Scope):
        assert isinstance(res[1], mdui.UIInfo)
    elif isinstance(res[1], shibmd.Scope):
        assert isinstance(res[0], mdui.UIInfo)

    found = idpsso.extensions.find_extensions(mdui.UIInfo.c_tag,
                                              mdui.NAMESPACE)
    assert len(found) == 1

    elem = idpsso.extensions.extensions_as_elements(mdui.UIInfo.c_tag, mdui)
    assert len(elem) == 1
    assert isinstance(elem[0], mdui.UIInfo)
Example #24
0
    def test_encrypted_signed_response_3(self):
        cert_str, cert_key_str = generate_cert()

        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=True,
            sign_assertion=True,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=False,
            encrypt_cert_assertion=cert_str,
        )

        sresponse = response_from_string(signed_resp)

        valid = self.server.sec.verify_signature(
            signed_resp,
            self.server.config.cert_file,
            node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response',
            node_id=sresponse.id,
            id_attr="")
        assert valid

        _, key_file = make_temp(str(cert_key_str).encode('ascii'),
                                decode=False)

        decr_text = self.server.sec.decrypt(signed_resp, key_file)

        resp = samlp.response_from_string(decr_text)

        resp.assertion = extension_elements_to_elements(
            resp.encrypted_assertion[0].extension_elements, [saml, samlp])

        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

        self.verify_assertion(resp.assertion)

        assert 'xmlns:encas' not in decr_text
Example #25
0
 def decrypt_assertions(self, encrypted_assertions, decr_txt):
     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:
                     if not self.sec.check_signature(
                             assertion, origdoc=decr_txt,
                             node_name=class_name(assertion)):
                         logger.error(
                             "Failed to verify signature on '%s'" % assertion)
                         raise SignatureError()
                 res.append(assertion)
     return res
Example #26
0
    def test_encrypted_signed_response_2(self):
        cert_str, cert_key_str = generate_cert()

        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=True,
            sign_assertion=False,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=True,
        )

        sresponse = response_from_string(signed_resp)

        valid = self.server.sec.verify_signature(
            signed_resp,
            self.server.config.cert_file,
            node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response',
            node_id=sresponse.id,
            id_attr="")
        assert valid

        decr_text_old = copy.deepcopy("%s" % signed_resp)

        decr_text = self.server.sec.decrypt(
            signed_resp, self.client.config.encryption_keypairs[0]["key_file"])

        assert decr_text == decr_text_old

        decr_text = self.server.sec.decrypt(
            signed_resp, self.client.config.encryption_keypairs[1]["key_file"])

        assert decr_text != decr_text_old

        resp = samlp.response_from_string(decr_text)

        resp.assertion = extension_elements_to_elements(
            resp.encrypted_assertion[0].extension_elements, [saml, samlp])

        assert resp.assertion[0].signature == None

        self.verify_assertion(resp.assertion)
Example #27
0
    def test_encrypted_signed_response_3(self):
        cert_str, cert_key_str = generate_cert()

        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=True,
            sign_assertion=True,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=False,
            encrypt_cert_assertion=cert_str,
        )

        sresponse = response_from_string(signed_resp)

        valid = self.server.sec.verify_signature(signed_resp,
                                                 self.server.config.cert_file,
                                                 node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response',
                                                 node_id=sresponse.id,
                                                 id_attr="")
        assert valid

        _, key_file = make_temp(str(cert_key_str).encode('ascii'), decode=False)

        decr_text = self.server.sec.decrypt(signed_resp, key_file)

        resp = samlp.response_from_string(decr_text)

        resp.assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp])

        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

        self.verify_assertion(resp.assertion)

        assert 'xmlns:encas' not in decr_text
Example #28
0
def to_dict(_dict, onts, mdb_safe=False):
    """
    Convert a pysaml2 SAML2 message class instance into a basic dictionary
    format.
    The export interface.

    :param _dict: The pysaml2 metadata instance
    :param onts: List of schemas to use for the conversion
    :return: The converted information
    """
    res = {}
    if isinstance(_dict, SamlBase):
        res["__class__"] = "%s&%s" % (_dict.c_namespace, _dict.c_tag)
        for key in _dict.keyswv():
            if key in IMP_SKIP:
                continue
            val = getattr(_dict, key)
            if key == "extension_elements":
                _eel = extension_elements_to_elements(val, onts)
                _val = [_eval(_v, onts, mdb_safe) for _v in _eel]
            elif key == "extension_attributes":
                if mdb_safe:
                    _val = dict([(k.replace(".", "__"), v) for k, v in
                                 val.items()])
                    #_val = {k.replace(".", "__"): v for k, v in val.items()}
                else:
                    _val = val
            else:
                _val = _eval(val, onts, mdb_safe)

            if _val:
                if mdb_safe:
                    key = key.replace(".", "__")
                res[key] = _val
    else:
        for key, val in _dict.items():
            _val = _eval(val, onts, mdb_safe)
            if _val:
                if mdb_safe and "." in key:
                    key = key.replace(".", "__")
                res[key] = _val
    return res
Example #29
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:
                        assertion_id_pos = decr_txt.index(assertion.id)
                        assertion_beg_tag = decr_txt.rindex(
                            '<', 0, assertion_id_pos)

                        closing_assertion_pos = decr_txt.index(
                            'Assertion', assertion_id_pos)
                        assertion_end_tag = decr_txt.index(
                            '>', closing_assertion_pos) + 1

                        origdoc = decr_txt[assertion_beg_tag:assertion_end_tag]

                        if not self.sec.check_signature(
                                assertion,
                                origdoc=origdoc,
                                node_name=class_name(assertion),
                                issuer=issuer):
                            logger.error("Failed to verify signature on '%s'" %
                                         assertion)
                            raise SignatureError()
                    res.append(assertion)
        return res
Example #30
0
def test_okta():
    conf = config.Config()
    conf.load_file("server_conf")
    conf.id_attr_name = 'Id'
    md = MetadataStore([saml, samlp], None, conf)
    md.load("local", IDP_EXAMPLE)

    conf.metadata = md
    conf.only_use_keys_in_metadata = False
    sec = sigver.security_context(conf)
    with open(OKTA_RESPONSE) as f:
        enctext = f.read()
    decr_text = sec.decrypt(enctext)
    _seass = saml.encrypted_assertion_from_string(decr_text)
    assers = extension_elements_to_elements(_seass.extension_elements,
                                            [saml, samlp])

    with open(OKTA_ASSERTION) as f:
        okta_assertion = f.read()
    expected_assert = assertion_from_string(okta_assertion)
    assert len(assers) == 1
    assert assers[0] == expected_assert
Example #31
0
def test_okta():
    conf = config.Config()
    conf.load_file("server_conf")
    conf.id_attr_name = 'Id'
    md = MetadataStore([saml, samlp], None, conf)
    md.load("local", IDP_EXAMPLE)

    conf.metadata = md
    conf.only_use_keys_in_metadata = False
    sec = sigver.security_context(conf)
    with open(OKTA_RESPONSE) as f:
        enctext = f.read()
    decr_text = sec.decrypt(enctext)
    _seass = saml.encrypted_assertion_from_string(decr_text)
    assers = extension_elements_to_elements(_seass.extension_elements,
                                            [saml, samlp])

    with open(OKTA_ASSERTION) as f:
        okta_assertion = f.read()
    expected_assert = assertion_from_string(okta_assertion)
    assert len(assers) == 1
    assert assers[0] == expected_assert
Example #32
0
    def test_encrypted_response_6(self):
        _server = Server("idp_conf_verify_cert")

        cert_str_advice, cert_key_str_advice = generate_cert()

        cert_str_assertion, cert_key_str_assertion = generate_cert()

        _resp = _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=False,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=True,
            pefim=True,
            encrypt_cert_advice=cert_str_advice,
            encrypt_cert_assertion=cert_str_assertion)

        sresponse = response_from_string(_resp)

        assert sresponse.signature is None

        _, key_file = make_temp(cert_key_str_assertion, decode=False)

        decr_text_1 = _server.sec.decrypt(_resp, key_file)

        _, key_file = make_temp(cert_key_str_advice, decode=False)

        decr_text_2 = _server.sec.decrypt(decr_text_1, key_file)

        resp = samlp.response_from_string(decr_text_2)

        resp.assertion = extension_elements_to_elements(
            resp.encrypted_assertion[0].extension_elements, [saml, samlp])

        self.verify_advice_assertion(resp, decr_text_2)
    def ava_from(self, attribute, allow_unknown=False):
        try:
            attr = self._fro[attribute.name.strip().lower()]
        except AttributeError:
            attr = attribute.friendly_name.strip().lower()
        except KeyError:
            if allow_unknown:
                try:
                    attr = attribute.name.strip().lower()
                except AttributeError:
                    attr = attribute.friendly_name.strip().lower()
            else:
                raise

        val = []
        for value in attribute.attribute_value:
            if value.extension_elements:
                ext = extension_elements_to_elements(value.extension_elements,
                                                     [saml])
                for ex in ext:
                    if attr == "eduPersonTargetedID" and ex.text:
                        val.append(ex.text.strip())
                    else:
                        cval = {}
                        for key, (name, typ, mul) in ex.c_attributes.items():
                            exv = getattr(ex, name)
                            if exv:
                                cval[name] = exv
                        if ex.text:
                            cval["value"] = ex.text.strip()
                        val.append({ex.c_tag: cval})
            elif not value.text:
                val.append('')
            else:
                val.append(value.text.strip())

        return attr, val
Example #34
0
    def _parse_response(self,
                        xmlstr,
                        response_cls,
                        service,
                        binding,
                        outstanding_certs=None,
                        **kwargs):
        """ Deal with a Response

        :param xmlstr: The response as a xml string
        :param response_cls: What type of response it is
        :param binding: What type of binding this message came through.
        :param kwargs: Extra key word arguments
        :return: None if the reply doesn't contain a valid SAML Response,
            otherwise the response.
        """

        response = None

        if self.config.accepted_time_diff:
            kwargs["timeslack"] = self.config.accepted_time_diff

        if "asynchop" not in kwargs:
            if binding in [BINDING_SOAP, BINDING_PAOS]:
                kwargs["asynchop"] = False
            else:
                kwargs["asynchop"] = True

        if xmlstr:
            if "return_addrs" not in kwargs:
                if binding in [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST]:
                    try:
                        # expected return address
                        kwargs["return_addrs"] = self.config.endpoint(
                            service, binding=binding)
                    except Exception:
                        logger.info("Not supposed to handle this!")
                        return None

            try:
                response = response_cls(self.sec, **kwargs)
            except Exception as exc:
                logger.info("%s" % exc)
                raise

            xmlstr = self.unravel(xmlstr, binding, response_cls.msgtype)
            origxml = xmlstr
            if outstanding_certs is not None:
                _response = samlp.any_response_from_string(xmlstr)
                if len(_response.encrypted_assertion) > 0:
                    _, cert_file = make_temp(
                        "%s" %
                        outstanding_certs[_response.in_response_to]["key"],
                        decode=False)
                    cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary)
                    xmlstr = cbxs.decrypt(xmlstr, cert_file)

            if not xmlstr:  # Not a valid reponse
                return None

            try:
                response = response.loads(xmlstr, False, origxml=origxml)
            except SigverError as err:
                logger.error("Signature Error: %s" % err)
                raise
            except UnsolicitedResponse:
                logger.error("Unsolicited response")
                raise
            except Exception as err:
                if "not well-formed" in "%s" % err:
                    logger.error("Not well-formed XML")
                    raise

            logger.debug("XMLSTR: %s" % xmlstr)

            if hasattr(response.response, 'encrypted_assertion'):
                for encrypted_assertion in response.response\
                        .encrypted_assertion:
                    if encrypted_assertion.extension_elements is not None:
                        assertion_list = extension_elements_to_elements(
                            encrypted_assertion.extension_elements, [saml])
                        for assertion in assertion_list:
                            _assertion = saml.assertion_from_string(
                                str(assertion))
                            response.response.assertion.append(_assertion)

            if response:
                response = response.verify()

            if not response:
                return None

                #logger.debug(response)

        return response
Example #35
0
    def test_encrypted_signed_response_4(self):

        cert_str, cert_key_str = generate_cert()

        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=True,
            sign_assertion=True,
            encrypt_assertion=True,
            encrypt_assertion_self_contained=True,
            pefim=True,
            encrypt_cert_advice=cert_str,
        )

        sresponse = response_from_string(signed_resp)

        valid = self.server.sec.verify_signature(
            signed_resp,
            self.server.config.cert_file,
            node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response',
            node_id=sresponse.id,
            id_attr="")
        assert valid

        decr_text = self.server.sec.decrypt(
            signed_resp, self.client.config.encryption_keypairs[1]["key_file"])

        resp = samlp.response_from_string(decr_text)

        resp.assertion = extension_elements_to_elements(
            resp.encrypted_assertion[0].extension_elements, [saml, samlp])

        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

        _, key_file = make_temp(cert_key_str, decode=False)

        decr_text = self.server.sec.decrypt(decr_text, key_file)

        resp = samlp.response_from_string(decr_text)

        assertion = extension_elements_to_elements(
            resp.encrypted_assertion[0].extension_elements, [saml, samlp])
        assertion = \
             extension_elements_to_elements(assertion[0].advice.encrypted_assertion[0].extension_elements,[saml, samlp])
        self.verify_assertion(assertion)

        #PEFIM never signs assertion in advice
        assert assertion[0].signature is None
        #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=assertion[0].id,
        #                                         id_attr="")
        assert valid
Example #36
0
    def test_sign_then_encrypt_assertion(self):
        # Begin with the IdPs side
        _sec = self.server.sec

        assertion = s_utils.assertion_factory(
            subject=factory(saml.Subject, text="_aaa",
                            name_id=factory(
                                saml.NameID,
                                format=saml.NAMEID_FORMAT_TRANSIENT)),
            attribute_statement=do_attribute_statement(
                {
                    ("", "", "surName"): ("Jeter", ""),
                    ("", "", "givenName"): ("Derek", ""),
                }
            ),
            issuer=self.server._issuer(),
        )

        assertion.signature = sigver.pre_signature_part(
            assertion.id, _sec.my_cert, 1)

        sigass = _sec.sign_statement(assertion, class_name(assertion),
                                     key_file="pki/mykey.pem",
                                     node_id=assertion.id)
        # Create an Assertion instance from the signed assertion
        _ass = saml.assertion_from_string(sigass)

        response = sigver.response_factory(
            in_response_to="_012345",
            destination="https:#www.example.com",
            status=s_utils.success_status_factory(),
            issuer=self.server._issuer(),
            assertion=_ass
        )

        enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file,
                                                pre_encryption_part())

        seresp = samlp.response_from_string(enctext)

        # Now over to the client side
        _csec = self.client.sec
        if seresp.encrypted_assertion:
            decr_text = _csec.decrypt(enctext)
            seresp = samlp.response_from_string(decr_text)
            resp_ass = []

            sign_cert_file = "pki/mycert.pem"
            for enc_ass in seresp.encrypted_assertion:
                assers = extension_elements_to_elements(
                    enc_ass.extension_elements, [saml, samlp])
                for ass in assers:
                    if ass.signature:
                        if not _csec.verify_signature("%s" % ass,
                                                      sign_cert_file,
                                                      node_name=class_name(ass)):
                            continue
                    resp_ass.append(ass)

            seresp.assertion = resp_ass
            seresp.encrypted_assertion = None
            #print _sresp

        assert seresp.assertion
Example #37
0
    def test_encrypted_signed_response_4(self):
        name_id = self.server.ident.transient_nameid(
            "urn:mace:example.com:saml:roland:sp", "id12")
        ava = {
            "givenName": ["Derek"],
            "surName": ["Jeter"],
            "mail": ["*****@*****.**"],
            "title": "The man"
        }

        cert_str, cert_key_str = generate_cert()

        signed_resp = self.server.create_authn_response(
            ava,
            "id12",  # in_response_to
            "http://lingon.catalogix.se:8087/",  # consumer_url
            "urn:mace:example.com:saml:roland:sp",  # sp_entity_id
            name_id=name_id,
            sign_response=True,
            sign_assertion=True,
            encrypt_assertion=True,
            encrypted_advice_attributes=True,
            encrypt_cert=cert_str,
        )

        sresponse = response_from_string(signed_resp)

        valid = self.server.sec.verify_signature(
            signed_resp,
            self.server.config.cert_file,
            node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response',
            node_id=sresponse.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': ['*****@*****.**'], 'givenname': ['Derek'], 'surname': ['Jeter'], 'title': ['The man']}

        #Should work, but I suspect that xmlsec manipulates the xml to much while encrypting that the signature
        #is no longer working. :(

        assert 'xmlns:encas' not in 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=assertion[0].id,
            id_attr="")
        assert valid
Example #38
0
                logger.error("Signature Error: %s" % err)
                raise
            except UnsolicitedResponse:
                logger.error("Unsolicited response")
                raise
            except Exception, err:
                if "not well-formed" in "%s" % err:
                    logger.error("Not well-formed XML")
                    raise

            logger.debug("XMLSTR: %s" % xmlstr)

            if hasattr(response.response, 'encrypted_assertion'):
                for encrypted_assertion in response.response.encrypted_assertion:
                    if encrypted_assertion.extension_elements is not None:
                        assertion_list = extension_elements_to_elements(encrypted_assertion.extension_elements, [saml])
                        for assertion in assertion_list:
                            _assertion = saml.assertion_from_string(str(assertion))
                            response.response.assertion.append(_assertion)

            if response:
                response = response.verify()

            if not response:
                return None

            #logger.debug(response)

        return response

    # ------------------------------------------------------------------------
Example #39
0
    def _parse_response(self, xmlstr, response_cls, service, binding,
                        outstanding_certs=None, **kwargs):
        """ Deal with a Response

        :param xmlstr: The response as a xml string
        :param response_cls: What type of response it is
        :param binding: What type of binding this message came through.
        :param kwargs: Extra key word arguments
        :return: None if the reply doesn't contain a valid SAML Response,
            otherwise the response.
        """

        response = None

        if self.config.accepted_time_diff:
            kwargs["timeslack"] = self.config.accepted_time_diff

        if "asynchop" not in kwargs:
            if binding in [BINDING_SOAP, BINDING_PAOS]:
                kwargs["asynchop"] = False
            else:
                kwargs["asynchop"] = True

        if xmlstr:
            if "return_addrs" not in kwargs:
                if binding in [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST]:
                    try:
                        # expected return address
                        kwargs["return_addrs"] = self.config.endpoint(
                            service, binding=binding)
                    except Exception:
                        logger.info("Not supposed to handle this!")
                        return None

            try:
                response = response_cls(self.sec, **kwargs)
            except Exception as exc:
                logger.info("%s" % exc)
                raise

            xmlstr = self.unravel(xmlstr, binding, response_cls.msgtype)
            origxml = xmlstr
            if outstanding_certs is not None:
                _response = samlp.any_response_from_string(xmlstr)
                if len(_response.encrypted_assertion) > 0:
                    _, cert_file = make_temp(
                        "%s" % outstanding_certs[_response.in_response_to][
                            "key"],
                        decode=False)
                    cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary)
                    xmlstr = cbxs.decrypt(xmlstr, cert_file)

            if not xmlstr:  # Not a valid reponse
                return None

            try:
                response = response.loads(xmlstr, False, origxml=origxml)
            except SigverError as err:
                logger.error("Signature Error: %s" % err)
                raise
            except UnsolicitedResponse:
                logger.error("Unsolicited response")
                raise
            except Exception as err:
                if "not well-formed" in "%s" % err:
                    logger.error("Not well-formed XML")
                    raise

            logger.debug("XMLSTR: %s" % xmlstr)

            if hasattr(response.response, 'encrypted_assertion'):
                for encrypted_assertion in response.response\
                        .encrypted_assertion:
                    if encrypted_assertion.extension_elements is not None:
                        assertion_list = extension_elements_to_elements(
                            encrypted_assertion.extension_elements, [saml])
                        for assertion in assertion_list:
                            _assertion = saml.assertion_from_string(
                                str(assertion))
                            response.response.assertion.append(_assertion)

            if response:
                response = response.verify()

            if not response:
                return None

                #logger.debug(response)

        return response
Example #40
0
cert = read_cert_from_file(full_path("test.pem"), "pem")

spcertenc = SPCertEnc(x509_data=ds.X509Data(
    x509_certificate=ds.X509Certificate(text=cert)))

extensions = Extensions(
    extension_elements=[element_to_extension_element(spcertenc)])

req_id, req = client.create_authn_request(
    "http://www.example.com/sso",
    "urn:mace:example.com:it:tek",
    nameid_format=saml.NAMEID_FORMAT_PERSISTENT,
    message_id="666",
    extensions=extensions)

print req

# Get a certificate from an authn request

xml = "%s" % req

parsed = authn_request_from_string(xml)

_elem = extension_elements_to_elements(parsed.extensions.extension_elements,
                                       [pefim, ds])

assert len(_elem) == 1
_spcertenc = _elem[0]
_cert = _spcertenc.x509_data[0].x509_certificate.text
assert cert == _cert
Example #41
0
    def test_encrypted_signed_response_4(self):
        name_id = self.server.ident.transient_nameid(
            "urn:mace:example.com:saml:roland:sp", "id12")
        ava = {"givenName": ["Derek"], "surName": ["Jeter"],
               "mail": ["*****@*****.**"], "title": "The man"}

        cert_str, cert_key_str = generate_cert()

        signed_resp = self.server.create_authn_response(
            ava,
            "id12",  # in_response_to
            "http://lingon.catalogix.se:8087/",  # consumer_url
            "urn:mace:example.com:saml:roland:sp",  # sp_entity_id
            name_id=name_id,
            sign_response=True,
            sign_assertion=True,
            encrypt_assertion=True,
            encrypted_advice_attributes=True,
            encrypt_cert=cert_str,
        )

        sresponse = response_from_string(signed_resp)

        valid = self.server.sec.verify_signature(signed_resp,
                                                 self.server.config.cert_file,
                                                 node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response',
                                                 node_id=sresponse.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': ['*****@*****.**'], 'givenname': ['Derek'], 'surname': ['Jeter'], 'title': ['The man']}

        #Should work, but I suspect that xmlsec manipulates the xml to much while encrypting that the signature
        #is no longer working. :(

        assert 'xmlns:encas' not in 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=assertion[0].id,
                                                 id_attr="")
        assert valid
Example #42
0
    def ava_from(self, attribute, allow_unknown=False):
        try:
            attr = self._fro[attribute.name.strip().lower()]
        except AttributeError:
            attr = attribute.friendly_name.strip().lower()
        except KeyError:
            if allow_unknown:
                try:
                    attr = attribute.name.strip().lower()
                except AttributeError:
                    attr = attribute.friendly_name.strip().lower()
            else:
                raise

        val = []
        for value in attribute.attribute_value:
            if value.extension_elements:
                ext = extension_elements_to_elements(value.extension_elements,
                                                     [saml])
                for ex in ext:
                    if attr == "eduPersonTargetedID" and ex.text:
                        val.append(ex.text.strip())
                    else:
                        cval = {}
                        for key, (name, typ, mul) in ex.c_attributes.items():
                            exv = getattr(ex, name)
                            if exv:
                                cval[name] = exv
                        if ex.text:
                            cval["value"] = ex.text.strip()
                        val.append({ex.c_tag: cval})
            elif not value.text:
                val.append('')
            else:
                cur_val = value.text.strip()
                if XSI_TYPE in value.extension_attributes:
                    cur_type = value.extension_attributes[XSI_TYPE]
                    cur_type_prefix = None
                    if cur_type.find(":") > 0:
                        cur_type_prefix = cur_type[0:cur_type.find(":")]
                        if ("xmlns:" +
                                cur_type_prefix) in value.extension_attributes:
                            cur_type = "{" + value.extension_attributes[
                                "xmlns:" + cur_type_prefix] + "}" + cur_type[
                                    (len(cur_type_prefix) + 1):]

                    if cur_type == "{http://www.w3.org/2001/XMLSchema}boolean":
                        cur_val = (True if cur_val == "true" else False)
                    elif cur_type in [
                            "{http://www.w3.org/2001/XMLSchema}decimal",
                            "{http://www.w3.org/2001/XMLSchema}float",
                            "{http://www.w3.org/2001/XMLSchema}double",
                            "{http://www.w3.org/2001/XMLSchema}float"
                    ]:
                        cur_val = float(cur_val)
                    elif cur_type in [
                            "{http://www.w3.org/2001/XMLSchema}integer",
                            "{http://www.w3.org/2001/XMLSchema}nonPositiveInteger",
                            "{http://www.w3.org/2001/XMLSchema}negativeInteger",
                            "{http://www.w3.org/2001/XMLSchema}int",
                            "{http://www.w3.org/2001/XMLSchema}short",
                            "{http://www.w3.org/2001/XMLSchema}byte",
                            "{http://www.w3.org/2001/XMLSchema}nonNegativeInteger",
                            "{http://www.w3.org/2001/XMLSchema}unsignedInt",
                            "{http://www.w3.org/2001/XMLSchema}unsignedShort",
                            "{http://www.w3.org/2001/XMLSchema}unsignedByte",
                            "{http://www.w3.org/2001/XMLSchema}positiveInteger"
                    ]:
                        cur_val = int(cur_val)
                    elif cur_type in [
                            "{http://www.w3.org/2001/XMLSchema}long",
                            "{http://www.w3.org/2001/XMLSchema}unsignedLong"
                    ]:
                        cur_val = long(cur_val)
                val.append(cur_val)

        return attr, val
Example #43
0
spcertenc = SPCertEnc(
    x509_data=ds.X509Data(
        x509_certificate=ds.X509Certificate(text=cert)))

extensions = Extensions(
    extension_elements=[element_to_extension_element(spcertenc)])

req_id, req = client.create_authn_request(
    "http://www.example.com/sso",
    "urn:mace:example.com:it:tek",
    nameid_format=saml.NAMEID_FORMAT_PERSISTENT,
    message_id="666",
    extensions=extensions)


print req

# Get a certificate from an authn request

xml = "%s" % req

parsed = authn_request_from_string(xml)

_elem = extension_elements_to_elements(parsed.extensions.extension_elements,
                                       [pefim, ds])

assert len(_elem) == 1
_spcertenc = _elem[0]
_cert = _spcertenc.x509_data[0].x509_certificate.text
assert cert == _cert
Example #44
0
    def test_sign_then_encrypt_assertion(self):
        # Begin with the IdPs side
        _sec = self.server.sec

        assertion = s_utils.assertion_factory(
            subject=factory(saml.Subject,
                            text="_aaa",
                            name_id=factory(
                                saml.NameID,
                                format=saml.NAMEID_FORMAT_TRANSIENT)),
            attribute_statement=do_attribute_statement({
                ("", "", "surName"): ("Jeter", ""),
                ("", "", "givenName"): ("Derek", ""),
            }),
            issuer=self.server._issuer(),
        )

        assertion.signature = sigver.pre_signature_part(
            assertion.id, _sec.my_cert, 1)

        sigass = _sec.sign_statement(assertion,
                                     class_name(assertion),
                                     key_file=full_path("test.key"),
                                     node_id=assertion.id)
        # Create an Assertion instance from the signed assertion
        _ass = saml.assertion_from_string(sigass)

        response = sigver.response_factory(
            in_response_to="_012345",
            destination="https:#www.example.com",
            status=s_utils.success_status_factory(),
            issuer=self.server._issuer(),
            assertion=_ass)

        enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file,
                                                pre_encryption_part())

        seresp = samlp.response_from_string(enctext)

        # Now over to the client side
        _csec = self.client.sec
        if seresp.encrypted_assertion:
            decr_text = _csec.decrypt(enctext)
            seresp = samlp.response_from_string(decr_text)
            resp_ass = []

            sign_cert_file = full_path("test.pem")
            for enc_ass in seresp.encrypted_assertion:
                assers = extension_elements_to_elements(
                    enc_ass.extension_elements, [saml, samlp])
                for ass in assers:
                    if ass.signature:
                        if not _csec.verify_signature(
                                "%s" % ass,
                                sign_cert_file,
                                node_name=class_name(ass)):
                            continue
                    resp_ass.append(ass)

            seresp.assertion = resp_ass
            seresp.encrypted_assertion = None
            #print _sresp

        assert seresp.assertion