Пример #1
0
    def test_sign_encrypt_id_token(self):
        client_info = RegistrationResponse(
            id_token_signed_response_alg="RS512", client_id="client_1")
        session_info = {
            "authn_req": AREQN,
            "sub": "sub",
            "authn_event": {
                "authn_info": "loa2",
                "authn_time": time.time()
            },
        }

        self.endpoint_context.jwx_def["signing_alg"] = {"id_token": "RS384"}
        self.endpoint_context.cdb["client_1"] = client_info.to_dict()

        _token = self.endpoint_context.idtoken.sign_encrypt(session_info,
                                                            "client_1",
                                                            sign=True)
        assert _token

        _jws = jws.factory(_token)

        assert _jws.jwt.headers["alg"] == "RS512"

        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(_token)
        assert isinstance(res, dict)
        assert res["aud"] == ["client_1"]
Пример #2
0
def test_sign_encrypt_id_token():
    client_info = RegistrationResponse(id_token_signed_response_alg='RS512',
                                       client_id='client_1')
    session_info = {
        'authn_req': AREQN,
        'sub': 'sub',
        'authn_event': {
            "authn_info": 'loa2',
            "authn_time": time.time()
        }
    }

    ENDPOINT_CONTEXT.jwx_def["signing_alg"] = {'id_token': 'RS384'}
    ENDPOINT_CONTEXT.cdb['client_1'] = client_info.to_dict()

    _token = sign_encrypt_id_token(ENDPOINT_CONTEXT,
                                   session_info,
                                   'client_1',
                                   sign=True)
    assert _token

    _jws = jws.factory(_token)

    assert _jws.jwt.headers['alg'] == 'RS512'

    client_keyjar = KeyJar()
    _jwks = KEYJAR.export_jwks()
    client_keyjar.import_jwks(_jwks, ENDPOINT_CONTEXT.issuer)

    _jwt = JWT(key_jar=client_keyjar, iss='client_1')
    res = _jwt.unpack(_token)
    assert isinstance(res, dict)
    assert res['aud'] == ['client_1']
Пример #3
0
def test_get_sign_algorithm_2():
    client_info = RegistrationResponse(id_token_signed_response_alg='RS512')
    endpoint_context = EndpointContext(conf)
    algs = get_sign_and_encrypt_algorithms(endpoint_context,
                                           client_info,
                                           'id_token',
                                           sign=True)
    # default signing alg
    assert algs == {'sign': True, 'encrypt': False, 'sign_alg': 'RS512'}
Пример #4
0
def test_no_default_encrypt_algorithms():
    client_info = RegistrationResponse()
    endpoint_context = EndpointContext(conf)
    with pytest.raises(UnknownAlgorithm):
        get_sign_and_encrypt_algorithms(endpoint_context,
                                        client_info,
                                        'id_token',
                                        sign=True,
                                        encrypt=True)
Пример #5
0
 def test_get_sign_algorithm(self):
     client_info = RegistrationResponse()
     endpoint_context = EndpointContext(conf)
     algs = get_sign_and_encrypt_algorithms(endpoint_context,
                                            client_info,
                                            "id_token",
                                            sign=True)
     # default signing alg
     assert algs == {"sign": True, "encrypt": False, "sign_alg": "RS256"}
Пример #6
0
 def process_request(self, request=None, **kwargs):
     _cli_info = self.server_get("endpoint_context").cdb[
         request["client_id"]]
     args = {
         k: v
         for k, v in _cli_info.items() if k in RegistrationResponse.c_param
     }
     comb_uri(args)
     return {"response_args": RegistrationResponse(**args)}
Пример #7
0
    def process_request(self, request=None, **kwargs):
        args = dict(
            [
                (k, v)
                for k, v in self.endpoint_context.cdb[request["client_id"]].items()
                if k in RegistrationResponse.c_param
            ]
        )

        comb_uri(args)
        return {"response_args": RegistrationResponse(**args)}
Пример #8
0
def test_get_sign_algorithm_3():
    client_info = RegistrationResponse()
    endpoint_context = EndpointContext(conf)
    endpoint_context.jwx_def["signing_alg"] = {'id_token': 'RS384'}

    algs = get_sign_and_encrypt_algorithms(endpoint_context,
                                           client_info,
                                           'id_token',
                                           sign=True)
    # default signing alg
    assert algs == {'sign': True, 'encrypt': False, 'sign_alg': 'RS384'}
