def make_entity_statement(iss, root_dir='.', sub=""): kj = KeyJar() if iss.startswith('https://'): iss_id = iss iss = iss[len("https://"):] else: iss_id = "https://{}".format(iss) _jwks = read_info(os.path.join(root_dir, iss), iss, "jwks") kj.import_jwks(_jwks, iss_id) if not sub: sub = iss if sub.startswith('https://'): sub_id = sub sub = sub[len("https://"):] else: sub_id = "https://{}".format(sub) _jwks = read_info(os.path.join(root_dir, iss), sub, "jwks") kj.import_jwks(_jwks, sub_id) metadata = read_info(os.path.join(root_dir, iss), sub, "metadata") policy = read_info(os.path.join(root_dir, iss), sub, "policy") _auth = get_authority_hints(iss, sub, root_dir) if _auth: _jwt = create_entity_statement(iss_id, sub_id, kj, metadata, policy, _auth) else: _jwt = create_entity_statement(iss_id, sub_id, kj, metadata, policy) return _jwt
def create_entity_statement(self, sub, **kwargs): _info = self.gather_info(sub) _info.update(kwargs) if sub.startswith("https"): return create_entity_statement(self.make_entity_id(self.iss), unquote_plus(sub), self.keyjar, **_info) return create_entity_statement(self.make_entity_id(self.iss), self.make_entity_id(sub), self.keyjar, **_info)
def test_create_self_signed(): metadata = { "application_type": "web", "claims": ["sub", "name", "email", "picture"], "id_token_signing_alg_values_supported": ["RS256", "RS512"], "redirect_uris": ["https://foodle.uninett.no/callback"], "response_types": ["code"] } iss = "https://example.com" sub = iss key_jar = build_keyjar(KEYSPEC, issuer_id=iss) authority = ["https://ntnu.no"] _jwt = create_entity_statement(iss, sub, key_jar, metadata=metadata, authority_hints=authority) assert _jwt _verifier = factory(_jwt) keys = key_jar.get_jwt_verify_keys(_verifier.jwt) res = _verifier.verify_compact(keys=keys) assert res assert res['iss'] == iss assert res['sub'] == sub assert set(res.keys()) == { 'metadata', 'iss', 'exp', 'sub', 'iat', 'authority_hints', 'jwks' }
def entity_statement_with_x5c(): metadata = { "application_type": "web", "claims": ["sub", "name", "email", "picture"], "id_token_signing_alg_values_supported": ["RS256", "RS512"], "redirect_uris": ["https://foodle.uninett.no/callback"], "response_types": ["code"] } iss = "https://example.com" sub = iss key_jar = build_keyjar(KEYSPEC, issuer_id=iss) authority = ["https://ntnu.no"] with open(os.path.join(BASE_PATH, "cert.pem")) as fp: pems = fp.read() _x5c_val = pems_to_x5c([pems]) _jws = create_entity_statement(iss, sub, key_jar, metadata=metadata, authority_hints=authority, x5c=_x5c_val) return _jws
def create_entity_statement(self, iss, sub, key_jar=None, metadata=None, metadata_policy=None, authority_hints=None, lifetime=0, jwks=None, **kwargs): if jwks: kwargs["jwks"] = jwks else: if "keys" in kwargs: kwargs["jwks"] = {'keys': kwargs["keys"]} del kwargs["keys"] key_jar = key_jar or self.keyjar if not authority_hints: authority_hints = self.authority_hints if not lifetime: lifetime = self.default_lifetime return create_entity_statement(iss, sub, key_jar=key_jar, metadata=metadata, metadata_policy=metadata_policy, authority_hints=authority_hints, lifetime=lifetime, **kwargs)
def test_signed_someone_else_metadata(): metadata = { "application_type": "web", "claims": ["sub", "name", "email", "picture"], "id_token_signing_alg_values_supported": ["RS256", "RS512"], "redirect_uris": ["https://foodle.uninett.no/callback"], "response_types": ["code"] } iss = "https://example.com" sub = "https://foo.example.org/rp" sub_key_jar = build_keyjar(KEYSPEC, issuer_id=sub) iss_key_jar = build_keyjar(KEYSPEC, issuer_id=iss) iss_key_jar.import_jwks_as_json( sub_key_jar.export_jwks_as_json(issuer_id=sub), issuer_id=sub) sub_key_jar.import_jwks_as_json( iss_key_jar.export_jwks_as_json(issuer_id=iss), issuer_id=iss) authority = { "https://core.example.com": ["https://federation.example.org"] } _jwt = create_entity_statement(iss, sub, iss_key_jar, metadata=metadata, authority_hints=authority) assert _jwt _verifier = factory(_jwt) keys = sub_key_jar.get_jwt_verify_keys(_verifier.jwt) res = _verifier.verify_compact(keys=keys) assert res assert res['iss'] == iss assert res['sub'] == sub assert set(res.keys()) == { 'metadata', 'iss', 'exp', 'sub', 'iat', 'authority_hints', 'jwks' }
def create_entity_statement(self, iss, sub, key_jar=None, metadata=None, metadata_policy=None, authority_hints=None, lifetime=0, **kwargs): if not key_jar: key_jar = self.keyjar if not authority_hints: authority_hints = self.authority_hints if not lifetime: lifetime = self.default_lifetime return create_entity_statement(iss, sub, key_jar=key_jar, metadata=metadata, metadata_policy=metadata_policy, authority_hints=authority_hints, lifetime=lifetime, **kwargs)
def create(iss, sub, domain, root_dir): kj = KeyJar() if iss.startswith("https://{}/".format(domain)): iss_id = iss iss = iss[len("https://{}/".format(domain)):] elif iss.startswith("https://"): iss_id = iss iss = iss[len("https://")] else: iss_id = "https://{}/{}".format(domain, iss) iss_jwks_file = os.path.join(root_dir, iss, "{}.jwks.json".format(iss)) kj.import_jwks_as_json(open(iss_jwks_file).read(), iss_id) if sub.startswith("https://{}/".format(domain)): sub_id = sub sub = sub[len("https://{}/".format(domain)):] elif sub.startswith("https://"): sub_id = sub sub = sub[len("https://"):] else: sub_id = "https://{}/{}".format(domain, sub) sub_jwks_file = os.path.join(root_dir, iss, "{}.jwks.json".format(sub)) kj.import_jwks_as_json(open(sub_jwks_file).read(), sub_id) metadata_file = os.path.join(root_dir, iss, "{}.metadata.json".format(sub)) if os.path.isfile(metadata_file): metadata = json.loads(open(metadata_file).read()) else: metadata = None if metadata: for typ, conf in metadata.items(): for key, val in conf.items(): if '<DOMAIN>' in val: metadata[typ][key] = val.replace('<DOMAIN>', domain) policy_file = os.path.join(root_dir, iss, "{}.policy.json".format(sub)) if os.path.isfile(policy_file): policy = json.loads(open(policy_file).read()) else: policy = None authority_file = os.path.join(root_dir, iss, "{}.authority.json".format(sub)) if os.path.isfile(authority_file): _auth = json.loads(open(authority_file).read()) for key, vals in _auth.items(): if '<DOMAIN>' in key: _key = key.replace('<DOMAIN>', domain) _vals = [v.replace('<DOMAIN>', domain) for v in vals] del _auth[key] _auth[_key] = _vals _jwt = create_entity_statement(iss_id, sub_id, kj, metadata, policy, _auth) else: _jwt = create_entity_statement(iss_id, sub_id, kj, metadata, policy) return _jwt