Beispiel #1
0
    def create_assertion_id_request_response(self,
                                             assertion_id,
                                             sign=False,
                                             sign_alg=None,
                                             digest_alg=None,
                                             **kwargs):
        """

        :param assertion_id:
        :param sign:
        :return:
        """

        try:
            (assertion, to_sign) = self.session_db.get_assertion(assertion_id)
        except KeyError:
            raise Unknown

        if to_sign:
            if assertion.signature is None:
                assertion.signature = pre_signature_part(assertion.id,
                                                         self.sec.my_cert,
                                                         1,
                                                         sign_alg=sign_alg,
                                                         digest_alg=digest_alg)

            return signed_instance_factory(assertion, self.sec, to_sign)
        else:
            return assertion
Beispiel #2
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
Beispiel #3
0
    def create_assertion_id_request_response(self, assertion_id, sign=False,
                                             sign_alg=None,
                                             digest_alg=None, **kwargs):
        """

        :param assertion_id:
        :param sign:
        :return:
        """

        try:
            (assertion, to_sign) = self.session_db.get_assertion(assertion_id)
        except KeyError:
            raise Unknown

        if to_sign:
            if assertion.signature is None:
                assertion.signature = pre_signature_part(assertion.id,
                                                         self.sec.my_cert, 1,
                                                         sign_alg=sign_alg,
                                                         digest_alg=digest_alg)

            return signed_instance_factory(assertion, self.sec, to_sign)
        else:
            return assertion
Beispiel #4
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))
Beispiel #5
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
Beispiel #6
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
Beispiel #7
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
Beispiel #8
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"
Beispiel #9
0
    def setup_class(self):
        # This would be one way to initialize the security context :
        #
        #    conf = config.SPConfig()
        #    conf.load_file("server_conf")
        #    conf.only_use_keys_in_metadata = False
        #
        # but instead, FakeConfig() is used to really only use the minimal
        # set of parameters needed for these test cases. Other test cases
        # (TestSecurityMetadata below) excersise the SPConfig() mechanism.
        #
        conf = FakeConfig()
        self.sec = sigver.security_context(conf)

        self._assertion = factory(
            saml.Assertion,
            version="2.0",
            id="11111",
            issue_instant="2009-10-30T13:20:28Z",
            signature=sigver.pre_signature_part("11111", self.sec.my_cert, 1),
            attribute_statement=do_attribute_statement({
                ("", "", "surName"): ("Föö", ""),
                ("", "", "givenName"): ("Bär", ""),
            })
        )
Beispiel #10
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)
Beispiel #11
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)
Beispiel #12
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
Beispiel #13
0
    def setup_class(self):
        conf = config.SPConfig()
        conf.load_file("server_conf")
        md = MetadataStore([saml, samlp], None, conf)
        md.load("local", full_path("metadata_cert.xml"))

        conf.metadata = md
        conf.only_use_keys_in_metadata = False
        self.sec = sigver.security_context(conf)

        assertion = factory(
            saml.Assertion, version="2.0", id="11111",
            issue_instant="2009-10-30T13:20:28Z",
            signature=sigver.pre_signature_part("11111", self.sec.my_cert, 1),
            attribute_statement=do_attribute_statement(
                {("", "", "surName"): ("Föö", ""),
                 ("", "", "givenName"): ("Bär", ""), })
        )
