Exemplo n.º 1
0
    def create_provider(self):
        kb = KeyBundle(JWKS["keys"])
        kj = KeyJar()
        kj.issuer_keys[''] = [kb]

        _sdb = SessionDB("https://example.com/",
                         token_factory=JWTToken('T',
                                                keyjar=kj,
                                                lt_pattern={
                                                    'code': 3600,
                                                    'token': 900
                                                },
                                                iss='https://example.com/as',
                                                sign_alg='RS256'),
                         refresh_token_factory=JWTToken(
                             'R',
                             keyjar=kj,
                             lt_pattern={'': 24 * 3600},
                             iss='https://example.com/as'))
        #  name, sdb, cdb, authn_broker, authz, client_authn,
        self.provider = Provider("as",
                                 _sdb,
                                 CDB,
                                 AUTHN_BROKER,
                                 AUTHZ,
                                 verify_client,
                                 baseurl='https://example.com/as')
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 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.º 4
0
    def create_sdb(self):
        kb = KeyBundle(JWKS["keys"])
        kj = KeyJar()
        kj.issuer_keys[""] = [kb]

        self.sdb = SessionDB(
            "https://example.com/",
            db=DictSessionBackend(),
            code_factory=DefaultToken("supersecret",
                                      "verybadpassword",
                                      typ="A",
                                      lifetime=600),
            token_factory=JWTToken(
                "T",
                keyjar=kj,
                lt_pattern={
                    "code": 3600,
                    "token": 900
                },
                iss="https://example.com/as",
                sign_alg="RS256",
            ),
            refresh_token_factory=JWTToken(
                "R",
                keyjar=kj,
                lt_pattern={"": 24 * 3600},
                iss="https://example.com/as",
                token_storage={},
            ),
        )
Exemplo n.º 5
0
    def load_keys(self, request, client_id, client_secret):
        try:
            self.keyjar.load_keys(request, client_id)
            try:
                logger.debug("keys for %s: [%s]" % (client_id, ",".join(
                    ["%s" % x for x in self.keyjar[client_id]])))
            except KeyError:
                pass
        except Exception as err:
            logger.error("Failed to load client keys: %s" % request.to_dict())
            logger.error("%s", err)
            err = ClientRegistrationError(
                error="invalid_configuration_parameter",
                error_description="%s" % err)
            return Response(err.to_json(),
                            content="application/json",
                            status="400 Bad Request")

        # Add the client_secret as a symmetric key to the keyjar
        _kc = KeyBundle([{
            "kty": "oct",
            "key": client_secret,
            "use": "ver"
        }, {
            "kty": "oct",
            "key": client_secret,
            "use": "sig"
        }])
        try:
            self.keyjar[client_id].append(_kc)
        except KeyError:
            self.keyjar[client_id] = [_kc]
Exemplo n.º 6
0
def test_dump_private_jwks():
    keys = [
        {
            "type": "RSA",
            "use": ["enc", "sig"]
        },
        {
            "type": "EC",
            "crv": "P-256",
            "use": ["sig"]
        },
    ]

    jwks, keyjar, kidd = build_keyjar(keys)

    kbl = keyjar.issuer_keys['']
    dump_jwks(kbl, 'foo.jwks', private=True)
    kb_public = KeyBundle(source='file://./foo.jwks')
    # All RSA keys
    for k in kb_public.keys():
        if k.kty == 'RSA':
            assert k.d
            assert k.p
            assert k.q
        else:  # MUST be 'EC'
            assert k.d
Exemplo n.º 7
0
def test_dump_public_jwks():
    keys = [
        {
            "type": "RSA",
            "use": ["enc", "sig"]
        },
        {
            "type": "EC",
            "crv": "P-256",
            "use": ["sig"]
        },
    ]

    jwks, keyjar, kidd = build_keyjar(keys)

    kbl = keyjar.issuer_keys[""]
    dump_jwks(kbl, "foo.jwks")
    kb_public = KeyBundle(source="file://./foo.jwks")
    # All RSA keys
    for k in kb_public.keys():
        if k.kty == "RSA":
            assert not k.d
            assert not k.p
            assert not k.q
        else:  # MUST be 'EC'
            assert not k.d
