Exemple #1
0
    def __call__(self,
                 session_id: Optional[str] = "",
                 token_class: Optional[str] = "",
                 **payload) -> str:
        """
        Return a token.

        :param session_id: Session id
        :param token_class: Token class
        :param payload: A dictionary with information that is part of the payload of the JWT.
        :return: Signed JSON Web Token
        """
        if not token_class and self.token_class:
            token_class = self.token_class
        else:
            token_class = "authorization_code"

        payload.update({"sid": session_id, "token_class": token_class})
        payload = self.load_custom_claims(payload)

        # payload.update(kwargs)
        _context = self.server_get("endpoint_context")
        signer = JWT(
            key_jar=_context.keyjar,
            iss=self.issuer,
            lifetime=self.lifetime,
            sign_alg=self.alg,
        )

        return signer.pack(payload)
Exemple #2
0
    def test_jwt_unknown_key(self):
        _keyjar = build_keyjar(KEYDEFS)

        _jwt = JWT(
            _keyjar,
            iss=self.introspection_endpoint.server_get(
                "endpoint_context").issuer,
            lifetime=3600,
        )

        _jwt.with_jti = True

        _payload = {"sub": "subject_id"}
        _token = _jwt.pack(_payload, aud="client_1")
        _context = self.introspection_endpoint.server_get("endpoint_context")

        _req = self.introspection_endpoint.parse_request({
            "token":
            _token,
            "client_id":
            "client_1",
            "client_secret":
            _context.cdb["client_1"]["client_secret"],
        })

        _req = self.introspection_endpoint.parse_request(_req)
        _resp = self.introspection_endpoint.process_request(_req)
        assert _resp["response_args"]["active"] is False
Exemple #3
0
def create_trust_mark(entity_id, key_jar, trust_mark_id, subject='', lifetime=0, trust_mark='',
                      reference=''):
    """
    Create Trust Mark.

    :param entity_id: The issuers entity_id
    :param key_jar: A KeyJar that contains useful keys
    :param trust_mark_id: The Trust Mark identifier
    :param subject: The subject's id
    :param lifetime: For how long the trust mark should be valid (0=for ever)
    :param trust_mark: A URL pointing to a graphic trust mark
    :param reference: A URL pointing to reference material for this trust mark
    :return: A signed JWT containing the provided information
    """
    _tm = TrustMark(
        id=trust_mark_id,
    )
    if trust_mark:
        _tm["mark"] = trust_mark
    if reference:
        _tm["ref"] = reference

    if subject:
        _tm['sub'] = subject
    else:
        _tm['sub'] = entity_id

    # Create the Signed JWT representing the Trust Mark
    _jwt = JWT(key_jar=key_jar, iss=entity_id, lifetime=lifetime)
    return _jwt.pack(_tm)
    def test_process_request_using_private_key_jwt(self):
        session_id = setup_session(
            self.endpoint.endpoint_context,
            AUTH_REQ,
            uid="user",
            acr=INTERNETPROTOCOLPASSWORD,
        )
        _token_request = TOKEN_REQ_DICT.copy()
        del _token_request["client_id"]
        del _token_request["client_secret"]
        _context = self.endpoint.endpoint_context

        _jwt = JWT(CLIENT_KEYJAR, iss=AUTH_REQ["client_id"], sign_alg="RS256")
        _jwt.with_jti = True
        _assertion = _jwt.pack({"aud": [_context.endpoint["token"].full_path]})
        _token_request.update({
            "client_assertion": _assertion,
            "client_assertion_type": JWT_BEARER
        })
        _token_request["code"] = self.endpoint.endpoint_context.sdb[
            session_id]["code"]

        _context.sdb.update(session_id, user="******")
        _req = self.endpoint.parse_request(_token_request)
        _resp = self.endpoint.process_request(request=_req)

        # 2nd time used
        with pytest.raises(UnAuthorizedClient):
            self.endpoint.parse_request(_token_request)
