Exemple #1
0
def test_verify_id_token_missing_c_hash():
    code = 'AccessCode1'

    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
            ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        })

    kj = KeyJar()
    kj.add_symmetric("", 'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    kj.add_symmetric("https://sso.qa.7pass.ctf.prosiebensat1.com",
                     'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    packer = JWT(kj, sign_alg='HS256',
                 iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                 lifetime=3600)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(code=code, id_token=_jws)
    with pytest.raises(MissingRequiredAttribute):
        verify_id_token(msg, check_hash=True, keyjar=kj,
                        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                        client_id="554295ce3770612820620000")
Exemple #2
0
def test_verify_id_token_at_hash_and_chash():
    token = 'AccessTokenWhichCouldBeASignedJWT'
    at_hash = left_hash(token)
    code = 'AccessCode1'
    c_hash = left_hash(code)

    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
            ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        "at_hash": at_hash,
        'c_hash': c_hash
        })

    kj = KeyJar()
    kj.add_symmetric("", 'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    kj.add_symmetric("https://sso.qa.7pass.ctf.prosiebensat1.com",
                     'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    packer = JWT(kj, sign_alg='HS256',
                 iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                 lifetime=3600)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(access_token=token, id_token=_jws, code=code)
    verify_id_token(msg, check_hash=True, keyjar=kj,
                    iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                    client_id="554295ce3770612820620000")
Exemple #3
0
def test_verify_id_token_at_hash_fail():
    token = 'AccessTokenWhichCouldBeASignedJWT'
    token2 = 'ACompletelyOtherAccessToken'
    lhsh = left_hash(token)

    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
            ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        "at_hash": lhsh
        })

    kj = KeyJar()
    kj.add_symmetric("", 'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    kj.add_symmetric("https://sso.qa.7pass.ctf.prosiebensat1.com",
                     'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    packer = JWT(kj, sign_alg='HS256',
                 iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                 lifetime=3600)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(access_token=token2, id_token=_jws)
    with pytest.raises(AtHashError):
        verify_id_token(msg, check_hash=True, keyjar=kj,
                        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                        client_id="554295ce3770612820620000")
Exemple #4
0
 def create_access_token(self, key_thumbprint):
     # creating the access_token
     jwt_constructor = JWT(self.keyjar, iss=self.me)
     # Audience is myself
     return jwt_constructor.pack(kid="abc",
                                 cnf={"kid": key_thumbprint},
                                 aud=self.me)
Exemple #5
0
def test_jwt_pack_and_unpack():
    srv = JWT(keyjar, iss=issuer)
    _jwt = srv.pack(sub="sub")

    info = srv.unpack(_jwt)

    assert _eq(info.keys(), ["jti", "iat", "exp", "iss", "sub", "kid"])
Exemple #6
0
    def __call__(self, req, **kwargs):
        """

        :param req: Original metadata statement as a 
            :py:class:`MetadataStatement` instance
        :param keyjar: KeyJar in which the necessary keys should reside
        :param iss: Issuer ID
        :param alg: Which signing algorithm to use
        :param kwargs: Additional metadata statement attribute values
        :return: A JWT
        """
        iss = self.iss
        keyjar = self.signing_keys

        # Own copy
        _metadata = copy.deepcopy(req)
        if self.add_ons:
            _metadata.update(self.add_ons)

        _jwt = JWT(keyjar,
                   iss=iss,
                   msgtype=_metadata.__class__,
                   lifetime=self.lifetime)
        _jwt.sign_alg = self.alg

        if iss in keyjar.issuer_keys:
            owner = iss
        else:
            owner = ''

        if kwargs:
            return _jwt.pack(cls_instance=_metadata, owner=owner, **kwargs)
        else:
            return _jwt.pack(cls_instance=_metadata, owner=owner)
Exemple #7
0
def test_jwt_pack_and_unpack():
    srv = JWT(keyjar, iss=issuer)
    _jwt = srv.pack(sub='sub')

    info = srv.unpack(_jwt)

    assert _eq(info.keys(), ['jti', 'iat', 'exp', 'iss', 'sub'])
Exemple #8
0
def test_verify_token_encrypted_no_key():
    idt = IdToken(
        sub="553df2bcf909104751cfd8b2",
        aud=["5542958437706128204e0000", "554295ce3770612820620000"],
        auth_time=1441364872,
        azp="554295ce3770612820620000",
    )
    kj = KeyJar()
    kb = KeyBundle()
    kb.do_local_der(
        os.path.join(os.path.dirname(__file__), "data", "keys", "cert.key"),
        "some",
        ["enc", "sig"],
    )
    kj.add_kb("", kb)
    kj.add_kb("https://sso.qa.7pass.ctf.prosiebensat1.com", kb)

    packer = JWT(
        kj,
        lifetime=3600,
        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
        encrypt=True,
    )
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    # Do not pass they keyjar with keys
    with pytest.raises(VerificationError):
        verify_id_token(
            msg,
            keyjar=KeyJar(),
            iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
            client_id="554295ce3770612820620000",
        )