Exemplo n.º 8
0
def test_pkce_token():
    kb = KeyBundle(JWKS["keys"])
    kj = KeyJar()
    kj.issuer_keys[''] = [kb]
    constructor = JWTToken('A',
                           keyjar=kj,
                           lt_pattern={'': 900},
                           iss='https://example.com/as',
                           sign_alg='RS256',
                           encrypt=True)

    sid = rndstr(32)
    session_info = {
        'sub': 'subject_id',
        'client_id': 'https://example.com/rp',
        'response_type': ['code'],
        'authzreq': '{}'
    }

    _cli = Client(config={'code_challenge': {'method': 'S512', 'length': 96}})
    args, cv = _cli.add_code_challenge()

    access_grant = constructor(
        sid,
        sinfo=session_info,
        kid='sign1',
        code_challenge=args['code_challenge'],
        code_challenge_method=args['code_challenge_method'])

    _info = constructor.get_info(access_grant)
    assert _info['code_challenge_method'] == args['code_challenge_method']
    assert _info['code_challenge'] == args['code_challenge']
Exemplo n.º 9
0
def test_key_export():
    kj = KeyJar()
    url = key_export(
        "http://example.com/keys/",
        "outbound",
        "secret",
        keyjar=kj,
        sig={
            "alg": "rsa",
            "format": ["x509", "jwk"]
        },
    )

    assert url == "http://example.com/keys/outbound/jwks"

    # Now a jwks should reside in './keys/outbound/jwks'

    kb = KeyBundle(source="file://./keys/outbound/jwks")

    # One key
    assert len(kb) == 1
    # more specifically one RSA key
    assert len(kb.get("RSA")) == 1
    k = kb.get("RSA")[0]
    # For signing
    assert k.use == "sig"
Exemplo n.º 10
0
    def export(self, client, cconf, role):
        # has to be there
        self.trace.info("EXPORT")

        if client.keyjar is None:
            client.keyjar = KeyJar()

        kbl = []
        for typ, info in cconf["keys"].items():
            kb = KeyBundle(source="file://%s" % info["key"],
                           fileformat="der",
                           keytype=typ)
            for k in kb.keys():
                k.serialize()
            client.keyjar.add_kb("", kb)
            kbl.append(kb)

        try:
            new_name = "static/%s_jwks.json" % role
            dump_jwks(kbl, new_name)
            client.jwks_uri = "%s%s" % (cconf["_base_url"], new_name)
        except KeyError:
            pass

        if not self.args.external_server and not self.keysrv_running:
            self._pop = start_key_server(cconf["_base_url"])

            self.environ["keyprovider"] = self._pop
            self.trace.info("Started key provider")
            time.sleep(1)
            self.keysrv_running = True
Exemplo n.º 11
0
    def test_issuer_mismatch(self):
        ISSUER = "https://login.microsoftonline.com/b4ea3de6-839e-4ad1-ae78-c78e5c0cdc06/v2.0/"
        kb = KeyBundle(JWK2["keys"])
        kj = KeyJar()
        kj.issuer_keys[ISSUER] = [kb]
        kj.issuer_keys[""] = []

        authz_resp = AuthorizationResponse().from_urlencoded(
            "id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSIsImtpZCI6Ik1u"
            "Q19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSJ9.eyJhdWQiOiIwMTZlZDBlNC1mYzUyLTRlYjgtOWVhYy1lODg1MmM4MjEwNTUiLCJpc3Mi"
            "OiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vYjRlYTNkZTYtODM5ZS00YWQxLWFlNzgtYzc4ZTVjMGNkYzA2L3YyLjAvI"
            "iwiaWF0IjoxNDM5OTIzNDY5LCJuYmYiOjE0Mzk5MjM0NjksImV4cCI6MTQzOTkyNzM2OSwidmVyIjoiMi4wIiwidGlkIjoiYjRlYTNkZT"
            "YtODM5ZS00YWQxLWFlNzgtYzc4ZTVjMGNkYzA2Iiwib2lkIjoiNDJjMzliNWUtYmQwNS00YTlhLTlhNWUtMTY5ZDc2N2ZlZjJmIiwicHJ"
            "lZmVycmVkX3VzZXJuYW1lIjoiaW50ZXJvcEBrYXV0aS5vbm1pY3Jvc29mdC5jb20iLCJzdWIiOiJFWGlaVldjakpsREN1LXZzOUxNb1V3"
            "ZGRNNEJZZ2ZISzBJNk40dWpXZkRFIiwibmFtZSI6ImludGVyb3AiLCJub25jZSI6IlpkSHRxQWwzR3c4QiJ9.tH4FKM4H9YCHX2XF4V64"
            "SsLaKh31c0oLpEVlFxFHw8jxL5HujUthZJDUMwngXZ2mPU_1G152ybKiRCV9DKaBh1rFSlZxTDBp0SV_YTwOkGYOt-sOzFUJyvVCjGmRh"
            "vFkOF1kiT3IYjDoRh72U8pMchj1duWSytLczdOc4LJmg24ya5jwqApuyQu7gVqoDH1kEqBAuhBj3a7ZDwxIt-bTKZklsht0RutZjv4Ckg"
            "8qJpzWnY7rIjSKFKfEpAAfk_LqWvTktvDMKTHXLxEPVZymoskE1LthtC8AYoNmtVPxgxf87yGCqYZBsuAnVChdnsItXP7tPeqUjC8Lm3J"
            "jabV-5g&id_token_expires_in=3599&state=6o3FmQ0QZl1zifsE&session_state=d2c97e8a-497c-4ce1-bb10-5058501164eb"
        )

        try:
            authz_resp.verify(keyjar=kj, skew=100000000)
        except MissingSigningKey:
            authz_resp.verify(keyjar=kj, sender=ISSUER, skew=100000000)