Exemple #5
0
def test_get_trust_mark_3rd_party():
    _iss = "https://feide.no"
    _sub = "https://op.ntnu.no"

    config = {'keys': {'key_defs': KEYSPEC}}

    federation_entity = FederationEntity(
        _iss,
        trusted_roots=ANCHOR,
        config=config,
        authority_hints=['https://ntnu.no'],
        entity_type='openid_relying_party',
        httpd=Publisher(ROOT_DIR),
        opponent_entity_type='openid_relying_party')

    federation_entity.collector = DummyCollector(httpd=Publisher(ROOT_DIR),
                                                 trusted_roots=ANCHOR,
                                                 root_dir=ROOT_DIR)

    _tm = TrustMark(
        id="https://refeds.org/wp-content/uploads/2016/01/Sirtfi-1.0.pdf",
        sub=_sub,
    )

    # Create the Signed JWT representing the Trust Mark
    _jwt0 = JWT(key_jar=federation_entity.keyjar, iss=_iss, lifetime=3600)
    _jws = _jwt0.pack(_tm)

    trust_anchor_id = list(ANCHOR.keys())[0]

    _tm = get_trust_mark(federation_entity, _jws, _sub, trust_anchor_id)

    assert isinstance(_tm, TrustMark)
    def test_client_claims_scopes_and_request_claims_no_match(self):
        session_id = self._create_session(AREQRC)
        grant = self.session_manager[session_id]

        self.session_manager.token_handler["id_token"].kwargs[
            "add_claims_by_scope"] = True

        _claims = self.endpoint_context.claims_interface.get_claims(
            session_id=session_id,
            scopes=AREQRC["scope"],
            claims_release_point="id_token")
        grant.claims = {"id_token": _claims}

        id_token = self._mint_id_token(grant, session_id)

        client_keyjar = KeyJar()
        _jwks = self.endpoint_context.keyjar.export_jwks()
        client_keyjar.import_jwks(_jwks, self.endpoint_context.issuer)
        _jwt = JWT(key_jar=client_keyjar, iss="client_1")
        res = _jwt.unpack(id_token.value)
        # User information, from scopes -> claims
        assert "address" in res
        assert "email" in res
        # User info, requested by claims parameter
        assert "nickname" in res
    def test_client_claims(self):
        session_id = self._create_session(AREQ)
        grant = self.session_manager[session_id]

        self.session_manager.token_handler["id_token"].kwargs[
            "enable_claims_per_client"] = True
        self.endpoint_context.cdb["client_1"]["id_token_claims"] = {
            "address": None
        }

        _claims = self.endpoint_context.claims_interface.get_claims(
            session_id=session_id,
            scopes=AREQ["scope"],
            claims_release_point="id_token")
        grant.claims = {"id_token": _claims}

        id_token = self._mint_id_token(grant, session_id)

        client_keyjar = KeyJar()
        _jwks = self.endpoint_context.keyjar.export_jwks()
        client_keyjar.import_jwks(_jwks, self.endpoint_context.issuer)
        _jwt = JWT(key_jar=client_keyjar, iss="client_1")
        res = _jwt.unpack(id_token.value)
        assert "address" in res
        assert "nickname" not in res
    def test_client_claims_scopes_and_request_claims_one_match(self):
        _req = AREQS.copy()
        _req["claims"] = {
            "id_token": {
                "email": {
                    "value": "*****@*****.**"
                }
            }
        }

        session_id = self._create_session(_req)
        grant = self.session_manager[session_id]

        self.session_manager.token_handler["id_token"].kwargs[
            "add_claims_by_scope"] = True

        _claims = self.endpoint_context.claims_interface.get_claims(
            session_id=session_id,
            scopes=_req["scope"],
            claims_release_point="id_token")
        grant.claims = {"id_token": _claims}

        id_token = self._mint_id_token(grant, session_id)

        client_keyjar = KeyJar()
        _jwks = self.endpoint_context.keyjar.export_jwks()
        client_keyjar.import_jwks(_jwks, self.endpoint_context.issuer)
        _jwt = JWT(key_jar=client_keyjar, iss="client_1")
        res = _jwt.unpack(id_token.value)
        # Email didn't match
        assert "email" not in res
        # Scope -> claims
        assert "address" in res
    def test_pushed_auth_request(self):
        _msg = Message().from_urlencoded(AUTHN_REQUEST)
        _jwt = JWT(key_jar=self.rp_keyjar, iss="s6BhdRkqt3")
        _jws = _jwt.pack(_msg.to_dict())

        authn_request = "request={}".format(_jws)
        http_info = {
            "headers": {"authorization": "Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3"}
        }

        _req = self.pushed_authorization_endpoint.parse_request(authn_request, http_info=http_info)

        assert isinstance(_req, AuthorizationRequest)
        _req = remove_jwt_parameters(_req)
        assert set(_req.keys()) == {
            "state",
            "redirect_uri",
            "response_type",
            "scope",
            "code_challenge_method",
            "client_id",
            "code_challenge",
            "request",
            "__verified_request",
        }