Exemple #9
0
def test_verify_id_token_missing_c_hash():
    code = "AccessCode1"

    idt = IdToken(
        **{
            "sub": "553df2bcf909104751cfd8b2",
            "aud": ["5542958437706128204e0000", "554295ce3770612820620000"],
            "auth_time": 1441364872,
            "azp": "554295ce3770612820620000",
        })

    kj = KeyJar()
    kj.add_symmetric("", "dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ", ["sig"])
    kj.add_symmetric(
        "https://sso.qa.7pass.ctf.prosiebensat1.com",
        "dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ",
        ["sig"],
    )
    packer = JWT(
        kj,
        sign_alg="HS256",
        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
        lifetime=3600,
    )
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(code=code, id_token=_jws)
    with pytest.raises(MissingRequiredAttribute):
        verify_id_token(
            msg,
            check_hash=True,
            keyjar=kj,
            iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
            client_id="554295ce3770612820620000",
        )
Exemple #10
0
def test_verify_id_token_at_hash():
    token = "AccessTokenWhichCouldBeASignedJWT"
    lhsh = left_hash(token)

    idt = IdToken(
        **{
            "sub": "553df2bcf909104751cfd8b2",
            "aud": ["5542958437706128204e0000", "554295ce3770612820620000"],
            "auth_time": 1441364872,
            "azp": "554295ce3770612820620000",
            "at_hash": lhsh,
        })

    kj = KeyJar()
    kj.add_symmetric("", "dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ", ["sig"])
    kj.add_symmetric(
        "https://sso.qa.7pass.ctf.prosiebensat1.com",
        "dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ",
        ["sig"],
    )
    packer = JWT(
        kj,
        sign_alg="HS256",
        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
        lifetime=3600,
    )
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(access_token=token, id_token=_jws)
    verify_id_token(
        msg,
        check_hash=True,
        keyjar=kj,
        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
        client_id="554295ce3770612820620000",
    )
Exemple #11
0
def test_verify_id_token_mismatch_aud_azp():
    idt = IdToken(
        **{
            "sub": "553df2bcf909104751cfd8b2",
            "aud": ["5542958437706128204e0000", "554295ce3770612820620000"],
            "auth_time": 1441364872,
            "azp": "aaaaaaaaaaaaaaaaaaaa",
        })

    kj = KeyJar()
    kj.add_symmetric("", "dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ", ["sig"])
    kj.add_symmetric(
        "https://sso.qa.7pass.ctf.prosiebensat1.com",
        "dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ",
        ["sig"],
    )
    packer = JWT(kj,
                 sign_alg="HS256",
                 iss="https://example.com/as",
                 lifetime=3600)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    with pytest.raises(ValueError):
        verify_id_token(
            msg,
            keyjar=kj,
            iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
            client_id="aaaaaaaaaaaaaaaaaaaa",
        )
Exemple #12
0
def test_verify_token_encrypted():
    idt = IdToken(
        sub="553df2bcf909104751cfd8b2",
        aud=["5542958437706128204e0000", "554295ce3770612820620000"],
        auth_time=1441364872,
        azp="554295ce3770612820620000",
    )
    kj = KeyJar()
    kb = KeyBundle()
    kb.do_local_der(
        os.path.join(os.path.dirname(__file__), "data", "keys", "cert.key"),
        "some",
        ["enc", "sig"],
    )
    kj.add_kb("", kb)
    kj.add_kb("https://sso.qa.7pass.ctf.prosiebensat1.com", kb)

    packer = JWT(
        kj,
        lifetime=3600,
        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
        encrypt=True,
    )
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    vidt = verify_id_token(
        msg,
        keyjar=kj,
        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
        client_id="554295ce3770612820620000",
    )
    assert vidt
    assert vidt.jwe_header == {"enc": "A128CBC-HS256", "alg": "RSA1_5", "cty": "JWT"}
Exemple #13
0
    def pack_metadata_statement(self,
                                metadata,
                                keyjar=None,
                                iss=None,
                                alg='',
                                **kwargs):
        """

        :param metas: Original metadata statement as a MetadataStatement
        instance
        :param keyjar: KeyJar in which the necessary keys should reside
        :param alg: Which signing algorithm to use
        :param kwargs: Additional metadata statement attribute values
        :return: A JWT
        """
        if iss is None:
            iss = self.iss
        if keyjar is None:
            keyjar = self.keyjar

        # Own copy
        _metadata = copy.deepcopy(metadata)
        _metadata.update(kwargs)
        _jwt = JWT(keyjar, iss=iss, msgtype=_metadata.__class__)
        if alg:
            _jwt.sign_alg = alg

        return _jwt.pack(cls_instance=_metadata)