Пример #9
0
 def test_no_default_encrypt_algorithms(self):
     client_info = RegistrationResponse()
     endpoint_context = EndpointContext(conf)
     args = get_sign_and_encrypt_algorithms(endpoint_context,
                                            client_info,
                                            "id_token",
                                            sign=True,
                                            encrypt=True)
     assert args["sign_alg"] == "RS256"
     assert args["enc_enc"] == "A128CBC-HS256"
     assert args["enc_alg"] == "RSA1_5"
Пример #10
0
    def test_get_sign_algorithm_4(self):
        client_info = RegistrationResponse(
            id_token_signed_response_alg="RS512")
        endpoint_context = EndpointContext(conf)
        endpoint_context.jwx_def["signing_alg"] = {"id_token": "RS384"}

        algs = get_sign_and_encrypt_algorithms(endpoint_context,
                                               client_info,
                                               "id_token",
                                               sign=True)
        # default signing alg
        assert algs == {"sign": True, "encrypt": False, "sign_alg": "RS512"}
Пример #11
0
    def test_begin_2(self):
        ISS_ID = "https://op.example.org"
        OP_KEYS = build_keyjar(DEFAULT_KEY_DEFS)
        # The 4 steps of client_setup
        client = self.rph.init_client(ISS_ID)
        with responses.RequestsMock() as rsps:
            request_uri = '{}/.well-known/openid-configuration'.format(ISS_ID)
            _jws = ProviderConfigurationResponse(
                issuer=ISS_ID,
                authorization_endpoint='{}/authorization'.format(ISS_ID),
                jwks_uri='{}/jwks.json'.format(ISS_ID),
                response_types_supported=[
                    'code', 'id_token', 'id_token token'
                ],
                subject_types_supported=['public'],
                id_token_signing_alg_values_supported=["RS256", "ES256"],
                token_endpoint='{}/token'.format(ISS_ID),
                registration_endpoint='{}/register'.format(ISS_ID)).to_json()
            rsps.add("GET", request_uri, body=_jws, status=200)

            rsps.add("GET",
                     '{}/jwks.json'.format(ISS_ID),
                     body=OP_KEYS.export_jwks_as_json(),
                     status=200)

            issuer = self.rph.do_provider_info(client)

        # Calculating request so I can build a reasonable response
        self.rph.add_callbacks(client.service_context)
        # Publishing a JWKS instead of a JWKS_URI
        client.service_context.jwks_uri = ''
        client.service_context.jwks = client.service_context.keyjar.export_jwks(
        )

        _req = client.service['registration'].construct_request()

        with responses.RequestsMock() as rsps:
            request_uri = client.service_context.get(
                'provider_info')["registration_endpoint"]
            _jws = RegistrationResponse(
                client_id="client uno",
                client_secret="VerySecretAndLongEnough",
                **_req.to_dict()).to_json()
            rsps.add("POST", request_uri, body=_jws, status=200)
            self.rph.do_client_registration(client, ISS_ID)

        assert 'jwks' in client.service_context.get('registration_response')
Пример #12
0
    def client_registration_setup(self, request, new_id=True, set_secret=True):
        try:
            request.verify()
        except MessageException as err:
            if "type" not in request:
                return ResponseMessage(error="invalid_type",
                                       error_description="%s" % err)
            else:
                return ResponseMessage(error="invalid_configuration_parameter",
                                       error_description="%s" % err)

        request.rm_blanks()
        try:
            self.match_client_request(request)
        except CapabilitiesMisMatch as err:
            return ResponseMessage(
                error="invalid_request",
                error_description="Don't support proposed %s" % err)

        _context = self.endpoint_context
        if new_id:
            # create new id och secret
            client_id = rndstr(12)
            while client_id in _context.cdb:
                client_id = rndstr(12)
        else:
            try:
                client_id = request['client_id']
            except KeyError:
                raise ValueError('Missing client_id')

        _rat = rndstr(32)

        _cinfo = {
            "client_id":
            client_id,
            "registration_access_token":
            _rat,
            "registration_client_uri":
            "%s?client_id=%s" % (self.endpoint_path, client_id),
            "client_salt":
            rndstr(8)
        }

        if new_id:
            _cinfo["client_id_issued_at"] = utc_time_sans_frac()

        if set_secret:
            client_secret = secret(_context.seed, client_id)
            _cinfo.update({
                "client_secret":
                client_secret,
                "client_secret_expires_at":
                client_secret_expiration_time()
            })
        else:
            client_secret = ''

        _context.cdb[client_id] = _cinfo
        _context.cdb[_rat] = client_id

        _cinfo = self.do_client_registration(
            request,
            client_id,
            ignore=["redirect_uris", "policy_uri", "logo_uri", "tos_uri"])
        if isinstance(_cinfo, ResponseMessage):
            return _cinfo

        args = dict([(k, v) for k, v in _cinfo.items()
                     if k in RegistrationResponse.c_param])

        self.comb_uri(args)
        response = RegistrationResponse(**args)

        # Add the client_secret as a symmetric key to the key jar
        if client_secret:
            _context.keyjar.add_symmetric(client_id, str(client_secret))

        _context.cdb[client_id] = _cinfo

        try:
            _context.cdb.sync()
        except AttributeError:  # Not all databases can be sync'ed
            pass

        logger.info("registration_response: %s" % sanitize(response.to_dict()))

        return response