Exemple #10
0
    def test_process_request_using_private_key_jwt(self):
        session_id = self._create_session(AUTH_REQ)
        grant = self.session_manager[session_id]
        code = self._mint_code(grant, AUTH_REQ["client_id"])

        _token_request = TOKEN_REQ_DICT.copy()
        del _token_request["client_id"]
        del _token_request["client_secret"]
        _context = self.endpoint_context

        _jwt = JWT(CLIENT_KEYJAR, iss=AUTH_REQ["client_id"], sign_alg="RS256")
        _jwt.with_jti = True
        _assertion = _jwt.pack({"aud": [self.token_endpoint.full_path]})
        _token_request.update({
            "client_assertion": _assertion,
            "client_assertion_type": JWT_BEARER
        })
        _token_request["code"] = code.value

        _req = self.token_endpoint.parse_request(_token_request)
        _resp = self.token_endpoint.process_request(request=_req)

        # 2nd time used
        with pytest.raises(UnAuthorizedClient):
            self.token_endpoint.parse_request(_token_request)
    def test_parse_request_uri(self):
        _jwt = JWT(key_jar=self.rp_keyjar, iss="client_1", sign_alg="HS256")
        _jws = _jwt.pack(
            AUTH_REQ_DICT,
            aud=self.endpoint.server_get(
                "endpoint_context").provider_info["issuer"],
        )

        request_uri = "https://client.example.com/req"
        # -----------------
        with responses.RequestsMock() as rsps:
            rsps.add("GET", request_uri, body=_jws, status=200)
            _req = self.endpoint.parse_request({
                "request_uri":
                request_uri,
                "redirect_uri":
                AUTH_REQ.get("redirect_uri"),
                "response_type":
                AUTH_REQ.get("response_type"),
                "client_id":
                AUTH_REQ.get("client_id"),
                "scope":
                AUTH_REQ.get("scope"),
            })

        assert "__verified_request" in _req
Exemple #12
0
    def _parse_remote_response(self, response):
        """
        Parse simple JWKS or signed JWKS from the HTTP response.

        :param response: HTTP response from the 'jwks_uri' or 'signed_jwks_uri'
            endpoint
        :return: response parsed as JSON or None
        """
        # Check if the content type is the right one.
        try:
            if response.headers["Content-Type"] == 'application/json':
                logger.debug(
                    "Loaded JWKS: %s from %s" % (response.text, self.source))
                try:
                    return json.loads(response.text)
                except ValueError:
                    return None
            elif response.headers["Content-Type"] == 'application/jwt':
                logger.debug(
                    "Signed JWKS: %s from %s" % (response.text, self.source))
                _jwt = JWT(key_jar=self.federation_keys)
                _resp = _jwt.unpack(response.text)
                return _resp
            else:
                logger.error('Wrong content type: {}'.format(
                    response.headers['Content-Type']))
                raise ValueError('Content-type mismatch')
        except KeyError:
            pass
    def test_pushed_auth_urlencoded(self):
        # since all endpoint used the same endpoint_context I can grab anyone
        _op_context = self.registration_endpoint.server_get("endpoint_context")

        # This is cheating. Getting the OP's provider info
        _fe = self.registration_service.client_get("service_context").federation_entity
        trust_chain = TrustChain()
        trust_chain.metadata = _op_context.provider_info
        trust_chain.anchor = "https://feide.no"
        trust_chain.verified_chain = [{'iss': "https://ntnu.no"}]

        self.discovery_service.update_service_context([trust_chain])
        # and the OP's federation keys
        _op_context.federation_entity.context.keyjar.import_jwks(
            read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no', 'jwks'),
            issuer_id=_op_context.provider_info['issuer'])

        # Add RP's OIDC keys to the OP's keyjar.
        _op_context.keyjar.import_jwks(
            self.discovery_service.client_get("service_context").keyjar.export_jwks(issuer_id=""),
            RP_ENTITY_ID
        )

        authn_request = AuthorizationRequest(
            response_type="code", state="af0ifjsldkj",
            client_id=RP_ENTITY_ID, redirect_uri="{}/callback".format(RP_ENTITY_ID),
            code_challenge="K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U",
            code_challenge_method="S256", scope=["ais", "openid"]
        )

        # Create the private_key_jwt assertion
        _jwt = JWT(self.registration_service.client_get("service_context").keyjar,
                   iss=RP_ENTITY_ID,
                   sign_alg="RS256")
        _jwt.with_jti = True
        _assertion = _jwt.pack(
            {
                "aud": [_op_context.provider_info["pushed_authorization_request_endpoint"]]
            })
        authn_request.update({"client_assertion": _assertion, "client_assertion_type": JWT_BEARER})

        _req = self.pushed_authorization_endpoint.parse_request(authn_request)

        assert isinstance(_req, AuthorizationRequest)
        assert set(_req.keys()) == {
            "state",
            "redirect_uri",
            "response_type",
            "scope",
            "code_challenge_method",
            "client_id",
            "code_challenge",
            "client_assertion",
            "client_assertion_type",
            '__verified_client_assertion'
        }

        # Should have a registered client now
        assert set(_op_context.cdb.keys()) == {RP_ENTITY_ID}
