Exemplo n.º 1
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",
    )
Exemplo n.º 2
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",
        )
Exemplo n.º 3
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)
Exemplo n.º 4
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)
Exemplo n.º 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'])
Exemplo n.º 6
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"])
Exemplo n.º 7
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
Exemplo n.º 8
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)
Exemplo n.º 9
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"}
Exemplo n.º 10
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",
        )
Exemplo n.º 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",
        )
Exemplo n.º 12
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
Exemplo n.º 13
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)
Exemplo n.º 14
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)
Exemplo n.º 15
0
    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
Exemplo n.º 16
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)
Exemplo n.º 17
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"
Exemplo n.º 18
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)
Exemplo n.º 19
0
Arquivo: adb.py Projeto: rohe/pyuma
    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 = {}
Exemplo n.º 20
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)
Exemplo n.º 21
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)
Exemplo n.º 22
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)
Exemplo n.º 23
0
    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())
Exemplo n.º 24
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)
Exemplo n.º 25
0
    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())
Exemplo n.º 26
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'
    }
Exemplo n.º 27
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())
Exemplo n.º 28
0
def unpack_software_statement(software_statement, iss, keyjar):
    _jwt = JWT(keyjar, iss=iss, msgtype=SoftwareStatement)
    return _jwt.unpack(software_statement)
Exemplo n.º 29
0
    def do_back_channel_logout(self, cinfo, sub, sid):
        try:
            back_channel_logout_uri = cinfo['backchannel_logout_uri']
        except KeyError:
            return None

        # always include sub and sid so I don't check for
        # backchannel_logout_session_required

        payload = {
            'sub': sub,
            'sid': sid,
        }

        if 'no_event' in self.behavior_type:
            # Remove a event specification from the JWT
            pass
        elif 'wrong_event' in self.behavior_type:
            # Set the event to be something it should not be
            payload['events'] = {"http://schemas.openid.net/event/foobar": {}}
        else:
            payload['events'] = {BACK_CHANNEL_LOGOUT_EVENT: {}}

        if 'with_nonce' in self.behavior_type:
            # Add a nonce to the logout token
            payload['nonce'] = rndstr(16)

        try:
            alg = cinfo['id_token_signed_response_alg']
        except KeyError:
            alg = self.capabilities['id_token_signing_alg_values_supported'][0]

        if 'wrong_alg' in self.behavior_type:
            # Figure out a alg I could use but that are not the one used
            # for ID Tokens. Pick one from id_token_signing_alg_values_supported
            if alg.startswith('RS'):
                alg = 'ES256'
            elif alg.startswith('ES'):
                alg = 'RS256'
            else:  # probably HS*
                alg = 'RS256'
        elif 'alg_none' in self.behavior_type:
            # Set signing algorithm to be none
            alg = 'none'

        if 'wrong_issuer' in self.behavior_type:
            # Set the wrong issuer on the logout token
            iss = self.other
        else:
            iss = self.name

        if 'wrong_aud' in self.behavior_type:
            # Set wrong audience of the logout token
            _aud = self.other
        else:
            _aud = cinfo["client_id"]

        _jws = JWT(self.keyjar, iss=iss, lifetime=86400, sign_alg=alg)

        if self.events:
            kw = {'iss': iss, 'sign_alg': alg, 'aud': _aud}
            kw.update(payload)
            self.events.store('Logout token', '{}'.format(kw))

        _jws.with_jti = True
        sjwt = _jws.pack(aud=_aud, **payload)

        return back_channel_logout_uri, sjwt
Exemplo n.º 30
0
def test_jwt_pack():
    _jwt = JWT(keyjar, lifetime=3600, iss=issuer).pack()

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