Exemple #14
0
def test_jwt_pack_and_unpack():
    srv = JWT(keyjar, iss=issuer)
    _jwt = srv.pack(sub="sub")

    info = srv.unpack(_jwt)

    assert _eq(info.keys(), ["jti", "iat", "exp", "iss", "sub", "kid"])
Exemple #15
0
def test_jwt_pack_and_unpack():
    srv = JWT(keyjar, iss=issuer)
    _jwt = srv.pack(sub='sub')

    info = srv.unpack(_jwt)

    assert _eq(info.keys(), ['jti', 'iat', 'exp', 'iss', 'sub', 'kid'])
Exemple #16
0
    def token_introspection(self, token):
        jwt_constructor = JWT(self.keyjar, iss=self.me)
        res = jwt_constructor.unpack(token)

        tir = TokenIntrospectionResponse(active=True)
        tir["key"] = json.dumps(self.thumbprint2key[res["cnf"]["kid"]])

        return tir
Exemple #17
0
    def token_introspection(self, token):
        jwt_constructor = JWT(self.keyjar, iss=self.me)
        res = jwt_constructor.unpack(token)

        tir = TokenIntrospectionResponse(active=True)
        tir['key'] = json.dumps(self.thumbprint2key[res['cnf']['kid']])

        return tir
Exemple #18
0
 def __init__(self, typ, keyjar, lifetime, **kwargs):
     self.type = typ
     JWT.__init__(self, keyjar, lifetime=lifetime, msgtype=TokenAssertion,
                  **kwargs)
     Token.__init__(self, typ, lifetime=lifetime, **kwargs)
     self.db = {}
     self.session_info = {}
     self.exp_args = ['sinfo']
Exemple #19
0
 def __init__(self, typ, keyjar, lt_pattern=None, **kwargs):
     self.type = typ
     JWT.__init__(self, keyjar, msgtype=TokenAssertion, **kwargs)
     Token.__init__(self, typ, **kwargs)
     self.lt_pattern = lt_pattern or {}
     self.db = {}
     self.session_info = {'': 600}
     self.exp_args = ['sinfo']
Exemple #20
0
 def __init__(self, typ, keyjar, lt_pattern=None, extra_claims=None, **kwargs):
     self.type = typ
     JWT.__init__(self, keyjar, msgtype=TokenAssertion, **kwargs)
     Token.__init__(self, typ, **kwargs)
     self.lt_pattern = lt_pattern or {}
     self.db = {}
     self.session_info = {"": 600}
     self.exp_args = ["sinfo"]
     self.extra_claims = extra_claims or {}
Exemple #21
0
 def create_signed_bundle(self, sign_alg='RS256', iss_list=None):
     """
     Create a signed JWT containing a dictionary with Issuer IDs as keys
     and JWKSs as values
     :param sign_alg: Which algorithm to use when signing the JWT
     :return: A signed JWT
     """
     data = json.dumps(self.dict(iss_list))
     _jwt = JWT(self.sign_keys, iss=self.iss, sign_alg=sign_alg)
     return _jwt.pack(bundle=data)
Exemple #22
0
def verify_signed_bundle(signed_bundle, ver_keys):
    """

    :param signed_bundle: A signed JWT where the body is a JWKS bundle
    :param ver_keys: Keys that can be used to verify signatures of the
        signed_bundle as a KeyJar.
    :return: The bundle or None
    """
    _jwt = JWT(ver_keys)
    return _jwt.unpack(signed_bundle)
    def test_logout_with_sub(self):
        # Simulate an authorization
        sid, request_location = self.consumer.begin("openid",
                                                    "code",
                                                    path="https://example.com")
        resp = self.provider.authorization_endpoint(request=request_location)
        part = self.consumer.parse_authz(resp.message)
        assert isinstance(part, tuple)
        aresp = part[0]
        assert aresp

        assert self.consumer.sdb[sid]["issuer"] == self.provider.baseurl

        # Simulate an accesstoken request
        areq = AccessTokenRequest(
            code=aresp["code"],
            client_id=CLIENT_ID,
            redirect_uri="http://example.com/authz",
            client_secret=self.consumer.client_secret,
            grant_type="authorization_code",
        )
        token_resp = self.provider.code_grant_type(areq)
        tresp = self.consumer.parse_response(AccessTokenResponse,
                                             token_resp.message,
                                             sformat="json")

        # Now, for the backchannel logout. This happens on the OP
        logout_info = {
            "sub": tresp["id_token"]["sub"],
            "events": {
                BACK_CHANNEL_LOGOUT_EVENT: {}
            },
        }
        alg = "RS256"
        _jws = JWT(
            self.provider.keyjar,
            iss=self.provider.baseurl,
            lifetime=86400,
            sign_alg=alg,
        )
        logout_token = _jws.pack(aud=CLIENT_ID, **logout_info)

        # The logout request that gets sent to the RP
        request = BackChannelLogoutRequest(logout_token=logout_token)

        # The RP evaluates the request. If everything is OK a session ID (== original state
        # value) is returned.
        _sid = self.consumer.backchannel_logout(request_args=request.to_dict())

        assert _sid == sid

        # Test other coding
        _sid = self.consumer.backchannel_logout(
            request=request.to_urlencoded())
        assert _sid == sid