Exemple #14
0
    def signed_jwks(self, issuer, sign_alg: Optional[str] = "RS256"):
        """

        :return: Signed JWT containing a JWKS
        """
        jwks = json.loads(self.jwks())
        _jwt = JWT(self.federation_keys, iss=issuer, sign_alg=sign_alg)
        return _jwt.pack(jwks)
Exemple #15
0
    def do_jws(self, token, default_response):
        _jwt = JWT(key_jar=self.endpoint_context.keyjar)

        try:
            _jwt_info = _jwt.unpack(token)
        except Exception:
            return {"response_args": default_response}

        return _jwt_info
Exemple #16
0
    def get_payload(self, token):
        _context = self.server_get("endpoint_context")
        verifier = JWT(key_jar=_context.keyjar, allowed_sign_algs=[self.alg])
        try:
            _payload = verifier.unpack(token)
        except JWSException:
            raise UnknownToken()

        return _payload
    def test_do_request_uri(self):
        request = AuthorizationRequest(
            redirect_uri="https://rp.example.com/cb", request_uri="https://example.com/request",
        )

        orig_request = AuthorizationRequest(
            client_id="client_id",
            redirect_uri="https://rp.example.com/cb",
            response_type=["id_token token"],
            state="state",
            nonce="nonce",
            scope="openid",
        )
        _jwt = JWT(key_jar=self.rp_keyjar, iss="client_1", sign_alg="HS256")
        _jws = _jwt.pack(
            orig_request.to_dict(),
            aud=self.endpoint.server_get("endpoint_context").provider_info["issuer"],
        )

        endpoint_context = self.endpoint.server_get("endpoint_context")
        endpoint_context.cdb["client_1"]["request_uris"] = [("https://example.com/request", {})]

        with responses.RequestsMock() as rsps:
            rsps.add(
                "GET",
                request["request_uri"],
                body=_jws,
                adding_headers={"Content-Type": "application/jose"},
                status=200,
            )

            self.endpoint._do_request_uri(request, "client_1", endpoint_context)

        request["request_uri"] = "https://example.com/request#1"

        with responses.RequestsMock() as rsps:
            rsps.add(
                "GET",
                request["request_uri"],
                body=_jws,
                adding_headers={"Content-Type": "application/jose"},
                status=200,
            )

            self.endpoint._do_request_uri(request, "client_1", endpoint_context)

        request["request_uri"] = "https://example.com/another"
        with pytest.raises(ValueError):
            self.endpoint._do_request_uri(request, "client_1", endpoint_context)

        endpoint_context.provider_info["request_uri_parameter_supported"] = False
        with pytest.raises(ServiceError):
            self.endpoint._do_request_uri(request, "client_1", endpoint_context)
Exemple #18
0
    def is_expired(self, token, when=0):
        """
        Evaluate whether the token has expired or not

        :param token: The token
        :param when: The time against which to check the expiration
            0 means now.
        :return: True/False
        """
        verifier = JWT(key_jar=self.key_jar, allowed_sign_algs=[self.alg])
        _payload = verifier.unpack(token)
        return is_expired(_payload["exp"], when)
Exemple #19
0
    def _create_jwt(self, uid, lifetime=0, with_jti=False):
        _jwt = JWT(
            self.introspection_endpoint.endpoint_context.keyjar,
            iss=self.introspection_endpoint.endpoint_context.issuer,
            lifetime=lifetime,
        )

        if with_jti:
            _jwt.with_jti = with_jti

        _info = self.introspection_endpoint.endpoint_context.userinfo.db[uid]
        _payload = {"sub": _info["sub"]}
        return _jwt.pack(_payload, aud="client_1")
