def public_jwks_bundle(eids): jb_copy = JWKSBundle('') for eid in eids: jwks = ENTITY[eid].signing_keys_as_jwks() kj_copy = KeyJar() kj_copy.import_jwks(jwks, eid) jb_copy.bundle[eid] = kj_copy return jb_copy
def public_jwks_bundle(jwks_bundle): jb_copy = JWKSBundle('') for fo, kj in jwks_bundle.bundle.items(): kj_copy = KeyJar() for owner in kj.owners(): public_keys_keyjar(kj, owner, kj_copy, owner) jb_copy.bundle[fo] = kj_copy return jb_copy
def test_dump_load(): jb = make_jwks_bundle('', ['fo0', 'fo1', 'fo2', 'fo3'], None, KEYDEFS) bs = jb.dumps() receiver = JWKSBundle('') receiver.loads(bs) assert len(receiver.keys()) == 4 assert set(receiver.keys()) == {'fo0', 'fo1', 'fo2', 'fo3'}
def test_set_del_get(): bundle = JWKSBundle(ISS, SIGN_KEYS) bundle['https://www.swamid.se'] = KEYJAR['https://www.swamid.se'] bundle['https://www.sunet.se'] = KEYJAR['https://www.sunet.se'] bundle['https://www.feide.no'] = KEYJAR['https://www.feide.no'] del bundle['https://www.sunet.se'] assert set( bundle.keys()) == {'https://www.swamid.se', 'https://www.feide.no'}
def test_update_metadata_statement(): make_signing_sequence(['https://op.sunet.se', 'https://sunet.se', 'https://swamid.sunet.se'], ENTITY) op = ENTITY['https://op.sunet.se'] metadata_statement = MetadataStatement(foo='bar') metadata_statement = op.update_metadata_statement(metadata_statement) assert metadata_statement assert set(metadata_statement.keys()) == {'foo', 'metadata_statements'} swamid = ENTITY['https://swamid.sunet.se'] # on the RP side rp = FederationEntityOOB(None, 'https://rp.sunet.se') # Need the FO bundle, which in this case only needs Swamid's key jb = JWKSBundle('https://rp.sunet.se') _kj = KeyJar() _kj.import_jwks(swamid.self_signer.public_keys(), swamid.iss) jb['https://swamid.sunet.se'] = _kj rp.jwks_bundle = jb l = rp.get_metadata_statement(metadata_statement, MetadataStatement, 'discovery') assert l[0].iss == 'https://op.sunet.se' assert l[0].fo == 'https://swamid.sunet.se' assert l[0].le == {'foo':'bar'}
def test_set_jwks(): bundle = JWKSBundle(ISS, SIGN_KEYS) bundle['https://www.sunet.se'] = KEYJAR[ 'https://www.sunet.se'].export_jwks(private=True) _kj = KEYJAR['https://www.sunet.se'].copy() _kj.issuer_keys['https://www.sunet.se'] = _kj.issuer_keys[''] del _kj.issuer_keys[''] assert bundle['https://www.sunet.se'] == _kj
def test_sign_verify(): bundle = JWKSBundle(ISS, SIGN_KEYS) bundle['https://www.swamid.se'] = KEYJAR['https://www.swamid.se'] bundle['https://www.sunet.se'] = KEYJAR['https://www.sunet.se'] bundle['https://www.feide.no'] = KEYJAR['https://www.feide.no'] _jws = bundle.create_signed_bundle() bundle2 = JWKSBundle(ISS2) verify_keys = public_keys_keyjar(SIGN_KEYS.copy(), '', None, ISS) bundle2.upload_signed_bundle(_jws, verify_keys) assert set(bundle.keys()) == set(bundle2.keys()) # Again can't compare straight off because bundle contains private keys # while bundle2 contains the public equivalents. for iss, kj in bundle.items(): assert len(kj.get_issuer_keys(iss)) == len( bundle2[iss].get_issuer_keys(iss))
def test_set_get(): bundle = JWKSBundle(ISS, SIGN_KEYS) bundle['https://www.swamid.se'] = KEYJAR['https://www.swamid.se'] # When imported the key in issuer_keys are changed from '' to the issuer ID _kj = KEYJAR['https://www.swamid.se'].copy() _kj.issuer_keys['https://www.swamid.se'] = _kj.issuer_keys[''] del _kj.issuer_keys[''] _sekj = bundle['https://www.swamid.se'] assert _sekj == _kj
def fo_member(*args): """ Anonymous member of a set of federations. Used to parse compounded metadata statements. :param args: The federations :return: An Operator instance """ _jb = JWKSBundle('https://sunet.se/op') for fo in args: _jb[fo.iss] = fo.signing_keys_as_jwks() return Operator(jwks_bundle=_jb)
def test_get_metadata_statement(): jb = JWKSBundle('') for iss in ['https://example.org/', 'https://example.com/']: jb[iss] = build_keyjar(KEYDEFS)[1] self_signer = InternalSigningService(keyjar=jb['https://example.com/'], iss='https://example.com/') op = Operator(self_signer=self_signer, iss='https://example.com/') req = MetadataStatement(foo='bar') sms = op.pack_metadata_statement(req, sign_alg='RS256') sms_dir = {'https://example.com': sms} req['metadata_statements'] = Message(**sms_dir) ent = FederationEntity(None, fo_bundle=public_jwks_bundle(jb)) loe = ent.get_metadata_statement(req) assert loe
def test_dumps_loads(): bundle = JWKSBundle(ISS, SIGN_KEYS) bundle['https://www.swamid.se'] = KEYJAR['https://www.swamid.se'] bundle['https://www.sunet.se'] = KEYJAR['https://www.sunet.se'] bundle['https://www.feide.no'] = KEYJAR['https://www.feide.no'] _str = bundle.dumps() fp = open('bundle.json', 'w') fp.write(_str) fp.close() bundle2 = JWKSBundle(ISS, SIGN_KEYS) bundle2.loads(_str) # bundle contains private keys # bundle2 contains the public keys # This comparision could be made better for fo, kj in bundle.items(): assert len(kj.get_issuer_keys(fo)) == len( bundle2[fo].get_issuer_keys(fo))
def test_add_sms_spec_to_request(): jb = JWKSBundle('') for iss in ['https://example.org/', 'https://example.com/']: jb[iss] = build_keyjar(KEYDEFS)[1] kj = build_keyjar(KEYDEFS)[1] sign_serv = InternalSigningService('https://signer.example.com', keyjar=kj) ent = FederationEntityOOB(None, self_signer=sign_serv, fo_bundle=public_jwks_bundle(jb), context='response') ent.metadata_statements = { 'response': { 'https://example.org/': 'https://example.org/sms1' } } req = MetadataStatement(foo='bar') ent.add_sms_spec_to_request(req, ['https://example.org/']) assert 'metadata_statement_uris' in req
def test_create(): bundle = JWKSBundle(ISS, SIGN_KEYS) assert bundle
SYMKEY = rndstr(16) TOOL_ISS = 'https://localhost' ALL = [ 'https://swamid.sunet.se', 'https://www.feide.no', 'https://sunet.se', 'https://uninett.no', 'https://sunet.se/op', 'https://foodle.uninett.no' ] _path = os.path.realpath(__file__) root_dir, _fname = os.path.split(_path) FEDENT = create_federation_entities(ALL, KEYDEFS, root_dir=root_dir) fo_keybundle = JWKSBundle('') for iss in ['https://swamid.sunet.se', 'https://www.feide.no']: kj = KeyJar() kj.import_jwks(FEDENT[iss].signing_keys_as_jwks(), iss) fo_keybundle[iss] = kj SUNET_OP = FEDENT['https://sunet.se/op'] ORG_SUNET = FEDENT['https://sunet.se'] SWAMID = FEDENT['https://swamid.sunet.se'] FOODLE = FEDENT['https://foodle.uninett.no'] FEIDE = FEDENT['https://www.feide.no'] UNINETT = FEDENT['https://uninett.no'] class DB(object): def __init__(self):
}] ALL = [ 'https://fo.example.org', 'https://fo1.example.org', 'https://org.example.org', 'https://inter.example.org', 'https://admin.example.org', 'https://ligo.example.org', 'https://op.example.org' ] _path = os.path.realpath(__file__) root_dir, _fname = os.path.split(_path) FEDENT = create_federation_entities(ALL, KEYDEFS, root_dir=root_dir) FOP = FEDENT['https://fo.example.org'] FOP.jwks_bundle = JWKSBundle(FOP.iss) FOP.jwks_bundle[FOP.iss] = FOP.self_signer.keyjar FO1P = FEDENT['https://fo1.example.org'] FO1P.jwks_bundle = JWKSBundle(FO1P.iss) FO1P.jwks_bundle[FO1P.iss] = FO1P.self_signer.keyjar ORGOP = FEDENT['https://org.example.org'] ADMINOP = FEDENT['https://admin.example.org'] INTEROP = FEDENT['https://inter.example.org'] LIGOOP = FEDENT['https://ligo.example.org'] OPOP = FEDENT['https://op.example.org'] def clear_metadata_statements(entities): for fedent in entities:
def make_federation_entity(config, eid='', httpcli=None, verify_ssl=True): """ Construct a :py:class:`fedoidcmsg.entity.FederationEntity` instance based on given configuration. :param config: Federation entity configuration :param eid: Entity ID :param httpcli: A http client instance to use when sending HTTP requests :param verify_ssl: Whether TLS/SSL certificates should be verified :return: A :py:class:`fedoidcmsg.entity.FederationEntity` instance """ args = {} if not eid: try: eid = config['entity_id'] except KeyError: pass if 'self_signer' in config: self_signer = make_internal_signing_service(config['self_signer'], eid) args['self_signer'] = self_signer try: bundle_cnf = config['fo_bundle'] except KeyError: pass else: _args = dict([(k, v) for k, v in bundle_cnf.items() if k in KJ_SPECS]) if _args: _kj = init_key_jar(**_args) else: _kj = None if 'dir' in bundle_cnf: jb = FSJWKSBundle(eid, _kj, bundle_cnf['dir'], key_conv={ 'to': quote_plus, 'from': unquote_plus }) else: jb = JWKSBundle(eid, _kj) args['fo_bundle'] = jb for item in ['context', 'entity_id', 'fo_priority', 'mds_owner']: try: args[item] = config[item] except KeyError: pass if 'entity_id' not in args: args['entity_id'] = eid # These are mutually exclusive if 'sms_dir' in config: args['sms_dir'] = config['sms_dir'] return FederationEntityOOB(httpcli, iss=eid, **args) elif 'mds_service' in config: args['verify_ssl'] = verify_ssl args['mds_service'] = config['mds_service'] return FederationEntityAMS(httpcli, iss=eid, **args) elif 'mdss_endpoint' in config: args['verify_ssl'] = verify_ssl # These are mandatory for this type of entity for key in ['mdss_endpoint', 'mdss_owner', 'mdss_keys']: args[key] = config[key] return FederationEntitySwamid(httpcli, iss=eid, **args)