Exemple #24
0
 def test_unpack_verify_key(self):
     srv = JWT(keyjar, iss=issuer)
     _jwt = srv.pack(sub="sub")
     # Remove the signing key from keyjar
     keyjar.remove_key("", "RSA", "")
     # And add it back as verify
     kb = keybundle_from_local_file(os.path.join(BASE_PATH, "cert.key"), "RSA", ["ver"])
     # keybundle_from_local_file doesn'assign kid, so assign manually
     kb._keys[0].kid = kidd["sig"]["RSA"]
     keyjar.add_kb("", kb)
     info = srv.unpack(_jwt)
     assert info["sub"] == "sub"
Exemple #25
0
def verify_signed_bundle(signed_bundle, ver_keys):
    """
    Verify the signature of a signed JWT.

    :param signed_bundle: A signed JWT where the body is a JWKS bundle
    :param ver_keys: Keys that can be used to verify signatures of the
        signed_bundle.
    :type ver_keys: oic.utils.KeyJar instance
    :return: The bundle or None
    """
    _jwt = JWT(ver_keys)
    return _jwt.unpack(signed_bundle)
Exemple #26
0
 def create_signed_bundle(self, sign_alg='RS256', iss_list=None):
     """
     Create a signed JWT containing a dictionary with Issuer IDs as keys
     and JWKSs as values. If iss_list is empty all then all issuers are 
     included.
     
     :param sign_alg: Which algorithm to use when signing the JWT
     :param iss_list: A list of issuer IDs who's keys should be included in 
         the signed bundle.
     :return: A signed JWT
     """
     data = self.dict(iss_list)
     _jwt = JWT(self.sign_keys, iss=self.iss, sign_alg=sign_alg)
     return _jwt.pack(bundle=data)
Exemple #27
0
    def pack_metadata_statement(self,
                                metadata,
                                keyjar=None,
                                iss=None,
                                alg='',
                                jwt_args=None,
                                lifetime=-1,
                                **kwargs):
        """
        Given a MetadataStatement instance create a signed JWT.

        :param metadata: Original metadata statement as a MetadataStatement
            instance
        :param keyjar: KeyJar in which the necessary signing keys should reside
        :param iss: Issuer ID
        :param alg: Which signing algorithm to use
        :param jwt_args: Additional JWT attribute values
        :param lifetime: Lifetime of the signed JWT
        :param kwargs: Additional metadata statement attribute values
        :return: A JWT
        """
        if iss is None:
            iss = self.iss

        if keyjar is None:
            keyjar = self.keyjar

        if lifetime == -1:
            lifetime = self.lifetime

        # Own copy
        _metadata = copy.deepcopy(metadata)
        _metadata.update(kwargs)
        _jwt = JWT(keyjar,
                   iss=iss,
                   msgtype=_metadata.__class__,
                   lifetime=lifetime)
        if alg:
            _jwt.sign_alg = alg

        if iss in keyjar.keys():
            owner = iss
        else:
            owner = ''

        if jwt_args:
            return _jwt.pack(cls_instance=_metadata, owner=owner, **jwt_args)
        else:
            return _jwt.pack(cls_instance=_metadata, owner=owner)
Exemple #28
0
def make_software_statement(keyjar, iss, **kwargs):
    params = list(inspect.signature(JWT.__init__).parameters.keys())
    params.remove('self')

    args = {}
    for param in params:
        try:
            args[param] = kwargs[param]
        except KeyError:
            pass
        else:
            del kwargs[param]

    _jwt = JWT(keyjar, msgtype=SoftwareStatement, iss=iss, **args)
    return _jwt.pack(**kwargs)