Exemple #20
0
    def create_trust_mark(self, id, sub):
        _now = utc_time_sans_frac()
        _add = {'iat': _now, 'id': id, 'sub': sub}
        lifetime = self.tm_lifetime.get(id)
        if lifetime:
            _add['exp'] = _now + lifetime

        content = self.trust_marks[id].copy()
        content.update(_add)
        self.issued.add(id, content)
        _ctx = self.server_get("context")
        packer = JWT(key_jar=_ctx.keyjar, iss=_ctx.entity_id)
        return packer.pack(payload=content)
    def test_no_available_claims(self):
        session_id = self._create_session(AREQ)
        grant = self.session_manager[session_id]
        grant.claims = {"id_token": {"foobar": None}}

        id_token = self._mint_id_token(grant, session_id)

        client_keyjar = KeyJar()
        _jwks = self.endpoint_context.keyjar.export_jwks()
        client_keyjar.import_jwks(_jwks, self.endpoint_context.issuer)
        _jwt = JWT(key_jar=client_keyjar, iss="client_1")
        res = _jwt.unpack(id_token.value)
        assert "foobar" not in res
    def test_lifetime_default(self):
        session_id = self._create_session(AREQ)
        grant = self.session_manager[session_id]

        id_token = self._mint_id_token(grant, session_id)

        client_keyjar = KeyJar()
        _jwks = self.endpoint_context.keyjar.export_jwks()
        client_keyjar.import_jwks(_jwks, self.endpoint_context.issuer)
        _jwt = JWT(key_jar=client_keyjar, iss="client_1")
        res = _jwt.unpack(id_token.value)

        assert res["exp"] - res["iat"] == LIFETIME
Exemple #23
0
def verify_self_signed_signature(config):
    """
    Verify signature. Will raise exception if signature verification fails.

    :param config: Signed JWT
    :return: Payload of the signed JWT
    """

    payload = unverified_entity_statement(config)
    keyjar = KeyJar()
    keyjar.import_jwks(payload['jwks'], payload['iss'])

    _jwt = JWT(key_jar=keyjar)
    _val = _jwt.unpack(config)
    return _val
    def test_sign_encrypt_id_token(self):
        session_id = self._create_session(AREQ)
        grant = self.session_manager[session_id]
        id_token = self._mint_id_token(grant, session_id)

        _jws = factory(id_token.value)
        assert _jws.jwt.headers["alg"] == "RS256"

        client_keyjar = KeyJar()
        _jwks = self.endpoint_context.keyjar.export_jwks()
        client_keyjar.import_jwks(_jwks, self.endpoint_context.issuer)

        _jwt = JWT(key_jar=client_keyjar, iss="client_1")
        res = _jwt.unpack(id_token.value)
        assert isinstance(res, dict)
        assert res["aud"] == ["client_1"]
 def test_parse_request(self):
     _jwt = JWT(key_jar=self.rp_keyjar, iss="client_1", sign_alg="HS256")
     _jws = _jwt.pack(
         AUTH_REQ_DICT, aud=self.endpoint.server_get("endpoint_context").provider_info["issuer"],
     )
     # -----------------
     _req = self.endpoint.parse_request(
         {
             "request": _jws,
             "redirect_uri": AUTH_REQ.get("redirect_uri"),
             "response_type": AUTH_REQ.get("response_type"),
             "client_id": AUTH_REQ.get("client_id"),
             "scope": AUTH_REQ.get("scope"),
         }
     )
     assert "__verified_request" in _req
Exemple #26
0
    def __call__(self, sid: str, uinfo: Dict, sinfo: Dict, *args,
                 aud: Optional[Any], client_id: Optional[str], **kwargs):
        """
        Return a token.

        :param sid: Session id
        :param uinfo: User information
        :param sinfo: Session information
        :param aud: The default audience == client_id
        :return:
        """
        payload = {"sid": sid, "ttype": self.type, "sub": sinfo["sub"]}

        if self.add_claims:
            self.do_add_claims(payload, uinfo, self.add_claims)
        if self.add_claims_by_scope:
            self.do_add_claims(
                payload,
                uinfo,
                scope2claims(sinfo["authn_req"]["scope"],
                             map=self.scope_claims_map).keys(),
            )
        # Add claims if is access token
        if self.type == 'T' and self.enable_claims_per_client:
            client = self.cdb.get(client_id, {})
            client_claims = client.get("access_token_claims")
            if client_claims:
                self.do_add_claims(payload, uinfo, client_claims)

        payload.update(kwargs)
        signer = JWT(
            key_jar=self.key_jar,
            iss=self.issuer,
            lifetime=self.lifetime,
            sign_alg=self.alg,
        )

        if aud is None:
            _aud = self.def_aud
        else:
            _aud = aud if isinstance(aud, list) else [aud]
            _aud.extend(self.def_aud)

        return signer.pack(payload, aud=_aud)