Beispiel #14
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
Beispiel #15
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
Beispiel #16
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
Beispiel #17
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'])
Beispiel #18
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
Beispiel #19
0
    def setup_class(self):
        logging.debug("Creating test pkcs11 token using softhsm")
        try:
            self.softhsm_db = self._tf()
            self.softhsm_conf = self._tf()
            self.signer_cert_pem = self._tf()
            self.openssl_conf = self._tf()
            self.signer_cert_der = self._tf()

            logging.debug("Generating softhsm.conf")
            with open(self.softhsm_conf, "w") as f:
                f.write("#Generated by pysaml2 cryptobackend test\n0:%s\n" %
                        self.softhsm_db)
            logging.debug("Initializing the token")
            self._p([
                'softhsm', '--slot', '0', '--label', 'test', '--init-token',
                '--pin', 'secret1', '--so-pin', 'secret2'
            ])

            logging.debug(
                "Importing test key {!r} into SoftHSM".format(PRIV_KEY))
            self._p([
                'softhsm', '--slot', '0', '--label', 'test', '--import',
                PRIV_KEY, '--id', 'a1b2', '--pin', 'secret1', '--so-pin',
                'secret2'
            ])

            logging.debug("Transforming PEM certificate to DER")
            self._p([
                'openssl', 'x509', '-inform', 'PEM', '-outform', 'DER', '-in',
                PUB_KEY, '-out', self.signer_cert_der
            ])

            logging.debug("Importing certificate into token")

            self._p([
                'pkcs11-tool', '--module', P11_MODULE, '-l', '--slot', '0',
                '--id', 'a1b2', '--label', 'test', '-y', 'cert', '-w',
                self.signer_cert_der, '--pin', 'secret1'
            ])

            # list contents of SoftHSM
            self._p([
                'pkcs11-tool', '--module', P11_MODULE, '-l', '--pin',
                'secret1', '-O'
            ])
            self._p([
                'pkcs11-tool', '--module', P11_MODULE, '-l', '--pin',
                'secret1', '-T'
            ])
            self._p([
                'pkcs11-tool', '--module', P11_MODULE, '-l', '--pin',
                'secret1', '-L'
            ])
            self.sec = sigver.security_context(FakeConfig(pub_key=PUB_KEY))
            self._assertion = factory(
                saml.Assertion,
                version="2.0",
                id="11111",
                issue_instant="2009-10-30T13:20:28Z",
                signature=sigver.pre_signature_part("11111", self.sec.my_cert,
                                                    1),
                attribute_statement=do_attribute_statement({
                    ("", "", "surName"): ("Foo", ""),
                    ("", "", "givenName"): ("Bar", ""),
                }))
            self.configured = True
        except Exception as ex:
            print("-" * 64)
            traceback.print_exc()
            print("-" * 64)
            logging.warning(
                "PKCS11 tests disabled: unable to initialize test token: %s" %
                ex)
            raise
Beispiel #20
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)
Beispiel #21
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)
Beispiel #22
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)
Beispiel #23
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)
    def setup_class(self):
        logging.debug("Creating test pkcs11 token using softhsm")
        try:
            self.softhsm_db = self._tf()
            self.softhsm_conf = self._tf()
            self.signer_cert_pem = self._tf()
            self.openssl_conf = self._tf()
            self.signer_cert_der = self._tf()

            logging.debug("Generating softhsm.conf")
            with open(self.softhsm_conf, "w") as f:
                f.write("#Generated by pysaml2 cryptobackend test\n0:%s\n" % self.softhsm_db)
            logging.debug("Initializing the token")
            self._p(['softhsm',
                    '--slot', '0',
                    '--label', 'test',
                    '--init-token',
                    '--pin', 'secret1',
                    '--so-pin', 'secret2'])

            logging.debug("Importing test key {!r} into SoftHSM".format(PRIV_KEY))
            self._p(['softhsm',
                    '--slot', '0',
                    '--label', 'test',
                    '--import', PRIV_KEY,
                    '--id', 'a1b2',
                    '--pin', 'secret1',
                    '--so-pin', 'secret2'])

            logging.debug("Transforming PEM certificate to DER")
            self._p(['openssl', 'x509',
                    '-inform', 'PEM',
                    '-outform', 'DER',
                    '-in', PUB_KEY,
                    '-out', self.signer_cert_der])

            logging.debug("Importing certificate into token")

            self._p(['pkcs11-tool',
                    '--module', P11_MODULE,
                    '-l',
                    '--slot', '0',
                    '--id', 'a1b2',
                    '--label', 'test',
                    '-y', 'cert',
                    '-w', self.signer_cert_der,
                    '--pin', 'secret1'])

            # list contents of SoftHSM
            self._p(['pkcs11-tool',
                     '--module', P11_MODULE,
                     '-l',
                     '--pin', 'secret1', '-O'])
            self._p(['pkcs11-tool',
                    '--module', P11_MODULE,
                    '-l',
                    '--pin', 'secret1', '-T'])
            self._p(['pkcs11-tool',
                    '--module', P11_MODULE,
                    '-l',
                    '--pin', 'secret1', '-L'])
            self.sec = sigver.security_context(FakeConfig(pub_key = PUB_KEY))
            self._assertion = factory(saml.Assertion,
                                      version="2.0",
                                      id="11111",
                                      issue_instant="2009-10-30T13:20:28Z",
                                      signature=sigver.pre_signature_part("11111", self.sec.my_cert, 1),
                                      attribute_statement=do_attribute_statement(
                                          {("", "", "surName"): ("Foo", ""),
                                           ("", "", "givenName"): ("Bar", ""),
                                           })
                                      )
            self.configured = True
        except Exception as ex:
            print("-" * 64)
            traceback.print_exc()
            print("-" * 64)
            logging.warning("PKCS11 tests disabled: unable to initialize test token: %s" % ex)
            raise