Exemple #29
0
 def __init__(self,
              typ,
              keyjar,
              lt_pattern=None,
              extra_claims=None,
              **kwargs):
     self.type = typ
     Token.__init__(self, typ, **kwargs)
     kwargs.pop("token_storage", None)
     JWT.__init__(self, keyjar, msgtype=TokenAssertion, **kwargs)
     self.lt_pattern = lt_pattern or {}
     self.db = {}  # type: Dict[str,str]
     self.session_info = {"": 600}
     self.exp_args = ["sinfo"]
     self.extra_claims = extra_claims or {}
Exemple #30
0
def make_software_statement(keyjar, iss, **kwargs):
    params = list(inspect.signature(JWT.__init__).parameters.keys())

    params.remove("self")

    args = {}
    for param in params:
        try:
            args[param] = kwargs[param]
        except KeyError:
            pass
        else:
            del kwargs[param]

    _jwt = JWT(keyjar, msgtype=SoftwareStatement, iss=iss, **args)
    return _jwt.pack(**kwargs)
Exemple #31
0
    def do_authentication(self, **kwargs) -> str:
        if not self._client:
            logger.debug('No OpenID Connect Client configured')
            raise AuthenticationFailed()

        token: str = kwargs.get('token', None)
        if not token:
            logger.debug('No JWT token provided')
            raise AuthenticationFailed()

        try:
            jwt = JWT(keyjar=self._client.keyjar).unpack(token)
            self._client.verify_id_token(jwt, authn_req={})
            username = jwt['name']

        except Exception as ex:
            logger.info(str(ex))
            raise AuthenticationFailed()

        #
        # Assuming the token is valid, if we can't find the user, we
        # add them as an admin
        #
        with dbm.session() as session:
            if not AuthManager(session=session).get_principal(username):
                self._create_admin(session, username)

            return username
Exemple #32
0
def pack_metadata_statement(metadata, keyjar, iss, alg='', **kwargs):
    """

    :param metas: Original metadata statement as a MetadataStatement instance
    :param keyjar: KeyJar in which the necessary keys should reside
    :param alg: Which signing algorithm to use
    :param kwargs: Additional metadata statement attribute values
    :return: A JWT
    """

    metadata.update(kwargs)
    _jwt = JWT(keyjar, iss=iss, msgtype=metadata.__class__)
    if alg:
        _jwt.sign_alg = alg

    return _jwt.pack(cls_instance=metadata)
Exemple #33
0
def test_verify_token_encrypted_no_key():
    idt = IdToken(sub='553df2bcf909104751cfd8b2', aud=['5542958437706128204e0000', '554295ce3770612820620000'],
                  auth_time=1441364872, azp='554295ce3770612820620000')
    kj = KeyJar()
    kb = KeyBundle()
    kb.do_local_der(os.path.join(os.path.dirname(__file__), 'data', 'keys', 'cert.key'), 'some', ['enc', 'sig'])
    kj.add_kb('', kb)
    kj.add_kb('https://sso.qa.7pass.ctf.prosiebensat1.com', kb)

    packer = JWT(kj, lifetime=3600, iss='https://sso.qa.7pass.ctf.prosiebensat1.com', encrypt=True)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    # Do not pass they keyjar with keys
    with pytest.raises(VerificationError):
        verify_id_token(msg, keyjar=KeyJar(),
                        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                        client_id="554295ce3770612820620000")
Exemple #34
0
def test_verify_token_encrypted():
    idt = IdToken(sub='553df2bcf909104751cfd8b2', aud=['5542958437706128204e0000', '554295ce3770612820620000'],
                  auth_time=1441364872, azp='554295ce3770612820620000')
    kj = KeyJar()
    kb = KeyBundle()
    kb.do_local_der(os.path.join(os.path.dirname(__file__), 'data', 'keys', 'cert.key'), 'some', ['enc', 'sig'])
    kj.add_kb('', kb)
    kj.add_kb('https://sso.qa.7pass.ctf.prosiebensat1.com', kb)

    packer = JWT(kj, lifetime=3600, iss='https://sso.qa.7pass.ctf.prosiebensat1.com', encrypt=True)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    vidt = verify_id_token(msg, keyjar=kj,
                           iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                           client_id="554295ce3770612820620000")
    assert vidt
    assert vidt.jwe_header == {'enc': 'A128CBC-HS256', 'alg': 'RSA1_5', 'cty': 'JWT'}
    def test_not_for_me(self):
        _sub = "sub"

        logout_info = {"sub": _sub, "events": {BACK_CHANNEL_LOGOUT_EVENT: {}}}
        alg = "RS256"
        _jws = JWT(
            self.provider.keyjar,
            iss=self.provider.baseurl,
            lifetime=86400,
            sign_alg=alg,
        )
        logout_token = _jws.pack(aud="someone", **logout_info)

        # The logout request that gets sent to the RP
        request = BackChannelLogoutRequest(logout_token=logout_token)

        with pytest.raises(MessageException):
            self.consumer.backchannel_logout(request_args=request.to_dict())