Пример #13
0
    def client_registration_setup(self, request, new_id=True, set_secret=True):
        try:
            request.verify()
        except (MessageException, ValueError) as err:
            return ResponseMessage(
                error="invalid_configuration_request", error_description="%s" % err
            )

        request.rm_blanks()
        try:
            self.match_client_request(request)
        except CapabilitiesMisMatch as err:
            return ResponseMessage(
                error="invalid_request",
                error_description="Don't support proposed %s" % err,
            )

        _context = self.endpoint_context
        if new_id:
            # create new id och secret
            client_id = rndstr(12)
            while client_id in _context.cdb:
                client_id = rndstr(12)
        else:
            try:
                client_id = request["client_id"]
            except KeyError:
                raise ValueError("Missing client_id")

        _cinfo = {"client_id": client_id, "client_salt": rndstr(8)}

        if "registration_api" in self.endpoint_context.endpoint:
            self.add_registration_api(_cinfo, client_id, _context)

        if new_id:
            _cinfo["client_id_issued_at"] = utc_time_sans_frac()

        if set_secret:
            client_secret = self.add_client_secret(_cinfo, client_id, _context)
        else:
            client_secret = ""

        _context.cdb[client_id] = _cinfo

        _cinfo = self.do_client_registration(
            request,
            client_id,
            ignore=["redirect_uris", "policy_uri", "logo_uri", "tos_uri"],
        )
        if isinstance(_cinfo, ResponseMessage):
            return _cinfo

        args = dict(
            [(k, v) for k, v in _cinfo.items() if k in RegistrationResponse.c_param]
        )

        comb_uri(args)
        response = RegistrationResponse(**args)

        # Add the client_secret as a symmetric key to the key jar
        if client_secret:
            _context.keyjar.add_symmetric(client_id, str(client_secret))

        _context.cdb[client_id] = _cinfo

        try:
            _context.cdb.sync()
        except AttributeError:  # Not all databases can be sync'ed
            pass

        logger.info("registration_response: %s" % sanitize(response.to_dict()))

        return response
Пример #14
0
# ============== 4.1.6 ==================
print("-" * 20, "4.1.6", "-" * 20)
fed_pol = open("4.1.6_fed_policy.json").read()
mp_fed = MetadataPolicy().from_json(fed_pol)
print("4.1.6_fed_policy.json", mp_fed.verify())

org_pol = open("4.1.6_org_policy.json").read()
mp_org = MetadataPolicy().from_json(org_pol)
print("4.1.6_org_policy.json", mp_org.verify())

comb_policy = MetadataPolicy(**combine_policy(mp_fed, mp_org))
print("comb", comb_policy.verify())

metadata = open("4.1.6_metadata.json").read()
md = RegistrationResponse().from_json(metadata)
print("4.1.6_metadata.json", mp_org.verify())

# apply policy

res = apply_policy(md, comb_policy)
res_md = RegistrationResponse(**res)

print(json.dumps(res_md.to_dict(), indent=4, sort_keys=True))
print('=', md.to_dict() == res_md.to_dict())

# ============== 4.3.3 ==================
print("-" * 20, "4.3.3", "-" * 20)

for item in ['4.3.3_1.json', '4.3.3_2.json']:
    data = open(item).read()