Exemplo n.º 12
0
def init_keyjar():
    # Keys that are kept by the AS
    kb = KeyBundle()
    kb.do_keys(JWKS["keys"])
    keyjar = KeyJar()
    keyjar.add_kb("", kb)
    return keyjar
Exemplo n.º 13
0
 def test_construct(self, client):
     _key = rsa_load(os.path.join(BASE_PATH, "data/keys/rsa.key"))
     kc_rsa = KeyBundle([
         {
             "key": _key,
             "kty": "RSA",
             "use": "ver"
         },
         {
             "key": _key,
             "kty": "RSA",
             "use": "sig"
         },
     ])
     client.keyjar[""] = kc_rsa
     client.token_endpoint = "https://example.com/token"
     client.provider_info = {
         "issuer": "https://example.com/",
         "token_endpoint": "https://example.com/token",
     }
     cis = AccessTokenRequest()
     pkj = PrivateKeyJWT(client)
     http_args = pkj.construct(cis,
                               algorithm="RS256",
                               authn_endpoint="token")
     assert http_args == {}
     cas = cis["client_assertion"]
     _jwt = JWT().unpack(cas)
     jso = _jwt.payload()
     assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
     assert _jwt.headers == {"alg": "RS256"}
     assert jso["aud"] == [client.provider_info["token_endpoint"]]
Exemplo n.º 14
0
    def load_keys(self, request, client_id, client_secret):
        try:
            self.keyjar.load_keys(request, client_id)
            try:
                n_keys = len(self.keyjar[client_id])
                msg = "Found {} keys for client_id={}"
                logger.debug(msg.format(n_keys, client_id))
            except KeyError:
                pass
        except Exception as err:
            msg = "Failed to load client keys: {}"
            logger.error(msg.format(sanitize(request.to_dict())))
            logger.error("%s", err)
            err = ClientRegistrationError(
                error="invalid_configuration_parameter",
                error_description="%s" % err)
            return Response(err.to_json(),
                            content="application/json",
                            status="400 Bad Request")

        # Add the client_secret as a symmetric key to the keyjar
        _kc = KeyBundle([{
            "kty": "oct",
            "key": client_secret,
            "use": "ver"
        }, {
            "kty": "oct",
            "key": client_secret,
            "use": "sig"
        }])
        try:
            self.keyjar[client_id].append(_kc)
        except KeyError:
            self.keyjar[client_id] = [_kc]