Exemple #36
0
def self_sign_jwks(keyjar, iss, kid='', lifetime=3600):
    """
    Create a signed JWT containing a JWKS. The JWT is signed by one of the
    keys in the JWKS.

    :param keyjar: A KeyJar instance with at least one private signing key
    :param iss: issuer of the JWT, should be the owner of the keys
    :param kid: A key ID if a special key should be used otherwise one
        is picked at random.
    :param lifetime: The lifetime of the signed JWT
    :return: A signed JWT
    """

    # _json = json.dumps(jwks)
    _jwt = JWT(keyjar, iss=iss, lifetime=lifetime)

    jwks = keyjar.export_jwks(issuer=iss)

    return _jwt.pack(owner=iss, jwks=jwks, kid=kid)
Exemple #37
0
def test_rpt():
    kb = KeyBundle(JWKS["keys"])
    kj = KeyJar()
    kj.issuer_keys[''] = [kb]

    token_factory = JWT(kj, lifetime=3600, iss=issuer)

    client_id = 'https://example.com/client'
    ressrv_id = 'https://rs.example.org/'

    rpt = token_factory.pack(kid='sign1', aud=[client_id, ressrv_id],
                             azp=ressrv_id, type='rpt')

    _rj = jws.factory(rpt)
    jti = json.loads(_rj.jwt.part[1].decode('utf8'))['jti']

    info = token_factory.unpack(rpt)
    assert set(info.keys()), {'aud', 'azp', 'ext', 'iat', 'iss', 'jti', 'kid',
                              'type'}
    def test_logout_with_none(self):
        # Now for the backchannel logout. This happens on the OP

        logout_info = LogoutToken(events={BACK_CHANNEL_LOGOUT_EVENT: {}})

        alg = "RS256"
        _jws = JWT(
            self.provider.keyjar,
            iss=self.provider.baseurl,
            lifetime=86400,
            sign_alg=alg,
        )
        logout_token = _jws.pack(aud=CLIENT_ID, **logout_info)

        # The logout request that gets sent to the RP
        request = BackChannelLogoutRequest(logout_token=logout_token)

        # The RP evaluates the request. If everything is OK a session ID (== original state
        # value) is returned.
        with pytest.raises(MessageException):
            self.consumer.backchannel_logout(request_args=request.to_dict())
Exemple #39
0
def test_rpt():
    kb = KeyBundle(JWKS["keys"])
    kj = KeyJar()
    kj.issuer_keys[''] = [kb]

    token_factory = JWT(kj, lifetime=3600, iss=issuer)

    client_id = 'https://example.com/client'
    ressrv_id = 'https://rs.example.org/'

    rpt = token_factory.pack(kid='sign1',
                             aud=[client_id, ressrv_id],
                             azp=ressrv_id,
                             type='rpt')

    _rj = jws.factory(rpt)
    jti = json.loads(_rj.jwt.part[1].decode('utf8'))['jti']

    info = token_factory.unpack(rpt)
    assert set(info.keys()), {
        'aud', 'azp', 'ext', 'iat', 'iss', 'jti', 'kid', 'type'
    }
Exemple #40
0
def request_signed_by_signing_keys(keyjar, msreq, iss, lifetime, kid=''):
    """
    A metadata statement signing request with 'signing_keys' signed by one
    of the keys in 'signing_keys'.

    :param keyjar: A KeyJar instance with the private signing key
    :param msreq: Metadata statement signing request. A MetadataStatement 
        instance.
    :param iss: Issuer of the signing request also the owner of the signing 
        keys.
    :return: Signed JWT where the body is the metadata statement
    """

    try:
        jwks_to_keyjar(msreq['signing_keys'], iss)
    except KeyError:
        jwks = keyjar.export_jwks(issuer=iss)
        msreq['signing_keys'] = jwks

    _jwt = JWT(keyjar, iss=iss, lifetime=lifetime)

    return _jwt.pack(owner=iss, kid=kid, **msreq.to_dict())