Exemple #27
0
    def __call__(
        self,
        sid: str,
        uinfo: Dict,
        sinfo: Dict,
        *args,
        aud: Optional[Any],
        **kwargs
    ):
        """
        Return a token.

        :param sid: Session id
        :param uinfo: User information
        :param sinfo: Session information
        :param aud: The default audience == client_id
        :return:
        """
        payload = {"sid": sid, "ttype": self.type, "sub": sinfo["sub"]}

        if "add_claims" in self.args:
            self.add_claims(payload, uinfo, self.args["add_claims"])
        if "add_claims_by_scope":
            self.add_claims(
                payload, uinfo, scope2claims(sinfo["authn_req"]["scope"]).keys()
            )

        payload.update(kwargs)
        signer = JWT(
            key_jar=self.key_jar,
            iss=self.issuer,
            lifetime=self.lifetime,
            sign_alg=self.alg,
        )

        if aud is None:
            _aud = self.def_aud
        else:
            _aud = aud if isinstance(aud, list) else [aud]
            _aud.extend(self.def_aud)

        return signer.pack(payload, aud=_aud)
Exemple #28
0
    def info(self, token):
        """
        Return type of Token (A=Access code, T=Token, R=Refresh token) and
        the session id.

        :param token: A token
        :return: tuple of token type and session id
        """
        verifier = JWT(key_jar=self.key_jar, allowed_sign_algs=[self.alg])
        _payload = verifier.unpack(token)

        if is_expired(_payload["exp"]):
            raise ToOld("Token has expired")
        # All the token metadata
        _res = {
            "sid": _payload["sid"],
            "type": _payload["ttype"],
            "exp": _payload["exp"],
            "handler": self,
        }
        return _res
    def test_client_claims_with_default(self):
        session_id = self._create_session(AREQ)
        grant = self.session_manager[session_id]

        _claims = self.endpoint_context.claims_interface.get_claims(
            session_id=session_id,
            scopes=AREQ["scope"],
            claims_release_point="id_token")
        grant.claims = {"id_token": _claims}

        id_token = self._mint_id_token(grant, session_id)

        client_keyjar = KeyJar()
        _jwks = self.endpoint_context.keyjar.export_jwks()
        client_keyjar.import_jwks(_jwks, self.endpoint_context.issuer)
        _jwt = JWT(key_jar=client_keyjar, iss="client_1")
        res = _jwt.unpack(id_token.value)

        # No user info claims should be there
        assert "address" not in res
        assert "nickname" not in res
Exemple #30
0
def test_create_trust_mark_self_signed():
    _entity_id = "https://example.com/op"
    _tm = TrustMark(
        id="https://openid.net/certification/op",
        sub=_entity_id,
        mark="http://openid.net/wordpress-content/uploads/2016/05/oid-l-certification-mark-l-cmyk" \
             "-150dpi-90mm.jpg",
        ref="https://openid.net/wordpress-content/uploads/2015/09/RolandHedberg-pyoidc-0.7.7"
            "-Basic-26-Sept-2015.zip"
    )

    _key_jar = build_keyjar(KEYSPEC, issuer_id=_entity_id)

    # Create the Signed JWT representing the Trust Mark
    _jwt0 = JWT(key_jar=_key_jar, iss=_entity_id, lifetime=3600)
    _jws = _jwt0.pack(_tm)

    # Unpack and verify the Trust Mark
    _jwt1 = JWT(key_jar=_key_jar,
                msg_cls=TrustMark,
                allowed_sign_algs=["RS256"])
    res_tm = _jwt1.unpack(_jws)
    res_tm.verify(entity_id=_entity_id)

    assert isinstance(res_tm, TrustMark)
    assert res_tm["id"] == "https://openid.net/certification/op"