Пример #15
0
    def test_begin(self):
        ISS_ID = "https://op.example.org"
        OP_KEYS = build_keyjar(DEFAULT_KEY_DEFS)
        # The 4 steps of client_setup
        client = self.rph.init_client(ISS_ID)
        with responses.RequestsMock() as rsps:
            request_uri = '{}/.well-known/openid-configuration'.format(ISS_ID)
            _jws = ProviderConfigurationResponse(
                issuer=ISS_ID,
                authorization_endpoint='{}/authorization'.format(ISS_ID),
                jwks_uri='{}/jwks.json'.format(ISS_ID),
                response_types_supported=[
                    'code', 'id_token', 'id_token token'
                ],
                subject_types_supported=['public'],
                id_token_signing_alg_values_supported=["RS256", "ES256"],
                token_endpoint='{}/token'.format(ISS_ID),
                registration_endpoint='{}/register'.format(ISS_ID)).to_json()
            rsps.add("GET", request_uri, body=_jws, status=200)

            rsps.add("GET",
                     '{}/jwks.json'.format(ISS_ID),
                     body=OP_KEYS.export_jwks_as_json(),
                     status=200)

            issuer = self.rph.do_provider_info(client)

        # Calculating request so I can build a reasonable response
        self.rph.add_callbacks(client.service_context)
        _req = client.service['registration'].construct_request()

        with responses.RequestsMock() as rsps:
            request_uri = client.service_context.get(
                'provider_info')["registration_endpoint"]
            _jws = RegistrationResponse(
                client_id="client uno",
                client_secret="VerySecretAndLongEnough",
                **_req.to_dict()).to_json()
            rsps.add("POST", request_uri, body=_jws, status=200)
            self.rph.do_client_registration(client, ISS_ID)

        self.rph.issuer2rp[issuer] = client

        assert set(client.service_context.get('behaviour').keys()) == {
            'token_endpoint_auth_method', 'response_types', 'scope',
            'application_type', 'application_name'
        }
        assert client.service_context.get('client_id') == "client uno"
        assert client.service_context.get(
            'client_secret') == "VerySecretAndLongEnough"
        assert client.service_context.get('issuer') == ISS_ID

        res = self.rph.init_authorization(client)
        assert set(res.keys()) == {'url', 'state'}
        p = urlparse(res["url"])
        assert p.hostname == 'op.example.org'
        assert p.path == "/authorization"
        qs = parse_qs(p.query)
        assert qs['state'] == [res['state']]
        # PKCE stuff
        assert 'code_challenge' in qs
        assert qs["code_challenge_method"] == ["S256"]
Пример #16
0
    def client_registration_setup(self, request, new_id=True, set_secret=True):
        try:
            request.verify()
        except (MessageException, ValueError) as err:
            return ResponseMessage(error="invalid_configuration_request",
                                   error_description="%s" % err)

        request.rm_blanks()
        try:
            self.match_client_request(request)
        except CapabilitiesMisMatch as err:
            return ResponseMessage(
                error="invalid_request",
                error_description="Don't support proposed %s" % err,
            )

        _context = self.endpoint_context
        if new_id:
            # create new id och secret
            client_id = rndstr(12)
            # cdb client_id MUST be unique!
            while client_id in _context.cdb:
                client_id = rndstr(12)
            if "client_id" in request:
                del request["client_id"]
        else:
            client_id = request.get("client_id")
            if not client_id:
                raise ValueError("Missing client_id")

        _cinfo = {"client_id": client_id, "client_salt": rndstr(8)}

        if "registration_read" in self.endpoint_context.endpoint:
            self.add_registration_api(_cinfo, client_id, _context)

        if new_id:
            _cinfo["client_id_issued_at"] = utc_time_sans_frac()

        client_secret = ""
        if set_secret:
            client_secret = self.add_client_secret(_cinfo, client_id, _context)

        logger.debug(
            "Stored client info in CDB under cid={}".format(client_id))

        _context.cdb[client_id] = _cinfo
        _cinfo = self.do_client_registration(
            request,
            client_id,
            ignore=["redirect_uris", "policy_uri", "logo_uri", "tos_uri"],
        )
        if isinstance(_cinfo, ResponseMessage):
            return _cinfo

        args = dict([(k, v) for k, v in _cinfo.items()
                     if k in RegistrationResponse.c_param])

        comb_uri(args)
        response = RegistrationResponse(**args)

        # Add the client_secret as a symmetric key to the key jar
        if client_secret:
            _context.keyjar.add_symmetric(client_id, str(client_secret))

        logger.debug(
            "Stored updated client info in CDB under cid={}".format(client_id))
        logger.debug("ClientInfo: {}".format(_cinfo))
        _context.cdb[client_id] = _cinfo

        # Not all databases can be sync'ed
        if hasattr(_context.cdb, "sync") and callable(_context.cdb.sync):
            _context.cdb.sync()

        msg = "registration_response: {}"
        logger.info(msg.format(sanitize(response.to_dict())))

        return response