def test_example_1(self): _symkey = KC_SYM_S.get(alg2keytype("HS256")) csr = CheckSessionRequest(id_token=IDTOKEN.to_jwt( key=_symkey, algorithm="HS256", lifetime=300)) keyjar = KeyJar() keyjar.add_kb(ISS, KC_SYM_S) assert csr.verify(keyjar=keyjar)
def store_signed_jwks(keyjar, sign_keyjar, path, alg, iss=''): _jwks = keyjar.export_jwks() _jws = JWS(_jwks, alg=alg) _jwt = _jws.sign_compact( sign_keyjar.get_signing_key(owner=iss, key_type=alg2keytype(alg))) fp = open(path, 'w') fp.write(_jwt) fp.close()
def test_example(self): _symkey = KC_SYM_S.get(alg2keytype("HS256")) csr = CheckSessionRequest(id_token=IDTOKEN.to_jwt( key=_symkey, algorithm="HS256", lifetime=300)) keyjar = KeyJar() keyjar.add_kb('', KC_SYM_S) with pytest.raises(ValueError): assert csr.verify(keyjar=keyjar)
def get_signing_key_from_keyjar(algorithm, service_context): """ Pick signing key based on signing algorithm to be used :param algorithm: Signing algorithm :param service_context: A :py:class:`oidcservice.service_context.ServiceContext` instance :return: A key """ return service_context.keyjar.get_signing_key(alg2keytype(algorithm), alg=algorithm)
def unpack_signed_jwt(self, sjwt, sig_alg=""): _jwt = factory(sjwt) if _jwt: if sig_alg: alg = sig_alg else: alg = self.kwargs["signing_alg"] sign_keys = self.server_get("endpoint_context").keyjar.get_signing_key(alg2keytype(alg)) _info = _jwt.verify_compact(keys=sign_keys, sigalg=alg) return _info else: raise ValueError("Not a signed JWT")
def _get_key_by_kid(kid, algorithm, service_context): """ Pick a key that matches a given key ID and signing algorithm. :param kid: Key ID :param algorithm: Signing algorithm :param service_context: A :py:class:`oidcservice.service_context.ServiceContext` instance :return: A matching key """ _key = service_context.keyjar.get_key_by_kid(kid) if _key: ktype = alg2keytype(algorithm) if _key.kty != ktype: raise MissingKey("Wrong key type") return _key raise MissingKey("No key with kid:%s" % kid)
def _get_signing_key(self, algorithm, context, kid=None): ktype = alg2keytype(algorithm) try: if kid: signing_key = [self._get_key_by_kid(kid, algorithm, context)] elif ktype in context.kid["sig"]: try: signing_key = [ self._get_key_by_kid(context.kid["sig"][ktype], algorithm, context) ] except KeyError: signing_key = self.get_signing_key_from_keyjar( algorithm, context) else: signing_key = self.get_signing_key_from_keyjar( algorithm, context) except (MissingKey, ) as err: LOGGER.error("%s", sanitize(err)) raise return signing_key
def test_example(self): _symkey = KC_SYM_S.get(alg2keytype("HS256")) esreq = EndSessionRequest(id_token_hint=IDTOKEN.to_jwt( key=_symkey, algorithm="HS256", lifetime=300), redirect_url="http://example.org/jqauthz", state="state0") request = EndSessionRequest().from_urlencoded(esreq.to_urlencoded()) keyjar = KeyJar() for _key in _symkey: keyjar.add_symmetric('', _key.key) keyjar.add_symmetric(ISS, _key.key) keyjar.add_symmetric(CLIENT_ID, _key.key) request.verify(keyjar=keyjar) assert isinstance(request, EndSessionRequest) assert set(request.keys()) == { verified_claim_name('id_token_hint'), 'id_token_hint', 'redirect_url', 'state' } assert request["state"] == "state0" assert request[verified_claim_name("id_token_hint")]["aud"] == [ "client_1" ]
def do_client_registration(self, request, client_id, ignore=None): if ignore is None: ignore = [] _context = self.endpoint_context _cinfo = _context.cdb[client_id].copy() logger.debug("_cinfo: %s" % sanitize(_cinfo)) for key, val in request.items(): if key not in ignore: _cinfo[key] = val if "post_logout_redirect_uris" in request: plruri = [] for uri in request["post_logout_redirect_uris"]: if urlparse(uri).fragment: err = ClientRegistrationErrorResponse( error="invalid_configuration_parameter", error_description="post_logout_redirect_uris " "contains " "fragment") return err base, query = splitquery(uri) if query: plruri.append((base, parse_qs(query))) else: plruri.append((base, query)) _cinfo["post_logout_redirect_uris"] = plruri if "redirect_uris" in request: try: ruri = self.verify_redirect_uris(request) _cinfo["redirect_uris"] = ruri except InvalidRedirectURIError as e: return ClientRegistrationErrorResponse( error="invalid_redirect_uri", error_description=str(e)) if "sector_identifier_uri" in request: try: _cinfo["si_redirects"], _cinfo[ "sector_id"] = self._verify_sector_identifier(request) except InvalidSectorIdentifier as err: return ResponseMessage(error="invalid_configuration_parameter", error_description=err) elif "redirect_uris" in request: if len(request["redirect_uris"]) > 1: # check that the hostnames are the same host = "" for url in request["redirect_uris"]: part = urlparse(url) _host = part.netloc.split(":")[0] if not host: host = _host else: try: assert host == _host except AssertionError: return ResponseMessage( error="invalid_configuration_parameter", error_description="'sector_identifier_uri' " "must be registered") for item in ["policy_uri", "logo_uri", "tos_uri"]: if item in request: if verify_url(request[item], _cinfo["redirect_uris"]): _cinfo[item] = request[item] else: return ResponseMessage( error="invalid_configuration_parameter", error_description="%s pointed to illegal URL" % item) # Do I have the necessary keys for item in [ "id_token_signed_response_alg", "userinfo_signed_response_alg" ]: if item in request: if request[item] in _context.provider_info[ PREFERENCE2PROVIDER[item]]: ktyp = alg2keytype(request[item]) # do I have this ktyp and for EC type keys the curve if ktyp not in ["none", "oct"]: _k = [] for iss in ['', _context.issuer]: _k.extend( _context.keyjar.get_signing_key( ktyp, alg=request[item], owner=iss)) if not _k: logger.warning('Lacking support for "{}"'.format( request[item])) del _cinfo[item] t = {'jwks_uri': '', 'jwks': None} for item in ['jwks_uri', 'jwks']: if item in request: t[item] = request[item] try: _context.keyjar.load_keys(client_id, jwks_uri=t['jwks_uri'], jwks=t['jwks']) try: n_keys = len(_context.keyjar[client_id]) msg = "found {} keys for client_id={}" logger.debug(msg.format(n_keys, client_id)) except KeyError: pass except Exception as err: logger.error("Failed to load client keys: %s" % sanitize(request.to_dict())) logger.error("%s", err) logger.debug('Verify SSL: {}'.format(_context.keyjar.verify_ssl)) return ClientRegistrationErrorResponse( error="invalid_configuration_parameter", error_description="%s" % err) return _cinfo
def do_client_registration(self, request, client_id, ignore=None): if ignore is None: ignore = [] _context = self.endpoint_context _cinfo = _context.cdb[client_id].copy() logger.debug("_cinfo: %s" % sanitize(_cinfo)) for key, val in request.items(): if key not in ignore: _cinfo[key] = val if "post_logout_redirect_uris" in request: plruri = [] for uri in request["post_logout_redirect_uris"]: if urlparse(uri).fragment: err = ClientRegistrationErrorResponse( error="invalid_configuration_parameter", error_description="post_logout_redirect_uris " "contains " "fragment", ) return err base, query = splitquery(uri) if query: plruri.append((base, parse_qs(query))) else: plruri.append((base, query)) _cinfo["post_logout_redirect_uris"] = plruri if "redirect_uris" in request: try: ruri = self.verify_redirect_uris(request) _cinfo["redirect_uris"] = ruri except InvalidRedirectURIError as e: return ClientRegistrationErrorResponse( error="invalid_redirect_uri", error_description=str(e) ) if "sector_identifier_uri" in request: try: _cinfo["si_redirects"], _cinfo[ "sector_id" ] = self._verify_sector_identifier(request) except InvalidSectorIdentifier as err: return ResponseMessage( error="invalid_configuration_parameter", error_description=str(err) ) for item in ["policy_uri", "logo_uri", "tos_uri"]: if item in request: if verify_url(request[item], _cinfo["redirect_uris"]): _cinfo[item] = request[item] else: return ResponseMessage( error="invalid_configuration_parameter", error_description="%s pointed to illegal URL" % item, ) # Do I have the necessary keys for item in ["id_token_signed_response_alg", "userinfo_signed_response_alg"]: if item in request: if request[item] in _context.provider_info[PREFERENCE2PROVIDER[item]]: ktyp = alg2keytype(request[item]) # do I have this ktyp and for EC type keys the curve if ktyp not in ["none", "oct"]: _k = [] for iss in ["", _context.issuer]: _k.extend( _context.keyjar.get_signing_key( ktyp, alg=request[item], owner=iss ) ) if not _k: logger.warning( 'Lacking support for "{}"'.format(request[item]) ) del _cinfo[item] t = {"jwks_uri": "", "jwks": None} for item in ["jwks_uri", "jwks"]: if item in request: t[item] = request[item] # if it can't load keys because the URL is false it will # just silently fail. Waiting for better times. _context.keyjar.load_keys(client_id, jwks_uri=t["jwks_uri"], jwks=t["jwks"]) try: n_keys = 0 for kb in _context.keyjar[client_id]: n_keys += len(kb.keys()) msg = "found {} keys for client_id={}" logger.debug(msg.format(n_keys, client_id)) except KeyError: pass return _cinfo
def get_signing_key_from_keyjar(self, algorithm, service_context=None): return service_context.keyjar.get_signing_key(alg2keytype(algorithm), "", alg=algorithm)