Exemplo n.º 15
0
    def test_remove_key(self):
        ks = KeyJar()
        ks[""] = KeyBundle([{
            "kty": "oct",
            "key": "a1b2c3d4",
            "use": "sig"
        }, {
            "kty": "oct",
            "key": "a1b2c3d4",
            "use": "ver"
        }])
        ks["http://www.example.org"] = [
            KeyBundle([{
                "kty": "oct",
                "key": "e5f6g7h8",
                "use": "sig"
            }, {
                "kty": "oct",
                "key": "e5f6g7h8",
                "use": "ver"
            }]),
            keybundle_from_local_file(RSAKEY, "rsa", ["enc", "dec"])
        ]
        ks["http://www.example.com"] = keybundle_from_local_file(
            RSA0, "rsa", ["enc", "dec"])

        coll = ks["http://www.example.org"]
        # coll is list of KeyBundles
        assert len(coll) == 2
        keys = ks.get_encrypt_key(key_type="RSA",
                                  owner="http://www.example.org")
        assert len(keys) == 1
        _key = keys[0]
        ks.remove_key("http://www.example.org", "RSA", _key)

        coll = ks["http://www.example.org"]
        assert len(coll) == 1  # Only one remaining key
        keys = ks.get_encrypt_key(key_type="rsa",
                                  owner="http://www.example.org")
        assert len(keys) == 0

        keys = ks.verify_keys("http://www.example.com")
        assert len(keys) == 2
        assert len([k for k in keys if k.kty == "oct"]) == 2

        keys = ks.decrypt_keys("http://www.example.org")
        assert keys == []
Exemplo n.º 16
0
 def test_get_inactive_ver(self):
     ks = KeyJar()
     ks['http://example.com'] = KeyBundle(
         [{"kty": "oct", "key": "a1b2c3d4", "use": "sig"},
          {"kty": "oct", "key": "a1b2c3d4", "use": "ver"}])
     ks['http://example.com'][0]._keys[1].inactive_since = 1
     key = ks.get_verify_key(owner='http://example.com')
     assert len(key) == 2
Exemplo n.º 17
0
def keybundle_from_local_file(filename, typ, usage, kid):
    if typ.upper() == "RSA":
        kb = KeyBundle()
        k = RSAKey(kid=kid)
        k.load(filename)
        k.use = usage[0]
        kb.append(k)
        for use in usage[1:]:
            _k = RSAKey(kid=kid + "1")
            _k.use = use
            _k.load_key(k.key)
            kb.append(_k)
    elif typ.lower() == "jwk":
        kb = KeyBundle(source=filename, fileformat="jwk", keyusage=usage)
    else:
        raise UnknownKeyType("Unsupported key type")
    return kb
Exemplo n.º 18
0
    def store_key(self, key):
        kb = KeyBundle()
        kb.do_keys([key])

        # Store key with thumbprint as key
        key_thumbprint = b64e(kb.keys()[0].thumbprint("SHA-256")).decode("utf8")
        self.thumbprint2key[key_thumbprint] = key
        return key_thumbprint
Exemplo n.º 19
0
    def create_token(self):
        kb = KeyBundle(JWKS["keys"])
        kj = KeyJar()
        kj.issuer_keys[''] = [kb]

        self.access_token = JWTToken('T',
                                     keyjar=kj,
                                     iss='https://example.com/as',
                                     sign_alg='RS256')
Exemplo n.º 20
0
    def __call__(self):
        kb = KeyBundle(source=self.conv.entity.provider_info["jwks_uri"])
        kb.verify_ssl = False
        kb.update()

        try:
            self.conv.keybundle.append(kb)
        except AttributeError:
            self.conv.keybundle = [kb]
Exemplo n.º 21
0
    def test_get_inactive_sig_for_ver(self):
        """get_verify_key can return inactive `sig` key."""
        ks = KeyJar()
        ks['http://example.com'] = KeyBundle(
            [{"kty": "oct", "key": "a1b2c3d4", "use": "sig"}])
        ks['http://example.com'][0]._keys[0].inactive_since = 1
        key = ks.get_verify_key(owner='http://example.com')

        assert len(key) == 1
Exemplo n.º 22
0
    def create_token(self):
        kb = KeyBundle(JWKS["keys"])
        kj = KeyJar()
        kj.issuer_keys[""] = [kb]

        self.access_token = JWTToken("T",
                                     keyjar=kj,
                                     iss="https://example.com/as",
                                     sign_alg="RS256")