Exemple #41
0
def test_verify_id_token_iss_not_in_keyjar():
    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
            ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        })

    kj = KeyJar()
    kj.add_symmetric("", 'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    kj.add_symmetric("https://sso.qa.7pass.ctf.prosiebensat1.com",
                     'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    packer = JWT(kj, sign_alg='HS256', lifetime=3600,
                 iss='https://example.com/op')
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    with pytest.raises(ValueError):
        verify_id_token(msg, check_hash=True, keyjar=kj,
                        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                        client_id="554295ce3770612820620000")
Exemple #42
0
    def __init__(self, keyjar, rpt_lifetime, iss, ressrv_id, rsr_path,
                 ticket_lifetime=3600):
        # database with all permission requests
        self.permission_requests = PermissionRequests()
        # database with all authorization decisions
        self.authz_db = AuthzDB()
        # database with all registered permissions
        self.permit = Permission()
        # database with all the registered resource sets
        self.resource_set = MemResourceSetDB(
            rsr_path=rsr_path, delete_rsid=self.permit.delete_rsid)

        self.map_rsid_id = {}
        self.map_id_rsid = {}
        self.map_user_id = {}

        self.rpt_factory = JWT(keyjar, lifetime=rpt_lifetime, iss=iss)
        self.ticket_factory = JWT(keyjar, lifetime=ticket_lifetime, iss=iss)
        self.authzdesc_lifetime = 3600
        self.client_id = ressrv_id
        self.rsr_path = rsr_path
        self.ad2rpt = {}
        self.rpt2adid = {}
Exemple #43
0
    def pack_metadata_statement(self, metadata, keyjar=None, iss=None, alg='',
                                **kwargs):
        """

        :param metas: Original metadata statement as a MetadataStatement
        instance
        :param keyjar: KeyJar in which the necessary keys should reside
        :param alg: Which signing algorithm to use
        :param kwargs: Additional metadata statement attribute values
        :return: A JWT
        """
        if iss is None:
            iss = self.iss
        if keyjar is None:
            keyjar = self.keyjar

        # Own copy
        _metadata = copy.deepcopy(metadata)
        _metadata.update(kwargs)
        _jwt = JWT(keyjar, iss=iss, msgtype=_metadata.__class__)
        if alg:
            _jwt.sign_alg = alg

        return _jwt.pack(cls_instance=_metadata)
Exemple #44
0
def test_verify_id_token():
    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
            ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        })

    kj = KeyJar()
    kj.add_symmetric("", 'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    kj.add_symmetric("https://sso.qa.7pass.ctf.prosiebensat1.com",
                     'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    packer = JWT(kj, sign_alg='HS256',
                 iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                 lifetime=3600)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    vidt = verify_id_token(msg, keyjar=kj,
                           iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                           client_id="554295ce3770612820620000")
    assert vidt
Exemple #45
0
def unpack_software_statement(software_statement, iss, keyjar):
    _jwt = JWT(keyjar, iss=iss, msgtype=SoftwareStatement)
    return _jwt.unpack(software_statement)
Exemple #46
0
 def create_access_token(self, key_thumbprint):
     # creating the access_token
     jwt_constructor = JWT(self.keyjar, iss=self.me)
     # Audience is myself
     return jwt_constructor.pack(
         kid='abc', cnf={'kid': key_thumbprint}, aud=self.me)
