def verify(self, **kwargs): super(LogoutToken, self).verify(**kwargs) if 'nonce' in self: raise MessageException('"nonce" is prohibited from appearing in ' 'a LogoutToken.') # Check the 'events' JSON _keys = list(self['events'].keys()) if len(_keys) != 1: raise ValueError('Must only be one member in "events"') if _keys[0] != "http://schemas.openid.net/event/backchannel-logout": raise ValueError('Wrong member in "events"') if self['events'][_keys[0]] != {}: raise ValueError('Wrong member value in "events"') # There must be either a 'sub' or a 'sid', and may contain both if not ('sub' in self or 'sid' in self): raise ValueError('There MUST be either a "sub" or a "sid"') try: if kwargs['aud'] not in self['aud']: raise NotForMe('Not among intended audience') except KeyError: pass try: if kwargs['iss'] != self['iss']: raise NotForMe('Wrong issuer') except KeyError: pass _now = utc_time_sans_frac() try: _skew = kwargs['skew'] except KeyError: _skew = 0 try: _exp = self['iat'] except KeyError: pass else: if self['iat'] > (_now + _skew): raise ValueError('Invalid issued_at time') _allowed = kwargs.get("allowed_sign_alg") if _allowed and self.jws_header['alg'] != _allowed: _msg = "Wrong token signing algorithm, {} != {}".format( self.jws_header['alg'], kwargs["allowed_sign_alg"]) raise UnsupportedAlgorithm(_msg) return True
def verify_id_token(msg, check_hash=False, claim="id_token", **kwargs): # Try to decode the JWT, checks the signature args = {} for arg in ID_TOKEN_VERIFY_ARGS: try: args[arg] = kwargs[arg] except KeyError: pass _jws = jws_factory(msg[claim]) if not _jws: raise ValueError("{} not a signed JWT".format(claim)) if _jws.jwt.headers["alg"] == "none": _signed = False _sign_alg = kwargs.get("sigalg") if _sign_alg == "none": _allowed = True else: # There might or might not be a specified signing alg if kwargs.get("allow_sign_alg_none", False) is False: logger.info("Signing algorithm None not allowed") raise UnsupportedAlgorithm("Signing algorithm None not allowed") else: _signed = True if "allowed_sign_alg" in kwargs: if _jws.jwt.headers["alg"] != kwargs["allowed_sign_alg"]: _msg = "Wrong token signing algorithm, {} != {}".format( _jws.jwt.headers["alg"], kwargs["allowed_sign_alg"] ) logger.error(_msg) raise UnsupportedAlgorithm(_msg) _body = _jws.jwt.payload() if _signed and "keyjar" in kwargs: try: if _body["iss"] not in kwargs["keyjar"]: logger.info("KeyJar issuers: {}".format(kwargs["keyjar"])) raise ValueError('Unknown issuer: "{}"'.format(_body["iss"])) except KeyError: raise MissingRequiredAttribute("iss") idt = IdToken().from_jwt(str(msg[claim]), **args) if not idt.verify(**kwargs): return False if _signed and check_hash: _alg = idt.jws_header["alg"] hfunc = "HS" + _alg[-3:] if "access_token" in msg: if "at_hash" not in idt: raise MissingRequiredAttribute("Missing at_hash property", idt) if idt["at_hash"] != left_hash(msg["access_token"], hfunc): raise AtHashError("Failed to verify access_token hash", idt) if "code" in msg: if "c_hash" not in idt: raise MissingRequiredAttribute("Missing c_hash property", idt) if idt["c_hash"] != left_hash(msg["code"], hfunc): raise CHashError("Failed to verify code hash", idt) msg[verified_claim_name(claim)] = idt logger.info("Verified {}: {}".format(claim, idt.to_dict())) return True