Exemplo n.º 23
0
    def test_parse_jwt_request(self):
        ar = AuthorizationRequest(
            response_type=["code"],
            client_id="foobar",
            redirect_uri="http://foobar.example.com/oaclient",
            state="cold",
        )

        self.srv.keyjar["foobar"] = KeyBundle([
            {
                "kty": "oct",
                "key": "A1B2C3D4".encode("utf-8"),
                "use": "ver"
            },
            {
                "kty": "oct",
                "key": "A1B2C3D4".encode("utf-8"),
                "use": "sig"
            },
        ])
        self.srv.keyjar[""] = KeyBundle([
            {
                "kty": "oct",
                "key": "A1B2C3D4".encode("utf-8"),
                "use": "ver"
            },
            {
                "kty": "oct",
                "key": "A1B2C3D4".encode("utf-8"),
                "use": "sig"
            },
        ])

        keys = self.srv.keyjar.get_signing_key(owner="foobar")
        _jwt = ar.to_jwt(key=keys, algorithm="HS256")

        req = self.srv.parse_jwt_request(txt=_jwt)

        assert isinstance(req, AuthorizationRequest)
        assert req["response_type"] == ["code"]
        assert req["client_id"] == "foobar"
        assert req["redirect_uri"] == "http://foobar.example.com/oaclient"
        assert req["state"] == "cold"
Exemplo n.º 24
0
    def __call__(self, conv, **kwargs):
        pi = conv.client.provider_info
        kb = KeyBundle(source=pi["jwks_uri"])
        kb.verify_ssl = False
        kb.update()

        try:
            conv.keybundle.append(kb)
        except AttributeError:
            conv.keybundle = [kb]
Exemplo n.º 25
0
    def test_get_inactive_sig(self):
        """get_signing_key cannot return inactive `sig` key."""
        ks = KeyJar()
        ks["http://example.com"] = KeyBundle(
            [{"kty": "oct", "key": "a1b2c3d4", "use": "sig"}]
        )
        ks["http://example.com"][0]._keys[0].inactive_since = 1
        key = ks.get_signing_key(owner="http://example.com")

        assert len(key) == 0
Exemplo n.º 26
0
    def test_update(self):
        kc = KeyBundle([{"kty": "oct", "key": "supersecret", "use": "sig"}])
        assert len(kc.get("oct")) == 1
        assert len(kc.get("rsa")) == 0
        assert kc.remote is False
        assert kc.source is None

        kc.update()  # Nothing should happen
        assert len(kc.get("oct")) == 1
        assert len(kc.get("rsa")) == 0
        assert kc.remote is False
        assert kc.source is None
Exemplo n.º 27
0
    def create_token(self):
        kb = KeyBundle(JWKS["keys"])
        kj = KeyJar()
        kj.issuer_keys[''] = [kb]

        self.access_token = JWTToken('T',
                                     keyjar=kj,
                                     lt_pattern={
                                         'code': 3600,
                                         'token': 900
                                     },
                                     iss='https://example.com/as',
                                     encrypt=True)
Exemplo n.º 28
0
    def verify(self, **kwargs):
        if "jwks" in self:
            try:
                _keys = self["jwks"]["keys"]
            except KeyError:
                raise SyntaxError('"keys" parameter missing')
            else:
                # will raise an exception if syntax error
                KeyBundle(_keys)
        for param in ["jwks_uri", "client_uri"]:
            verify_url(self[param])

        JasonWebToken.verify(self, **kwargs)
Exemplo n.º 29
0
def test_reload():
    """Emulate what happens if you fetch keys from a remote site and you get back the same JWKS as the last time."""
    _jwks = JWK0

    kb = KeyBundle()
    kb.imp_jwks = _jwks
    kb.do_keys(kb.imp_jwks["keys"])

    assert len(kb) == 1

    kb.do_keys(kb.imp_jwks["keys"])

    assert len(kb) == 1
Exemplo n.º 30
0
    def test_keyjar_group_keys(self):
        ks = KeyJar()
        ks[""] = KeyBundle(
            [
                {"kty": "oct", "key": "a1b2c3d4", "use": "sig"},
                {"kty": "oct", "key": "a1b2c3d4", "use": "ver"},
            ]
        )
        ks["http://www.example.org"] = KeyBundle(
            [
                {"kty": "oct", "key": "e5f6g7h8", "use": "sig"},
                {"kty": "oct", "key": "e5f6g7h8", "use": "ver"},
            ]
        )
        ks["http://www.example.org"].append(
            keybundle_from_local_file(RSAKEY, "rsa", ["ver", "sig"])
        )

        verified_keys = ks.verify_keys("http://www.example.org")
        assert len(verified_keys) == 6
        assert len([k for k in verified_keys if k.kty == "oct"]) == 4
        assert len([k for k in verified_keys if k.kty == "RSA"]) == 2