Exemple #47
0
class ADB(object):
    """ Expects to be one ADB instance per Resource Server """

    def __init__(self, keyjar, rpt_lifetime, iss, ressrv_id, rsr_path,
                 ticket_lifetime=3600):
        # database with all permission requests
        self.permission_requests = PermissionRequests()
        # database with all authorization decisions
        self.authz_db = AuthzDB()
        # database with all registered permissions
        self.permit = Permission()
        # database with all the registered resource sets
        self.resource_set = MemResourceSetDB(
            rsr_path=rsr_path, delete_rsid=self.permit.delete_rsid)

        self.map_rsid_id = {}
        self.map_id_rsid = {}
        self.map_user_id = {}

        self.rpt_factory = JWT(keyjar, lifetime=rpt_lifetime, iss=iss)
        self.ticket_factory = JWT(keyjar, lifetime=ticket_lifetime, iss=iss)
        self.authzdesc_lifetime = 3600
        self.client_id = ressrv_id
        self.rsr_path = rsr_path
        self.ad2rpt = {}
        self.rpt2adid = {}

    def pending_permission_requests(self, owner, user):
        """
        Return outstanding permission requests that is known to belong to
        an owner and bound to a requestor.

        :param owner:
        :param user:
        :return:
        """
        res = []
        for tick in self.permission_requests.requestor2tickets(user):
            rsid = self.permission_requests.ticket2rsid(tick)
            if self.resource_set.belongs_to(rsid, owner):
                res.append(tick)
        return res

    def is_expired(self, tinfo):
        if utc_time_sans_frac() <= tinfo['exp']:
            return False
        return True

    def permission_request_allowed(self, ticket, identity):
        """
        Verify that whatever permission requests the ticket represents
        they are now allow.

        :param ticket: The ticket
        :param identity: Who has the ticket
        :return: Dictionary, with permission request as key and
            identifiers of authz decisions that permits the requests as values.
        """

        _tinfo = self.rpt_factory.unpack(ticket)
        if self.is_expired(_tinfo):
            raise TicketError('expired',
                              '{} > {}'.format(utc_time_sans_frac(),
                                               _tinfo['exp']))

        try:
            prrs = self.permission_requests[ticket]
        except KeyError:
            logger.warning("Someone is using a ticket that doesn't exist")
            raise TicketError('invalid', ticket)
        else:
            result = {}
            for prr in prrs:
                owner = self.resource_set.owner(prr['resource_set_id'])
                _adids = self.authz_db.match(owner, identity, **prr.to_dict())
                if not _adids:
                    # all or nothing
                    raise TicketError('not_authorized')
                result[prr.to_json()] = _adids
            return result

    def store_permission(self, permission, owner):
        """
        Store a permission

        :param permission: The permission to store
        :param owner: The user setting the permission
        :return: A permission ID
        """
        max_scopes = self.resource_set.read(
            owner, permission['resource_set_id'])["scopes"]

        # if no scopes are defined == all are requested
        try:
            _scopes = permission['scopes']
        except KeyError:
            permission['scopes'] = max_scopes
        else:
            permission['scopes'] = [s for s in _scopes if s in max_scopes]

        pm = PermissionDescription(**permission)
        return self.authz_db.add(owner, perm_desc=pm)

    def register_permission(self, owner, rpt, rsid, scopes):
        """

        :param owner: Resource owner
        :param rpt: Requesting party token
        :param rsid: Resource set id
        :param scopes: list of scopes
        """

        now = utc_time_sans_frac()
        authz = AuthzDescription(resource_set_id=rsid, scopes=scopes,
                                 exp=now + self.authzdesc_lifetime,
                                 iat=now)

        self.permit.set(owner, rpt, authz)

    def resource_set_registration(self, method, owner, body=None, rsid=''):
        """

        :param method: HTTP method
        :param owner: The owner of the resource set
        :param body: description of the resource set
        :param rsid: resource set id
        :return: tuple (http response code, http message, http response args)
        """

        return self.resource_set.registration(method, owner, body, rsid)

    def issue_rpt(self, ticket, identity):
        """
        As a side effect if a RPT is issued the ticket is removed and
        can not be used again.

        :param ticket: The ticket
        :param identity: Information about the entity who wants the RPT
        :return: A RPT
        """
        idmap = self.permission_request_allowed(ticket, identity)
        if not idmap:
            return None

        rpt = self.rpt_factory.pack(aud=[self.client_id], type='rpt')

        for rsd in self.permission_requests[ticket]:
            owner = self.resource_set.owner(rsd['resource_set_id'])
            self.permit.bind_owner_to_rpt(owner, rpt)
            self.bind_rpt_to_authz_dec(rpt, idmap[rsd.to_json()])
            self.register_permission(owner, rpt, rsd['resource_set_id'],
                                     rsd['scopes'])

        del self.permission_requests[ticket]
        return rpt

    def introspection(self, rpt):
        try:
            res = []
            for owner in self.permit.rpt2owner[rpt]:
                res.extend(self.permit.get(owner, rpt))
            return res
        except KeyError:
            return []

    def bind_rpt_to_authz_dec(self, rpt, adid):
        for id in adid:
            try:
                self.ad2rpt[id].append(rpt)
            except KeyError:
                self.ad2rpt[id] = [rpt]

        try:
            self.rpt2adid[rpt].extend(adid)
        except KeyError:
            self.rpt2adid[rpt] = adid

    def remove_permission(self, owner, pid):
        """
        :param owner: The owner of the resource set
        :param pid: The permission id
        """
        # find all RPTs that has been issued based on this permission
        for rpt in self.ad2rpt[pid]:
            if self.rpt2adid[rpt] == [pid]:
                del self.rpt2adid[rpt]
            else:
                self.rpt2adid[rpt].remove(pid)
            self.permit.delete_rpt(rpt)

        del self.ad2rpt[pid]

        self.authz_db.delete(owner, pid=pid)

    def read_permission(self, owner, pid):
        return self.authz_db.read(owner, pid)
Exemple #48
0
def test_jwt_pack():
    _jwt = JWT(keyjar, lifetime=3600, iss=issuer).pack()

    assert _jwt
    assert len(_jwt.split('.')) == 3